58 lines
4.2 KiB
Python
58 lines
4.2 KiB
Python
from pathlib import Path
|
|
import hashlib
|
|
import io
|
|
import json
|
|
import re
|
|
import zipfile
|
|
|
|
root = Path(__file__).resolve().parent
|
|
def digest(data): return {'bytes':len(data), 'sha256':hashlib.sha256(data).hexdigest()}
|
|
def require(ok, message):
|
|
if not ok: raise SystemExit(message)
|
|
manifest = json.loads((root / 'files.json').read_text())
|
|
actual = {p.relative_to(root).as_posix() for p in root.rglob('*') if p.is_file() and p.name != 'files.json' and '__pycache__' not in p.parts}
|
|
require(actual == set(manifest), 'Outer membership mismatch')
|
|
for name, expected in manifest.items(): require(digest((root/name).read_bytes()) == expected, f'Outer hash: {name}')
|
|
with zipfile.ZipFile(root / 'evidence.zip') as evidence:
|
|
def read(name): return json.loads(evidence.read(name))
|
|
payloads = read('capture-files.json')
|
|
require(set(evidence.namelist()) == set(payloads) | {'capture-files.json'}, 'Capture membership mismatch')
|
|
for name, expected in payloads.items(): require(digest(evidence.read(name)) == expected, f'Capture hash: {name}')
|
|
for gate, status in [('production-focused-1',0),('production-core-1',101)]:
|
|
result = read(gate+'/result.json')
|
|
require(result['exitCode'] == status and result['inputsUnchanged'], f'{gate}: outcome')
|
|
require(all(result[k] == v for k,v in read(gate+'/started.json').items()), f'{gate}: start')
|
|
for key, file in [('inputs','inputs.json'),('archive','inputs.zip'),('stdout','stdout.log'),('stderr','stderr.log')]:
|
|
require(digest(evidence.read(gate+'/'+file)) == result[key], f'{gate}: {key}')
|
|
require(digest(evidence.read('gate-policy.py')) == result['helper'], f'{gate}: runner')
|
|
inputs = read(gate+'/inputs.json')
|
|
require(len(inputs) == result['inputCount'], f'{gate}: input count')
|
|
with zipfile.ZipFile(io.BytesIO(evidence.read(gate+'/inputs.zip'))) as sources:
|
|
require(set(sources.namelist()) == set(inputs), f'{gate}: source membership')
|
|
for path, expected in inputs.items(): require(digest(sources.read(path)) == expected, f'{gate}: source {path}')
|
|
def totals(prefix, filenames):
|
|
rows = [tuple(map(int,m)) for f in filenames for m in re.findall(r'test result: (?:ok|FAILED)\. (\d+) passed; (\d+) failed; (\d+) ignored;', evidence.read(prefix+f).decode())]
|
|
return tuple(sum(row[i] for row in rows) for i in range(3))
|
|
require(totals('production-focused-1/', ['stdout.log']) == (75,0,0), 'Focused totals')
|
|
require(b'No space left on device' in evidence.read('production-core-1/stdout.log'), 'Missing disk failure evidence')
|
|
built = read('production-built-tests-1/results.json')
|
|
compiler = {r['cargo']['target']['name']:r for r in read('production-core-1/result.json')['artifacts']}
|
|
require(len(built) == 36, 'Built test inventory')
|
|
for run in built:
|
|
name = run['name']
|
|
require(run['binary'] == compiler[name]['readback'], f'{name}: binary receipt')
|
|
for stream in ['stdout','stderr']:
|
|
require(digest(evidence.read(f'production-built-tests-1/{name}.{stream}.log')) == run[stream], f'{name}: stream')
|
|
require(totals('production-built-tests-1/', [r['name']+'.stdout.log' for r in built]) == (354,2,1), 'Built test totals')
|
|
receipt = read('production-built-tests-1/receipt.json')
|
|
require(receipt['inputsUnchanged'] and receipt['testsRun'] == 36, 'Execution receipt')
|
|
teaching = read('production-teaching-1/result.json')
|
|
require(teaching['nonSourceFilesUnchanged'] and len(teaching['changed']) == 29, 'Teaching delta')
|
|
require(all(p.endswith('.arcadia') for p in teaching['changed']), 'Non-source teaching change')
|
|
for run in teaching['runs']:
|
|
require(run['exitCode'] == 0 and run['binary'] == compiler[run['name']]['readback'], 'Teaching runner receipt')
|
|
require(totals('production-teaching-1/', ['release1_teaching.stdout.log']) == (4,0,0), 'Teaching rerun')
|
|
require(read('language-doc-3/result.json')['warnings']['bytes'] == 0, 'Documentation warnings')
|
|
print('Verified captures: focused 75 pass; disk-limited build; separately executed 354 pass/2 fail/1 ignored; teaching rerun 4 pass.')
|
|
print('Final candidate still needs corrected anchor test, full core, strict Clippy, native/public-consumer and release verification.')
|