Camunda 7 旧引擎兼容性测试套件 qa/test-old-engine 实战指南:用旧版本引擎验证新数据库 Schema,为滚动升级保驾护航
【免费下载链接】camunda-bpm-platformCamunda 7 CE is End of Life (EoL). Please check out Camunda 8 instead (https://github.com/camunda/camunda) or read about Camunda 7 Enterprise End of Life (https://camunda.com/blog/2025/02/camunda-7-enterprise-end-of-life-extension/) – Camunda 7 CE was a flexible framework for workflow and decision automation using BPMN and DMN.项目地址: https://gitcode.com/GitHub_Trending/ca/camunda-bpm-platform
导读
本文以 Camunda BPM Platform 仓库中的 qa/test-old-engine/README.md 为骨架,完整讲解这套"旧引擎 + 新数据库 Schema"兼容性测试套件的设计动机、构建流程与运行方式。你将掌握:为什么 Camunda 需要用上一个版本的引擎去跑当前版本建出来的数据库表结构、如何通过两条 Maven 命令把整套测试跑起来、以及 pom.xml 中每一条关键配置背后的工程意图。读完即可在自己的环境中复现该测试,并理解滚动升级(Rolling Upgrade)场景下的兼容性保障逻辑。
为什么需要"旧引擎跑新 Schema":滚动升级的兼容性前提
Camunda 7 的升级路径有两种典型形态:
- 停机升级(Downtime Upgrade):停掉所有引擎,执行数据库升级脚本,再启动新版本引擎。
- 滚动升级(Rolling Upgrade):在集群中分批替换引擎节点,新、旧版本引擎在升级窗口期内会同时连接同一套数据库。此时数据库 Schema 可能已经先被升级到了新版本(或部分节点还在用旧版本代码),因此必须保证:旧版本的引擎能够在新版本的数据库 Schema 上正常读写。
qa/test-old-engine/README.md 开门见山地点明了本测试套件的核心目标:
This test suite tests the engine of the last version with the current database schema. This guarantees that an old engine can execute on a newer database schema, which is needed for rolling upgrades.
翻译过来就是:用上一个发布版本的引擎(即"旧引擎"),去连接当前版本建出来的数据库 Schema,跑完引擎自带的全量测试用例,从而证明"旧引擎在新 Schema 上可以执行"。
从 qa/test-old-engine/pom.xml 可以看到具体的版本配对:
camunda.old.engine.version = 7.23.0:旧引擎版本(上一个社区版发布);- 项目自身版本为
7.24.0-SNAPSHOT:当前正在开发的版本,其对应的 SQL 脚本代表"当前数据库 Schema"。
同时,pom.xml 的 description 也提示了项目状态:7.24.0 是 Camunda 7 社区版在 Maven Central 上的最后一个发布版本,本模块不会再发布新版本;如需长期维护可关注企业版。这意味着该套件在当前仓库中更多承担的是"收官前的最后一道兼容性验证"职责。
测试套件的整体架构
本模块位于 qa/test-old-engine 目录,Maven 坐标为org.camunda.bpm.qa:camunda-qa-old-engine,模块名为 "Camunda Platform - QA - test new schema with old engine"。
它的整体思路可以用三步概括:
- 引入旧引擎的测试代码:通过 Maven 依赖把旧版本(7.23.0)
camunda-engine的test-jar解压到当前构建中,作为本模块的测试源码执行; - 引入新版本的 SQL 脚本:通过
camunda-sql-scripts(当前版本)的test-jar拿到最新建表脚本; - 用新 Schema 跑旧测试:先用最新脚本建库建表,再让旧引擎的测试用例在这套 Schema 上运行,最后清理数据库。
模块目录结构如下:
qa/test-old-engine/ ├── README.md # 本测试套件的使用说明 ├── pom.xml # 构建与测试配置 ├── config/ │ ├── camunda.cfg.xml # 引擎测试默认配置(Spring Bean 形式) │ └── org/camunda/bpm/engine/test/ │ └── concurrency/ │ └── historycleanup.camunda.cfg.xml # 历史清理并发测试专用配置 └── clear.authorization.table.sql # 清理授权表的辅助 SQL默认被跳过的模块:distro Profile
一个容易被忽略的细节是 pom.xml 中的distroprofile 默认激活(activeByDefault=true),它会通过maven-surefire-plugin设置skipTests=true。也就是说,在普通构建中本模块的测试是被默认跳过的,只有在显式激活old-engineprofile 时才会真正执行测试。这也是 qa/pom.xml 中把test-old-engine模块挂到old-engineprofile 下的原因——整个套件必须"显式点名"才会运行。
前置准备:构建数据库 SQL 脚本
旧引擎测试需要当前版本的数据库 SQL 脚本(建表、删表、升级脚本)。这些脚本由 distro/sql-script 模块负责打包,因此在运行测试之前,必须先构建该模块。
按 README.md 的说明,构建命令为:
cd camunda-bpm-platform/distro/sql-script mvn clean installcamunda-sql-scripts模块(artifactId 为camunda-sql-scripts)在构建时完成以下工作(详见 distro/sql-script/pom.xml):
- 通过
maven-dependency-plugin解压当前版本camunda-engineJAR 中org/camunda/bpm/engine/db下的原始 SQL 资源(如 engine/src/main/resources/org/camunda/bpm/engine/db/create/activiti.h2.create.engine.sql); - 用
maven-antrun-plugin把 engine、case engine、decision engine、history、case history、decision history 等零散的 create/drop 脚本按数据库类型拼接成{db}_engine_{version}.sql形式的完整脚本(例如h2_engine_7.24.0-SNAPSHOT.sql),同时复制 identity 脚本、upgrade 脚本与 liquibase 脚本; - 通过
maven-jar-plugin的test-jargoal 生成test-jar,把拼接好的脚本连同 patch 文件打进测试包,供下游的test-old-engine模块以依赖方式解压使用。
也就是说,这一步产出的camunda-sql-scriptstest-jar 正是后文"新 Schema"脚本的来源,务必在跑测试前先执行。
运行测试:命令与参数详解
标准 Maven 命令
在构建完 SQL 脚本后,按 README.md 的说明执行:
mvn clean install -Pold-engine,${DATABASE}其中-Pold-engine激活旧引擎测试 profile,${DATABASE}是数据库类型对应的 profile 名。以 H2 为例:
mvn clean install -Pold-engine,h2使用 Maven Wrapper 从项目根目录运行
如果不想依赖本机全局 Maven,可以从仓库根目录直接用mvnw运行(README 原文):
./mvnw clean install -f qa/test-old-engine/pom.xml -Pold-engine,${database-id}其中${database-id}例如h2。-f参数显式指定构建文件,因此这条命令不要求先进入模块目录,在仓库根目录即可执行。
数据库类型 profile
${database-id}/${DATABASE}支持仓库中定义的各种数据库类型,从 SQL 脚本的拼接规则(见 distro/sql-script/pom.xml)可以看出,至少包括:h2、mysql、postgres、oracle、mssql、db2。不同的数据库 profile 会通过database.type属性解析出对应的建表/删表脚本(详见下文 SQL 执行阶段),因此理论上同一套验证逻辑可以覆盖 Camunda 支持的所有数据库方言。
注意:H2 是最轻量、最常用于快速验证的选择;MySQL 等外部数据库还需要确保对应数据库实例可用,且连接参数(URL、驱动、账号密码)由 config/camunda.cfg.xml 中的
${database.*}占位符注入。
构建流程逐步解析:从解压依赖到执行测试
pom.xml 的old-engineprofile 完整描述了测试生命周期中的每一步,可以拆解为四个阶段。
阶段一:解压旧引擎测试套件
<execution> <id>unpack-engine-tests</id> <phase>generate-test-sources</phase> ... <artifactItem> <groupId>org.camunda.bpm</groupId> <artifactId>camunda-engine</artifactId> <version>${camunda.old.engine.version}</version> <!-- 7.23.0 --> <type>test-jar</type> <outputDirectory>${project.build.directory}/test-classes</outputDirectory> </artifactItem> </execution>maven-dependency-plugin在generate-test-sources阶段解压7.23.0 旧版引擎的 test-jar到测试类目录,旧引擎的测试类因此直接成为本模块的测试源码。同时 pom.xml 把testSourceDirectory指向${project.build.directory}/engine-test-sources,确保解压出的测试类被 surefire 正确识别。
阶段二:解压当前版本 SQL 脚本
<execution> <id>unpack-new-scripts</id> <phase>generate-test-sources</phase> ... <artifactItem> <groupId>org.camunda.bpm.distro</groupId> <artifactId>camunda-sql-scripts</artifactId> <version>${project.version}</version> <!-- 7.24.0-SNAPSHOT --> <type>test-jar</type> <outputDirectory>${project.build.directory}/scripts-current</outputDirectory> <overWrite>true</overWrite> </artifactItem> </execution>这一步把前置构建好的当前版本SQL 脚本 test-jar 解压到target/scripts-current,作为"新 Schema"的脚本源。旧引擎(7.23.0)+ 新脚本(7.24.0-SNAPSHOT)的组合由此正式成型。
阶段三:SQL 生命周期管理(建表前清理 → 建表 → 测试后清理)
sql-maven-plugin定义了三个执行点,构成了完整的数据库生命周期:
| 执行点 | 触发阶段 | 作用 |
|---|---|---|
drop-db-if-present | generate-test-resources | 用sql/drop/{db}_engine_{version}.sql和sql/drop/{db}_identity_{version}.sql清理可能残留的旧表,onError=continue容忍"表不存在"类错误,autocommit=true保证逐条生效 |
create-new-schema | generate-test-resources | 用sql/create/{db}_engine_{version}.sql和sql/create/{db}_identity_{version}.sql创建当前版本的完整 Schema(含引擎表与身份认证表) |
drop-db | post-integration-test | 测试结束后再次删除引擎表和身份表,保证测试环境可重复、无污染 |
脚本路径中的{db}即${database.type}(如h2),{version}即${project.version}(如7.24.0-SNAPSHOT)。正是这套"先删后建、测完再删"的编排,保证了旧引擎测试始终运行在一套全新、干净且属于当前版本的数据库 Schema 之上。
阶段四:Surefire 执行旧引擎测试
surefire负责实际执行测试,其配置体现了两个关键工程决策:
- JVM 参数:
-Xmx2g、-Duser.language=en -Duser.region=US、-XX:+HeapDumpOnOutOfMemoryError以及--add-opens=java.base/java.util=ALL-UNNAMED等(见 pom.xml),为旧引擎测试在较新 JDK 上稳定运行提供保障; redirectTestOutputToFile=true:测试输出重定向到文件,避免海量日志淹没终端,便于事后排查。
测试引擎配置解析:camunda.cfg.xml
本模块的测试引擎配置以 Spring Bean 形式定义在 config/camunda.cfg.xml 中,采用StandaloneProcessEngineConfiguration。这份配置非常值得逐项研读,因为它直接反映了"旧引擎连接新 Schema"测试场景下的工程取舍:
| 配置项 | 取值 | 含义与测试意图 |
|---|---|---|
jdbcUrl/jdbcDriver/jdbcUsername/jdbcPassword | ${database.*} | 由构建时注入的数据库连接参数,保证测试可针对任意目标数据库运行 |
databaseSchemaUpdate | keep-your-hands-off-my-database | 核心配置:禁止引擎自动建表或改表。Schema 已由 SQL 脚本在测试前建好,引擎必须原样使用,从而真正检验"旧引擎在新 Schema 上的兼容性",而不是让引擎自说自话地建一套旧表 |
jobExecutorActivate | false | 关闭 Job Executor,避免异步任务与测试竞态 |
dbMetricsReporterActivate/taskMetricsEnabled | false | 关闭数据库指标上报与任务指标,减少测试噪音 |
mailServerPort | ${mail.server.port} | 邮件相关测试(如邮件发送任务)使用的本地 SMTP 端口 |
history | full | 开启完整历史记录,确保历史数据相关的测试用例可运行 |
jdbcBatchProcessing | false | 关闭 JDBC 批量处理,规避旧引擎与新版驱动/方言在批处理上的兼容性问题,保证行为可预期 |
enforceHistoryTimeToLive | false | 不强制历史数据 TTL,避免清理任务干扰测试 |
其中databaseSchemaUpdate的取值keep-your-hands-off-my-database(字面意思"别碰我的数据库")是全套测试的灵魂:旧引擎必须老老实实读写新 Schema,而不是试图把它改回自己熟悉的模样。
历史清理并发测试的专用配置
除了默认配置,模块还提供了 config/org/camunda/bpm/engine/test/concurrency/historycleanup.camunda.cfg.xml,它在默认配置基础上额外设置了:
bpmnStacktraceVerbose=false:关闭 BPMN 堆栈详细输出;historyCleanupBatchWindowStartTime=16:00:将历史清理批处理窗口固定为 16:00,为历史清理相关的并发测试提供确定性的时间窗口。
这份配置通过 pom.xml 的 testResources 规则(config目录启用资源过滤,同时排除camunda.cfg.xml与historycleanup.camunda.cfg.xml不被打入 jar)与解压出的旧引擎测试资源协同工作,让旧引擎测试用例能找到并加载自己需要的引擎配置。
被排除的测试类及其原因
旧引擎测试并非"原样全跑",pom.xml 中维护了一份经过长期迭代沉淀的排除清单,每一类排除都有明确的工程理由:
- 与旧引擎场景不兼容的资源依赖:如
ProcessDiagramRetrievalTest、ProcessDiagramParseTest、ConnectionPersistenceExceptionTest——这些测试需要的资源文件不在旧引擎 classpath 中; - 与新 Schema 验证目的冲突:如
SchemaLogEnsureSqlScriptTest——它验证的是"脚本与 Schema 日志一致",而旧引擎测试恰恰是"旧引擎跑新 Schema",语义相悖,必须排除; - 已知在其他版本修复的历史问题:如
RepeatingServiceTaskTest、MultiTenancyHistoricProcessInstanceReportCmdTenantCheckTest(4 个用例在后续 patch 版本中才修复); - 依赖较新依赖库的行为:如
AsyncEmailTaskTest、EmailSendTaskTest、EmailServiceTaskTest(commons-email 1.5 升级影响)、CompetingMessageCorrelationTest(仅在 mysql profile 下排除); - 功能已移除或环境不匹配:如
ConcurrentTelemetryConfigurationTest(telemetry 功能已移除)、DatabaseNamingConsistencyTest(缺少必要资源文件); - 与数据库无关的历史遗留:如
ClassPathScannerTest、WSDLImporterTest、JobExecutorTest、HistoricTaskInstanceUpdateTest、ManagementServiceTableCountTest(各自关联历史 JIRA 问题或与旧引擎场景无关)。
此外,exclude-post-jdk15-testsprofile(JDK 15+ 自动激活)会额外排除所有*NashornTest.java,因为 Nashorn 脚本引擎自 JDK 15 起已从 JDK 中移除——这保证了旧引擎测试在较新 JDK 上依然可编译、可运行。
这份排除清单本身就是一份宝贵的兼容性知识库:它精确记录了"旧版本在何种边界条件下无法与新版共处",对判断滚动升级风险窗口极具参考价值。
辅助资源:授权表清理脚本
模块根目录还提供了一个辅助 SQL 脚本 clear.authorization.table.sql,内容为:
DELETE FROM ACT_RU_AUTHORIZATION;它用于在测试过程中或测试前清理运行时授权表ACT_RU_AUTHORIZATION。由于本模块的测试会创建用户、组与授权数据,若授权数据残留到下一轮测试,可能触发权限校验失败(例如CompetingMessageCorrelationTest这类涉及多租户/权限的用例)。该脚本是测试排障与重复运行时的实用工具。
与滚动升级测试套件的分工
本模块与同仓库的 qa/test-db-rolling-update/README.md 描述的另一套测试(-Prolling-update,${DATABASE},5 步流程:建旧 Schema → 旧引擎造数据 → 升级 Schema → 新引擎续跑 → 旧引擎再验证)互为补充:
- test-db-rolling-update:模拟"旧 Schema → 新 Schema"的完整升级路径,既验证数据迁移正确性,也验证新旧引擎在同一数据上的读写;
- test-old-engine(本文):直接构造"新 Schema + 旧引擎"的静态组合,把旧引擎的整套测试用例跑一遍,从功能回归层面兜底兼容性。
前者验证"升级动作本身",后者验证"升级后仍存续的旧节点"。两者结合,才构成了 Camunda 对滚动升级场景的完整测试覆盖。
运行注意事项与限制
- 必须先构建 SQL 脚本模块:
distro/sql-script的 test-jar 是测试的前置依赖,未构建会直接导致依赖解析失败(README 明确强调了这一步)。 - 必须显式激活 profile:默认的
distroprofile 会跳过测试,只有-Pold-engine(以及对应的数据库 profile)才会真正执行,切勿以为"构建成功"就等于"测试通过"。 - 数据库环境前提:除 H2 外,MySQL、PostgreSQL、Oracle、MSSQL、DB2 等数据库 profile 需要预先准备可用实例,连接参数通过
${database.*}注入 config/camunda.cfg.xml。 - JDK 版本:JDK 15+ 环境下 Nashorn 相关测试会被自动排除,JVM 参数中的
--add-opens项是为兼容较新 JDK 的模块系统限制而设置。 - 项目生命周期:如 pom.xml 所述,Camunda 7 社区版已停止演进(7.24.0 为最后一个社区版),本模块不会再随新版本发布;该套件对当前仓库而言,是 7.x 系列滚动升级兼容性验证的收官之作。
小结
qa/test-old-engine通过"旧引擎(7.23.0)+ 新 Schema(7.24.0-SNAPSHOT)"的组合方式,用最朴素也最彻底的手段回答了滚动升级中最关键的问题——旧节点在升级窗口期内能否安全地读写新数据库。整条链路(SQL 脚本构建 → 依赖解压 → 建库建表 → 旧测试执行 → 环境清理)均由 Maven 编排,可一键复现;其camunda.cfg.xml中的keep-your-hands-off-my-database配置、精心维护的测试排除清单,以及与之互补的 test-db-rolling-update 套件,共同构成了 Camunda 面向生产环境升级场景的工程化验证体系。对于正在规划 Camunda 7 升级路径或自行维护 Camunda 分支的团队,这套测试的思路与配置都极具借鉴价值。
【免费下载链接】camunda-bpm-platformCamunda 7 CE is End of Life (EoL). Please check out Camunda 8 instead (https://github.com/camunda/camunda) or read about Camunda 7 Enterprise End of Life (https://camunda.com/blog/2025/02/camunda-7-enterprise-end-of-life-extension/) – Camunda 7 CE was a flexible framework for workflow and decision automation using BPMN and DMN.项目地址: https://gitcode.com/GitHub_Trending/ca/camunda-bpm-platform
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考