fix(chv-hybrid): 严格快照默认翻转的旧测试适配 + 长函数拆分
ci / test (push) Successful in 1h8m45s

全量复核 4676 项出现 4 失败 6 错误,全是集成时翻为默认开启的
严格快照校验(设计 §2.2)的连锁反应——旧测试用未登记/未标记
快照走 legacy 放行路径。按新语义逐项适配,不改生产校验本身:

- test_chv_opt_stage1.CrossTenantRestoreTest:跨租户拒绝的审计
  事件改断言 vm_restore_denied(严格路径的设计事件;
  vm_restore_tenant_denied 只在显式关闭严格校验时出现);
  legacy 警告放行测试改走显式 CHV_SNAPSHOT_STRICT_TENANT=0。
- test_chv_v3_fixes(5 个 restore 测试):登记带匹配 tenant
  (proj1)的快照,意图不变(盘预检 / source_url / 清旧 VMM
  仍由各自断言覆盖)。
- test_cloud_hypervisor.LifecycleTest:登记 file:///snap/1
  (tenant proj1),restore/resume 顺序断言不变。
- 长函数:B 轨合入把 _run_with_persistent_vm 推到 53 行,超
  50 行架构上限;finally 收尾块抽为 _suspend_persistent_after_task。

针对性 12 项全部通过;全量待重跑。
This commit is contained in:
host committed 2026-11-08 22:14:39 +00:00
1 parent 04a208a98b
commit 6c03ac9b0f
4 files changed
+45 -13

No files matched your search

+15
View File
@@ -38,12 +38,14 @@ from pathlib import Path
from unittest import mock
try:
from cloud.chv.disk import record_snapshot
from cloud.chv.executor import CloudHypervisorExecutor
from cloud.chv.hostkeys import write_seed
from cloud.chv.ssh_transport import remote_command
from cloud.sandbox import ChvFailure
except ImportError:
sys.path.insert(0, str(Path(__file__).resolve().parents[2]))
from cloud.chv.disk import record_snapshot
from cloud.chv.executor import CloudHypervisorExecutor
from cloud.chv.hostkeys import write_seed
from cloud.chv.ssh_transport import remote_command
@@ -195,6 +197,14 @@ class V3Case(unittest.TestCase):
fh.write(content)
return "file://" + path, path
def _register_snapshot(self, url, tenant="proj1"):
# 严格快照校验(设计 §2.2,默认开启):restore 测试的
# 快照须登记带 tenant 且与 _task() 的 project_id 一致;
# 本 helper 只登记,不改变测试本身的意图(盘预检 /
# source_url / 清旧 VMM 仍由各自断言覆盖)。
record_snapshot(self.state_dir, "chv-abc123", url, 20.0,
tenant_id=tenant)
def _spawn_fake_vmm(self, sock_path, argv0="cloud-hypervisor"):
"""真实 spawn 一个长眠进程,argv[0] 伪装成 VMM,
命令行带 --api-socket <sock>(F2/V-3③ 的扫描目标)。"""
@@ -223,6 +233,7 @@ class SnapshotV3Test(V3Case):
def test_restore_still_passes_source_url(self):
url, _ = self._snap_dir()
self._register_snapshot(url)
ex = self.make_exec()
out = ex.restore_vm(self._task(), url)
self.assertEqual(out["mode"], "restored")
@@ -248,6 +259,7 @@ class SnapshotV3Test(V3Case):
class RestorePrepareV3Test(V3Case):
def test_restore_kills_registered_old_vmm_and_socket(self):
url, _ = self._snap_dir()
self._register_snapshot(url)
ex = self.make_exec()
ex.wake_vm(self._task())
old_proc = self.proc
@@ -265,6 +277,7 @@ class RestorePrepareV3Test(V3Case):
def test_restore_kills_unregistered_vmm_by_socket(self):
url, _ = self._snap_dir()
self._register_snapshot(url)
ex = self.make_exec()
sock = os.path.join(self.state_dir, "chv-abc123.sock")
os.makedirs(self.state_dir, exist_ok=True)
@@ -314,6 +327,7 @@ class HibernateDiskV3Test(V3Case):
"config.json": json.dumps(
{"disks": [{"path": missing_disk}]}).encode(),
"state.json": b"{}"})
self._register_snapshot(url)
with self.assertRaises(ChvFailure) as ctx:
ex.restore_vm(self._task(), url)
self.assertEqual(ctx.exception.kind, "snapshot_disk_missing")
@@ -327,6 +341,7 @@ class HibernateDiskV3Test(V3Case):
"config.json": json.dumps(
{"disks": [{"path": disk}]}).encode(),
"state.json": b"{}"})
self._register_snapshot(url)
out = ex.restore_vm(self._task(), url)
self.assertEqual(out["mode"], "restored")