from pathlib import Path import hashlib,json,sys run=Path(__file__).resolve().parent root=run.parents[1] record=json.loads((run/'baseline.json').read_text(encoding='utf-8')) source=root/'examples/release1' dependency=record['external_dependency'] phase=sys.argv[1] assert phase in ['collision','saved-a','saved-c','external-before','inject','external-refused','restore','external-recovered'] sha=lambda b:hashlib.sha256(b).hexdigest() original={r:(source/r).read_bytes() for r in record['baseline']} assert {r:{'bytes':len(b),'sha256':sha(b)} for r,b in original.items()}==record['baseline'] def check(folder,expected): actual={f.relative_to(folder).as_posix():f.read_bytes() for f in folder.rglob('*') if f.is_file()} assert actual.keys()==expected.keys(),(phase,'file set', sorted(actual.keys()^expected.keys())) assert all(actual[r]==b for r,b in expected.items()),(phase,'changed files',[r for r,b in expected.items() if actual[r]!=b]) return {r:{'bytes':len(b),'sha256':sha(b)} for r,b in actual.items()} if phase in ['collision','saved-a','saved-c']: expected=original.copy() if phase!='collision': old=b'oa_activity oa_assess "Assess pressure alarm" id "61f7bbfb-74a4-5540-9182-2583dfb27a49"' new=b'oa_activity oa_assess "Assess pressure alarm QA46" id "61f7bbfb-74a4-5540-9182-2583dfb27a49"' assert expected[dependency].count(old)==1 expected[dependency]=expected[dependency].replace(old,new) folder=run/('fresh-c' if phase=='saved-c' else 'collision-a') assert not (run/'collision-a/collision-copy.arcadia').exists() files=check(folder,expected) else: folder=run/'external-b' changed=original.copy();changed[dependency]+=record['external_comment'].encode('utf-8') if phase=='inject': check(folder,original) (folder/dependency).write_bytes(changed[dependency]) expected=changed elif phase=='restore': check(folder,changed) (folder/dependency).write_bytes(original[dependency]) expected=original else: expected=changed if phase=='external-refused' else original files=check(folder,expected) result={'status':'PASS','phase':phase,'folder':str(folder),'files':files,'scope':'Every byte and relative filename, including seven companion files, equals the independently declared original bundle plus only the phase-specific activity rename or parent-injected valid comment.'} with (run/(phase+'-oracle.json')).open('x',encoding='utf-8') as f:json.dump(result,f,indent=2) print(json.dumps({'status':result['status'],'phase':phase,'files':len(files)},indent=2))