from __future__ import annotations import importlib.util import json import sys import unittest from pathlib import Path SCRIPT_PATH = Path(__file__).with_name("launch-nas-preview-g8-helpers.py") SPEC = importlib.util.spec_from_file_location( "launch_nas_preview_g8_helpers", SCRIPT_PATH ) assert SPEC is not None and SPEC.loader is not None MODULE = importlib.util.module_from_spec(SPEC) sys.modules[SPEC.name] = MODULE SPEC.loader.exec_module(MODULE) RUN_ID = "20260807a1" IMAGE = "sha256:" + "5e" * 32 MANIFEST_SHA = "e" * 64 BASELINE_LABELS = { "com.docker.compose.project": MODULE.TARGET_PROJECT, "com.docker.compose.service": "api", "com.docker.compose.version": "2.20.1", } def executor_spec() -> object: return MODULE.executor_spec( run_id=RUN_ID, image=IMAGE, manifest_sha256=MANIFEST_SHA ) def control_plane_spec() -> object: return MODULE.control_plane_spec(run_id=RUN_ID, image=IMAGE) def probe_spec(plan_name: str = "rollback-old") -> object: return MODULE.probe_spec(run_id=RUN_ID, image=IMAGE, plan_name=plan_name) def container_labels(spec: object, **overrides: str) -> dict[str, str]: labels = dict(BASELINE_LABELS) labels.update(spec.isolated_labels) labels.update(spec.provenance_labels) labels.update(overrides) return labels class FakeRunner: """Record every argv and answer from a canned, operation-keyed map.""" def __init__(self, responses: dict[str, str] | None = None): self.calls: list[tuple[str, list[str]]] = [] self.responses = responses or {} def run(self, operation: str, argv: list[str], *, timeout: float) -> str: assert isinstance(argv, list) and argv assert all(isinstance(item, str) for item in argv) assert timeout > 0 self.calls.append((operation, list(argv))) return self.responses.get(operation, "") def argv_for(self, operation: str) -> list[str]: matches = [argv for name, argv in self.calls if name == operation] assert len(matches) == 1, operation return matches[0] def _label_values(argv: list[str]) -> dict[str, str]: values: dict[str, str] = {} for index, item in enumerate(argv): if item == "--label": key, _, value = argv[index + 1].partition("=") values[key] = value return values class SpecContractTest(unittest.TestCase): def test_isolated_project_is_never_the_target_project(self) -> None: for spec in (executor_spec(), control_plane_spec(), probe_spec()): self.assertNotEqual(spec.isolated_project, MODULE.TARGET_PROJECT) self.assertTrue( spec.isolated_project.startswith(MODULE.HELPER_PROJECT_PREFIX) ) def test_isolated_service_is_never_a_target_service(self) -> None: for spec in (executor_spec(), control_plane_spec(), probe_spec()): self.assertNotIn(spec.isolated_service, MODULE.TARGET_SERVICES) def test_container_name_is_not_a_target_compose_container(self) -> None: for spec in (executor_spec(), control_plane_spec(), probe_spec()): for service in MODULE.TARGET_SERVICES: self.assertNotEqual( spec.container_name, f"{MODULE.TARGET_PROJECT}-{service}-1" ) def test_invalid_run_id_and_image_fail_closed(self) -> None: with self.assertRaises(MODULE.HelperError): MODULE.control_plane_spec(run_id="BAD ID", image=IMAGE) with self.assertRaises(MODULE.HelperError): MODULE.control_plane_spec(run_id=RUN_ID, image="latest") with self.assertRaises(MODULE.HelperError): MODULE.executor_spec(run_id=RUN_ID, image=IMAGE, manifest_sha256="nope") class RunArgvContractTest(unittest.TestCase): def test_argv_never_labels_the_target_project_or_service(self) -> None: for spec in (executor_spec(), control_plane_spec(), probe_spec()): argv = MODULE.build_run_argv(spec) labels = _label_values(argv) self.assertEqual( labels[MODULE.PROJECT_LABEL], spec.isolated_project ) self.assertEqual( labels[MODULE.SERVICE_LABEL], spec.isolated_service ) self.assertNotIn(MODULE.TARGET_PROJECT, labels.values()) self.assertNotIn(labels[MODULE.SERVICE_LABEL], MODULE.TARGET_SERVICES) def test_argv_declares_only_the_two_isolated_compose_labels(self) -> None: argv = MODULE.build_run_argv(executor_spec()) compose_labels = { key for key in _label_values(argv) if key.startswith(MODULE.COMPOSE_LABEL_PREFIX) } self.assertEqual( compose_labels, {MODULE.PROJECT_LABEL, MODULE.SERVICE_LABEL} ) def test_injected_target_project_label_is_rejected(self) -> None: spec = executor_spec() argv = MODULE.build_run_argv(spec) tampered = argv + [ "--label", f"{MODULE.PROJECT_LABEL}={MODULE.TARGET_PROJECT}", ] with self.assertRaises(MODULE.HelperError) as ctx: MODULE.assert_argv_isolation(tampered, spec) self.assertEqual(ctx.exception.code, "helper_argv_targets_project") def test_injected_target_service_label_is_rejected(self) -> None: spec = control_plane_spec() tampered = MODULE.build_run_argv(spec) + [ "--label", f"{MODULE.SERVICE_LABEL}=api", ] with self.assertRaises(MODULE.HelperError) as ctx: MODULE.assert_argv_isolation(tampered, spec) self.assertEqual(ctx.exception.code, "helper_argv_targets_service") def test_undeclared_compose_label_is_rejected(self) -> None: spec = executor_spec() tampered = MODULE.build_run_argv(spec) + [ "--label", f"{MODULE.COMPOSE_LABEL_PREFIX}config-hash=deadbeef", ] with self.assertRaises(MODULE.HelperError) as ctx: MODULE.assert_argv_isolation(tampered, spec) self.assertEqual(ctx.exception.code, "helper_argv_undeclared_compose_label") def test_label_file_and_non_host_network_are_rejected(self) -> None: spec = executor_spec() with self.assertRaises(MODULE.HelperError): MODULE.assert_argv_isolation( MODULE.build_run_argv(spec) + ["--label-file", "/tmp/labels"], spec ) with self.assertRaises(MODULE.HelperError) as ctx: MODULE.assert_argv_isolation( [ "docker", "run", "--network", f"{MODULE.TARGET_PROJECT}_vignette", spec.image, ], spec, ) self.assertEqual(ctx.exception.code, "helper_argv_network_not_isolated") def test_executor_argv_carries_the_hardening_flags(self) -> None: argv = MODULE.build_run_argv(executor_spec()) self.assertIn("--read-only", argv) self.assertIn("--cap-drop", argv) self.assertEqual(argv[argv.index("--cap-drop") + 1], "ALL") self.assertIn("--security-opt", argv) self.assertEqual( argv[argv.index("--security-opt") + 1], "no-new-privileges" ) self.assertEqual( argv[argv.index("--user") + 1], f"{MODULE.HELPER_UID}:{MODULE.HELPER_GID}", ) self.assertEqual( argv[argv.index("--group-add") + 1], str(MODULE.HELPER_SUPPLEMENTAL_GID), ) self.assertEqual(argv[argv.index("--network") + 1], "host") def test_executor_argv_mounts_target_root_read_only_and_state_rw(self) -> None: argv = MODULE.build_run_argv(executor_spec()) mounts = [ argv[index + 1] for index, item in enumerate(argv) if item == "--mount" ] self.assertIn( f"type=bind,source={MODULE.TARGET_ROOT}," f"target={MODULE.TARGET_ROOT},readonly", mounts, ) self.assertIn( f"type=bind,source={MODULE.STATE_DIR},target={MODULE.STATE_DIR}", mounts, ) self.assertIn( f"type=bind,source={MODULE.DOCKER_BINARY_SOURCE}," f"target={MODULE.DOCKER_BINARY_TARGET},readonly", mounts, ) self.assertIn( f"type=bind,source={MODULE.COMPOSE_PLUGIN_SOURCE}," f"target={MODULE.COMPOSE_PLUGIN_TARGET},readonly", mounts, ) self.assertIn( f"type=bind,source={MODULE.TARGET_DOCKER_SOCKET}," f"target={MODULE.TARGET_DOCKER_SOCKET}", mounts, ) def test_executor_argv_binds_loopback_and_the_audited_manifest(self) -> None: argv = MODULE.build_run_argv(executor_spec()) self.assertEqual(argv[argv.index("--entrypoint") + 1], "python3.11") self.assertEqual(argv[argv.index("--host") + 1], MODULE.EXECUTOR_HOST) self.assertEqual(argv[argv.index("--port") + 1], str(MODULE.EXECUTOR_PORT)) self.assertEqual(argv[argv.index("--manifest") + 1], str(MODULE.MANIFEST_PATH)) self.assertEqual(argv[argv.index("--manifest-sha256") + 1], MANIFEST_SHA) self.assertIn("--enable", argv) def test_control_plane_argv_binds_its_own_loopback_port(self) -> None: argv = MODULE.build_run_argv(control_plane_spec()) self.assertEqual(argv[argv.index("--entrypoint") + 1], "uvicorn") self.assertEqual(argv[argv.index("--host") + 1], MODULE.CONTROL_PLANE_HOST) self.assertEqual( argv[argv.index("--port") + 1], str(MODULE.CONTROL_PLANE_PORT) ) self.assertNotIn("--publish", argv) def test_argv_never_mutates_the_target_compose_project(self) -> None: for spec in (executor_spec(), control_plane_spec(), probe_spec()): argv = MODULE.build_run_argv(spec) self.assertEqual(argv[1], "run") for forbidden in ("compose", "down", "prune", "rm", "stop", "kill"): self.assertNotIn(forbidden, argv[1:2]) self.assertNotIn(MODULE.TARGET_PROJECT, argv[3:]) class ProbeRoleTest(unittest.TestCase): def test_probe_never_mounts_the_docker_socket(self) -> None: argv = MODULE.build_run_argv(probe_spec()) mounts = [ argv[index + 1] for index, item in enumerate(argv) if item == "--mount" ] self.assertFalse( any(MODULE.TARGET_DOCKER_SOCKET in mount for mount in mounts) ) self.assertNotIn("--group-add", argv) def test_probe_targets_the_separate_control_plane_origin(self) -> None: argv = MODULE.build_run_argv(probe_spec()) control = argv[argv.index("--control-plane-base-url") + 1] preview = argv[argv.index("--preview-base-url") + 1] self.assertEqual(control, MODULE.CONTROL_PLANE_BASE_URL) self.assertEqual(preview, MODULE.PREVIEW_BASE_URL) self.assertNotEqual(control, preview) def test_probe_plan_and_output_stay_inside_the_state_dir(self) -> None: for plan_name in ("rollback-old", "restore-current"): argv = MODULE.build_run_argv(probe_spec(plan_name)) plan = argv[argv.index("--plan") + 1] output = argv[argv.index("--output") + 1] self.assertEqual( plan, f"{MODULE.PLANS_DIR}/{plan_name}.plan.json" ) self.assertTrue(output.startswith(f"{MODULE.EVIDENCE_DIR}/")) self.assertIn("execute", argv) def test_probe_plan_name_is_validated(self) -> None: for bad in ("../escape", "Rollback", "a", "x" * 80): with self.assertRaises(MODULE.HelperError): MODULE.probe_spec(run_id=RUN_ID, image=IMAGE, plan_name=bad) def test_wait_reports_the_exit_code(self) -> None: spec = probe_spec() runner = FakeRunner( { "wait_helper": "0\n", "inspect_container_id": "b" * 64 + "\n", "inspect_container_state": "false\n", } ) result = MODULE.HelperLauncher(runner).wait(spec, timeout_seconds=60) self.assertEqual(result["exit_code"], 0) self.assertFalse(result["container_running"]) self.assertEqual( runner.argv_for("wait_helper"), ["docker", "wait", spec.container_name] ) def test_wait_rejects_an_unbounded_timeout(self) -> None: with self.assertRaises(MODULE.HelperError): MODULE.HelperLauncher(FakeRunner()).wait(probe_spec(), timeout_seconds=0) class IsolationVerificationTest(unittest.TestCase): def test_inherited_baseline_labels_are_accepted(self) -> None: spec = executor_spec() evidence = MODULE.verify_container_isolation( spec=spec, baseline_labels=BASELINE_LABELS, container_labels=container_labels(spec), target_project_members=[f"{MODULE.TARGET_PROJECT}-api-1"], ) self.assertEqual( evidence["inherited_compose_labels"], {"com.docker.compose.version": "2.20.1"}, ) self.assertEqual( evidence["isolated_override_labels"], { MODULE.PROJECT_LABEL: spec.isolated_project, MODULE.SERVICE_LABEL: spec.isolated_service, }, ) self.assertEqual( evidence["baseline_compose_labels"]["com.docker.compose.project"], MODULE.TARGET_PROJECT, ) def test_zero_compose_labels_is_not_required(self) -> None: spec = executor_spec() labels = container_labels(spec) self.assertTrue( any(key.startswith(MODULE.COMPOSE_LABEL_PREFIX) for key in labels) ) MODULE.verify_container_isolation( spec=spec, baseline_labels=BASELINE_LABELS, container_labels=labels, target_project_members=[], ) def test_target_project_membership_is_rejected(self) -> None: spec = executor_spec() with self.assertRaises(MODULE.HelperError) as ctx: MODULE.verify_container_isolation( spec=spec, baseline_labels=BASELINE_LABELS, container_labels=container_labels( spec, **{MODULE.PROJECT_LABEL: MODULE.TARGET_PROJECT} ), target_project_members=[], ) self.assertEqual(ctx.exception.code, "helper_isolated_label_mismatch") def test_target_service_claim_is_rejected(self) -> None: spec = MODULE.HelperSpec( role="executor", run_id=RUN_ID, image=IMAGE, env_file=str(MODULE.STATE_DIR / "x.env"), entrypoint="python3.11", command=("-c", "pass"), ) labels = container_labels(spec) labels[MODULE.SERVICE_LABEL] = "db" with self.assertRaises(MODULE.HelperError): MODULE.verify_container_isolation( spec=spec, baseline_labels=BASELINE_LABELS, container_labels=labels, target_project_members=[], ) def test_unexpected_compose_label_drift_is_rejected(self) -> None: spec = executor_spec() labels = container_labels(spec) labels["com.docker.compose.version"] = "9.9.9" with self.assertRaises(MODULE.HelperError) as ctx: MODULE.verify_container_isolation( spec=spec, baseline_labels=BASELINE_LABELS, container_labels=labels, target_project_members=[], ) self.assertEqual(ctx.exception.code, "helper_compose_label_drift") def test_missing_isolated_override_is_rejected(self) -> None: spec = executor_spec() labels = container_labels(spec) del labels[MODULE.SERVICE_LABEL] with self.assertRaises(MODULE.HelperError) as ctx: MODULE.verify_container_isolation( spec=spec, baseline_labels=BASELINE_LABELS, container_labels=labels, target_project_members=[], ) self.assertEqual(ctx.exception.code, "helper_isolated_label_missing") def test_helper_listed_in_target_project_is_rejected(self) -> None: spec = executor_spec() with self.assertRaises(MODULE.HelperError) as ctx: MODULE.verify_container_isolation( spec=spec, baseline_labels=BASELINE_LABELS, container_labels=container_labels(spec), target_project_members=[spec.container_name], ) self.assertEqual(ctx.exception.code, "helper_listed_in_target_project") def test_missing_provenance_label_is_rejected(self) -> None: spec = executor_spec() labels = container_labels(spec) del labels[MODULE.HELPER_LABEL] with self.assertRaises(MODULE.HelperError) as ctx: MODULE.verify_container_isolation( spec=spec, baseline_labels=BASELINE_LABELS, container_labels=labels, target_project_members=[], ) self.assertEqual(ctx.exception.code, "helper_provenance_label_missing") class LauncherRunnerTest(unittest.TestCase): def _responses(self, spec: object) -> dict[str, str]: return { "inspect_image_labels": json.dumps(BASELINE_LABELS), "inspect_container_labels": json.dumps(container_labels(spec)), "inspect_container_id": "a" * 64 + "\n", "inspect_container_state": "true\n", "list_target_project_members": ( f"{MODULE.TARGET_PROJECT}-api-1\n{MODULE.TARGET_PROJECT}-web-1\n" ), } def test_start_uses_the_exact_argv_and_returns_the_container_id(self) -> None: spec = executor_spec() runner = FakeRunner(self._responses(spec)) launcher = MODULE.HelperLauncher(runner) container_id = launcher.start(spec) self.assertEqual(container_id, "a" * 64) self.assertEqual( runner.argv_for("run_helper"), MODULE.build_run_argv(spec) ) def test_verify_emits_exact_container_identity_evidence(self) -> None: spec = control_plane_spec() runner = FakeRunner(self._responses(spec)) evidence = MODULE.HelperLauncher(runner).verify(spec) self.assertEqual(evidence["schema_version"], MODULE.EVIDENCE_SCHEMA) self.assertEqual(evidence["container_name"], spec.container_name) self.assertEqual(evidence["container_id"], "a" * 64) self.assertTrue(evidence["container_running"]) self.assertEqual(evidence["target_project"], MODULE.TARGET_PROJECT) self.assertNotIn(spec.container_name, evidence["target_project_members"]) def test_membership_query_filters_on_the_target_project_label(self) -> None: spec = executor_spec() runner = FakeRunner(self._responses(spec)) MODULE.HelperLauncher(runner).verify(spec) argv = runner.argv_for("list_target_project_members") self.assertIn("ps", argv) self.assertIn( f"label={MODULE.PROJECT_LABEL}={MODULE.TARGET_PROJECT}", argv ) def test_stop_refuses_a_container_outside_the_isolated_project(self) -> None: spec = executor_spec() responses = self._responses(spec) foreign = container_labels(spec) foreign[MODULE.PROJECT_LABEL] = "someone-else" responses["inspect_container_labels"] = json.dumps(foreign) launcher = MODULE.HelperLauncher(FakeRunner(responses)) with self.assertRaises(MODULE.HelperError) as ctx: launcher.stop(spec) self.assertEqual(ctx.exception.code, "helper_stop_project_mismatch") def test_stop_only_touches_the_exact_helper_name(self) -> None: spec = executor_spec() runner = FakeRunner(self._responses(spec)) MODULE.HelperLauncher(runner).stop(spec) stop_argv = runner.argv_for("stop_helper") remove_argv = runner.argv_for("remove_helper") self.assertEqual(stop_argv[-1], spec.container_name) self.assertEqual(remove_argv, ["docker", "rm", spec.container_name]) self.assertNotIn("--force", remove_argv) self.assertNotIn("--volumes", remove_argv) def test_invalid_label_json_fails_closed(self) -> None: spec = executor_spec() responses = self._responses(spec) responses["inspect_image_labels"] = "not-json" launcher = MODULE.HelperLauncher(FakeRunner(responses)) with self.assertRaises(MODULE.HelperError) as ctx: launcher.image_labels(spec.image) self.assertEqual(ctx.exception.code, "helper_labels_unreadable") def test_null_image_labels_are_read_as_empty(self) -> None: runner = FakeRunner({"inspect_image_labels": "null\n"}) launcher = MODULE.HelperLauncher(runner) self.assertEqual(launcher.image_labels(IMAGE), {}) def test_ssh_runner_quotes_the_argv_into_one_remote_command(self) -> None: inner = FakeRunner() runner = MODULE.SshCommandRunner( destination="user@host", identity_file="C:/key", inner=inner, ) runner.run("probe", ["docker", "ps", "--filter", "label=a=b c"], timeout=5) argv = inner.argv_for("probe") self.assertEqual(argv[0], "ssh") self.assertIn("BatchMode=yes", argv) self.assertEqual(argv[-2], "user@host") self.assertEqual(argv[-1], "docker ps --filter 'label=a=b c'") if __name__ == "__main__": unittest.main()