Files
ARCADIA-Studio/harness/experiments/canvas-repair-native-33e30c1-20260912/scripts/check-repair-native.py
T

42 lines
2.8 KiB
Python

"""Snapshot one native working project and compare independently prepared expectations."""
from pathlib import Path
import argparse,datetime,hashlib,json,shutil,subprocess
base=Path(__file__).resolve().parent
fixtures=base/'repair-native-fixtures-20260912'
output=base/'repair-native-observations-20260912'
parser=argparse.ArgumentParser()
parser.add_argument('name');parser.add_argument('working');parser.add_argument('expected')
parser.add_argument('--bytes-only',action='store_true')
args=parser.parse_args()
for name in [args.name,args.working,args.expected]:
if not name or any(c not in 'abcdefghijklmnopqrstuvwxyz0123456789-' for c in name):raise RuntimeError('Simple fixture names required')
work=fixtures/args.working;expected=fixtures/args.expected
if not work.is_dir() or not expected.is_dir():raise RuntimeError('Unknown prepared fixture')
checkpoint=output/'checkpoints'/args.name
logs=output/'logs';logs.mkdir(parents=True,exist_ok=True)
if checkpoint.exists():raise RuntimeError('Checkpoint already exists')
def files(root):
result={}
for p in root.rglob('*'):
if p.is_symlink():raise RuntimeError('Symlink in fixture')
if p.is_file():result[p.relative_to(root).as_posix()]=p.read_bytes()
return result
before=files(work);shutil.copytree(work,checkpoint)
if before!=files(checkpoint) or before!=files(work):raise RuntimeError('Source changed during snapshot')
matched=before==files(expected)
record={'utc':datetime.datetime.now(datetime.timezone.utc).isoformat(),'scope':'Saved filesystem checkpoint and independent expectation comparison; GUI actions recorded separately','working':str(work),'expected':str(expected),'checkpoint':str(checkpoint),'physical_equal':matched,'files':[{'path':n,'bytes':len(b),'sha256':hashlib.sha256(b).hexdigest()} for n,b in sorted(before.items())]}
if not args.bytes_only and matched:
oracle=base/'native-a57c334-camera/oracles/lifecycle.exe'
if hashlib.sha256(oracle.read_bytes()).hexdigest().upper()!='798D7A1907B894C13549BAD35511B21D6BC7F3D67D63674042B7DF71184C7524':raise RuntimeError('Oracle changed')
command=[str(oracle),'same',str(expected/'project.arcadia'),str(checkpoint/'project.arcadia')]
result=subprocess.run(command,capture_output=True,creationflags=subprocess.CREATE_NO_WINDOW)
for suffix,data in [('stdout.log',result.stdout),('stderr.log',result.stderr)]:
with (logs/(args.name+'.'+suffix)).open('xb') as f:f.write(data)
record.update(command=command,oracle_exit=result.returncode)
matched=matched and result.returncode==0
record['result']='passed' if matched else 'failed'
record['completed_utc']=datetime.datetime.now(datetime.timezone.utc).isoformat()
with (output/(args.name+'.json')).open('x',encoding='utf-8') as f:json.dump(record,f,indent=2)
print(json.dumps(record))
raise SystemExit(0 if matched else 1)