feat(platform): complete the Gelios external data loop

This commit is contained in:
Codex
2026-07-20 20:45:05 +03:00
parent def9a24e0d
commit 8a7465cf0e
66 changed files with 5730 additions and 123 deletions
@@ -372,8 +372,10 @@ class CanonicalPlatformRegistryTest(unittest.TestCase):
original_root = RUNNER.COMPONENTS["engine"]["payload_root"]
original_hashes = RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_SHA256
original_installed_hashes = RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_INSTALLED_FOUNDATION_SHA256
RUNNER.COMPONENTS["engine"]["payload_root"] = root
RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_SHA256 = expected
RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_INSTALLED_FOUNDATION_SHA256 = expected
try:
self.assertEqual(
RUNNER.preflight_engine_data_product_publish_grant_predecessor(),
@@ -391,6 +393,7 @@ class CanonicalPlatformRegistryTest(unittest.TestCase):
RUNNER.preflight_engine_data_product_publish_grant_predecessor()
finally:
RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_SHA256 = original_hashes
RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_INSTALLED_FOUNDATION_SHA256 = original_installed_hashes
RUNNER.COMPONENTS["engine"]["payload_root"] = original_root
def test_installed_publish_update_preserves_foundation_and_allows_only_grant_source_changes(self):
@@ -441,8 +444,10 @@ class CanonicalPlatformRegistryTest(unittest.TestCase):
original_root = RUNNER.COMPONENTS["engine"]["payload_root"]
original_hashes = RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_SHA256
original_installed_hashes = RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_INSTALLED_FOUNDATION_SHA256
RUNNER.COMPONENTS["engine"]["payload_root"] = root
RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_SHA256 = expected
RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_INSTALLED_FOUNDATION_SHA256 = expected
try:
self.assertEqual(
RUNNER.preflight_engine_data_product_publish_grant_predecessor(payload),
@@ -470,6 +475,99 @@ class CanonicalPlatformRegistryTest(unittest.TestCase):
RUNNER.preflight_engine_data_product_publish_grant_predecessor(payload)
finally:
RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_PREDECESSOR_SHA256 = original_hashes
RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_INSTALLED_FOUNDATION_SHA256 = original_installed_hashes
RUNNER.COMPONENTS["engine"]["payload_root"] = original_root
def test_composite_provider_update_requires_exact_v3_to_v4_catalog_and_four_paths(self):
engine_source = SCRIPT_DIR.parent.parent.parent / "NODEDC_ENGINE_INFRA"
current_target_sha256 = {
rel: hashlib.sha256((engine_source / rel).read_bytes()).hexdigest()
for rel in RUNNER.ENGINE_COMPOSITE_PROVIDER_V4_ARTIFACT_ENTRIES
}
if current_target_sha256 != RUNNER.ENGINE_COMPOSITE_PROVIDER_V4_TARGET_SHA256:
self.skipTest("historical v3-to-v4 fixture source has advanced to its exact successor")
with tempfile.TemporaryDirectory(prefix="nodedc-composite-provider-update-") as directory:
base = Path(directory)
root = base / "installed"
payload = base / "payload"
root.mkdir()
payload.mkdir()
v3_catalog = {
"schemaVersion": "nodedc.engine.provider-security-catalog/v1",
"packages": [{
"id": "gelios.provider.v3",
"version": "3.0.0",
"providerId": "gelios",
"providerCredential": {
"authModeId": "gelios.rest-rotating-bearer.v3",
"credentialType": "httpBearerAuth",
},
"capabilities": [{
"id": "gelios.units.current.read",
"classification": "read",
"status": "implemented",
"request": {
"method": "GET",
"url": "https://api.geliospro.com/api/v1/units",
},
"dataProductIds": ["fleet.positions.current.v2"],
}],
"publisher": {
"nodeType": "n8n-nodes-ndc.ndcDataProductPublish",
"credentialType": "ndcDataProductWriterApi",
},
}],
}
installed_catalog = f"{json.dumps(v3_catalog, indent=2)}\n"
self.assertEqual(
hashlib.sha256(installed_catalog.encode()).hexdigest(),
RUNNER.ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CATALOG_PREDECESSOR_SHA256,
)
for rel in RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_ARTIFACT_ENTRIES:
if rel == "nodedc-source/server/dataProductPublishGrant":
continue
for destination in (root, payload):
path = destination / rel
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(f"shared:{rel}\n", encoding="utf-8")
for name in RUNNER.ENGINE_DATA_PRODUCT_PUBLISH_GRANT_SOURCE_FILES:
rel = f"nodedc-source/server/dataProductPublishGrant/{name}"
for destination in (root, payload):
path = destination / rel
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(f"installed:{name}\n", encoding="utf-8")
catalog_rel = RUNNER.ENGINE_PROVIDER_SECURITY_CATALOG_REL
(root / catalog_rel).write_text(installed_catalog, encoding="utf-8")
for rel in RUNNER.ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CHANGED_PATHS:
source = engine_source / rel
(payload / rel).write_bytes(source.read_bytes())
original_root = RUNNER.COMPONENTS["engine"]["payload_root"]
RUNNER.COMPONENTS["engine"]["payload_root"] = root
try:
with mock.patch.object(
RUNNER,
"validate_installed_engine_data_product_publish_grant_foundation",
return_value="compose-sha256",
):
self.assertEqual(
RUNNER.preflight_engine_data_product_publish_grant_predecessor(payload),
{
"mode": "installed-composite-provider-update",
"compose_sha256": "compose-sha256",
"changed_paths": RUNNER.ENGINE_PUBLISH_GRANT_COMPOSITE_PROVIDER_CHANGED_PATHS,
},
)
(root / catalog_rel).write_text("{}\n", encoding="utf-8")
with self.assertRaisesRegex(
RUNNER.DeployError,
"composite provider catalog transition mismatch",
):
RUNNER.preflight_engine_data_product_publish_grant_predecessor(payload)
finally:
RUNNER.COMPONENTS["engine"]["payload_root"] = original_root
def test_edp_healthcheck_requires_database_and_managed_provisioning(self):