2026-09-15 15:28:32 +08:00
|
|
|
|
# 11 模拟测试体系、并发验证与测试沙箱要求 (Testing and Mock Plan)
|
|
|
|
|
|
|
|
|
|
|
|
> **测试最高铁律**:**严禁在持续集成 (CI/CD) 或单元测试中使用真实 DMS 生产环境与真实门锁设备**!
|
|
|
|
|
|
> 门锁下发密码将直接修改物理设备存储并消耗锁端电量与无线频段。
|
|
|
|
|
|
> 必须基于 **本地 Mock HTTP Server (WireMock / MockWebServer)** 搭建完备的多层级可复现测试套件。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. 分层测试策略体系 (Testing Strategy)
|
|
|
|
|
|
|
2026-09-18 09:36:39 +08:00
|
|
|
|
```mermaid
|
|
|
|
|
|
flowchart BT
|
|
|
|
|
|
L1["L1. 纯领域单元测试<br/>Unit Test - CardNumberCodec 编码 / 状态机转换 / DTO 转换"]
|
|
|
|
|
|
L2["L2. 并发与状态机集成测试<br/>Concurrency & State Machine Test - 20并发Token竞争/幂等"]
|
|
|
|
|
|
L3["L3. 契约与故障注入测试<br/>WireMock Failure Injection - 401/超时/宕机/乱序状态"]
|
|
|
|
|
|
L4["L4. 现场沙箱验收测试<br/>Live Sandbox E2E - 独立测试账号 + 实验台独立挂载测试锁"]
|
|
|
|
|
|
|
|
|
|
|
|
L1 --> L2
|
|
|
|
|
|
L2 --> L3
|
|
|
|
|
|
L3 --> L4
|
2026-09-15 15:28:32 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. Mock DMS 仿真覆盖矩阵 (22 项核心场景)
|
|
|
|
|
|
|
|
|
|
|
|
在后续 R.3B 实现阶段,集成测试套件必须基于 Mock 服务器完整覆盖以下 22 项场景:
|
|
|
|
|
|
|
|
|
|
|
|
| # | 测试场景用例 | Mock 桩行为定义 | 预期系统断言与表现 |
|
|
|
|
|
|
| :-: | :--- | :--- | :--- |
|
|
|
|
|
|
| 1 | **Login Success** | 返回 200,包含新 Token 与 `expiresIn: 7200` | `DmsTokenManager` 缓存 Token,设置正确到期时间戳 |
|
|
|
|
|
|
| 2 | **Token Cache Reuse** | 连续 10 次请求同一接口 | 仅在第 1 次触发 Mock 登录,后续 9 次请求 Header 均复用相同 Token |
|
|
|
|
|
|
| 3 | **Token Expiry** | 模拟系统时钟快进至失效时间前 5 分钟 | 自动触发平滑预防性刷新,获取新 Token |
|
|
|
|
|
|
| 4 | **Concurrent Token Refresh** | **20 个并发业务线程**同时探测到 Token 缺失/过期 | **单飞排他锁生效**:Mock 登录接口**被且仅被调用 1 次**,20 个线程全部安全复用该 Token,无踩踏覆盖 |
|
|
|
|
|
|
| 5 | **401 Auto Relogin** | 业务请求收到 Mock 返回 `401 Unauthorized` | 自动使缓存失效,触发单飞重登录,并**自动安全重试原请求 1 次且成功** |
|
|
|
|
|
|
| 6 | **Room Lookup Normal** | 精确匹配返回单个房间 `placeId: 1320` | 正常持久化映射记录 |
|
|
|
|
|
|
| 7 | **Room Lookup Not Found** | 返回 `{"success": false, "message": "Room not found!"}` | 抛出 `RoomNotFoundException`,不阻塞其他业务 |
|
|
|
|
|
|
| 8 | **Room Multiple Results** | 模糊查询返回同名房间(多楼层同房号) | 触发精准过滤,若仍有多条抛出歧义异常提醒管理员人工介入 |
|
|
|
|
|
|
| 9 | **Lock Lookup Normal** | 返回房间挂载的 1 把锁 | 绑定该锁并派发授权 |
|
|
|
|
|
|
| 10 | **Lock Lookup Multiple** | 返回房间挂载的 2 把锁(外门+内门) | **一房多锁验证**:为该住宿安排分别生成 2 条授权记录并同时下发 |
|
|
|
|
|
|
| 11 | **Lock Lookup None** | 返回空数组(该房间未装门锁) | 抛出 `LockNotConfiguredException`,状态标记为无锁,不影响入住 |
|
|
|
|
|
|
| 12 | **Password Issue Accepted** | 调用 create 返回 200 + `operationId` | 本地授权状态置为 `ISSUING`,操作记录置为 `ACCEPTED`,**不得直接置为 ACTIVE** |
|
|
|
|
|
|
| 13 | **Password Operation Success** | 10 秒后轮询返回 `operationStatus: "success"` | 授权状态正式推进为 `ACTIVE`,操作记录置为 `SUCCESS` |
|
|
|
|
|
|
| 14 | **Password Operation Undone** | 首次轮询返回 `operationStatus: "undone"` | 保持 `ISSUING` 状态,触发第 2 次退避轮询 |
|
|
|
|
|
|
| 15 | **Password Operation Failed** | 轮询返回 `operationStatus: "failed"` | 授权状态置为 `ISSUE_FAILED`,记录详细错误原因 |
|
|
|
|
|
|
| 16 | **Password Operation Timeout** | 轮询返回 `operationStatus: "timeout"` | 轮询上限后停止,状态置为 `ISSUE_FAILED (TIMEOUT)`,页面显示重试按钮 |
|
|
|
|
|
|
| 17 | **Card Issue & Codec** | 下发 10 进制卡号 `3161082660` | 验证 Mock 实际收到的 Body 中 `cardNumber` 为小端序 `244B6ABC` |
|
|
|
|
|
|
| 18 | **Revoke Flow** | 调房或退宿时调用 delete 接口 | 正确携带 `external_key_id`,轮询成功后状态置为 `REVOKED` |
|
|
|
|
|
|
| 19 | **DMS Unavailable** | Mock 服务断开或返回 HTTP 500/502 | **住宿业务事务正常提交完成**,门禁状态置为 `ISSUE_FAILED`,记录故障日志 |
|
|
|
|
|
|
| 20 | **Unknown Result Reconcile** | 发送 create 时遭遇网络读取超时 | 触发未决对账流程,查询当前房间钥匙列表,避免重复发码 |
|
|
|
|
|
|
| 21 | **Idempotent Duplicate Grant** | 连续快速点击 5 次“下发权限” | 本地幂等生效,仅派发 1 次 DMS 请求,无重复钥匙生成 |
|
|
|
|
|
|
| 22 | **Accommodation Transfer** | 学员换房(旧房 A -> 新房 B) | 验证“先发新房 B,确认成功后再撤销旧房 A”的时序与失败补偿 |
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. 关键专项验证测试设计细节
|
|
|
|
|
|
|
|
|
|
|
|
### 3.1 Token 并发竞争专项测试设计 (`Token Concurrency Test`)
|
|
|
|
|
|
```java
|
|
|
|
|
|
// 测试伪代码设计示意 (后续 R.3B 落地至 src/test/java)
|
|
|
|
|
|
@Test
|
|
|
|
|
|
public void testConcurrentLoginDeduplication() throws Exception {
|
|
|
|
|
|
int threadCount = 20;
|
|
|
|
|
|
CountDownLatch startLatch = new CountDownLatch(1);
|
|
|
|
|
|
CountDownLatch doneLatch = new CountDownLatch(threadCount);
|
|
|
|
|
|
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
|
|
|
|
|
|
|
|
|
|
|
|
// 清空当前 Token 缓存
|
|
|
|
|
|
dmsTokenManager.invalidate();
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < threadCount; i++) {
|
|
|
|
|
|
executor.submit(() -> {
|
|
|
|
|
|
try {
|
|
|
|
|
|
startLatch.await(); // 确保 20 个线程在瞬间同时并发冲击
|
|
|
|
|
|
String token = dmsTokenManager.getToken();
|
|
|
|
|
|
assertThat(token).isNotBlank();
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
doneLatch.countDown();
|
|
|
|
|
|
}
|
|
|
|
|
|
});
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
startLatch.countDown(); // 发令枪响
|
|
|
|
|
|
doneLatch.await(10, TimeUnit.SECONDS);
|
|
|
|
|
|
|
|
|
|
|
|
// 严苛断言:Mock 服务端的登录接口在整个并发过程中被调用的次数必须精确为 1!
|
|
|
|
|
|
wireMockServer.verify(1, postRequestedFor(urlEqualTo("/public/rest/third-party-app/token/get")));
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3.2 异步状态生命周期防抢跑断言 (`Async Anti-Premature Test`)
|
|
|
|
|
|
- **断言目标**:杜绝将 HTTP 200 直接视为下发成功。
|
|
|
|
|
|
- **验证步骤**:
|
|
|
|
|
|
1. 调用 `doorAccessGateway.grantAccess(...)`。
|
|
|
|
|
|
2. 立即检查数据库中的 `train_dorm_auth` 记录:
|
|
|
|
|
|
- 断言 `auth_status == ISSUING`(下发中)。
|
|
|
|
|
|
- 断言绝不能等于 `ACTIVE`。
|
|
|
|
|
|
3. 执行一次调度轮询(此时 Mock 返回 `operationStatus = undone`):
|
|
|
|
|
|
- 断言 `auth_status` 依然维持在 `ISSUING`。
|
|
|
|
|
|
4. 执行第二次调度轮询(此时 Mock 返回 `operationStatus = success`):
|
|
|
|
|
|
- 断言 `auth_status` 顺利跃迁为 `ACTIVE`。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. 生产环境接入前联调沙箱要求 (`DMS_SANDBOX_REQUIREMENTS`)
|
|
|
|
|
|
|
|
|
|
|
|
在未来正式将 RailwaySystem 部署到沈阳房建公寓段并对接真实门锁前,**必须向 DMS 供应商及公寓设备管理方书面申请独立测试沙箱环境**。
|
|
|
|
|
|
|
|
|
|
|
|
### 4.1 核心沙箱准入条件
|
|
|
|
|
|
1. **独立测试租户**:必须提供专属的测试用 `appid`、`appsecret` 及 `projectId`,严禁与正在运行的既有公寓楼共用租户。
|
|
|
|
|
|
2. **物理实验台测试锁具**:
|
|
|
|
|
|
- 必须在实验台/机房单独架设 **至少 1 台测试网关 + 2 把独立挂载的测试智能门锁**。
|
|
|
|
|
|
- 严禁直接使用学员已经实际入住的宿舍门锁进行研发调试!
|
|
|
|
|
|
3. **测试数据隔离**:
|
|
|
|
|
|
- 在 DMS 中建立虚拟楼栋(如“联调测试楼”),配置测试房间(如“9901室”、“9902室”)。
|
|
|
|
|
|
4. **技术支撑配合**:
|
|
|
|
|
|
- 供应商提供联调期间的技术接口人,并确认正式环境网络是否具备固定公网 IP 白名单或专网通道。
|
2026-09-16 10:22:50 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. Wave 1 Implementation Result (Wave 1 implemented)
|
|
|
|
|
|
- **阶段状态**:Wave 1 implemented。
|
|
|
|
|
|
- **新增自动化测试清单**:
|
|
|
|
|
|
1. `ExternalResourceMappingServiceTest.java` (10 项测试,涵盖 A 到 I 全部场景及 A2 跨资源类型同 ID 合法共存场景)。
|
|
|
|
|
|
2. `ExternalOperationServiceTest.java` (12 项测试,涵盖 A 到 J 全部场景、K 场景 REVOKE 成功达成 SUCCESS 终态与 L 场景非法 REVOKED 操作状态抛错校验)。
|
|
|
|
|
|
3. `ExternalResourceOperationMigrationContractTest.java` (7 项静态契约测试:表名、外键、局部唯一索引、幂等键索引、无破坏性语句、无敏感字段、多字段组合联合唯一性校验)。
|
|
|
|
|
|
- **全量测试指标**:
|
|
|
|
|
|
- 基线测试数:174 项。
|
|
|
|
|
|
- 新增测试数:29 项(10 + 12 + 7)。
|
|
|
|
|
|
- 当前测试总数:203 项(ruoyi-train: 175 项,ruoyi-admin: 28 项),Failures = 0, Errors = 0, Skipped = 0。
|
|
|
|
|
|
- Maven `clean test` 与 `clean package` 顺利构建成功。
|
|
|
|
|
|
- **迁移验证与准入标记**:
|
|
|
|
|
|
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`
|
|
|
|
|
|
- `008_RUNTIME_SECOND_RUN = NOT_EXECUTED`
|
|
|
|
|
|
- `008_CONTRACT_TEST = PASS`
|
|
|
|
|
|
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`
|
|
|
|
|
|
- 明确声明:008 迁移脚本已通过静态语法与结构契约测试(Contract Test PASS),未在实际生产库或非隔离库执行;在投产前必须在隔离 Kingbase 实例执行双跑准入门禁。
|
2026-09-16 10:58:29 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. Wave 2 Implementation Result (Wave 2 implemented against Mock DMS only)
|
|
|
|
|
|
- **阶段状态**:Wave 2 implemented against Mock DMS only。
|
|
|
|
|
|
- **新增自动化测试清单 (26 项)**:
|
|
|
|
|
|
1. `DmsTokenManagerTest.java` (4 项):
|
|
|
|
|
|
- `testTokenConcurrency_SingleFlightLogin` (20 线程并发获取 Token,单飞登录仅 1 次,所有线程获取相同 Token)。
|
|
|
|
|
|
- `testTokenRefresh_SingleFlightRefresh` (推进时间至提前刷新窗口,20 线程并发单飞刷新,旧 Token 废弃)。
|
|
|
|
|
|
- `testSuccessfulApiExtendsLocalTtl` (成功调用 API 触发滑动延展本地有效期限)。
|
|
|
|
|
|
- `testAuthFailureRecovery_NoLoginStorm` (401 集中失效自愈,无并发 login storm)。
|
|
|
|
|
|
2. `DmsHttpClientTest.java` (3 项):
|
|
|
|
|
|
- `testMutationAmbiguity_NoAutoRetryOnTimeout` (写操作读取超时坚决不自动重试,`passwordCreatePostCounter = 1`)。
|
|
|
|
|
|
- `testTokenTransport_CookieHeader` (验证请求注入 `Cookie: token=...`,严禁 `Bearer`)。
|
|
|
|
|
|
- `testSensitiveDataRedaction` (密码明文、Token、Secret 全局脱敏断言)。
|
|
|
|
|
|
3. `DmsLocationAdapterTest.java` (1 项):
|
|
|
|
|
|
- `testLocationLookup_FullHierarchy` (建筑、楼层、房间完整层级查询与 placeId 解析)。
|
|
|
|
|
|
4. `DmsDoorLockAdapterTest.java` (2 项):
|
|
|
|
|
|
- `testZeroLock_ReturnsEmptyList` (0 把锁场景正常返回空列表,非 NPE,非假锁)。
|
|
|
|
|
|
- `testMultiLock_ReturnsAllLocks` (多把锁场景完整返回全部 3 把门锁)。
|
|
|
|
|
|
5. `DmsPasswordAdapterTest.java` (4 项):
|
|
|
|
|
|
- `testCreateOnlinePassword_Success` (正常下发 6 位限时密码,获得 keyId 与 operationId)。
|
|
|
|
|
|
- `testCreateOnlinePassword_ValidRanges` (支持 4~8 位范围内的合法密码)。
|
|
|
|
|
|
- `testCreateOnlinePassword_InvalidFormatsRejected` (非法格式参数拦截)。
|
|
|
|
|
|
- `testDeleteOnlinePassword_Success` (删除在线密码成功返回 operationId)。
|
|
|
|
|
|
6. `DmsOperationStatusAdapterTest.java` (4 项):
|
|
|
|
|
|
- `testQueryOperationStatus_FromMock` (查询门锁操作状态)。
|
|
|
|
|
|
- `testStatusMapper_AllKnownTransitions` (success->SUCCESS, undone->PENDING, failed->FAILED, timeout->TIMEOUT)。
|
|
|
|
|
|
- `testStatusMapper_UnknownStatusNeverSuccess` (未知状态映射为 UNKNOWN,绝非 SUCCESS)。
|
|
|
|
|
|
- `testStatusMapper_TerminalStatusIdentification` (终态识别判定)。
|
|
|
|
|
|
7. `DmsOperationPollerTest.java` (6 项):
|
|
|
|
|
|
- `testSafeDefaults_DisabledPollerDoesNothing` (安全默认:enabled=false 绝不执行轮询)。
|
|
|
|
|
|
- `testPollFlow_ReachesSuccess` (轮询流转到 SUCCESS 终态)。
|
|
|
|
|
|
- `testPollFlow_ReachesFailed` (轮询流转到 FAILED 终态)。
|
|
|
|
|
|
- `testPollFlow_ReachesTimeout` (轮询流转到 TIMEOUT 终态)。
|
|
|
|
|
|
- `testPollFlow_PendingUndoneRetained` (设备 undone 保持 PENDING 并延展时间)。
|
|
|
|
|
|
- `testTerminalStateProtection_NeverRewritten` (终态记录不可篡改)。
|
|
|
|
|
|
8. `DmsAsyncLifecycleAndSecurityTest.java` (2 项):
|
|
|
|
|
|
- `testAcceptedNotEqualsSuccess_LifecycleVerification` (核心验证:HTTP 200 仅为 ACCEPTED,轮询成功后才为 SUCCESS)。
|
|
|
|
|
|
- `testCredentialDataLeak_ZeroPlaintextStorage` (反射断言持久化实体绝无密码明文属性)。
|
|
|
|
|
|
- **全量测试指标**:
|
|
|
|
|
|
- 基线测试数:203 项。
|
|
|
|
|
|
- 新增测试数:26 项。
|
|
|
|
|
|
- 当前测试总数:229 项(ruoyi-train: 201 项,ruoyi-admin: 28 项),Failures = 0, Errors = 0, Skipped = 0。
|
|
|
|
|
|
- Maven `clean test` 与 `clean package` 顺利构建成功。
|
|
|
|
|
|
- **环境纪律与迁移标记**:
|
|
|
|
|
|
- `LIVE_DMS_REQUEST_COUNT = 0`
|
|
|
|
|
|
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`
|
|
|
|
|
|
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`
|
2026-09-16 11:21:21 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. Wave 3A Implementation Result (Wave 3A implemented against Mock DMS only)
|
|
|
|
|
|
- **阶段状态**:Wave 3A Access Authorization Orchestration Dry-Run implemented against Mock DMS only。
|
|
|
|
|
|
- **新增测试用例清单 (共计新增 18 项,全量总计 251 项)**:
|
|
|
|
|
|
1. `DormAuthorizationOrchestrationMigrationContractTest.java` (4 项):
|
|
|
|
|
|
- `testMigrationFileExistsAndNamedCorrectly` (009 脚本命名与唯一编号校验)。
|
|
|
|
|
|
- `testIdempotency_AlterTableAddColumnIfNotExists` (ALTER TABLE ADD COLUMN IF NOT EXISTS 幂等静态断言)。
|
|
|
|
|
|
- `testSafety_NoPlaintextSecretColumns` (静态审计脚本绝无 password/secret 明文存储列)。
|
|
|
|
|
|
- `testSafety_NoDestructiveDdlOrDml` (静态审计脚本绝无 DROP/TRUNCATE 等破坏性语句)。
|
|
|
|
|
|
2. `AccessAuthorizationOrchestrationTest.java` (9 项):
|
|
|
|
|
|
- `testScenarioA_AccommodationFirstThenReportConfirm` (先分配宿舍,后报到确认:报到确认前 WAITING,报到确认后 GRANT,Poller 确认后推进 ACTIVE)。
|
|
|
|
|
|
- `testScenarioB_ReportConfirmFirstThenAccommodation` (先报到确认,后分配宿舍:初次对账 WAITING,分房后 GRANT,Poller 确认后推进 ACTIVE)。
|
|
|
|
|
|
- `testReconciliationIdempotency_NoDuplicateOperations` (ACTIVE 状态下重复触发 5 次对账,无新增授权、无重复发码)。
|
|
|
|
|
|
- `testGrantFailureScenario_RetryGeneratesNewOperation` (设备执行 FAILED,状态置为 ERROR,重试对账安全创建全新操作流水,旧 FAILED 留存)。
|
|
|
|
|
|
- `testRevokeLifecycle_OnEnrollmentTermination` (退训/结训触发主动撤权,下发成功先为 REVOKING,Poller 确认后成为 REVOKED)。
|
|
|
|
|
|
- `testTransfer_GrantNewThenRevokeOld` (调房安全时序:新房 Grant 成功且 ACTIVE 后,才发起旧房 Revoke)。
|
|
|
|
|
|
- `testTransferFailure_PreservesOldRoomAccess` (新房 Grant 失败时,旧房授权严格保持 ACTIVE,杜绝学员无门可进)。
|
|
|
|
|
|
- `testLockSelectionPolicy_PrimaryLockOnly` (Least Privilege:0 主锁阻断、1 主锁放行、2 主锁配置错误阻断、次锁不自动发码)。
|
|
|
|
|
|
- `testStaleOperationProtection_NeverOverwritesNewState` (防迟到覆盖保护:旧操作迟到结果绝不覆盖已推进的新授权状态)。
|
|
|
|
|
|
3. `BusinessTransactionIndependenceTest.java` (5 项):
|
|
|
|
|
|
- `testSecurePasswordGenerator` (验证 SecureRandom 强随机、6 位数字生成,杜绝弱密码)。
|
|
|
|
|
|
- `testSensitiveDataScans_ZeroPlaintextPasswordPersistence` (实体字段、toString、Operation 流水敏感数据全要素防泄露扫描)。
|
|
|
|
|
|
- `testReportConfirmExternalFailureRollback_IsNo` (报到业务事务独立性:DMS 崩溃超时时报到确认主流程成功,`REPORT_CONFIRM_EXTERNAL_FAILURE_ROLLBACK = NO`)。
|
|
|
|
|
|
- `testAccommodationCheckout_ExternalRevokeFailureDoesNotRollback` (退宿业务事务独立性:DMS 撤权失败不影响退宿完成)。
|
|
|
|
|
|
- `testPlanComplete_ExternalRevokeFailureDoesNotRollback` (结训业务事务独立性:结训归档在 DMS 失败下仍成功提交)。
|
|
|
|
|
|
- **全量测试指标**:
|
|
|
|
|
|
- 旧测试基线:233 项。
|
|
|
|
|
|
- 新增测试数:18 项。
|
|
|
|
|
|
- 当前测试总数:251 项(ruoyi-train: 219 项,ruoyi-admin: 32 项),Failures = 0, Errors = 0, Skipped = 0。
|
|
|
|
|
|
- Maven `clean test` 与 `clean package` 全部成功。
|
|
|
|
|
|
- **环境与安全纪律**:
|
|
|
|
|
|
- `LIVE_DMS_REQUEST_COUNT = 0`(全量测试连接 MockDmsServer,真实 DMS 调用严格为 0)。
|
|
|
|
|
|
- `FRONTEND_MODIFIED = 0`,`CONTROLLER_COUNT = 0`。
|
|
|
|
|
|
- `008_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`008_RUNTIME_SECOND_RUN = NOT_EXECUTED`。
|
|
|
|
|
|
- `009_RUNTIME_FIRST_RUN = NOT_EXECUTED`,`009_RUNTIME_SECOND_RUN = NOT_EXECUTED`。
|
|
|
|
|
|
- `RUNTIME_MIGRATION_GATE_BEFORE_PRODUCTION = REQUIRED`。
|