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

166 lines
7.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):
current_sha256 = {
relative_path: hashlib.sha256((ENGINE_ROOT / relative_path).read_bytes()).hexdigest()
for relative_path in RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES
}
if current_sha256 != RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_TARGET_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)
relative_path = RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_ARTIFACT_ENTRIES[0]
path = root / relative_path
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("predecessor\n", encoding="utf-8")
expected = 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", return_value=expected),
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")
target_hash = next(iter(RUNNER.ENGINE_PROVIDER_AUTHORITY_DIAGNOSTICS_TARGET_SHA256.values()))
with (
mock.patch.object(RUNNER, "component_root", return_value=root),
mock.patch.object(RUNNER, "sha256_file", return_value=target_hash),
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 (
mock.patch.object(RUNNER, "component_root", return_value=ENGINE_ROOT),
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)