"""CHV guest-env 集成测试:Gitea 同步变量供给链路。 只用标准库与 mock runner/launcher/api_client,绝不启动真实 VM、不联网、不含任何真实 token(测试值全是假值)。 覆盖: - gitea_sync 纯函数:三源合并优先级、白名单清洗、完整性 校验(fail-closed)与空=不同步; - ssh_transport:GITEA_TOKEN 进密钥集(argv 拒绝)、其余 5 键进 guest-env 集; - hostkeys.write_seed:guest_env 与 secret_env 合并写同一 条目、仍无 runcmd、0600; - 执行器 wake_vm:完整同步变量进 seed(5 键 guest-env + GITEA_TOKEN 走 authd-seed);缺失必填 键时起 VMM 前 ChvFailure 且不启动;无同步变量时正常启动 且不写 guest-env;seed 投递后 build_ssh_command 才能用 GITEA_TOKEN 且 argv 里绝无 token 值; - worker:_gitea_sync_env 取值;_run_attempt 只对 CHV 执行器 把同步变量并进 gateway_env。 """ import os import sys import tempfile import unittest from pathlib import Path from types import SimpleNamespace import yaml try: from cloud.chv.gitea_sync import ( GITEA_SYNC_KEYS, config_gitea_sync_env, extract_gitea_sync_env, validate_gitea_sync_env, ) from cloud.chv.hostkeys import write_seed from cloud.chv.ssh_transport import ( _CHV_SECRET_ENV_NAMES, build_ssh_command, remote_command, split_guest_env, split_secret_env, ) from cloud.sandbox import ChvFailure, CloudHypervisorExecutor from cloud.worker import Worker except ImportError: sys.path.insert(0, str(Path(__file__).resolve().parents[2])) from cloud.chv.gitea_sync import ( GITEA_SYNC_KEYS, config_gitea_sync_env, extract_gitea_sync_env, validate_gitea_sync_env, ) from cloud.chv.hostkeys import write_seed from cloud.chv.ssh_transport import ( _CHV_SECRET_ENV_NAMES, build_ssh_command, remote_command, split_guest_env, split_secret_env, ) from cloud.sandbox import ChvFailure, CloudHypervisorExecutor from cloud.worker import Worker FAKE_SYNC = { "GITEA_URL": "https://gitea.tose.top", "GITEA_USER": "admin", "GITEA_TOKEN": "fake-token-123", "SYNC_REPO": "admin/chv-sync-test", "SYNC_BRANCH": "main", "GITEA_EMAIL": "admin@tose.top", } class FakeResult: def __init__(self, returncode=0, stdout="", stderr=""): self.returncode = returncode self.stdout = stdout self.stderr = stderr class FakeProc: def __init__(self, alive=True): self._alive = alive def poll(self): return None if self._alive else 1 def terminate(self): self._alive = False def wait(self, timeout=None): return 0 def kill(self): self._alive = False def _write(path, content=b"x"): with open(path, "wb") as fh: fh.write(content) os.chmod(path, 0o755) return path def _seed_user_text(state_dir, vm_name): with open(os.path.join(state_dir, vm_name, "seed", "user-data")) as fh: return fh.read() def _guest_env_lines(user_text): parsed = yaml.safe_load(user_text) entries = parsed["write_files"] guest = [e for e in entries if e["path"] == "/etc/chv/guest-env"] assert len(guest) == 1, entries return guest[0]["content"], guest[0]["permissions"] def _authd_seed_lines(user_text): parsed = yaml.safe_load(user_text) entries = parsed["write_files"] authd = [e for e in entries if e["path"] == "/etc/chv/authd-seed"] assert len(authd) == 1, entries return authd[0]["content"], authd[0]["permissions"] # -- (1) gitea_sync 纯函数 --------------------------------------------- class GiteaSyncPureTest(unittest.TestCase): def test_keys_are_six(self): self.assertEqual(GITEA_SYNC_KEYS, set(FAKE_SYNC)) def test_config_mapping(self): env = {"CHV_GITEA_URL": "https://gitea.tose.top", "CHV_GITEA_USER": "admin", "CHV_GITEA_TOKEN": "tok", "CHV_SYNC_REPO": "admin/chv-sync-test", "CHV_SYNC_BRANCH": "main", "CHV_GITEA_EMAIL": "admin@tose.top", "CHV_UNRELATED": "x"} self.assertEqual(config_gitea_sync_env(env), { "GITEA_URL": "https://gitea.tose.top", "GITEA_USER": "admin", "GITEA_TOKEN": "tok", "SYNC_REPO": "admin/chv-sync-test", "SYNC_BRANCH": "main", "GITEA_EMAIL": "admin@tose.top"}) def test_extract_priority_config_lt_task_lt_extra_env(self): task = {"id": "t1", "gitea_sync": { "GITEA_URL": "https://task.example", "GITEA_USER": "task-user", "GITEA_TOKEN": "task-tok", "SYNC_REPO": "task/repo"}} out = extract_gitea_sync_env( task=task, extra_env={"SYNC_REPO": "extra/repo"}, config_sync={"GITEA_URL": "https://config.example", "GITEA_USER": "config-user", "GITEA_TOKEN": "config-tok", "SYNC_REPO": "config/repo", "SYNC_BRANCH": "dev"}) self.assertEqual(out["GITEA_URL"], "https://task.example") self.assertEqual(out["GITEA_USER"], "task-user") self.assertEqual(out["GITEA_TOKEN"], "task-tok") self.assertEqual(out["SYNC_REPO"], "extra/repo") self.assertEqual(out["SYNC_BRANCH"], "dev") def test_extract_drops_unknown_and_empty_and_nonstr(self): task = {"id": "t1", "gitea_sync": { "GITEA_URL": "https://gitea.tose.top", "EVIL": "nope", "SYNC_REPO": " ", "GITEA_TOKEN": 12345}} out = extract_gitea_sync_env(task=task) self.assertEqual(out, {"GITEA_URL": "https://gitea.tose.top"}) self.assertNotIn("gitea_sync", out) def test_build_chv_config_maps_gitea_env(self): from cloud.chv.config import build_chv_config cfg = build_chv_config({}, { "CHV_GITEA_URL": "https://gitea.tose.top", "CHV_GITEA_USER": "admin", "CHV_GITEA_TOKEN": "tok", "CHV_SYNC_REPO": "admin/chv-sync-test"}) self.assertEqual(cfg.gitea_sync_env, { "GITEA_URL": "https://gitea.tose.top", "GITEA_USER": "admin", "GITEA_TOKEN": "tok", "SYNC_REPO": "admin/chv-sync-test"}) cfg2 = build_chv_config({}, {}) self.assertEqual(cfg2.gitea_sync_env, {}) def test_validate_empty_passes_partial_fails_with_names_only(self): validate_gitea_sync_env({}) validate_gitea_sync_env(None) validate_gitea_sync_env(dict(FAKE_SYNC)) with self.assertRaises(ValueError) as ctx: validate_gitea_sync_env({"GITEA_URL": "https://gitea.tose.top", "SYNC_REPO": "admin/chv-sync-test"}) msg = str(ctx.exception) self.assertIn("GITEA_TOKEN", msg) self.assertIn("GITEA_USER", msg) self.assertNotIn("gitea.tose.top", msg) self.assertNotIn("chv-sync-test", msg) # -- (2) ssh_transport ------------------------------------------------- class SshTransportSyncTest(unittest.TestCase): def test_gitea_token_is_secret(self): self.assertIn("GITEA_TOKEN", _CHV_SECRET_ENV_NAMES) self.assertIn("SUB2API_API_KEY", _CHV_SECRET_ENV_NAMES) secrets, plain = split_secret_env( {"GITEA_TOKEN": "tok", "GITEA_URL": "https://x", "OTHER": "1"}) self.assertEqual(secrets, {"GITEA_TOKEN": "tok"}) self.assertEqual(plain, {"GITEA_URL": "https://x", "OTHER": "1"}) def test_split_guest_env_covers_all_six_keys(self): guest, plain = split_guest_env(dict(FAKE_SYNC, OTHER="1")) self.assertEqual(set(guest), set(FAKE_SYNC)) self.assertEqual(guest["GITEA_TOKEN"], "fake-token-123") # 非密钥子集仍含同步普通变量(任务期 SSH 前缀照常带它们)。 self.assertIn("GITEA_URL", plain) self.assertNotIn("GITEA_TOKEN", plain) self.assertIn("OTHER", plain) self.assertNotIn("OTHER", guest) def test_remote_command_rejects_gitea_token(self): with self.assertRaises(ValueError): remote_command(["true"], extra_env={"GITEA_TOKEN": "tok"}) with self.assertRaises(ValueError): build_ssh_command(2222, "/tmp/key", "root", None, "/tmp/known_hosts", ["true"], extra_env={"GITEA_TOKEN": "tok"}) # -- (3) hostkeys.write_seed ------------------------------------------- class WriteSeedGuestEnvTest(unittest.TestCase): def test_guest_env_and_secret_merge_into_one_entry_no_runcmd(self): # feat-chv-muse-p3:GITEA_TOKEN 不再进 guest-env,改走 # authd_env(独立的 authd-seed 条目,0600);guest-env # 条目里只剩非 authd 密钥与同步普通变量。guest_env 里 # 直接给 GITEA_TOKEN 即 ValueError(调用方须先 # split_authd_env 拆出来,旧的“同名键 secret 优先”语义 # 已由“authd 通道只装 authd 密钥”取代)。 with tempfile.TemporaryDirectory() as tmp: seed_dir = os.path.join(tmp, "seed") write_seed(seed_dir, "vm1", "PRIV", "ssh-ed25519 AAAAx", secret_env={"SUB2API_API_KEY": "gw-key"}, guest_env={"GITEA_URL": "https://gitea.tose.top", "GITEA_USER": "admin", "SYNC_REPO": "admin/chv-sync-test"}, authd_env={"GITEA_TOKEN": "dup-should-lose"}) with open(os.path.join(seed_dir, "user-data")) as fh: content = fh.read() self.assertEqual(content.count("write_files:"), 1) parsed = yaml.safe_load(content) self.assertNotIn("runcmd", parsed) self.assertEqual(len(parsed["write_files"]), 4) text, perms = _guest_env_lines(content) self.assertEqual(perms, "0600") self.assertIn("GITEA_URL=https://gitea.tose.top", text) self.assertIn("SUB2API_API_KEY=gw-key", text) self.assertNotIn("GITEA_TOKEN", text) authd_text, authd_perms = _authd_seed_lines(content) self.assertEqual(authd_perms, "0600") self.assertIn("GITEA_TOKEN=dup-should-lose", authd_text) with tempfile.TemporaryDirectory() as tmp: seed_dir = os.path.join(tmp, "seed") with self.assertRaises(ValueError): write_seed(seed_dir, "vm1", "PRIV", "ssh-ed25519 AAAAx", guest_env={"GITEA_TOKEN": "dup-should-lose"}) def test_guest_env_only_still_no_runcmd(self): with tempfile.TemporaryDirectory() as tmp: seed_dir = os.path.join(tmp, "seed") write_seed(seed_dir, "vm1", "PRIV", "ssh-ed25519 AAAAx", guest_env={"GITEA_URL": "https://gitea.tose.top"}) with open(os.path.join(seed_dir, "user-data")) as fh: content = fh.read() parsed = yaml.safe_load(content) self.assertNotIn("runcmd", parsed) self.assertEqual(len(parsed["write_files"]), 3) # -- (4) 执行器 wake_vm ------------------------------------------------- class WakeGuestEnvCase(unittest.TestCase): def setUp(self): self.tmp = tempfile.TemporaryDirectory() self.dir = self.tmp.name self.binary = _write(os.path.join(self.dir, "cloud-hypervisor")) self.ch_remote = _write(os.path.join(self.dir, "ch-remote")) self.kernel = _write(os.path.join(self.dir, "vmlinux")) self.rootfs = _write(os.path.join(self.dir, "disk.raw"), b"R" * 100) self.ssh_key = _write(os.path.join(self.dir, "id_chv")) self.kvm = _write(os.path.join(self.dir, "kvm")) self.cpuinfo = os.path.join(self.dir, "cpuinfo") with open(self.cpuinfo, "w") as fh: fh.write("flags : fpu vmx sse\n") self.state_dir = os.path.join(self.dir, "state") self.calls = [] self.audit = [] self.launches = [] def tearDown(self): self.tmp.cleanup() def _runner(self, cmd, timeout=None): self.calls.append(list(cmd)) if cmd and cmd[0] == "ssh-keygen": priv = cmd[cmd.index("-f") + 1] with open(priv, "w") as fh: fh.write("-----BEGIN OPENSSH PRIVATE KEY-----\nFAKE\n") os.chmod(priv, 0o600) with open(priv + ".pub", "w") as fh: fh.write("ssh-ed25519 AAAAfake1 vm-key\n") return FakeResult(0, "", "") if cmd and cmd[0] == "genisoimage": out = cmd[cmd.index("-output") + 1] with open(out, "wb") as fh: fh.write(b"ISO") return FakeResult(0, "", "") return FakeResult(0, "", "") def _launcher(self, cmd): self.launches.append(list(cmd)) return FakeProc(alive=True) def make_exec(self, env_extra=None): env = {"CHV_EGRESS_PROXY": "http://10.0.0.1:8888", "CHV_HOST_KEY_MODE": "provisioned", "CHV_SSH_FORWARD": "1", # feat-chv-muse-p3:wake 前 Sentinel 预审要求 # Gitea 主机在白名单内;解析器用假的(测试不联网)。 "CHV_SENTINEL_ALLOW_HOSTS": "gitea.tose.top"} if env_extra: env.update(env_extra) ex = CloudHypervisorExecutor( binary=self.binary, ch_remote=self.ch_remote, kernel=self.kernel, rootfs=self.rootfs, ssh_key=self.ssh_key, kvm_path=self.kvm, cpuinfo_path=self.cpuinfo, state_dir=self.state_dir, runner=self._runner, launcher=self._launcher, api_client=lambda s, m, p, payload=None: (200, {}), sleeper=lambda s: None, env=env, sentinel_resolver=lambda host, port: ["93.184.216.34"]) ex.audit_callback = lambda e, t, d, k=None: self.audit.append( (e, t.get("id") if isinstance(t, dict) else t, d, k)) return ex def test_wake_with_task_gitea_sync_writes_all_six_to_seed(self): ex = self.make_exec() task = {"id": "sync1", "gitea_sync": dict(FAKE_SYNC)} out = ex.wake_vm(task) self.assertEqual(out["state"], "running") text = _seed_user_text(self.state_dir, "chv-sync1") self.assertNotIn("runcmd", yaml.safe_load(text)) guest_text, perms = _guest_env_lines(text) self.assertEqual(perms, "0600") # feat-chv-muse-p3:六键仍全进 seed,但分两路—— # 5 个普通键进 guest-env,GITEA_TOKEN 只进 authd-seed。 for key in ("GITEA_URL", "GITEA_USER", "SYNC_REPO", "SYNC_BRANCH", "GITEA_EMAIL"): self.assertIn("%s=%s" % (key, FAKE_SYNC[key]), guest_text) self.assertNotIn("GITEA_TOKEN", guest_text) authd_text, authd_perms = _authd_seed_lines(text) self.assertEqual(authd_perms, "0600") self.assertIn("GITEA_TOKEN=fake-token-123", authd_text) # seed.iso 已制盘且 0600。 seed_iso = os.path.join(self.state_dir, "chv-sync1", "seed.iso") self.assertTrue(os.path.exists(seed_iso)) self.assertEqual(oct(os.stat(seed_iso).st_mode & 0o777), "0o600") def test_wake_with_config_env_sync(self): ex = self.make_exec(env_extra={ "CHV_GITEA_URL": "https://gitea.tose.top", "CHV_GITEA_USER": "admin", "CHV_GITEA_TOKEN": "fake-token-123", "CHV_SYNC_REPO": "admin/chv-sync-test", "CHV_SYNC_BRANCH": "main"}) self.assertEqual(ex.gitea_sync_env["SYNC_REPO"], "admin/chv-sync-test") out = ex.wake_vm({"id": "sync2"}) self.assertEqual(out["state"], "running") guest_text, _ = _guest_env_lines( _seed_user_text(self.state_dir, "chv-sync2")) # feat-chv-muse-p3:GITEA_TOKEN 不再进 guest-env, # 改走 authd-seed;其余同步变量仍在 guest-env 里。 self.assertNotIn("GITEA_TOKEN", guest_text) self.assertIn("SYNC_BRANCH=main", guest_text) authd_text, authd_perms = _authd_seed_lines( _seed_user_text(self.state_dir, "chv-sync2")) self.assertEqual(authd_perms, "0600") self.assertIn("GITEA_TOKEN=fake-token-123", authd_text) def test_wake_partial_sync_fails_closed_before_launch(self): ex = self.make_exec() task = {"id": "sync3", "gitea_sync": { "GITEA_URL": "https://gitea.tose.top", "SYNC_REPO": "admin/chv-sync-test"}} with self.assertRaises(ChvFailure) as ctx: ex.wake_vm(task) self.assertEqual(ctx.exception.kind, "gitea_sync_incomplete") self.assertEqual(self.launches, []) self.assertFalse(os.path.exists( os.path.join(self.state_dir, "chv-sync3", "seed.iso"))) kinds = [a[0] for a in self.audit] self.assertIn("vm_failed", kinds) def test_wake_partial_sync_from_config_also_fails_closed(self): ex = self.make_exec(env_extra={ "CHV_GITEA_URL": "https://gitea.tose.top"}) with self.assertRaises(ChvFailure) as ctx: ex.wake_vm({"id": "sync4"}) self.assertEqual(ctx.exception.kind, "gitea_sync_incomplete") self.assertEqual(self.launches, []) def test_wake_without_sync_writes_no_guest_env(self): ex = self.make_exec() out = ex.wake_vm({"id": "plain1"}) self.assertEqual(out["state"], "running") parsed = yaml.safe_load( _seed_user_text(self.state_dir, "chv-plain1")) self.assertEqual(len(parsed["write_files"]), 2) def test_build_ssh_command_after_wake_sources_guest_env(self): ex = self.make_exec() ex.wake_vm({"id": "sync5", "gitea_sync": dict(FAKE_SYNC)}) # feat-chv-muse-p3:GITEA_TOKEN 走 authd 投递——任务期 # 认“已投递、不报错”,但绝不 source 进 codex 进程环境, # 所以命令里既无 token 值、也不 source 任何客内密钥文件。 cmd = ex.build_ssh_command( {"id": "sync5"}, ["true"], extra_env={"GITEA_TOKEN": "fake-token-123"}) joined = " ".join(cmd) self.assertNotIn("fake-token-123", joined) self.assertNotIn("/etc/chv/guest-env", joined) self.assertNotIn("/etc/chv/authd-seed", joined) # 非 authd 密钥仍走 guest-env:wake 时投递,任务期 source。 ex.wake_vm({"id": "sync5b"}, extra_env={"SUB2API_API_KEY": "gw-key"}) cmd = ex.build_ssh_command( {"id": "sync5b"}, ["true"], extra_env={"SUB2API_API_KEY": "gw-key"}) joined = " ".join(cmd) self.assertNotIn("gw-key", joined) self.assertIn("/etc/chv/guest-env", joined) # 未 wake 投递的 VM 用密钥即拒绝。 with self.assertRaises(ChvFailure) as ctx: ex.build_ssh_command( {"id": "other"}, ["true"], extra_env={"GITEA_TOKEN": "fake-token-123"}) self.assertEqual(ctx.exception.kind, "secret_env_not_delivered") def test_wake_keyscan_mode_with_token_fails_closed(self): ex = self.make_exec(env_extra={"CHV_HOST_KEY_MODE": "keyscan"}) with self.assertRaises(ChvFailure): ex.wake_vm({"id": "sync6", "gitea_sync": dict(FAKE_SYNC)}) self.assertEqual(self.launches, []) # -- (4b) seed 附加项(users 块 + network-config)------------------------ class SeedExtrasTest(unittest.TestCase): USERS_BLOCK = ("users:\n" " - name: chv\n" " sudo: ALL=(ALL) NOPASSWD:ALL\n" " shell: /bin/bash\n" " ssh_authorized_keys:\n" " - ssh-ed25519 AAAAfake chv-guest\n") NETCFG = ("version: 2\nethernets:\n ens4:\n" " addresses: [192.168.10.10/24]\n") def test_write_seed_extras(self): with tempfile.TemporaryDirectory() as tmp: seed_dir = os.path.join(tmp, "seed") write_seed(seed_dir, "vm1", "PRIV", "ssh-ed25519 AAAAx", user_data_extra=self.USERS_BLOCK, network_config=self.NETCFG) with open(os.path.join(seed_dir, "user-data")) as fh: content = fh.read() with open(os.path.join(seed_dir, "network-config")) as fh: net = fh.read() net_mode = oct(os.stat( os.path.join(seed_dir, "network-config")).st_mode & 0o777) parsed = yaml.safe_load(content) self.assertNotIn("runcmd", parsed) self.assertIn("users:", content) self.assertIn("ssh-ed25519 AAAAfake chv-guest", content) self.assertEqual(net, self.NETCFG) self.assertEqual(net_mode, "0o600") def test_write_seed_extra_with_runcmd_rejected(self): with tempfile.TemporaryDirectory() as tmp: with self.assertRaises(ValueError): write_seed(os.path.join(tmp, "seed"), "vm1", "PRIV", "ssh-ed25519 AAAAx", user_data_extra="runcmd:\n - echo hi\n") def test_config_fragment_maps_seed_files(self): from cloud.chv.config import build_chv_config cfg = build_chv_config({}, { "CHV_SEED_USER_DATA_EXTRA_FILE": "/tmp/users.yaml", "CHV_SEED_NETWORK_CONFIG_FILE": "/tmp/net.yaml"}) self.assertEqual(cfg.seed_user_data_extra_file, "/tmp/users.yaml") self.assertEqual(cfg.seed_network_config_file, "/tmp/net.yaml") self.assertIsNone(build_chv_config({}, {}).seed_user_data_extra_file) class WakeSeedExtrasCase(WakeGuestEnvCase): def test_wake_with_seed_extras(self): users_path = os.path.join(self.dir, "users.yaml") net_path = os.path.join(self.dir, "net.yaml") with open(users_path, "w") as fh: fh.write(SeedExtrasTest.USERS_BLOCK) with open(net_path, "w") as fh: fh.write(SeedExtrasTest.NETCFG) ex = self.make_exec(env_extra={ "CHV_SEED_USER_DATA_EXTRA_FILE": users_path, "CHV_SEED_NETWORK_CONFIG_FILE": net_path}) out = ex.wake_vm({"id": "extra1"}) self.assertEqual(out["state"], "running") seed_dir = os.path.join(self.state_dir, "chv-extra1", "seed") with open(os.path.join(seed_dir, "user-data")) as fh: self.assertIn("ssh-ed25519 AAAAfake chv-guest", fh.read()) with open(os.path.join(seed_dir, "network-config")) as fh: self.assertEqual(fh.read(), SeedExtrasTest.NETCFG) def test_wake_missing_seed_extra_fails_closed(self): ex = self.make_exec(env_extra={ "CHV_SEED_USER_DATA_EXTRA_FILE": "/nonexistent/users.yaml"}) with self.assertRaises(ChvFailure) as ctx: ex.wake_vm({"id": "extra2"}) self.assertEqual(ctx.exception.kind, "seed_extra_missing") self.assertEqual(self.launches, []) # -- (5) worker --------------------------------------------------------- class WorkerGiteaSyncTest(unittest.TestCase): def setUp(self): self.tmp = tempfile.TemporaryDirectory() self.db_path = os.path.join(self.tmp.name, "control.db") from cloud.server import init_db init_db(self.db_path) def tearDown(self): self.tmp.cleanup() def _worker(self, executor, env_extra=None): env = {"XCM_API_KEY": "test-placeholder"} if env_extra: env.update(env_extra) return Worker(self.db_path, "/fake/host.py", executor=executor, env=env) def test_gitea_sync_env_from_worker_env_and_task(self): worker = self._worker(None, env_extra={ "CHV_GITEA_URL": "https://gitea.tose.top", "CHV_GITEA_USER": "admin", "CHV_GITEA_TOKEN": "env-tok", "CHV_SYNC_REPO": "admin/chv-sync-test"}) out = worker._gitea_sync_env({"id": "t1"}) self.assertEqual(out["GITEA_TOKEN"], "env-tok") out2 = worker._gitea_sync_env( {"id": "t1", "gitea_sync": {"GITEA_TOKEN": "task-tok"}}) self.assertEqual(out2["GITEA_TOKEN"], "task-tok") self.assertEqual(out2["SYNC_REPO"], "admin/chv-sync-test") worker2 = self._worker(None) self.assertEqual(worker2._gitea_sync_env({"id": "t1"}), {}) def test_run_attempt_merges_sync_env_only_for_chv(self): import tempfile as _tf case_dir = _tf.mkdtemp() binary = _write(os.path.join(case_dir, "cloud-hypervisor")) ch_remote = _write(os.path.join(case_dir, "ch-remote")) kernel = _write(os.path.join(case_dir, "vmlinux")) rootfs = _write(os.path.join(case_dir, "disk.raw"), b"R" * 100) ssh_key = _write(os.path.join(case_dir, "id_chv")) kvm = _write(os.path.join(case_dir, "kvm")) cpuinfo = os.path.join(case_dir, "cpuinfo") with open(cpuinfo, "w") as fh: fh.write("flags : fpu vmx sse\n") ex = CloudHypervisorExecutor( binary=binary, ch_remote=ch_remote, kernel=kernel, rootfs=rootfs, ssh_key=ssh_key, kvm_path=kvm, cpuinfo_path=cpuinfo, state_dir=os.path.join(case_dir, "state"), runner=lambda cmd, timeout=None: FakeResult(0, "", ""), launcher=lambda cmd: FakeProc(alive=True), api_client=lambda s, m, p, payload=None: (200, {}), sleeper=lambda s: None, env={"CHV_EGRESS_PROXY": "http://10.0.0.1:8888", "CHV_HOST_KEY_MODE": "provisioned", "CHV_SSH_FORWARD": "1"}) seen = {} orig_dispatch = ex.dispatch_task def fake_dispatch(task, extra_env=None, model_provider=None): seen["extra_env"] = dict(extra_env or {}) return {"executor": "cloud-hypervisor", "task_id": task["id"], "status": "completed", "stdout": "", "stderr": "", "returncode": 0, "host_status": "completed", "usage": None} ex.dispatch_task = fake_dispatch worker = self._worker(ex, env_extra={ "CHV_GITEA_URL": "https://gitea.tose.top", "CHV_GITEA_USER": "admin", "CHV_GITEA_TOKEN": "fake-token-123", "CHV_SYNC_REPO": "admin/chv-sync-test"}) worker._ensure_gateway = lambda task: (None, {}) task = {"id": "w1", "project_id": "p1", "prompt": "做事"} result, error = worker._run_attempt(task) self.assertIsNone(error) self.assertEqual(result["status"], "completed") self.assertEqual(seen["extra_env"]["GITEA_TOKEN"], "fake-token-123") self.assertEqual(seen["extra_env"]["SYNC_REPO"], "admin/chv-sync-test") worker.close() if __name__ == "__main__": unittest.main()