protocol: add generated bindings and conformance fixtures
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Dependency-free structural and scope validation for the Protocol sources."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import pathlib
|
||||
import hashlib
|
||||
import re
|
||||
import sys
|
||||
|
||||
ROOT = pathlib.Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def main() -> int:
|
||||
schema_path = ROOT / "schemas/control-v1.schema.json"
|
||||
schema = json.loads(schema_path.read_text(encoding="utf-8"))
|
||||
assert schema["$schema"].endswith("2020-12/schema")
|
||||
defs = schema["$defs"]
|
||||
assert len(defs) >= 16
|
||||
for name, definition in defs.items():
|
||||
assert definition["type"] == "object", name
|
||||
assert definition["additionalProperties"] is False, name
|
||||
assert set(definition["required"]).issubset(definition["properties"]), name
|
||||
|
||||
compatibility = json.loads((ROOT / "compatibility.json").read_text(encoding="utf-8"))
|
||||
assert set([compatibility["current"], compatibility["n_minus_1"], compatibility["n_minus_2"]]) == {"1", "0", "-1"}
|
||||
assert len(set(compatibility["unsupported"])) == len(compatibility["unsupported"])
|
||||
|
||||
for registry in ("registries/features.json", "registries/datagrams.json"):
|
||||
value = json.loads((ROOT / registry).read_text(encoding="utf-8"))
|
||||
entries = value.get("features", value.get("datagrams"))
|
||||
assert entries and len({entry["id"] for entry in entries}) == len(entries)
|
||||
for entry in entries:
|
||||
maximum = entry.get("max_frame_bytes", entry.get("max_payload_bytes"))
|
||||
assert isinstance(maximum, int) and 1 <= maximum <= 65536
|
||||
|
||||
manifest = json.loads((ROOT / "fixtures/valid/manifest.json").read_text(encoding="utf-8"))
|
||||
assert set(manifest).issubset(set(defs["ConnectionManifest"]["properties"]))
|
||||
forbidden = json.loads((ROOT / "fixtures/invalid/manifest-provider-field.json").read_text(encoding="utf-8"))
|
||||
assert "provider_url" not in defs["ConnectionManifest"]["properties"] and "provider_url" in forbidden
|
||||
|
||||
expected_header = "id\tversion\tkind\tinput\texpected"
|
||||
ids = set()
|
||||
for fixture_path in sorted((ROOT / "fixtures/conformance").glob("*.tsv")):
|
||||
lines = fixture_path.read_text(encoding="utf-8").splitlines()
|
||||
assert lines and lines[0] == expected_header, fixture_path
|
||||
for line in lines[1:]:
|
||||
fields = line.split("\t")
|
||||
assert len(fields) == 5, line
|
||||
assert fields[0] not in ids, fields[0]
|
||||
ids.add(fields[0])
|
||||
assert fields[4] == "valid" or fields[4].startswith("invalid:"), line
|
||||
|
||||
fixture_manifest = json.loads((ROOT / "fixtures/manifest.json").read_text(encoding="utf-8"))
|
||||
assert fixture_manifest["files"] == sorted(
|
||||
path.relative_to(ROOT).as_posix() for path in (ROOT / "fixtures/conformance").glob("*.tsv")
|
||||
)
|
||||
fixture_hash = hashlib.sha256()
|
||||
for relative in fixture_manifest["files"]:
|
||||
fixture_hash.update(relative.encode("utf-8"))
|
||||
fixture_hash.update(b"\0")
|
||||
fixture_hash.update((ROOT / relative).read_bytes())
|
||||
fixture_hash.update(b"\0")
|
||||
assert fixture_manifest["corpus_sha256"] == fixture_hash.hexdigest()
|
||||
|
||||
openapi = (ROOT / "openapi/control-v1.yaml").read_text(encoding="utf-8")
|
||||
assert "openapi: 3.1.0" in openapi
|
||||
assert "/api/v1/auth/refresh:" in openapi and "/api/v1/resources:" in openapi and "/api/v1/events:" in openapi
|
||||
assert "provider_url" not in openapi and "vm_address" not in openapi
|
||||
print("Protocol source validation passed")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
raise SystemExit(main())
|
||||
except (AssertionError, OSError, json.JSONDecodeError) as exc:
|
||||
print(f"validate: {exc}", file=sys.stderr)
|
||||
raise SystemExit(1)
|
||||
Reference in New Issue
Block a user