Merge authoritative main into the task branch
Why: include the current integration baseline before verification. Evidence: fetched origin/main=5aebedebeb963b5c01f39fd9122ec60dbe6d34d3. Impact: integrate upstream changes without rewriting task history. Refs: task-sync
This commit is contained in:
@@ -409,15 +409,25 @@ jobs:
|
||||
GIT_CONFIG_VALUE_2 GIT_CONFIG_KEY_3 GIT_CONFIG_VALUE_3
|
||||
unset SUBMODULE_TOKEN
|
||||
make -C rdm build
|
||||
- name: Real-combination identity gates over real PostgreSQL (U3, required)
|
||||
- name: Install Node 22
|
||||
run: |
|
||||
set -euo pipefail
|
||||
curl -fsSL -o "$RUNNER_TEMP/node.tar.xz" https://npmmirror.com/mirrors/node/v22.23.3/node-v22.23.3-linux-x64.tar.xz
|
||||
tar -C /usr/local --strip-components=1 -xJf "$RUNNER_TEMP/node.tar.xz"
|
||||
- name: Build the real agent-system binary
|
||||
run: make build
|
||||
- name: Real-combination lifecycle gate (make test-lifecycle, required)
|
||||
env:
|
||||
AGENT_PG_TEST_DSN: postgres://ci_agent:ci_job_local_only@127.0.0.1:5432/agent_test?sslmode=disable
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# 路径变量在脚本内解析(YAML env: 不做 shell 展开)。
|
||||
# 不设 SVC_RDM_ORIGIN:全轨 git 部署由 svc-realcombo 作业覆盖。
|
||||
export SVC_TEST_REAL=1 SVC_TEST_PG=1
|
||||
export SVC_REAL_BIN="$PWD/bin/agent-system"
|
||||
export SVC_REAL_RDM_BIN="$PWD/rdm/bin/agent-system-rdm"
|
||||
python3 -m unittest tests.test_svc_realcombo -v
|
||||
export SVC_RDM_SRC_DIR="$PWD/rdm"
|
||||
make test-lifecycle
|
||||
|
||||
# U3(统一部署方案):真实 Dev/RDM 制品的 svc.sh 生命周期门禁——桩套件
|
||||
# (test_svc*.py)只证明脚本逻辑;本作业证明「声明≠能力」的最后一道:真实
|
||||
|
||||
+9
-2
@@ -1,6 +1,6 @@
|
||||
# feature/svc-d1-identity-flow 任务卡
|
||||
|
||||
任务主记录:<PR 链接,交付前填写>;状态:进行中;owner:weichen
|
||||
任务主记录:PR #485 https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/pulls/485(merge cd61bbb112);状态:已完成(回填);owner:weichen
|
||||
|
||||
## 基线与授权
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
| 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) |
|
||||
|---|---|---|---|---|---|
|
||||
|
||||
## 结果与验证(完成后填写)
|
||||
## 结果与验证
|
||||
|
||||
- 结果:
|
||||
- 验证:<结论摘要 PASS/FAIL/SKIP/NOT_RUN 逐项;逐条证据由 make evidence 写入上方证据表>
|
||||
@@ -181,3 +181,10 @@
|
||||
"receipt_sha256": "6a9970081b050083f7d4ee50ced8fa1b114cb0e5fd6bbde4c591231287a9168f"
|
||||
}
|
||||
```
|
||||
|
||||
## 闭合记录(定向回填)
|
||||
|
||||
- 依据:merge cd61bbb112eea6a210a64e84f2cef00b0d64bfc1(PR #485)已包含于 origin/main。
|
||||
- 合并主题:Merge pull request 'Gate deploys on identity capabilities and a reversible release' (#485) from feature/svc-d1-identity-flow into main
|
||||
- 范围:只闭合本轮 D1/D3 两张卡。未运行全局 task-close,避免把其他仍进行中的已合入卡片标成完成。
|
||||
- 归档:移入 .task/archive/。
|
||||
File diff suppressed because one or more lines are too long
@@ -113,7 +113,7 @@ test-backend-pg:
|
||||
cd $(BACKEND) && go test -count=1 ./...
|
||||
|
||||
# 真实 Dev/RDM + PostgreSQL 生命周期门禁。缺环境直接失败,不静默跳过。
|
||||
# 登录入口未就绪时套件保持失败(NOT_RUN),不把 D3 报成完成。
|
||||
# 登录单独标 NOT_RUN(依赖账户方案 U7/U5),不把其余真实组合场景记成失败。
|
||||
test-lifecycle:
|
||||
@test -n "$${AGENT_PG_TEST_DSN}" || { echo "test-lifecycle: AGENT_PG_TEST_DSN 未设置(真实 PostgreSQL 必需,不静默跳过)"; exit 1; }
|
||||
@test -n "$${SVC_RDM_SRC_DIR}" || { echo "test-lifecycle: SVC_RDM_SRC_DIR 未设置(RDM 检出必需,不静默跳过)"; exit 1; }
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@ U2 起实施与部署分别评审。
|
||||
- [服务重启与全量数据恢复方案 r3.1](modules/documents/docs/proposals/2026-10-12-service-restart-data-recovery.md):
|
||||
svc 启停、异常进程/主机退出后的依赖、配置/数据身份、任务/HITL/副作用、文件与组合备份恢复;
|
||||
r2 已批准。r3.1 增补 D1 实例身份收尾、D2 可回滚切换、D3 真实组合门禁,并记录 2026-10-12 rdmcand 数据归属:会话不在 dev 库的 rdmcand 窗口内,领域事件为空,不跨实例搬迁。
|
||||
D1/D2/D3 按实施计划推进到可合入;r3 其余未批条款仍待人工评审。
|
||||
D1 与 D2 已合入 Backend #184、RDM #291、Dev #485。D3 的 `make test-lifecycle` 跑真实组合用例;登录仍是 NOT_RUN,依赖账户方案 U7/U5,不在本轮公共化账户 CLI。r3 其余未批条款仍待人工评审。
|
||||
|
||||
- [svc 统一部署与一次性登录 Key 方案 r1](modules/documents/docs/proposals/2026-10-12-svc-unified-deploy-and-login-key.md):
|
||||
二进制/源码统一部署、环境准备、无初始密码开户与账户恢复;一次性 Key 仅兑换设密受限会话;
|
||||
|
||||
@@ -2074,6 +2074,7 @@ with open(tmp, "w") as f:
|
||||
f.write(json.dumps(j, ensure_ascii=False) + "\n")
|
||||
os.replace(tmp, out)
|
||||
PYJ
|
||||
svc_fault_check "$phase"
|
||||
}
|
||||
|
||||
svc_journal_get() { # KEY → 值(journal 缺失/损坏 → 空)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
"""真实 Dev/RDM 组合门禁。由 make test-lifecycle 调用。
|
||||
|
||||
缺 PostgreSQL、RDM 源码或制品时直接失败,不静默跳过。
|
||||
RDM 登录依赖账户 CLI 公共化(账户方案 U7/U5),当前标 NOT_RUN,本套件因此不能报完成。
|
||||
登录依赖账户 CLI 公共化(账户方案 U7/U5),单独标 NOT_RUN,
|
||||
不因此把已经跑过的真实组合场景记成失败。
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
@@ -15,32 +17,42 @@ def main():
|
||||
missing = []
|
||||
if not os.environ.get("AGENT_PG_TEST_DSN"):
|
||||
missing.append("AGENT_PG_TEST_DSN")
|
||||
if not os.environ.get("SVC_RDM_SRC_DIR") or not Path(os.environ.get("SVC_RDM_SRC_DIR", "")).is_dir():
|
||||
src = os.environ.get("SVC_RDM_SRC_DIR", "")
|
||||
if not src or not Path(src).is_dir():
|
||||
missing.append("SVC_RDM_SRC_DIR")
|
||||
if not (ROOT / "bin" / "agent-system").is_file() and not os.environ.get("SVC_DEV_BIN"):
|
||||
missing.append("Dev 制品(make build 或 SVC_DEV_BIN)")
|
||||
dev = os.environ.get("SVC_REAL_BIN") or str(ROOT / "bin" / "agent-system")
|
||||
rdm = os.environ.get("SVC_REAL_RDM_BIN", "")
|
||||
if not Path(dev).is_file():
|
||||
missing.append("Dev 制品(SVC_REAL_BIN 或 bin/agent-system)")
|
||||
if not rdm or not Path(rdm).is_file():
|
||||
missing.append("RDM 制品(SVC_REAL_RDM_BIN)")
|
||||
if missing:
|
||||
print("test-lifecycle 失败。缺:%s" % ", ".join(missing))
|
||||
return 1
|
||||
|
||||
print("组合清单")
|
||||
print("pin", PIN.read_text().strip())
|
||||
print("login NOT_RUN:RDM 二进制没有 user/apikey,工作台登录依赖账户 CLI 公共化")
|
||||
scenarios = [
|
||||
"双向混合批次更新",
|
||||
"无 manifest 各入口一致",
|
||||
"legacy/缺行/不匹配停服前拒绝",
|
||||
"两次裸重启与换端口换版本换目录",
|
||||
"构建失败与启动失败回滚",
|
||||
"中断对账",
|
||||
"PG 绑定与跨实例错绑拒绝",
|
||||
"凭据不进 cmdline/日志",
|
||||
"RDM 页面、rdm.ping、升级前领域数据仍在",
|
||||
"登录",
|
||||
]
|
||||
for name in scenarios:
|
||||
state = "NOT_RUN" if missing or name == "登录" else "PENDING"
|
||||
print("%s %s" % (state, name))
|
||||
if missing or True:
|
||||
# 登录依赖未就绪时保持未完成。缺环境同样失败。
|
||||
print("test-lifecycle 未完成。缺:%s" % (", ".join(missing) if missing else "登录入口"))
|
||||
return 1
|
||||
print("rdm_src", src)
|
||||
print("dev_bin", dev)
|
||||
print("rdm_bin", rdm)
|
||||
print("将运行 tests.test_svc_realcombo:SQLite 身份、RDM 二进制生命周期、PostgreSQL 身份环境交付")
|
||||
if os.environ.get("SVC_RDM_ORIGIN"):
|
||||
print("将运行全轨部署:SVC_RDM_ORIGIN 已设置")
|
||||
else:
|
||||
print("全轨部署 NOT_RUN:未设置 SVC_RDM_ORIGIN(由 svc-realcombo 作业覆盖)")
|
||||
print("登录 NOT_RUN:RDM 二进制没有 user/apikey,工作台登录依赖账户方案 U7/U5")
|
||||
env = os.environ.copy()
|
||||
env["SVC_TEST_REAL"] = "1"
|
||||
env["SVC_TEST_PG"] = "1"
|
||||
env["SVC_REAL_BIN"] = dev
|
||||
env["SVC_REAL_RDM_BIN"] = rdm
|
||||
proc = subprocess.run(
|
||||
[sys.executable, "-m", "unittest", "tests.test_svc_realcombo", "-q"],
|
||||
cwd=str(ROOT), env=env)
|
||||
if proc.returncode != 0:
|
||||
print("test-lifecycle 失败:真实组合用例未通过")
|
||||
return proc.returncode
|
||||
print("test-lifecycle 可跑场景通过;登录与未设 origin 的全轨部署保持 NOT_RUN")
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
@@ -229,6 +229,53 @@ class U2ReleaseTests(tsi.IdentityTests):
|
||||
|
||||
# ---- T5:legacy 布局未迁移 → 裸 start/restart 仍走原路径(兼容) ----
|
||||
|
||||
def test_U2_fault_after_switch_rolls_back_on_next_start(self):
|
||||
self.seed_agent("u2f", 9466)
|
||||
self.set_makefile(self.stub)
|
||||
self.svc("u2f", "deploy", "--from", "local")
|
||||
v1 = self.cur_release("u2f")
|
||||
self.svc("u2f", "stop")
|
||||
env = dict(self.env)
|
||||
env["SVC_TEST_FAULTS"] = "1"
|
||||
env["SVC_FAULT_AT"] = "switched"
|
||||
result = self.svc("u2f", "deploy", "--from", "local", check=False, env=env)
|
||||
self.assertEqual(result.returncode, 86, result.stdout)
|
||||
self.assertIn("故障注入于 switched", result.stdout)
|
||||
result = self.svc("u2f", "start")
|
||||
self.assertIn("已回退上一版本", result.stdout)
|
||||
self.assertEqual(self.cur_release("u2f"), v1)
|
||||
self.assertTrue(self.running("u2f"))
|
||||
self.svc("u2f", "stop")
|
||||
|
||||
def test_U2_health_timeout_rolls_back(self):
|
||||
self.seed_agent("u2g", 9467)
|
||||
self.set_makefile(self.stub)
|
||||
self.svc("u2g", "deploy", "--from", "local")
|
||||
v1 = self.cur_release("u2g")
|
||||
good = self.active_bin("u2g").read_bytes()
|
||||
self.set_makefile(self.hang_stub())
|
||||
result = self.svc("u2g", "deploy", "--from", "local", check=False)
|
||||
self.assertNotEqual(result.returncode, 0, result.stdout)
|
||||
self.assertIn("健康检查未通过", result.stdout)
|
||||
self.assertIn("已回退上一版本", result.stdout)
|
||||
self.assertEqual(self.cur_release("u2g"), v1)
|
||||
self.assertEqual(self.active_bin("u2g").read_bytes(), good)
|
||||
self.assertTrue(self.running("u2g"))
|
||||
self.svc("u2g", "stop")
|
||||
|
||||
def hang_stub(self):
|
||||
"""identity 可用、serve 挂起且不监听,用来触发健康检查超时。"""
|
||||
p = self.root / "stub-agent-system-hang"
|
||||
if not p.exists():
|
||||
stub = tsr.STUB
|
||||
head, sep, tail = stub.partition(" serve)")
|
||||
assert sep, "STUB 缺 serve 分支锚点"
|
||||
_, sep2, tail2 = tail.partition(' wait "$child"\n ;;')
|
||||
assert sep2, "STUB 缺 serve 分支结尾锚点"
|
||||
p.write_text(head + " serve)\n shift\n sleep 60\n exit 0 ;;" + tail2)
|
||||
p.chmod(0o755)
|
||||
return p
|
||||
|
||||
def test_U2_legacy_layout_bare_lifecycle_still_works(self):
|
||||
self.seed_agent("u2e", 9465)
|
||||
self.start_ok("u2e")
|
||||
|
||||
Reference in New Issue
Block a user