Replace the hardcoded static-deploy test port with a kernel-assigned one
ci / svc-realcombo (pull_request) Successful in 2m34s
ci / test (pull_request) Failing after 9m13s
ci / test-pg (pull_request) Successful in 12m42s

Why: test_static_fresh_deploy_registers_pidcheck_and_starts hardcoded
port 18951, so any process already holding that port made svc.sh refuse
to bind (correct behaviour) and the test failed for a reason unrelated to
what it guards. Host reproduced this deterministically: with 18951
occupied the case failed, on a clean host it passed 10/10.

Evidence: fix/svc-static-deploy-test-port-flake @ 4ebf9e1, SELF receipts
7dfe7b09 (target case clean, target case while 18951 is held, whole
tests.test_svc module 23 tests) and the earlier 518-test test-affected
run; independent review session (pi/glm-5.3-flash, fresh process)
concluded PASS.

Impact: tests/test_svc.py only. All eight assertions kept verbatim;
svc.sh is untouched, and the tests/test_svc.py:753-754 register_pg
fixture is deliberately left alone.

Refs: tests/test_svc.py:989
This commit is contained in:
2026-10-21 03:17:12 +00:00
parent 4ebf9e1b47
commit 996cbf07e1
+62 -7
View File
@@ -7,7 +7,7 @@
- 分支类型:standalone;root_target:main;immediate_target:main;accepting_requirements:false
- 需求分流:verdict=NEW;selected_initiative=无;requirement_sha256=9dd8c0eec3933926486dbc7537df17ada16cbe48d6151410626f43be81914353;triage_receipt=/tmp/svc-flaky-triage.json;receipt_sha256=7e0e09ea9fd8067ba091a3b657f7930bac6d5eceb08da1a0a2c86c415a4c2c7a
- 授权与交付终点:<本次允许的动作与终点;未授权事项写明>
- 授权与交付终点:修复 `tests/test_svc.py` 中因硬编码端口导致的偶发失败用例,standalone 直达 main(PR + 完整 CI + 独立 Review)。不含 `scripts/svc.sh` 改动、不含其它用例的端口治理、不含发布/部署。
- 交付模式:goal-first(目标、范围和交付终点一次确认;范围内连续推进)
- 实施执行:agent-per-unit(配置:AGENT-EXECUTION.md)
- 合入执行:agent(已授权交付范围内,Review 通过、冲突解决且当前 HEAD 的 CI 通过后合入)
@@ -15,7 +15,10 @@
## 目标与非目标
<预期结果、受影响入口/模块/契约;明确不做什么。>
- 预期结果:`tests/test_svc.py` 的 `SvcDbRecoveryTests.test_static_fresh_deploy_registers_pidcheck_and_starts` 不再因端口占用而偶发失败;该用例守护的语义(static 首启探活不得把 `http.server` 判成「进程即退」)保持不变。
- 根因(host 确定性复现,非推断):用例第 989 行硬编码 `port = 18951`。只要机器上任何进程占用该端口,`scripts/svc.sh` 的 `check_port_free` 就会正确拒绝(「端口被占用(非本服务)」、退出 1),用例因此失败。host 实测:占用 18951 时该用例稳定失败(`AssertionError: 1 != 0`),不占用时 10/10 通过。
- 受影响面:仅 `tests/test_svc.py`(测试代码)。产品侧 `scripts/svc.sh` 不改——其拒绝占口的行为是正确的。
- 非目标:不改 `scripts/svc.sh`;不改 `tests/test_svc.py:753-754` 的 `register_pg("pg1", 18951, ...)` 夹具(只写 `svc.env` 文本、从不绑端口,与本问题无关);不重构测试类;不新增跨用例端口管理框架(TOCTOU 套件级解法属独立增量)。
## Agent 实施收据
@@ -23,13 +26,17 @@
| 单元 ID | 预期范围 | 配置摘要 | 角色 | 候选顺序 | attempt | CLI/模型 | 终态 | transport | fallback | 源码外收据路径 |
|---|---|---|---|---|---|---|---|---|---|---|
| 待定义 | — | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | NOT_RUN | — |
| svc-static-deploy-test-port-flake | `tests/test_svc.py` 单文件:硬编码端口 → 内核分配空闲端口 | AGENT-EXECUTION.md digest ccceb3bf | implementation | cursor→agy→pi-glm→pi→codex | 1 | cursor(`cursor-agent-stable`,model auto;session f4bd5b1f-6258-48f5-bcbd-442e1f8a66f2) | success | d0b217d3(refs/agent-exec/850b1455f…/5ca3ade8a790),已 `agent-exec apply` 快进入分支 | never | /tmp/svc-flake-run.json |
| review-svc-static-deploy-test-port-flake | 只读审查 | 同上 digest | review | pi-glm→pi→agy→cursor→codex | 1 | pi-glm(`pi`,zai-coding-cn/glm-5.3-flash,session not-observable) | **failed-unknown**(worker exit 0 且只读无改动,控制器不建 transport) | 无 | never | /tmp/svc-flake-review-run.json |
> 第二次 Review 尝试以全新 `pi` CLI 进程(非 `--continue`/`--resume`,fresh session)单独执行,结论 PASS;原始输出 `/tmp/svc-flake-review-final.log`。上表 failed-unknown 一行如实保留:按 policy/delivery.md,该终态不得计为门禁 Review。
## 同步记录
| 节点 | sync_base_sha | tested_head_sha | checked_at |
|---|---|---|---|
| 启动 | a9566a68505ac97dead15ed3b5672954f15cea1c | a9566a68505ac97dead15ed3b5672954f15cea1c | 2026-10-21T02:38:22Z |
| 合入前同步 | a496ea0f0249b2b412354677ef97612ccd692d25 | 4ebf9e1b47edb701541f57a72020b31d9e3fb323 | 2026-10-21T03:16:00Z |
## 证据(Evidence)
@@ -39,14 +46,21 @@
## 结果与验证(完成后填写)
- 结果:
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
- 结果:`tests/test_svc.py:989` 的硬编码 `port = 18951` 换成 `socket.bind(("127.0.0.1", 0))` 内核分配空闲端口(3 增 1 删,单文件单 hunk)。用例的 8 条断言一条未删未弱化。
- 验证:
- PASS|目标用例在干净主机通过(被测 HEAD 4ebf9e1,SELF,收据 7dfe7b09)
- PASS|**目标用例在旧硬编码端口 18951 被外部进程占用时仍通过**——这是修复的决定性一腿;同一场景在修复前确定性失败
- PASS|`tests.test_svc` 全模块 23 项 OK(被测 HEAD 4ebf9e1,SELF,收据 7dfe7b09)
- PASS|`make test-affected BASE=main` 全量 518 项 OK(被测 HEAD d0b217d3,SELF;同步后非卡片变更触发 WARN,该收据按治理规则作废并以 4ebf9e1 重跑,见上)
- NOT_RUN|交付信任所需的精确 HEAD CI(`test`/`test-pg`/`svc-realcombo`)——合入前由 `make ci-wait` 取得 GATE
- 影响与剩余项:
- 未解决但非阻塞:释放保留端口到 `svc.sh` 真正 bind 之间存在 TOCTOU 窗口。失效模式是响亮失败(`check_port_free` 报错退出),不会静默假绿;且与本仓既有 5 处同类夹具(`test_svc_recover.py:187`、`test_svc.py:366`、`test_task_pr_check.py:100`、`test_task_triage.py:230`、`test_svc_realcombo.py:128`)风险同级。套件级解法属独立增量,不在本任务扩围。
- 本任务不解决「其它用例也硬编码端口」这一更大面上的同类脆弱性;仅记录,不在本任务处理。
## 合入与清理
- Review 记录:NOT_RUN(审阅智能体/平台身份、base/head、结论、问题闭合及重放依据)
- 冲突记录:NOT_RUN(最新目标同步、冲突处置、组合兼容核验及复审/补测)
- Review 记录:PASS。审阅者:独立全新 CLI 会话,`pi`(zai-coding-cn/glm-5.3-flash),非 host 主模型、非实施会话,未使用 `--continue`/`--resume`/既有 session id,session 身份 not-observable。base=origin/main a496ea0f,head=0bd5a4b(同步前)/ 4ebf9e1(同步后)。核对项:动态取端口写法与仓内 5 处既有夹具惯例一致且 `socket` 已在 `:12` 导入;逐条核对 8 条断言未删未弱化;diff 仅 `tests/test_svc.py` 单 hunk,`:753-754` 夹具未动;TOCTOU 与既有惯例同级、非阻塞;无回归面。重放依据:host 已在 4ebf9e1 独立重跑目标用例(含占端口一腿)与全模块,收据 7dfe7b09;审阅原始输出在仓外 `/tmp/svc-flake-review-final.log`。
- 冲突记录:无冲突。合入前同步 `make task-sync` 纳入 origin/main a496ea0f(仅并入另一任务的归档卡与 spec,无代码变更、无组件 pin 变动);同步导致被测 HEAD 变化,关键检查已在 4ebf9e1 重跑。
- CI 记录:NOT_RUN(当前 HEAD 完整 SHA、全部必需检查、运行链接、执行身份及 GATE 结果)
- 合入记录:NOT_RUN(交付授权范围、PR、被核验 HEAD、合入 SHA、目标分支及内容核验)
- 清理记录:NOT_RUN(授权依据、写者退出确认、worktree/分支/任务卡处置)
@@ -132,3 +146,44 @@
}
```
| 同步(记录前对象) | a496ea0f0249b2b412354677ef97612ccd692d25 | bbb9024e9718497adf0d6385f6795cb5c7d9255f | 2026-10-21T03:16:00Z |
<!-- Local receipt: SELF. Digests detect corruption; they do not authenticate a reviewer or CI. -->
```json
{
"summary_schema": 1,
"source": "SELF",
"timestamp": "2026-10-21T03:16:10.154890+00:00",
"command": "sh -c 'set -e; echo \"[1] target test, clean host:\"; PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc.SvcDbRecoveryTests.test_static_fresh_deploy_registers_pidcheck_and_starts 2>&1 | tail -3; echo; echo \"[2] target test while legacy hard-coded port is held:\"; bash /tmp/occupy-port.sh 18951 env PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc.SvcDbRecoveryTests.test_static_fresh_deploy_registers_pidcheck_and_starts 2>&1 | tail -3; echo; echo \"[3] whole module:\"; PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tests.test_svc 2>&1 | tail -3; echo; echo \"[4] port released:\"; (ss -ltn | grep -q \":18951 \" && echo LEAK) || echo released'",
"exit_code": 0,
"cwd": "/home/weichen/projects/Agent-System-Dev-wt-fix-svc-static-deploy-test-port-flake",
"before_head": "4ebf9e1b47edb701541f57a72020b31d9e3fb323",
"after_head": "4ebf9e1b47edb701541f57a72020b31d9e3fb323",
"branch": "fix/svc-static-deploy-test-port-flake",
"target_branch": "main",
"target_head": "a496ea0f0249b2b412354677ef97612ccd692d25",
"root_target": "main",
"immediate_target": "main",
"before_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"after_tracked_diff_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"output_tail": [
"",
"OK",
"",
"[2] target test while legacy hard-coded port is held:",
"Ran 1 test in 0.574s",
"",
"OK",
"",
"[3] whole module:",
"Ran 23 tests in 26.871s",
"",
"OK",
"",
"[4] port released:",
"released"
],
"output_sha256": "41ab6880e27c3f44906b392bbe76d342d1019ae1a2aad0690c2739d691330669",
"receipt_sha256": "7dfe7b09cfcb370d00c0e9a504a8857530b8637d18e1ab7bf2d4e434093bdb33",
"receipt_path": "/home/weichen/.cache/agent-system-dev/evidence/7dfe7b09cfcb370d00c0e9a504a8857530b8637d18e1ab7bf2d4e434093bdb33.json"
}
```