Files
OpenShell/python/openshell/gateway_schema_v2_live_results_test.py
Jesse JaggarsandDrew Newberry 02b664bb0d refactor(config): normalize and enforce gateway schema v2 (#2814)
* refactor(config): normalize compute driver field names

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* refactor(config): introduce canonical gateway fields

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* refactor(config): enforce gateway schema version 2

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(config): preserve compute driver runtime guarantees

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(config): address schema v2 review regressions

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(config): complete schema v2 migration safeguards

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(config): expand schema v2 regression coverage

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(config): add schema v2 parity manifest

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(config): correct parity manifest inventory

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* docs(config): record schema v2 intentional changes

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* docs(config): disposition schema v2 parity gaps

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): add dual schema parity harness

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): establish compute lifecycle parity baseline

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(config): preserve gateway option compatibility

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): record gateway option parity

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* docs(config): close gateway-wide parity gaps

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(podman): apply configured pids limit

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): validate Podman option parity

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): add Kubernetes option parity harness

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): record Kubernetes option parity

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): disposition VM parity lanes

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): add external driver parity lane

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(e2e): preserve external driver pull policy

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): attest parity artifacts and launches

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): require clean parity build sources

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): bind parity runtime artifacts

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(e2e): use isolated supervisor tags

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(e2e): qualify parity image tags

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(e2e): serve parity supervisor locally

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): isolate parity podman services

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): harden parity evidence provenance

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): pin parity sandbox artifacts

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): attest parity runtime inputs

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): bind parity runtime evidence

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): record compute boundary parity

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(e2e): disposition cross-cutting parity lanes

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(packaging): preflight gateway config upgrades

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(config): preserve rebase integration guarantees

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(ci): isolate temporary git signing config

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(config): update remaining schema v2 consumers

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(ci): provide e2fs tools to VM tests

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(config): align preflight with gateway startup

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(vm): preserve rootfs tar configuration

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* chore(config): adopt duration unit constructors

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(packaging): preflight RPM gateway config

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(config): address driver review findings

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(e2e): require fresh semantic parity evidence

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* fix(docker): update tests for renamed sandbox label

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>

* test(gateway): preserve selective driver coverage after rebase

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

---------

Signed-off-by: Jesse Jaggars <jjaggars@redhat.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Co-authored-by: Drew Newberry <anewberry@nvidia.com>
2026-09-11 05:00:24 +00:00

450 lines
17 KiB
Python

# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Validate machine-readable schema-v2 live parity results."""
from __future__ import annotations
import hashlib
import json
import re
import subprocess
import tomllib
from pathlib import Path
from typing import Any
REPO_ROOT = Path(__file__).resolve().parents[2]
RESULTS_PATH = REPO_ROOT / "e2e/configs/gateway/schema-v2-live-results.toml"
CAPABILITY_PATH = REPO_ROOT / "e2e/configs/gateway/schema-v2-capability-parity.toml"
COMPUTE_BOUNDARY_PATH = (
REPO_ROOT / "e2e/configs/gateway/schema-v2-compute-boundary-comparison.json"
)
CROSS_CUTTING_DISPOSITIONS_PATH = (
REPO_ROOT / "e2e/configs/gateway/schema-v2-cross-cutting-dispositions.toml"
)
REQUIRED_HEADER_FIELDS = {
"manifest_version",
"baseline_commit",
"candidate_start_commit",
"result",
}
REQUIRED_STEP_5_IDS = {
"portable-lifecycle-docker",
"portable-lifecycle-kubernetes",
"portable-lifecycle-mxc",
"portable-lifecycle-podman",
"portable-lifecycle-vm",
}
REQUIRED_STEP_6_IDS = {
"gateway-tls-client-auth-policy",
"gateway-wide-process-options",
}
REQUIRED_STEP_7_IDS = {
"docker-driver-option-parity",
"podman-driver-option-parity",
"podman-qualified-security-option-parity",
}
REQUIRED_STEP_8_IDS = {
"kubernetes-core-option-parity",
"kubernetes-qualified-option-parity",
}
REQUIRED_STEP_9_IDS = {
"vm-guest-security-and-spiffe",
"vm-launch-and-resource-configuration",
}
REQUIRED_STEP_10_IDS = {"compute-driver-boundary-parity"}
REQUIRED_STEP_11_IDS = {
"credential-driver-backend-tables",
"credential-driver-selection-and-kek",
"gateway-interceptor-registration",
"gateway-minted-sandbox-jwt",
"inference-control-plane-configuration",
"mtls-user-authentication",
"oidc-bearer-authentication",
"otlp-observability",
"provider-profile-sources",
"supervisor-middleware-registration",
"unsafe-unauthenticated-user-mode",
}
REQUIRED_STEP_12_IDS = {
"debian-package-upgrade",
"homebrew-package-upgrade",
"rpm-package-upgrade",
"snap-package-refresh",
}
EXPECTED_EXECUTED_CANDIDATE_COMMITS = {
"portable-lifecycle-podman": "a3860084d019ed2ac979e3eaa1ddf085a96b773c",
"gateway-wide-process-options": "e6aac1aa7c624c5df43535ab4fbe2bc6f9697dea",
"gateway-tls-client-auth-policy": "e6aac1aa7c624c5df43535ab4fbe2bc6f9697dea",
"podman-driver-option-parity": "e09070d4ba0b30f0ac278fbb9938c1520ecff696",
"kubernetes-core-option-parity": "0f08b5822e4da98c9ced3d4b0f2bf4f30dae28fd",
"compute-driver-boundary-parity": "4a39da510e4d278a24dd60291149519c9a570b46",
}
STEP_10_CANDIDATE_COMMIT = EXPECTED_EXECUTED_CANDIDATE_COMMITS[
"compute-driver-boundary-parity"
]
STEP_10_REPORT_SHA256 = (
"65541eec5f642461a88b04b5459474fd7a475adeb7071a65a53fe183caad6a01"
)
STEP_10_EVIDENCE_BUNDLES = {
"in_tree": "target/parity/step10-intree-4a39da51",
"external_uds": "target/parity/step10-external-4a39da51",
}
ALLOWED_STATUSES = {
"pass",
"intentional_change",
"regression",
"platform_blocked",
}
BASE_FIELDS = {"id", "step", "capability", "driver", "status", "lane"}
PASS_FIELDS = {
"validated_baseline_commit",
"validated_candidate_commit",
"evidence",
}
BLOCKED_FIELDS = {"owner", "blocker"}
def load_toml(path: Path) -> dict[str, Any]:
with path.open("rb") as toml_file:
return tomllib.load(toml_file)
def assert_full_sha(value: object, field: str) -> str:
assert isinstance(value, str), f"{field} must be a string"
assert len(value) == 40 and all(char in "0123456789abcdef" for char in value), (
f"{field} must be a full lowercase SHA"
)
return value
def test_live_results_manifest_is_well_formed() -> None:
manifest = load_toml(RESULTS_PATH)
assert set(manifest) == REQUIRED_HEADER_FIELDS
assert manifest["manifest_version"] == 1
baseline = assert_full_sha(manifest["baseline_commit"], "baseline_commit")
assert_full_sha(manifest["candidate_start_commit"], "candidate_start_commit")
assert baseline == load_toml(CAPABILITY_PATH)["baseline_commit"]
results = manifest["result"]
assert isinstance(results, list) and results
ids: list[str] = []
for result in results:
assert set(result) >= BASE_FIELDS
result_id = result["id"]
assert isinstance(result_id, str) and result_id.strip()
ids.append(result_id)
assert result["status"] in ALLOWED_STATUSES
assert isinstance(result["step"], int) and 1 <= result["step"] <= 15
for field in ("capability", "driver", "lane"):
assert isinstance(result[field], str) and result[field].strip(), (
f"{result_id}: {field} is required"
)
assert len(ids) == len(set(ids))
def test_step_5_covers_every_in_tree_compute_driver() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 5
]
assert {result["id"] for result in results} == REQUIRED_STEP_5_IDS
assert {result["driver"] for result in results} == {
"docker",
"kubernetes",
"mxc",
"podman",
"vm",
}
def test_executed_results_pin_commits_and_evidence() -> None:
manifest = load_toml(RESULTS_PATH)
executed = {
result["id"]: result
for result in manifest["result"]
if result["status"] in {"pass", "intentional_change"}
}
assert set(executed) == set(EXPECTED_EXECUTED_CANDIDATE_COMMITS)
for result_id, result in executed.items():
assert set(result) >= PASS_FIELDS, result_id
assert result["validated_baseline_commit"] == manifest["baseline_commit"]
candidate = assert_full_sha(
result["validated_candidate_commit"],
f"{result_id}.validated_candidate_commit",
)
assert candidate == EXPECTED_EXECUTED_CANDIDATE_COMMITS[result_id]
assert isinstance(result["evidence"], list) and result["evidence"]
assert all(
isinstance(item, str) and item.strip() for item in result["evidence"]
)
# These immutable SHAs bind the original live-validation artifacts.
# A later history-preserving source rebase can intentionally make those
# exact execution commits non-ancestors without changing the evidence.
def test_step_6_records_gateway_option_and_tls_dispositions() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 6
]
assert {result["id"] for result in results} == REQUIRED_STEP_6_IDS
statuses = {result["id"]: result["status"] for result in results}
assert statuses["gateway-wide-process-options"] == "pass"
assert statuses["gateway-tls-client-auth-policy"] == "intentional_change"
def test_step_7_records_driver_option_dispositions() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 7
]
assert {result["id"] for result in results} == REQUIRED_STEP_7_IDS
statuses = {result["id"]: result["status"] for result in results}
assert statuses["podman-driver-option-parity"] == "intentional_change"
assert statuses["docker-driver-option-parity"] == "platform_blocked"
assert statuses["podman-qualified-security-option-parity"] == "platform_blocked"
def test_step_8_records_kubernetes_option_dispositions() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 8
]
assert {result["id"] for result in results} == REQUIRED_STEP_8_IDS
statuses = {result["id"]: result["status"] for result in results}
assert statuses["kubernetes-core-option-parity"] == "pass"
assert statuses["kubernetes-qualified-option-parity"] == "platform_blocked"
def test_step_9_records_vm_runtime_dispositions() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 9
]
assert {result["id"] for result in results} == REQUIRED_STEP_9_IDS
assert all(result["status"] == "platform_blocked" for result in results)
assert all(result["driver"] == "vm" for result in results)
def test_step_10_records_verified_compute_boundary_parity(tmp_path: Path) -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 10
]
assert {result["id"] for result in results} == REQUIRED_STEP_10_IDS
assert results[0]["status"] == "pass"
with COMPUTE_BOUNDARY_PATH.open(encoding="utf-8") as report_file:
report = json.load(report_file)
assert report["manifest_version"] == 2
assert report["baseline_commit"] == load_toml(RESULTS_PATH)["baseline_commit"]
assert report["candidate_commit"] == results[0]["validated_candidate_commit"]
assert report["candidate_commit"] == STEP_10_CANDIDATE_COMMIT
assert report["retained_evidence_bundles"] == STEP_10_EVIDENCE_BUNDLES
assert (
hashlib.sha256(COMPUTE_BOUNDARY_PATH.read_bytes()).hexdigest()
== STEP_10_REPORT_SHA256
)
assert report["classification"] == "pass"
assert report["accepted"] is True
assert all(report["oracle"].values())
assert all(report["verification"].values())
launch_attestations = []
for topology_name in ("in_tree", "external_uds"):
topology = report[topology_name]
assert topology["classification"] == "pass"
assert topology["parity"] is True
assert topology["accepted"] is True
assert re.fullmatch(r"[0-9a-f]{64}", topology["comparison_sha256"])
baseline_launch = topology["baseline"]["launch_attestation"]
candidate_launch = topology["candidate"]["launch_attestation"]
for field in (
"sandbox_image_id",
"sandbox_image_digest",
"sandbox_runtime_image",
"supervisor_base_image",
"supervisor_base_image_id",
"supervisor_base_image_digest",
"supervisor_package_manifest_sha256",
):
assert baseline_launch[field] == candidate_launch[field]
launch_attestations.extend((baseline_launch, candidate_launch))
for variant_name, schema_version in (("baseline", 1), ("candidate", 2)):
variant = topology[variant_name]
assert variant["schema_version"] == schema_version
assert variant["success"] is True
assert variant["artifacts_verified"] is True
assert variant["raw_output_verified"] is True
assert all(
re.fullmatch(r"[0-9a-f]{64}", digest)
for digest in variant["artifact_sha256"].values()
)
assert all(
re.fullmatch(r"[0-9a-f]{64}", digest)
for digest in variant["raw_evidence_sha256"].values()
)
launch = variant["launch_attestation"]
supervisor_digest = launch["supervisor_image_digest"]
assert re.fullmatch(r"sha256:[0-9a-f]{64}", supervisor_digest)
assert launch["supervisor_runtime_image"].endswith(f"@{supervisor_digest}")
sandbox_digest = launch["sandbox_image_digest"]
assert re.fullmatch(r"sha256:[0-9a-f]{64}", sandbox_digest)
assert launch["sandbox_image_request"] == launch["sandbox_runtime_image"]
assert launch["sandbox_runtime_image"].endswith(f"@{sandbox_digest}")
for field in (
"sandbox_image_id",
"sandbox_image_digest",
"sandbox_runtime_image",
"supervisor_base_image",
"supervisor_base_image_id",
"supervisor_base_image_digest",
"supervisor_base_runtime_image",
"supervisor_package_manifest_sha256",
"supervisor_dockerfile_sha256_before_execution",
):
assert len({launch[field] for launch in launch_attestations}) == 1, field
external_sockets = []
for variant_name in ("baseline", "candidate"):
external_variant = report["external_uds"][variant_name]
external_launch = external_variant["launch_attestation"]
assert external_launch["compute_driver_transport"] == "remote_uds"
assert external_launch["external_compute_driver"] is True
assert external_launch["external_driver_grpc_endpoint"].startswith("https://")
assert external_launch["external_driver_host_gateway_ip"] == "host-gateway"
assert external_launch["external_driver_userns"] is None
assert external_launch["external_driver_spiffe"] is False
assert external_launch["external_driver_proxy"] is False
assert external_launch["external_driver_app_armor"] is False
driver_environment = external_launch["external_driver_environment"]
assert driver_environment["OPENSHELL_COMPUTE_DRIVER_SOCKET"]
assert driver_environment["OPENSHELL_PODMAN_SOCKET"]
assert driver_environment["OPENSHELL_GRPC_ENDPOINT"].startswith("https://")
assert driver_environment["OPENSHELL_ENABLE_BIND_MOUNTS"] is True
for tls_field in (
"OPENSHELL_PODMAN_TLS_CA",
"OPENSHELL_PODMAN_TLS_CERT",
"OPENSHELL_PODMAN_TLS_KEY",
):
assert re.fullmatch(
r"[0-9a-f]{64}", driver_environment[tls_field]["sha256"]
)
external_sockets.append(driver_environment["OPENSHELL_COMPUTE_DRIVER_SOCKET"])
assert f"{variant_name}.driver.log" in external_variant["raw_evidence_sha256"]
assert f"{variant_name}.exec.stdout" in external_variant["raw_evidence_sha256"]
assert len(set(external_sockets)) == 2
evidence_paths = {
name: REPO_ROOT / relative_path
for name, relative_path in STEP_10_EVIDENCE_BUNDLES.items()
}
present = {name: path.is_dir() for name, path in evidence_paths.items()}
assert len(set(present.values())) == 1, "Step 10 retained evidence is incomplete"
if all(present.values()):
reproduced = tmp_path / "schema-v2-compute-boundary-comparison.json"
subprocess.run(
[
"python3",
str(REPO_ROOT / "e2e/parity/verify-results.py"),
"--baseline-sha",
report["baseline_commit"],
"--candidate-sha",
STEP_10_CANDIDATE_COMMIT,
"--in-tree",
STEP_10_EVIDENCE_BUNDLES["in_tree"],
"--external-uds",
STEP_10_EVIDENCE_BUNDLES["external_uds"],
"--output",
str(reproduced),
],
cwd=REPO_ROOT,
check=True,
)
assert reproduced.read_bytes() == COMPUTE_BOUNDARY_PATH.read_bytes()
def test_step_11_records_cross_cutting_live_lane_dispositions() -> None:
results = {
result["id"]: result
for result in load_toml(RESULTS_PATH)["result"]
if result["step"] == 11
}
dispositions = {
entry["id"]: entry
for entry in load_toml(CROSS_CUTTING_DISPOSITIONS_PATH)["capabilities"]
}
assert set(results) == REQUIRED_STEP_11_IDS
assert set(dispositions) == REQUIRED_STEP_11_IDS
for result_id, result in results.items():
disposition = dispositions[result_id]
assert result["status"] == "platform_blocked"
for field in ("status", "owner", "lane", "blocker"):
assert result[field] == disposition[field]
def test_step_12_keeps_real_package_upgrade_lanes_blocked() -> None:
results = [
result for result in load_toml(RESULTS_PATH)["result"] if result["step"] == 12
]
assert {result["id"] for result in results} == REQUIRED_STEP_12_IDS
assert all(result["status"] == "platform_blocked" for result in results)
by_id = {result["id"]: result for result in results}
rpm = by_id["rpm-package-upgrade"]
assert rpm["owner"] == "OpenShell RPM package upgrade CI lane"
assert rpm["lane"] == "fedora-rpm-prior-release-upgrade"
assert "prior RPM" in rpm["blocker"]
assert "installed and upgraded" in rpm["blocker"]
debian = by_id["debian-package-upgrade"]
assert debian["owner"] == "OpenShell Debian package upgrade CI lane"
assert debian["lane"] == "ubuntu-debian-prior-release-upgrade"
assert "installed prior Debian artifact" in debian["blocker"]
assert "source-tree tests" in debian["blocker"]
snap = by_id["snap-package-refresh"]
assert snap["owner"] == "OpenShell Snap refresh CI lane"
assert snap["lane"] == "ubuntu-snap-prior-release-refresh"
assert "refresh confined Snap revisions" in snap["blocker"]
assert "source-tree tests" in snap["blocker"]
homebrew = by_id["homebrew-package-upgrade"]
assert homebrew["owner"] == "OpenShell macOS Homebrew package upgrade CI lane"
assert homebrew["lane"] == "macos-homebrew-prior-release-upgrade"
assert "prior-release upgrade" in homebrew["blocker"]
assert "Linux host" in homebrew["blocker"]
def test_platform_blocked_results_name_owner_lane_and_blocker() -> None:
for result in load_toml(RESULTS_PATH)["result"]:
if result["status"] != "platform_blocked":
continue
assert set(result) >= BLOCKED_FIELDS, result["id"]
assert isinstance(result["owner"], str) and result["owner"].strip()
assert isinstance(result["blocker"], str) and len(result["blocker"]) >= 80
def test_step_5_records_only_executed_podman_as_pass() -> None:
statuses = {
result["driver"]: result["status"]
for result in load_toml(RESULTS_PATH)["result"]
if result["step"] == 5
}
assert statuses["podman"] == "pass"
assert all(
status == "platform_blocked"
for driver, status in statuses.items()
if driver != "podman"
)