#!/usr/bin/env python3 """Install the released CLI in a fresh cache, then test its generated consumer. The fixture tests custom scalars, dynamic JSON, uploads, raw callback signatures, downloads, body limits and regeneration protection. Only local temporary resources are used; the framework and CLI are fetched from the specified remote version. """ import argparse import hashlib import json import os from pathlib import Path import re import subprocess import tempfile import time ROOT = Path(__file__).resolve().parents[1] MODULE = "git.yuntuo.hk/k2safe/go-omni" def run(args, cwd, env, timeout=300): result = subprocess.run([str(arg) for arg in args], cwd=cwd, env=env, capture_output=True, text=True, timeout=timeout) output = re.sub(r"https://[^/@\s]+:[^/@\s]+@", "https://", result.stdout + result.stderr) if result.returncode: raise RuntimeError(f"{args[0]} failed ({result.returncode}):\n{output}") return output def main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--version", required=True) parser.add_argument("--report", type=Path, default=ROOT / "performance/compatibilityRemote.json") args = parser.parse_args() if not re.fullmatch(r"v\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?", args.version): parser.error("a fixed release version is required") env = {k: v for k, v in os.environ.items() if not k.startswith("GO_OMNI_")} env.update(GOWORK="off", GOFLAGS="", GOPRIVATE="git.yuntuo.hk", GONOSUMDB="git.yuntuo.hk") start = time.monotonic() with tempfile.TemporaryDirectory(prefix="goOmniCompatibilityRelease-") as directory: temp = Path(directory) (temp / "bin").mkdir() env.update(GOBIN=str(temp / "bin"), GOMODCACHE=str(temp / "modcache")) print(f"Installing CLI {args.version} in an empty module cache", flush=True) run(["go", "install", MODULE + "/cmd/go-omni@" + args.version], temp, env) cli = temp / "bin/go-omni" run([cli, "api", "validate", "--api", ROOT / "examples/contracts/compatibility.api"], temp, env) env.update(GO_OMNI_SCAFFOLD_INTEGRATION="1", GO_OMNI_RELEASE_CLI=str(cli), GO_OMNI_RELEASE_VERSION=args.version) print("Testing remote generation, scalar binding, uploads and callback signatures", flush=True) output = run(["go", "test", "-race", "-count=1", "-json", "-timeout=180s", "./cmd/go-omni/apigen", "-run", "^TestCompatibilityConsumer$"], ROOT, env) events = [json.loads(line) for line in output.splitlines() if line.startswith("{")] passed = [e["Test"] for e in events if e.get("Action") == "pass" and "Test" in e] assert passed == ["TestCompatibilityConsumer"], output evidence = "".join(e.get("Output", "") for e in events) checksum = re.search(r"checksum (h1:\S+); no local replace", evidence) assert checksum, "consumer did not verify its remote dependency" report = { "passed": True, "frameworkVersion": args.version, "frameworkSum": checksum.group(1), "freshModuleCache": True, "noLocalReplace": True, "durationSeconds": round(time.monotonic() - start, 2), "checks": ["remoteCLIInstall", "scalarContractValidation", "manualProjectGeneration", "int64MaxValueOnWire", "dynamicJSON", "rawBodySignature", "routeBodyLimits", "multipartTempCleanup", "unwrappedDownloads", "handwrittenFilesPreserved", "generatedConsumerRaceTests", "fixedRemoteModuleChecksum"], "sourceHashes": {name: hashlib.sha256((ROOT / name).read_bytes()).hexdigest() for name in ("scripts/verifyCompatibilityRelease.py", "cmd/go-omni/apigen/compatibility_test.go", "examples/contracts/compatibility.api", "cmd/go-omni/apigen/testdata/compatibility/consumer_test.go", "cmd/go-omni/apigen/testdata/compatibility/hooks.go", "cmd/go-omni/apigen/testdata/compatibility/echo.go", "cmd/go-omni/apigen/testdata/compatibility/download.go")}, } args.report.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n") print(f"PASS remote compatibility contract {args.version}; temporary files removed", flush=True) if __name__ == "__main__": main()