121 lines
8.9 KiB
Python
121 lines
8.9 KiB
Python
from pathlib import Path
|
|
import ast, hashlib, json, re, subprocess
|
|
|
|
ORIGIN = Path('C:/Users/User/Documents/Git/ARCADIA-Studio')
|
|
ROOT = Path('C:/ar-nav440-evidence-956atf')
|
|
SOURCE = '44095f78c28b79d6d085863dc928adba8e24d955'
|
|
BASE = '355f6d4d244e6b57fd89a8afd80a2dacdea69ba1'
|
|
REL = Path('harness/experiments/navigation-440-windows-20260913')
|
|
ARCHIVE = ROOT / REL
|
|
assert not ARCHIVE.exists()
|
|
GATES = ORIGIN / '.local/navigation-palette-gates-20260913'
|
|
def sha(raw): return hashlib.sha256(raw).hexdigest()
|
|
def read(path): return json.loads(path.read_bytes())
|
|
def git(*args): return subprocess.check_output(['git','-c','core.longpaths=true',*args],cwd=ROOT)
|
|
assert git('rev-parse','HEAD').decode().strip() == BASE
|
|
raws = sorted(p for p in GATES.glob('*-44095f7.*') if p.is_file())
|
|
assert len(raws) == 43, len(raws)
|
|
raws += [GATES/'artifacts-44095f7'/n for n in ('result.json','inputs.json','environment.json','cargo.jsonl','cargo.stderr.log')]
|
|
raws += [ORIGIN/n for n in ('.local/run-navigation-palette-gate.py', '.local/run-navigation-service-gate.py',
|
|
'.local/build-navigation-palette-artifacts.py', '.local/admit-navigation-selection-gate.py',
|
|
'.local/navigation-palette-required-tests-20260913.json', '.local/audit-navigation-service-gates-44095f7.py',
|
|
'.local/navigation-service-gates-44095f7-audit.json', '.local/navigation-service-gates-44095f7-review.md',
|
|
'.local/toolchain/env.ps1')]
|
|
assert len(raws) == len(set(raws))
|
|
desktop = {}
|
|
manual = [
|
|
'app::source_rename::timing_tests::accepted_release1_prepare_commit_sync_and_confirm_timing',
|
|
'app::source_rename::timing_tests::layout_timing_tests::accepted_release1_constructor_vs_reuse_through_next_highlight',
|
|
'app::source_symbols::tests::source_symbols_100_modules_1000_definitions_10000_uses']
|
|
listed = read(GATES/'list-44095f7.result.json')
|
|
names = listed['listing_members']; assert len(names) == len(set(names)) == 1098
|
|
required = read(ORIGIN/'.local/navigation-palette-required-tests-20260913.json')['groups']
|
|
new_names = None
|
|
for node in ast.walk(ast.parse((ORIGIN/'.local/admit-navigation-selection-gate.py').read_text())):
|
|
if isinstance(node,ast.Assign) and any(isinstance(t,ast.Name) and t.id=='new_names' for t in node.targets):
|
|
new_names = ast.literal_eval(node.value)
|
|
assert len(new_names)==16
|
|
baseline_rel = Path('harness/experiments/navigation-palette-e124029-windows-20260913/gates/list-e124029.result.json')
|
|
baseline = read(ROOT/baseline_rel)
|
|
assert len(baseline['listing_members'])==1082 and set(names)==set(baseline['listing_members'])|set(new_names)
|
|
selectors = {'full':None,'navigation':'navigation_union','scroll':'preview_scroll_tests',
|
|
'symbols':'app::source_symbols','rename-escape':'actual_captured_escape_closes_only_its_priority_owner_and_retains_worker'}
|
|
for mode in ('list','full','strict','navigation','scroll','symbols','rename-escape'):
|
|
r=read(GATES/f'{mode}-44095f7.result.json')
|
|
assert r['source']==r['head_after']==SOURCE and r['exit']==0 and not r['changed_inputs']
|
|
log=(GATES/f'{mode}-44095f7.log').read_text()
|
|
assert not re.search(r'^(error|warning)(\[|:)',log,re.M)
|
|
prefix=['cargo','test','--locked','-p','oa-desktop','--bin','arcadia-studio']
|
|
expected = ['cargo','clippy','--locked','-p','oa-desktop','--all-targets','--','-D','warnings'] if mode=='strict' else prefix+(['--','--list'] if mode=='list' else ([selectors[mode]] if selectors[mode] else [])+['--','--test-threads=1'])
|
|
assert r['command']==expected
|
|
outcomes=None
|
|
if mode!='strict':
|
|
assert r['artifacts']==listed['artifacts']
|
|
if mode!='list':
|
|
rows=re.findall(r'^test ([^\r\n]+) \.\.\. (ok|FAILED|ignored)(?:, [^\r\n]*)?$',log,re.M)
|
|
outcomes=dict(rows); assert len(rows)==len(outcomes)
|
|
wanted=[n for n in names if selectors[mode] is None or selectors[mode] in n]
|
|
assert [n for n,_ in rows]==wanted
|
|
assert all(v==('ignored' if n in manual else 'ok') for n,v in rows)
|
|
totals=[sum(v==status for _,v in rows) for status in ('ok','FAILED','ignored')]
|
|
assert re.findall(r'^test result: ok\. (\d+) passed; (\d+) failed; (\d+) ignored; 0 measured; (\d+) filtered out;',log,re.M)==[tuple(map(str,totals+[1098-len(rows)]))]
|
|
if mode=='full': assert all(outcomes[n]=='ok' for n in new_names)
|
|
if mode in ('navigation','scroll'): assert set(outcomes)==set(required[selectors[mode]])
|
|
desktop[mode]={'result_file':f'raw/.local/navigation-palette-gates-20260913/{mode}-44095f7.result.json','outcomes':outcomes,'command':r['command'],'start':r['start'],'end':r['end']}
|
|
build=read(GATES/'artifacts-44095f7/result.json')
|
|
assert build['source']==build['head_after']==SOURCE and build['exit']==0 and build['outcome']=='passed' and build['failure'] is None and not build['changed_inputs']
|
|
assert build['command'][1:]==['build','--locked','--offline','-p','oa-desktop','-p','oa-server','--bins','--message-format=json-render-diagnostics']
|
|
for key,filename in [('inputs','inputs.json'),('environment','environment.json'),('stdout','cargo.jsonl'),('stderr','cargo.stderr.log')]:
|
|
data=(GATES/'artifacts-44095f7'/filename).read_bytes(); assert build[key]=={'bytes':len(data),'sha256':sha(data)}
|
|
assert build['launcher']=={'bytes':(ORIGIN/'.local/build-navigation-palette-artifacts.py').stat().st_size,'sha256':sha((ORIGIN/'.local/build-navigation-palette-artifacts.py').read_bytes())}
|
|
cargo=[json.loads(line) for line in (GATES/'artifacts-44095f7/cargo.jsonl').read_text().splitlines()]
|
|
assert cargo[-1]=={'reason':'build-finished','success':True}
|
|
assert {a['name'] for a in build['artifacts']}=={'arcadia-studio','arcadia-server'}
|
|
for a in build['artifacts']:
|
|
raw=Path(a['preserved']).read_bytes(); assert len(raw)==a['bytes'] and sha(raw)==a['sha256']
|
|
assert a['cargo_artifact'] in cargo
|
|
assert a['cargo_artifact']['profile']=={'opt_level':'0','debuginfo':0,'debug_assertions':True,'overflow_checks':True,'test':False}
|
|
for path in raws:
|
|
if path.name.endswith('.admission.json'):
|
|
a=read(path); stem=path.name.removesuffix('.admission.json')
|
|
assert a['source']==SOURCE and a['verified_inputs']==581
|
|
for key,suffix in [('result_sha256','.result.json'),('log_sha256','.log'),('inputs_sha256','.inputs.json')]:
|
|
assert a[key]==sha((GATES/(stem+suffix)).read_bytes())
|
|
maps=[]
|
|
for path in raws:
|
|
if path.name.endswith('.inputs.json') or path==GATES/'artifacts-44095f7/inputs.json':
|
|
m=read(path); assert m['source']==SOURCE
|
|
assert len(m['inputs'])==(615 if path.name=='inputs.json' else 581)
|
|
maps.append(m)
|
|
for m in maps:
|
|
assert all(item in maps[0]['inputs'] for item in m['inputs']) if len(m['inputs'])==581 else True
|
|
unique={i['path']:i for m in maps for i in m['inputs']};assert len(unique)==615
|
|
scopes=['Cargo.toml','Cargo.lock','rust-toolchain.toml','.cargo','build','crates','assets','docs','examples','harness/fixtures','scripts']
|
|
assert sorted(unique)==git('ls-tree','-r','--name-only',SOURCE,*scopes).decode().splitlines()
|
|
assert not git('diff','--name-only',SOURCE,BASE,'--',*scopes)
|
|
specs=[f'{SOURCE}:{p}' for p in sorted(unique)]
|
|
blobs=subprocess.check_output(['git','cat-file','--batch'],cwd=ROOT,input=('\n'.join(specs)+'\n').encode());offset=0
|
|
for p in sorted(unique):
|
|
end=blobs.index(b'\n',offset);_,kind,size=blobs[offset:end].split();size=int(size);raw=blobs[end+1:end+1+size];offset=end+size+2
|
|
assert kind==b'blob' and unique[p]=={'path':p,'bytes':len(raw),'sha256':sha(raw)} and (ROOT/p).read_bytes()==raw
|
|
assert offset==len(blobs)
|
|
ARCHIVE.mkdir(parents=True)
|
|
entries=[]
|
|
def write(rel,raw,origin):
|
|
dst=ROOT/rel;dst.parent.mkdir(parents=True,exist_ok=True)
|
|
with dst.open('xb') as f:f.write(raw)
|
|
assert dst.read_bytes()==raw
|
|
entries.append({'path':rel.as_posix(),'bytes':len(raw),'sha256':sha(raw),'origin':origin})
|
|
for path in raws:
|
|
original=path.relative_to(ORIGIN)
|
|
write(REL/'raw'/original,path.read_bytes(),{'kind':'verbatim original','repository_relative_local_path':original.as_posix()})
|
|
audit={'source':SOURCE,'publication_base':BASE,'source_scope_identical_to_base':scopes,'unique_build_inputs':615,'gate_inputs':581,
|
|
'desktop':desktop,'desktop_listing':names,'new_16_passed':new_names,'manual_desktop_cases':manual,
|
|
'baseline_listing':{'path':baseline_rel.as_posix(),'sha256':sha((ROOT/baseline_rel).read_bytes())},
|
|
'build_artifacts_omitted':build['artifacts'],'service_audit':'raw/.local/navigation-service-gates-44095f7-audit.json',
|
|
'scope':'Actual closed 440 Windows gates only; not native/package/release acceptance or a later source correction.'}
|
|
write(REL/'runtime-audit.json',(json.dumps(audit,indent=2)+'\n').encode(),{'kind':'generated readback from original records'})
|
|
write(REL/'.gitattributes',b'* -text\n',{'kind':'generated byte-preservation policy'})
|
|
(ROOT/'.local/archive-entries.json').write_text(json.dumps(entries,indent=2)+'\n')
|
|
print(json.dumps({'originals':len(raws),'raw_bytes':sum(p.stat().st_size for p in raws),'entries':len(entries),'unique_inputs':len(unique)}))
|