50 lines
2.9 KiB
Python
50 lines
2.9 KiB
Python
import hashlib
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
import sys
|
|
|
|
root = Path(__file__).resolve().parents[2]
|
|
prior = root/'.local/native-qa/contextual-source-20260911-v1'
|
|
stage = root/'.local/native-qa/contextual-source-20260911-v2'
|
|
base = root/'harness/fixtures/staged-source-authoring/base'
|
|
oracle = root/'.local/staged-source-oracle-20260911/staged-source-authoring-contract.exe'
|
|
digest = lambda p: hashlib.sha256(p.read_bytes()).hexdigest().upper()
|
|
resume = sys.argv[1:] == ['--resume-preflight']
|
|
assert not stage.exists() or resume, 'Refuse to overwrite native stage'
|
|
assert digest(base/'project.arcadia') == 'AA844950EC4FB86F262A257E1FC370A26557EA7978D8A4CAB78265037660234C'
|
|
assert digest(base/'notes.arcadia') == 'AD9DE02963C20D1F43856455A797DEB05CA674659E45F2C4B96B52783024F8BD'
|
|
assert digest(oracle) == '967D9BA3C6FB3A7EFB410833903EC94556CA2D48A67D5072C8BB160F40A00F9C'
|
|
assert digest(prior/'bin/libunwind.dll') == 'F45604A12E8BCD839FD86F667C1BE1CC7C4F9DA2B3C69FF381AC708F0E1AE7D4'
|
|
def inventory(directory):
|
|
return {p.relative_to(directory).as_posix():digest(p) for p in directory.rglob('*') if p.is_file()}
|
|
assert inventory(prior/'checkpoint-chain-redo') == inventory(prior/'checkpoint-chain')
|
|
assert len(inventory(prior/'checkpoint-chain-redo')) == 4
|
|
if resume:
|
|
assert not (stage/'preflight.json').exists()
|
|
assert inventory(base) == inventory(stage/'lifeline/work')
|
|
assert inventory(prior/'checkpoint-chain-redo') == inventory(stage/'machine/work')
|
|
else:
|
|
shutil.copytree(base, stage/'lifeline/work')
|
|
shutil.copytree(prior/'checkpoint-chain-redo', stage/'machine/work')
|
|
env = dict(os.environ)
|
|
system_root = next(v for k,v in env.items() if k.upper() == 'SYSTEMROOT')
|
|
env['PATH'] = str(prior/'bin') + ';' + system_root + '\\System32;' + system_root
|
|
entry = lambda p:str(p/'project.arcadia')
|
|
checks = [
|
|
('self-check', ['self-check', entry(base)]),
|
|
('lifeline-initial', ['check', 'baseline', entry(base), entry(stage/'lifeline/work')]),
|
|
('machine-initial', ['check', 'chain', entry(base), entry(stage/'machine/work'), entry(prior/'checkpoint-lifeline'), entry(prior/'checkpoint-chain')]),
|
|
]
|
|
results = []
|
|
for name,args in checks:
|
|
assert not (stage/(name+'.log')).exists(), 'Refuse to overwrite earlier checker log'
|
|
p = subprocess.run([str(oracle),*args],env=env,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
|
|
(stage/(name+'.log')).write_bytes(p.stdout)
|
|
results.append({'check':name, 'exitCode':p.returncode, 'args':args})
|
|
assert p.returncode == 0, p.stdout
|
|
(stage/'preflight.json').write_text(json.dumps({'scope':'Frozen inputs only; no new GUI or native interaction', 'oracle':str(oracle), 'oracleSha256':digest(oracle), 'checks':results, 'lifelineInput':inventory(stage/'lifeline/work'), 'machineInput':inventory(stage/'machine/work')},indent=2)+'\n',encoding='utf8')
|
|
print(json.dumps({'state':'prepared', 'checks':len(results), 'path':str(stage)}))
|