89 lines
4.6 KiB
Python
89 lines
4.6 KiB
Python
"""Read-only packet check; Python 3 stdlib + Git. Optional --index verifies staged bytes."""
|
|
from pathlib import Path
|
|
import copy
|
|
import hashlib
|
|
import json
|
|
import subprocess
|
|
import sys
|
|
|
|
packet = Path(__file__).resolve().parent
|
|
root = packet.parents[2]
|
|
load = lambda p: json.loads(p.read_text(encoding="utf-8"))
|
|
digest = lambda data: {"bytes": len(data), "sha256": hashlib.sha256(data).hexdigest()}
|
|
inventory = load(packet / "evidence-files.json")
|
|
files = {p.relative_to(packet).as_posix() for p in packet.rglob("*") if p.is_file()}
|
|
assert files == set(inventory) | {"evidence-files.json"}, "Unexpected/missing packet file"
|
|
for name, expected in inventory.items():
|
|
assert digest((packet / name).read_bytes()) == expected, name
|
|
if "--index" in sys.argv:
|
|
for name in files:
|
|
rel = (packet / name).relative_to(root).as_posix()
|
|
staged = subprocess.check_output(["git", "show", ":" + rel], cwd=root)
|
|
assert staged == (packet / name).read_bytes(), "Index changed bytes: " + name
|
|
|
|
native = packet / "native"
|
|
baseline = load(native / "baseline.json")
|
|
source = baseline["source"]
|
|
identity = load(packet / "source-files.json")
|
|
assert identity["source"] == source
|
|
for name, expected in identity["files"].items():
|
|
data = subprocess.check_output(["git", "show", source + ":" + name], cwd=root)
|
|
assert digest(data) == expected, name
|
|
original = {name: subprocess.check_output(
|
|
["git", "show", source + ":examples/release1/" + name], cwd=root
|
|
) for name in baseline["baseline"]}
|
|
assert len(original) == 37
|
|
assert {name: digest(data) for name, data in original.items()} == baseline["baseline"]
|
|
dependency = baseline["external_dependency"]
|
|
renamed = original.copy()
|
|
old = b'oa_activity oa_assess "Assess pressure alarm" id "61f7bbfb-74a4-5540-9182-2583dfb27a49"'
|
|
new = old.replace(b'"Assess pressure alarm"', b'"Assess pressure alarm QA46"')
|
|
assert renamed[dependency].count(old) == 1
|
|
renamed[dependency] = renamed[dependency].replace(old, new)
|
|
injected = original.copy()
|
|
injected[dependency] += baseline["external_comment"].encode("utf-8")
|
|
phases = {
|
|
"collision": original, "saved-a": renamed, "saved-c": renamed,
|
|
"external-before": original, "inject": injected, "external-refused": injected,
|
|
"restore": original, "external-recovered": original,
|
|
}
|
|
for phase, expected in phases.items():
|
|
receipt = load(native / (phase + "-oracle.json"))
|
|
assert receipt["status"] == "PASS" and receipt["phase"] == phase
|
|
assert receipt["files"] == {name: digest(data) for name, data in expected.items()}, phase
|
|
assert len(list(native.glob("*.png"))) == 16
|
|
finish = load(native / "finished.json")
|
|
assert finish["source"] == source and finish["exit_code"] == 0
|
|
assert finish["binary_unchanged"] and finish["runtime_unchanged"]
|
|
for stream in ["stdout", "stderr"]:
|
|
assert finish[stream + "_bytes"] == 0 and (native / (stream + ".log")).read_bytes() == b""
|
|
assert finish["binary_sha256"] == baseline["binary"]["sha256"]
|
|
assert finish["runtime_sha256"] == baseline["runtime"]["sha256"]
|
|
|
|
oracle = native / "native-model-oracle"
|
|
models = []
|
|
for request_number, response_number, expected in [(2, 3, original), (4, 5, renamed)]:
|
|
request = load(oracle / f"{request_number:02d}.request.json")
|
|
response = load(oracle / f"{response_number:02d}.response.json")
|
|
expected_sources = {name: data.decode("utf-8") for name, data in expected.items() if name.endswith(".arcadia")}
|
|
assert len(expected_sources) == 30
|
|
assert request == {"entry": "project.arcadia", "files": expected_sources}
|
|
assert response["source_project"] == request
|
|
models.append(response["model"])
|
|
expected_model = copy.deepcopy(models[0])
|
|
activity = baseline["declared_rename"]
|
|
assert expected_model["elements"][activity["activity"]]["name"] == activity["before"]
|
|
expected_model["elements"][activity["activity"]]["name"] = activity["after"]
|
|
assert models[1] == expected_model
|
|
result = load(oracle / "result.json")
|
|
assert result["status"] == "PASS" and result["server_exit"] == 1
|
|
assert result["runtime_sha256"] == baseline["runtime"]["sha256"]
|
|
donor = load(packet / "donor/build-evidence.json")
|
|
extraction = load(packet / "donor/extraction-check.json")
|
|
assert result["server_sha256"] == donor["binary_sha256"]["arcadia-server.exe"]
|
|
assert result["server_sha256"] == extraction["sha256"]["arcadia-server.exe"]
|
|
assert result["runtime_sha256"] == donor["runtime_sha256"] == extraction["sha256"]["libunwind.dll"]
|
|
print(json.dumps({"status": "PASS", "inventory_files": len(inventory), "phase_receipts": 8,
|
|
"source_files_per_request": 30, "complete_model_delta": activity,
|
|
"indexed_bytes_checked": "--index" in sys.argv}, indent=2))
|