NODEDC_PLATFORM/infra/deploy-runner/test_engine_provider_author...

192 lines
8.3 KiB
Python

import hashlib
import importlib.machinery
import importlib.util
import json
import os
from pathlib import Path
import subprocess
import tarfile
import tempfile
import unittest
from unittest import mock
SCRIPT_DIR = Path(__file__).resolve().parent
RUNNER_PATH = SCRIPT_DIR / "nodedc-deploy"
BUILDER_PATH = SCRIPT_DIR / "build-engine-provider-authority-diagnostics-artifact.mjs"
ENGINE_ROOT = SCRIPT_DIR.parent.parent.parent / "NODEDC_ENGINE_INFRA"
PATCH_ID = "engine-provider-authority-diagnostics-20991231-999"
def load_runner():
loader = importlib.machinery.SourceFileLoader(
"nodedc_engine_provider_authority_diagnostics",
str(RUNNER_PATH),
)
spec = importlib.util.spec_from_loader(loader.name, loader)
module = importlib.util.module_from_spec(spec)
loader.exec_module(module)
return module
RUNNER = load_runner()
class EngineProviderAuthorityDiagnosticsTest(unittest.TestCase):
def require_historical_target(self):
source_entries = [
relative_path
for relative_path in RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES
if relative_path != RUNNER.ENGINE_NODE_INTELLIGENCE_DESCRIPTOR_REL
]
current_sha256 = {
relative_path: hashlib.sha256((ENGINE_ROOT / relative_path).read_bytes()).hexdigest()
for relative_path in source_entries
}
expected_sha256 = {
relative_path: RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_TARGET_SHA256[relative_path]
for relative_path in source_entries
}
if current_sha256 != expected_sha256:
self.skipTest("historical provider authority diagnostics source has advanced")
def build(self, artifact_dir):
self.require_historical_target()
environment = os.environ.copy()
environment["NODEDC_ENGINE_SOURCE_ROOT"] = str(ENGINE_ROOT)
environment["NODEDC_DEPLOY_ARTIFACT_DIR"] = str(artifact_dir)
completed = subprocess.run(
["node", str(BUILDER_PATH), PATCH_ID],
check=True,
capture_output=True,
text=True,
env=environment,
)
return json.loads(completed.stdout)
def test_builder_emits_exact_deterministic_one_file_slice(self):
with tempfile.TemporaryDirectory(prefix="nodedc-provider-authority-") as directory:
root = Path(directory)
first = self.build(root / "first")
second = self.build(root / "second")
first_artifact = Path(first["artifact"])
second_artifact = Path(second["artifact"])
self.assertEqual(first_artifact.read_bytes(), second_artifact.read_bytes())
self.assertEqual(first["sha256"], hashlib.sha256(first_artifact.read_bytes()).hexdigest())
self.assertEqual(first["services"], ["nodedc-backend"])
self.assertEqual(
tuple(first["entries"]),
RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES,
)
extract = root / "extract"
with tarfile.open(first_artifact, "r:gz") as archive:
archive.extractall(extract, filter="data")
entries = tuple((extract / "files.txt").read_text(encoding="utf-8").splitlines())
payload = extract / "payload"
self.assertTrue(RUNNER.is_engine_provider_authority_diagnostics_slice("engine", entries))
self.assertEqual(RUNNER.component_services("engine", entries), ("nodedc-backend",))
self.assertEqual(
RUNNER.component_healthchecks("engine", entries, ("nodedc-backend",)),
("http://127.0.0.1:3001/health",),
)
RUNNER.validate_engine_provider_authority_diagnostics_slice(payload, entries)
loaded_manifest, loaded_entries, loaded_payload = RUNNER.load_artifact(
first_artifact,
root / "loaded",
)
self.assertEqual(loaded_manifest["component"], "engine")
self.assertEqual(tuple(loaded_entries), entries)
RUNNER.validate_engine_provider_authority_diagnostics_slice(
loaded_payload,
loaded_entries,
)
def test_preflight_requires_the_exact_deployed_predecessor(self):
with tempfile.TemporaryDirectory(prefix="nodedc-provider-authority-preflight-") as directory:
root = Path(directory)
for relative_path in RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES:
path = root / relative_path
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("predecessor\n", encoding="utf-8")
def predecessor_sha256(path):
relative_path = path.relative_to(root).as_posix()
return RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_PREDECESSOR_SHA256[
relative_path
]
with (
mock.patch.object(RUNNER, "component_root", return_value=root),
mock.patch.object(RUNNER, "sha256_file", side_effect=predecessor_sha256),
mock.patch.object(
RUNNER,
"preflight_engine_credential_backend_runtime",
return_value={"mode": "verified-derived-retry"},
),
):
result = RUNNER.preflight_engine_provider_authority_diagnostics_predecessor()
self.assertEqual(result["mode"], "private-node-name-reconciliation")
with (
mock.patch.object(RUNNER, "component_root", return_value=root),
mock.patch.object(RUNNER, "sha256_file", return_value="0" * 64),
):
with self.assertRaises(RUNNER.DeployError):
RUNNER.preflight_engine_provider_authority_diagnostics_predecessor()
def test_healthchecks_dispatch_authority_diagnostics_acceptance(self):
entries = RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES
root = Path("/engine")
def target_sha256(path):
relative_path = path.relative_to(root).as_posix()
return RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_TARGET_SHA256[relative_path]
with (
mock.patch.object(RUNNER, "component_root", return_value=root),
mock.patch.object(RUNNER, "sha256_file", side_effect=target_sha256),
mock.patch.object(RUNNER, "healthcheck_compose_service"),
mock.patch.object(RUNNER, "component_healthchecks", return_value=()),
mock.patch.object(
RUNNER,
"preflight_engine_credential_backend_runtime",
return_value={"mode": "verified-derived-retry"},
),
mock.patch.object(
RUNNER,
"accept_engine_provider_authority_diagnostics_runtime",
return_value={"live": "accepted"},
) as acceptance,
mock.patch.object(RUNNER, "healthcheck_container"),
):
RUNNER.run_healthchecks("engine", entries, ("nodedc-backend",))
acceptance.assert_called_once_with()
def test_live_acceptance_uses_private_node_reconciliation_contract(self):
self.require_historical_target()
expected_live = "engine-private-node-reconciliation:exact-id-or-name:v1"
with tempfile.TemporaryDirectory(prefix="nodedc-provider-authority-live-") as directory:
root = Path(directory)
built = self.build(root / "artifact")
_manifest, _entries, payload = RUNNER.load_artifact(
Path(built["artifact"]),
root / "loaded",
)
with (
mock.patch.object(RUNNER, "component_root", return_value=payload),
mock.patch.object(RUNNER, "engine_backend_container_id", return_value="backend"),
mock.patch.object(
RUNNER,
"run_engine_backend_probe",
return_value=expected_live,
) as backend_probe,
):
result = RUNNER.accept_engine_provider_authority_diagnostics_runtime()
self.assertEqual(result["live"], expected_live)
self.assertEqual(backend_probe.call_args.args[1], "Engine private node validation reconciliation")
if __name__ == "__main__":
unittest.main(verbosity=2)