Files
FreeCADWasmDev/tools/replay_scheduler_failure_composite.py
wangdequan 9a7c4f0335 Save FreeCAD Web workspace sources and user validation evidence
IFC native binding remains incomplete; preserve accurate test results.
2026-09-15 22:01:58 +08:00

89 lines
2.9 KiB
Python

#!/usr/bin/env python3
"""Replay bounded scheduler-failure command groups with durable summaries."""
from __future__ import annotations
import argparse
import hashlib
import json
import subprocess
from datetime import datetime, timezone
from pathlib import Path
ROOT = Path("/home/mes123456/FreeCADWasmDev/working/FreeCAD")
LEDGER = ROOT / "docs/current/freecad-web-scheduler-failures.json"
EVIDENCE = ROOT / "docs/p6/scheduler-failure-composite-replay-20260903.json"
GROUPS = {
"all": [
"d8adbe1d57f5337d2df4",
"5edf8e1a9fdd7a075e31",
"eb0aa522833316439ddc",
"d9af1131d2221d88009b",
"285fefc5661260434679",
"1a736f486824f4769b89",
"490b7cb48eb8ac5615ec",
"da3dc21fe80f404d135f",
],
"partdesign": [
"285fefc5661260434679",
"490b7cb48eb8ac5615ec",
"1a736f486824f4769b89",
],
}
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("group", choices=sorted(GROUPS))
args = parser.parse_args()
ledger = json.loads(LEDGER.read_text(encoding="utf-8"))
failures = ledger.get("failures", {})
if not isinstance(failures, dict):
raise SystemExit("failure ledger is not a keyed map")
results = []
for key in GROUPS[args.group]:
entry = failures.get(key)
if not isinstance(entry, dict):
raise SystemExit(f"failure ledger entry missing: {key}")
command = str(entry.get("command", ""))
completed = subprocess.run(
command,
shell=True,
cwd=ROOT,
text=True,
capture_output=True,
timeout=240,
)
output = (completed.stdout + "\n" + completed.stderr).strip()
results.append(
{
"key": key,
"command": command,
"exitCode": completed.returncode,
"outputTail": output[-2000:],
"outputSha256": hashlib.sha256(output.encode("utf-8")).hexdigest(),
}
)
if completed.returncode != 0:
break
now = datetime.now(timezone.utc).isoformat()
report = {
"schema": "freecad-web-scheduler-composite-replay/v1",
"taskId": "FW-P6-FPA-Y",
"group": args.group,
"recordedAt": now,
"results": results,
"allExitCodesZero": bool(results) and all(item["exitCode"] == 0 for item in results),
}
report["resultSha256"] = hashlib.sha256(
json.dumps(report["results"], sort_keys=True).encode("utf-8")
).hexdigest()
EVIDENCE.write_text(json.dumps(report, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
print(json.dumps({"group": args.group, "results": len(results), "allExitCodesZero": report["allExitCodesZero"], "resultSha256": report["resultSha256"]}))
return 0 if report["allExitCodesZero"] else 1
if __name__ == "__main__":
raise SystemExit(main())