NODEDC_PLATFORM/infra/deploy-runner/test_engine_mcp_ontology_sd...

141 lines
6.2 KiB
Python

#!/usr/bin/env python3
import hashlib
import importlib.machinery
import importlib.util
import json
import os
import subprocess
import tarfile
import tempfile
import unittest
from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
PLATFORM_ROOT = SCRIPT_DIR.parent.parent
ENGINE_ROOT = PLATFORM_ROOT.parent / "NODEDC_ENGINE_INFRA"
RUNNER_PATH = SCRIPT_DIR / "nodedc-deploy"
ENGINE_BUILDER = SCRIPT_DIR / "build-engine-mcp-ontology-sdk-artifact.mjs"
PLATFORM_BUILDER = SCRIPT_DIR / "build-platform-gelios-provider-v2-artifact.mjs"
ENGINE_ARTIFACT = (
PLATFORM_ROOT
/ "infra/deploy-artifacts/nodedc-engine-mcp-control-plane-20260718-005.tgz"
)
PLATFORM_ARTIFACT = (
PLATFORM_ROOT
/ "infra/deploy-artifacts/nodedc-platform-gelios-provider-v2-20260718-005.tgz"
)
ENGINE_SHA256 = "8d6e1581ebbba420984e2393b8c6f0f21e0b644f630c4ca6483a7cc4a0ae5c71"
PLATFORM_SHA256 = "e1b838ec265369af735766fc7d1bf23c5e05bd2d15ef65e2446b4f7efa7a1baa"
def load_runner():
loader = importlib.machinery.SourceFileLoader("nodedc_engine_mcp_ontology_sdk", 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 EngineMcpOntologySdkTest(unittest.TestCase):
def test_canonical_artifacts_have_pinned_digests_and_safe_members(self):
for artifact, expected in (
(ENGINE_ARTIFACT, ENGINE_SHA256),
(PLATFORM_ARTIFACT, PLATFORM_SHA256),
):
self.assertEqual(hashlib.sha256(artifact.read_bytes()).hexdigest(), expected)
self.assertEqual(artifact.read_bytes()[4:8], b"\0\0\0\0")
with tarfile.open(artifact, "r:gz") as archive:
for member in archive:
self.assertTrue(member.isfile() or member.isdir())
self.assertFalse(Path(member.name).name.startswith("._"))
def test_engine_builder_is_byte_reproducible(self):
current_sha256 = {
relative_path: hashlib.sha256((ENGINE_ROOT / relative_path).read_bytes()).hexdigest()
for relative_path in RUNNER.ENGINE_MCP_ONTOLOGY_SDK_TARGET_SHA256
}
if current_sha256 != RUNNER.ENGINE_MCP_ONTOLOGY_SDK_TARGET_SHA256:
self.skipTest("historical Ontology/SDK builder source has advanced to its exact successor")
outputs = []
with tempfile.TemporaryDirectory(prefix="nodedc-engine-mcp-ontology-sdk-") as directory:
for index in range(2):
target = Path(directory) / str(index)
target.mkdir()
env = os.environ.copy()
env["NODEDC_DEPLOY_ARTIFACT_DIR"] = str(target)
result = subprocess.run(
["node", str(ENGINE_BUILDER), "20260718-005"],
cwd=PLATFORM_ROOT,
env=env,
check=True,
capture_output=True,
text=True,
)
outputs.append(Path(json.loads(result.stdout)["artifact"]).read_bytes())
self.assertEqual(outputs[0], outputs[1])
self.assertEqual(outputs[0], ENGINE_ARTIFACT.read_bytes())
def test_platform_builder_is_byte_reproducible(self):
outputs = []
with tempfile.TemporaryDirectory(prefix="nodedc-platform-gelios-v2-") as directory:
for index in range(2):
target = Path(directory) / str(index)
target.mkdir()
env = os.environ.copy()
env["NODEDC_DEPLOY_ARTIFACT_DIR"] = str(target)
result = subprocess.run(
["node", str(PLATFORM_BUILDER), "20260718-005"],
cwd=PLATFORM_ROOT,
env=env,
check=True,
capture_output=True,
text=True,
)
outputs.append(Path(json.loads(result.stdout)["artifact"]).read_bytes())
self.assertEqual(outputs[0], outputs[1])
self.assertEqual(outputs[0], PLATFORM_ARTIFACT.read_bytes())
def test_engine_slice_is_exact_and_restarts_only_backend(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
manifest, entries, payload = RUNNER.load_artifact(ENGINE_ARTIFACT, root)
descriptor = RUNNER.validate_engine_mcp_ontology_sdk_payload(payload, entries)
self.assertEqual(manifest["component"], "engine")
self.assertEqual(tuple(entries), RUNNER.ENGINE_MCP_ONTOLOGY_SDK_ARTIFACT_ENTRIES)
self.assertEqual(RUNNER.component_services("engine", entries), ("nodedc-backend",))
self.assertEqual(RUNNER.component_builds("engine", entries), ())
self.assertEqual(
descriptor["source"]["gatewaySha256"],
RUNNER.ENGINE_MCP_ONTOLOGY_SDK_TARGET_SHA256[
RUNNER.ENGINE_NODE_INTELLIGENCE_GATEWAY_REL
],
)
def test_platform_provider_package_is_metadata_only(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
manifest, entries, _payload = RUNNER.load_artifact(PLATFORM_ARTIFACT, root)
self.assertEqual(manifest["component"], "platform")
self.assertTrue(RUNNER.is_platform_provider_catalog_only(entries))
self.assertEqual(RUNNER.component_services("platform", entries), ())
self.assertEqual(RUNNER.component_builds("platform", entries), ())
self.assertEqual(RUNNER.component_healthchecks("platform", entries, ()), ())
def test_engine_payload_tampering_is_rejected(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
RUNNER.safe_extract(ENGINE_ARTIFACT, root)
entries = RUNNER.parse_files_list(root / "files.txt")
catalog = root / "payload/nodedc-source/server/assets/provider-packages/v1/catalog.json"
catalog.write_text("{}\n", encoding="utf-8")
with self.assertRaisesRegex(RUNNER.DeployError, "target sha256 mismatch"):
RUNNER.validate_engine_mcp_ontology_sdk_payload(root / "payload", entries)
if __name__ == "__main__":
unittest.main(verbosity=2)