Files
OpenShell/python/openshell/gateway_schema_v2_capability_parity_test.py
T
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

294 lines
9.7 KiB
Python

# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
"""Validate the schema-v2 live capability-parity manifest without a runtime."""
from __future__ import annotations
import re
import tomllib
from copy import deepcopy
from pathlib import Path
from typing import Any
import pytest
REPO_ROOT = Path(__file__).resolve().parents[2]
MANIFEST_PATH = REPO_ROOT / "e2e/configs/gateway/schema-v2-capability-parity.toml"
REQUIRED_MANIFEST_FIELDS = {
"manifest_version",
"baseline_ref",
"baseline_commit",
"baseline_schema_version",
"candidate_ref",
"candidate_commit",
"candidate_schema_version",
"capabilities",
}
REQUIRED_CAPABILITY_FIELDS = {
"id",
"topics",
"origin_main_access_paths",
"schema_v2_access_paths",
"behavioral_oracle",
"required_environment",
"test_lane",
"status",
}
REQUIRED_TOPICS = {
"auth_tls_jwt",
"configuration_producers",
"credentials",
"database",
"docker",
"external_drivers",
"inference",
"interceptors",
"kubernetes",
"listeners",
"middleware",
"mxc",
"observability",
"packaging_upgrades",
"podman",
"vm",
}
REQUIRED_CAPABILITY_IDS = {
"configuration-source-precedence",
"schema-version-and-strict-layout",
"gateway-identity-and-logging",
"primary-health-and-metrics-listeners",
"database-url-and-persistence-backends",
"ssh-rate-limit-and-policy-posture",
"sandbox-service-routing",
"gateway-listener-tls-and-sni",
"plaintext-listener-mode",
"guest-callback-tls-ownership",
"oidc-bearer-authentication",
"mtls-user-authentication",
"unsafe-unauthenticated-user-mode",
"gateway-minted-sandbox-jwt",
"otlp-observability",
"gateway-interceptor-registration",
"supervisor-middleware-registration",
"provider-profile-sources",
"inference-control-plane-configuration",
"credential-driver-selection-and-kek",
"credential-driver-backend-tables",
"docker-image-and-callback-configuration",
"docker-security-and-provider-configuration",
"podman-image-and-callback-configuration",
"podman-runtime-security-and-health",
"kubernetes-core-placement-and-images",
"kubernetes-workspace-isolation",
"kubernetes-supervisor-topology",
"kubernetes-egress-spiffe-and-security",
"vm-launch-and-resource-configuration",
"vm-guest-security-and-spiffe",
"mxc-windows-driver-configuration",
"external-compute-driver-socket",
"helm-configuration-producer",
"local-launch-script-producers",
"e2e-fixture-producers",
"rpm-schema-upgrade",
"homebrew-debian-and-snap-upgrades",
}
ALLOWED_LANES = {
"deterministic",
"e2e-docker",
"e2e-podman",
"e2e-kubernetes",
"e2e-vm",
"windows-mxc",
"extension-driver",
"auth-oidc",
"observability",
"packaging",
}
# This inventory plans execution. Live results belong in the execution record,
# not in this baseline manifest, so a PASS cannot be accidentally implied.
ALLOWED_STATUSES = {"not_run", "blocked", "planned"}
def load_manifest() -> dict[str, Any]:
with MANIFEST_PATH.open("rb") as manifest_file:
return tomllib.load(manifest_file)
def require_nonempty_string(value: Any, field: str, entry_id: str) -> None:
assert isinstance(value, str) and value.strip(), f"{entry_id}: {field} is required"
def require_string_list(value: Any, field: str, entry_id: str) -> None:
assert isinstance(value, list) and value, f"{entry_id}: {field} must be non-empty"
assert all(isinstance(item, str) and item.strip() for item in value), (
f"{entry_id}: {field} must contain only non-empty strings"
)
assert len(value) == len(set(value)), f"{entry_id}: {field} contains duplicates"
def validate_manifest(manifest: dict[str, Any]) -> None:
assert set(manifest) == REQUIRED_MANIFEST_FIELDS, (
"unexpected or missing manifest metadata"
)
assert manifest["manifest_version"] == 1
assert manifest["baseline_ref"] == "origin/main"
assert manifest["baseline_commit"] == "74960ebfaeec4673885089ed995fad902459749f"
assert manifest["baseline_schema_version"] == 1
assert manifest["candidate_ref"] == "HEAD"
assert manifest["candidate_commit"] == "8c868e430e9cd3284d7e274628419ab484ebcee0"
assert manifest["candidate_schema_version"] == 2
capabilities = manifest["capabilities"]
assert isinstance(capabilities, list) and capabilities, (
"capabilities must be non-empty"
)
ids: list[str] = []
topics: set[str] = set()
for capability in capabilities:
assert isinstance(capability, dict), "each capability must be a TOML table"
assert set(capability) == REQUIRED_CAPABILITY_FIELDS, (
"capability has unexpected or missing metadata"
)
entry_id = capability["id"]
require_nonempty_string(entry_id, "id", "capability")
ids.append(entry_id)
require_string_list(capability["topics"], "topics", entry_id)
topics.update(capability["topics"])
require_string_list(
capability["origin_main_access_paths"],
"origin_main_access_paths",
entry_id,
)
require_string_list(
capability["schema_v2_access_paths"],
"schema_v2_access_paths",
entry_id,
)
require_nonempty_string(
capability["behavioral_oracle"], "behavioral_oracle", entry_id
)
require_nonempty_string(
capability["required_environment"], "required_environment", entry_id
)
assert capability["test_lane"] in ALLOWED_LANES, (
f"{entry_id}: unknown test lane {capability['test_lane']!r}"
)
assert capability["status"] in ALLOWED_STATUSES, (
f"{entry_id}: live PASS results are not valid in this planning manifest"
)
assert len(ids) == len(set(ids)), "capability IDs must be unique"
assert set(ids) == REQUIRED_CAPABILITY_IDS, (
"capability inventory is incomplete or stale"
)
assert topics == REQUIRED_TOPICS, (
"topic inventory is incomplete or contains an unknown topic"
)
def capability_by_id(manifest: dict[str, Any], capability_id: str) -> dict[str, Any]:
return next(
capability
for capability in manifest["capabilities"]
if capability["id"] == capability_id
)
def test_schema_v2_capability_parity_manifest_is_well_formed() -> None:
validate_manifest(load_manifest())
def test_frozen_comparison_commits_are_full_git_object_ids() -> None:
manifest = load_manifest()
for field in ("baseline_commit", "candidate_commit"):
commit = manifest[field]
assert len(commit) == 40
assert all(character in "0123456789abcdef" for character in commit)
def test_vm_gateway_inventory_excludes_standalone_driver_only_fields() -> None:
capability = capability_by_id(
load_manifest(), "vm-launch-and-resource-configuration"
)
gateway_paths = " ".join(
capability["origin_main_access_paths"] + capability["schema_v2_access_paths"]
)
gateway_fields = set(re.findall(r"[a-z][a-z0-9_]*", gateway_paths))
for standalone_field in ("launcher_bin", "log_level", "gpu_enabled", "gpu_mem_mib"):
assert standalone_field not in gateway_fields
assert "driver_dir" in gateway_fields
def test_new_docker_capabilities_are_not_attributed_to_origin_main() -> None:
capability = capability_by_id(
load_manifest(), "docker-security-and-provider-configuration"
)
origin_paths = " ".join(capability["origin_main_access_paths"])
candidate_paths = " ".join(capability["schema_v2_access_paths"])
assert "no origin/main Docker equivalent" in origin_paths
for added_field in (
"https_proxy",
"provider_spiffe_workload_api_socket",
"app_armor_profile",
):
assert added_field not in origin_paths
assert added_field in candidate_paths
@pytest.mark.parametrize("field", sorted(REQUIRED_MANIFEST_FIELDS - {"capabilities"}))
def test_manifest_rejects_missing_header_metadata(field: str) -> None:
manifest = deepcopy(load_manifest())
del manifest[field]
with pytest.raises(AssertionError, match="missing manifest metadata"):
validate_manifest(manifest)
@pytest.mark.parametrize("field", sorted(REQUIRED_CAPABILITY_FIELDS - {"id"}))
def test_manifest_rejects_missing_capability_metadata(field: str) -> None:
manifest = deepcopy(load_manifest())
del manifest["capabilities"][0][field]
with pytest.raises(AssertionError, match=r"metadata|required|must be"):
validate_manifest(manifest)
@pytest.mark.parametrize(
("field", "value", "match"),
[
("topics", [], "must be non-empty"),
("behavioral_oracle", "", "is required"),
("required_environment", "", "is required"),
("test_lane", "not-a-lane", "unknown test lane"),
],
)
def test_manifest_rejects_malformed_capability_metadata(
field: str, value: Any, match: str
) -> None:
manifest = deepcopy(load_manifest())
manifest["capabilities"][0][field] = value
with pytest.raises(AssertionError, match=match):
validate_manifest(manifest)
def test_manifest_rejects_duplicate_capability_id() -> None:
manifest = deepcopy(load_manifest())
manifest["capabilities"][1]["id"] = manifest["capabilities"][0]["id"]
with pytest.raises(AssertionError, match=r"unique|incomplete"):
validate_manifest(manifest)
def test_manifest_does_not_claim_live_pass_results() -> None:
manifest = deepcopy(load_manifest())
manifest["capabilities"][0]["status"] = "pass"
with pytest.raises(AssertionError, match="live PASS"):
validate_manifest(manifest)