187 lines
9.7 KiB
Markdown
187 lines
9.7 KiB
Markdown
# javaTest 调度闭环完成审计实施计划
|
||
|
||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||
|
||
**Goal:** 在不改变已确认的历史字段和中心选车语义的前提下,补齐路线输入安全、反向活动冲突和历史调度边界的可执行证据,并完成全量验收。
|
||
|
||
**Architecture:** 保留 `RouteCandidatePlanner` 负责地图候选、`RouteQualityEvaluator` 负责同一交通快照下的字典序质量、`HistoricalDispatchSimulator` 负责真实业务闭环。新增约束集中在质量评价入口;新增业务测试使用小型 `HistoricalSimulationInput` 夹具,避免修改 240 条真实历史基线。报告和页面只验证 Java 已产生的证据,不在前端复制算法。
|
||
|
||
**Tech Stack:** Java 8、Maven Surefire、JUnit 5、Jackson、现有 vanilla HTML/JavaScript、Playwright 浏览器 QA。
|
||
|
||
## Global Constraints
|
||
|
||
- 历史 `path_info` 不得作为新规划输入。
|
||
- 历史 `agv_id` 不得强制绑定车辆。
|
||
- `finish_date` 和历史完成状态不得推进仿真完成。
|
||
- 路线质量不使用故障或等待时间。
|
||
- 临时冲突必须 HOLD;只有永久地图不可达才 `NO_ROUTE` 失效关闭。
|
||
- 所有修改限制在 `javaTest`、本审计设计/计划文档和本轮新增测试;保留用户已有 `docs/*.html`。
|
||
- Java 编译目标保持 8,不新增生产依赖。
|
||
|
||
---
|
||
|
||
### Task 1: 锁定路线评价输入和反向活动冲突
|
||
|
||
**Files:**
|
||
- Modify: `javaTest/src/main/java/com/ft546/wcs/demo/traffic/TrafficRouteSnapshot.java`
|
||
- Modify: `javaTest/src/main/java/com/ft546/wcs/demo/traffic/RouteQualityEvaluator.java`
|
||
- Modify: `javaTest/src/test/java/com/ft546/wcs/demo/traffic/RouteQualityEvaluatorTest.java`
|
||
|
||
**Interfaces:**
|
||
- `TrafficRouteSnapshot` 新增包内查询 `hasOppositeActiveRoute(String from, String to, String taskId)`。
|
||
- `RouteQualityEvaluator.evaluate(...)` 继续返回 `RouteQuality`;非法节点、非邻接边或距离不一致时抛 `IllegalArgumentException`。
|
||
|
||
- [x] **Step 1: 写失败测试**
|
||
|
||
增加三个测试:活动路线 `D -> B -> A` 对候选 `A -> B -> D` 计入对向冲突;候选包含未知站点或断边时被拒绝;候选声明距离与地图距离不一致时被拒绝。现有同向活动路线仍只计重合,不重复计对向。
|
||
|
||
- [x] **Step 2: 运行 RED**
|
||
|
||
```bash
|
||
mvn -f javaTest/pom.xml -Dtest=RouteQualityEvaluatorTest test
|
||
```
|
||
|
||
预期新增断言失败或编译失败,证明测试没有被旧实现意外满足。
|
||
|
||
- [x] **Step 3: 实现最小修复**
|
||
|
||
在快照中遍历其他活动路线的有向相邻边,只有 `to -> from` 命中时返回对向;在评价入口调用 `RouteCandidatePlanner.pathDistance(map, path)` 校验路径连续性和距离,使用数值容差 `1e-6`,再执行现有质量元组计算。对已识别的对向边跳过不兼容预约重复计数。
|
||
|
||
- [x] **Step 4: 运行 GREEN**
|
||
|
||
```bash
|
||
mvn -f javaTest/pom.xml -Dtest=RouteQualityEvaluatorTest,RouteCandidatePlannerTest test
|
||
```
|
||
|
||
预期所有路线单测通过,并保留原有确定性、110%边界和候选上限行为。
|
||
|
||
- [x] **Step 5: 提交**
|
||
|
||
```bash
|
||
git add javaTest/src/main/java/com/ft546/wcs/demo/traffic/TrafficRouteSnapshot.java javaTest/src/main/java/com/ft546/wcs/demo/traffic/RouteQualityEvaluator.java javaTest/src/test/java/com/ft546/wcs/demo/traffic/RouteQualityEvaluatorTest.java
|
||
git commit -m "fix(javaTest): validate route quality inputs"
|
||
```
|
||
|
||
### Task 2: 补齐真实调度边界集成测试
|
||
|
||
**Files:**
|
||
- Modify: `javaTest/src/test/java/com/ft546/wcs/shadow/history/simulation/HistoricalDispatchSimulatorTest.java`
|
||
- Modify: `javaTest/src/test/java/com/ft546/wcs/shadow/history/simulation/SimulationTaskQueueTest.java`
|
||
|
||
**Interfaces:**
|
||
- 不新增生产 API;测试通过现有 `HistoricalSimulationInput`、`SimulationConfig` 和 `HistoricalDispatchSimulator.simulate(...)` 验证业务闭环。
|
||
|
||
- [ ] **Step 1: 写未来到达与优先级测试**
|
||
|
||
构造两个站点路线和两条任务:低优先级任务在 `t=0` 到达,高优先级任务在仿真时间 `t=5000` 到达。断言 `t<5000` 的事件中不存在高优先级任务 `ASSIGN`,任务到达后它按优先级先获得 `ASSIGN`;另保留队列 aging 单测证明长期低优先级任务不会饥饿。
|
||
|
||
- [ ] **Step 2: 写无路失效关闭测试**
|
||
|
||
构造已知但被 `GridMap.block(target)` 永久阻断的服务目标,运行模拟并断言该任务为 `FAILED`、reason=`NO_ROUTE`、无 `ASSIGN`/`COMPLETE`,且结果数量仍保持闭环。对未知站点输入继续由 normalizer 形成 `HistoricalDispatchFailure`,断言同样进入明确失败结果而不是等待。
|
||
|
||
- [ ] **Step 3: 写 PLC 重试边界测试**
|
||
|
||
使用现有 `DeterministicFaultPlan` 注入一次 `SEND_FAILURE`,断言任务保持未移动并在后续 tick 产生 `PLC_RETRY`;使用重试上限夹具验证超过上限时 reason 非空且不伪造 `COMPLETED`。
|
||
|
||
- [ ] **Step 4: 运行专项 GREEN**
|
||
|
||
```bash
|
||
mvn -f javaTest/pom.xml -Dtest=HistoricalDispatchSimulatorTest,SimulationTaskQueueTest,HistoricalDispatchFaultMatrixTest test
|
||
```
|
||
|
||
预期新旧测试全部通过;若生产代码行为与测试暴露的状态不一致,先添加最小生产修复,再重新运行同一命令。
|
||
|
||
- [ ] **Step 5: 提交**
|
||
|
||
```bash
|
||
git add javaTest/src/test/java/com/ft546/wcs/shadow/history/simulation/HistoricalDispatchSimulatorTest.java javaTest/src/test/java/com/ft546/wcs/shadow/history/simulation/SimulationTaskQueueTest.java
|
||
git commit -m "test(javaTest): prove history dispatch boundary states"
|
||
```
|
||
|
||
### Task 3: 资源和重规划集成门禁
|
||
|
||
**Files:**
|
||
- Modify: `javaTest/src/test/java/com/ft546/wcs/shadow/history/simulation/CorridorReservationManagerTest.java`
|
||
- Modify: `javaTest/src/test/java/com/ft546/wcs/shadow/history/simulation/HistoricalDispatchSimulatorTest.java`
|
||
- Modify: `javaTest/src/test/java/com/ft546/wcs/shadow/history/simulation/SimulationProgressWatchdogTest.java`
|
||
|
||
**Interfaces:**
|
||
- 保持 `CorridorReservationManager.replaceRoute(...)` 原子接口和 `TrafficHoldTracker` 第三次触发协议不变。
|
||
|
||
- [ ] **Step 1: 锁定旧预约回滚**
|
||
|
||
在替换失败测试中同时断言旧路线每条边仍由原任务持有、其他同向持有者仍存在、没有新路线残留;在成功测试中断言不再使用的旧边释放且共享边保留。
|
||
|
||
- [ ] **Step 2: 锁定 HOLD 集成行为**
|
||
|
||
扩展模拟测试断言第三次相同交通 HOLD 产生一次 `REROUTE_TRIGGER`,失败替换产生 `REROUTE_REJECTED` 且原路线继续执行;成功替换后在下一次 MOVE 前不重复产生普通重规划。
|
||
|
||
- [ ] **Step 3: 锁定死锁 watchdog**
|
||
|
||
增加连续无进展达到阈值才判死锁、未来到达任务不判死锁、车辆 MOVE 后计数清零的测试;确认 `SimulationInvariantSummary.deadlocks` 与异常路径均可追溯。
|
||
|
||
- [ ] **Step 4: 运行专项 GREEN**
|
||
|
||
```bash
|
||
mvn -f javaTest/pom.xml -Dtest=CorridorReservationManagerTest,HistoricalDispatchSimulatorTest,SimulationProgressWatchdogTest,TrafficHoldTrackerTest test
|
||
```
|
||
|
||
- [ ] **Step 5: 提交**
|
||
|
||
```bash
|
||
git add javaTest/src/test/java/com/ft546/wcs/shadow/history/simulation
|
||
git commit -m "test(javaTest): lock reroute and resource safety gates"
|
||
```
|
||
|
||
### Task 4: 报告、API、浏览器和真实负载验收
|
||
|
||
**Files:**
|
||
- Modify only if an acceptance check fails: `javaTest/src/main/java/com/ft546/wcs/shadow/history/visualizer/*`, `javaTest/src/main/resources/visualizer/*`, `javaTest/scripts/visualizer_browser_qa.py`
|
||
- Generated and removed after audit: `javaTest/outputs/acceptance-final`, `javaTest/outputs/browser-qa-final`
|
||
|
||
**Interfaces:**
|
||
- HTTP `GET /api/health` remains `UP/mapLoaded/simulationBusy`.
|
||
- Simulation output remains `summary.json`, `route-decisions.json`, `task-results.csv`, `tick-events.csv`, `invariant-results.json`, `manifest.sha256`.
|
||
|
||
- [ ] **Step 1: Run clean full suite**
|
||
|
||
```bash
|
||
mvn -f javaTest/pom.xml clean test
|
||
```
|
||
|
||
Record the actual Surefire count; never reuse an earlier count.
|
||
|
||
- [ ] **Step 2: Run one fresh 240-task replay**
|
||
|
||
```bash
|
||
mvn -f javaTest/pom.xml compile exec:java "-Dexec.mainClass=com.ft546.wcs.shadow.history.simulation.HistoricalDispatchSimulationApplication" "-Dexec.args=outputs/acceptance-final 100"
|
||
```
|
||
|
||
Parse the generated JSON with a structured parser and assert task totals, per-vehicle totals, route candidate bounds, safety invariants, archive count, WMS idempotence and nonblank failure/HOLD/retry reasons.
|
||
|
||
- [ ] **Step 3: Run browser black-box QA**
|
||
|
||
```bash
|
||
python "C:/Users/13623/.agents/skills/webapp-testing/scripts/with_server.py" --server 'mvn compile exec:java "-Dexec.mainClass=com.ft546.wcs.shadow.history.visualizer.HistoricalDispatchVisualizerApplication" "-Dexec.args=18086"' --port 18086 --timeout 120 -- python scripts/visualizer_browser_qa.py http://127.0.0.1:18086 outputs/browser-qa-final
|
||
```
|
||
|
||
Check desktop and mobile map rendering, route layer visibility, full-map viewport, route evidence and console error count.
|
||
|
||
- [ ] **Step 4: Verify health and repository state**
|
||
|
||
```powershell
|
||
Invoke-RestMethod http://127.0.0.1:18086/api/health
|
||
git status --short
|
||
git diff --check
|
||
```
|
||
|
||
Only pre-existing user `docs/*.html` may remain untracked.
|
||
|
||
- [ ] **Step 5: Commit only implementation/test changes**
|
||
|
||
Use a focused commit for any production fix and a separate commit for tests. Do not stage generated reports or user documents.
|
||
|
||
## Completion Audit
|
||
|
||
Before claiming completion, map every original requirement to fresh evidence: `create_date` admission, priority/aging, vehicle selection, route stages, node/edge/opposite arbitration, HOLD/reroute, PLC retry, MOVE/release, archive/WMS idempotence, fault matrix, no-route closure, report/API/UI evidence, 240-task totals, route quality comparison, timing as operational-only evidence, and offline boundary.
|