test(opcua): add fixed candidate saturation diagnosis with observer barriers
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Prepare a fresh immutable candidate bundle. This command never launches the experiment."""
|
||||
import argparse
|
||||
import hashlib
|
||||
import json
|
||||
from pathlib import Path
|
||||
import shutil
|
||||
import subprocess
|
||||
from build_saturation_observer import build
|
||||
|
||||
|
||||
def sha(path):
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument("--output", type=Path, required=True)
|
||||
parser.add_argument("--libraries", type=Path, required=True)
|
||||
parser.add_argument("--image", required=True)
|
||||
options = parser.parse_args()
|
||||
source = Path(__file__).resolve().parent
|
||||
repo = source.parents[2]
|
||||
revision = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=repo, text=True).strip()
|
||||
if subprocess.check_output(["git", "status", "--porcelain"], cwd=repo, text=True).strip():
|
||||
raise RuntimeError("Commit and review the exact source before preparing immutable artifacts")
|
||||
if not options.image.startswith("sha256:"):
|
||||
raise ValueError("Use an immutable Linux .NET SDK image digest")
|
||||
root = options.output.resolve()
|
||||
root.mkdir(parents=True, exist_ok=False)
|
||||
project = repo / "tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.csproj"
|
||||
command = ["dotnet", "publish", str(project), "-c", "Release", "-r", "linux-arm64", "--self-contained", "true",
|
||||
"-p:RuntimeFrameworkVersion=10.0.14", "-p:PublishSingleFile=false", "-p:PublishTrimmed=false", "-p:UseAppHost=true",
|
||||
"--artifacts-path", str(root / "build"), "-o", str(root / "app"), "-m:2", "--nologo"]
|
||||
with (root / "publish.log").open("w") as log:
|
||||
subprocess.run(command, cwd=repo, stdout=log, stderr=subprocess.STDOUT, check=True)
|
||||
observer = build(root / "observer-build", options.libraries, True)
|
||||
shutil.copytree(observer, root / "observer")
|
||||
tools = root / "tools"
|
||||
tools.mkdir()
|
||||
for name in ["launch_saturation.py", "container_saturation.sh", "SATURATION.md"]:
|
||||
shutil.copy2(source / name, tools / name)
|
||||
manifest = {str(path.relative_to(root)): sha(path) for directory in ["app", "observer", "tools"]
|
||||
for path in sorted((root / directory).rglob("*")) if path.is_file()}
|
||||
runtime = json.loads((root / "app/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.runtimeconfig.json").read_text())
|
||||
included = runtime["runtimeOptions"]["includedFrameworks"]
|
||||
if not included or any(value["version"] != "10.0.14" for value in included):
|
||||
raise RuntimeError("Published app is not the prospectively fixed self-contained runtime")
|
||||
receipt = {"protocol": "sdk2-saturation-v1", "sourceRevision": revision, "image": options.image,
|
||||
"rid": "linux-arm64", "runtimeVersion": "10.0.14", "selfContained": True,
|
||||
"canonicalCycles": 384, "completedRestarts": 96, "settlingCycles": 1, "maximumPhaseSeconds": 1800,
|
||||
"windows": [[321, 352], [353, 384]], "observerBufferMiB": 16, "runtimeKeywords": "0x18", "rundown": False,
|
||||
"acceptance": False, "publishCommand": command,
|
||||
"testSourceSha256": sha(project.parent / "Sdk2LifecycleSoakTests.cs"),
|
||||
"observerSourceSha256": sha(source / "SaturationObserver.cs"), "files": manifest}
|
||||
receipt_path = root / "receipt.json"
|
||||
receipt_path.write_text(json.dumps(receipt, indent=2) + "\n")
|
||||
print(json.dumps({"bundle": str(root), "receiptSha256": sha(receipt_path), "sourceRevision": revision,
|
||||
"launched": False}, indent=2))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user