Files
ARCADIA-Studio/harness/experiments/analysis-carried-phase-20260925/inspect_runtime.py
T

135 lines
7.3 KiB
Python

"""Reconcile committed Windows carried-phase gates against raw logs and prior outcomes."""
from pathlib import Path
import hashlib
import json
import re
import subprocess
import sys
base = Path(__file__).resolve().parents[2]
root = base / '.local/as3batch'
directory = base / '.local/analysis-carried-phase-gates-20260925'
prior = base / '.local/analysis-mixed-rename-plan-gates-20260924'
source, stem, expected_added = sys.argv[1], sys.argv[2], int(sys.argv[3])
assert 1 <= expected_added <= 100
assert re.fullmatch(r'[0-9a-f]{40}', source)
assert re.fullmatch(r'[a-zA-Z0-9-]+', stem)
sha = lambda raw: hashlib.sha256(raw).hexdigest()
def git(*args):
return subprocess.check_output(['git', '--no-replace-objects', *args], cwd=root)
def receipt(folder, name):
path = folder / (name + '.result.json')
data = json.loads(path.read_bytes())
raw = (folder / (name + '.log')).read_bytes()
assert data['log_sha256'] == sha(raw)
return data, raw
assert git('rev-parse', 'HEAD').decode().strip() == source
assert not git('status', '--porcelain', '--untracked-files=no').strip()
scope = ['Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml', '.cargo', 'build', 'crates', 'assets', 'docs', 'examples', 'harness/fixtures', 'vendor']
paths = git('ls-tree', '-r', '--name-only', source, *scope).decode().splitlines()
blobs = subprocess.check_output(['git', '--no-replace-objects', 'cat-file', '--batch'], cwd=root,
input=''.join(f'{source}:{p}\n' for p in paths).encode())
offset = 0
expected_inputs = []
for path in paths:
end = blobs.index(b'\n', offset)
_, kind, count = blobs[offset:end].split()
count = int(count)
raw = blobs[end + 1:end + 1 + count]
assert kind == b'blob' and (root / path).read_bytes() == raw, path
expected_inputs.append({'path': path, 'bytes': count, 'sha256': sha(raw)})
offset = end + count + 2
assert offset == len(blobs)
prefix = ['cargo', 'test', '--locked', '--offline', '-p', 'oa-core', '--lib']
focus = 'language::analysis_source::mixed::carried::tests::'
commands = {
'focused': prefix + [focus, '--', '--test-threads=1'],
'full': prefix + ['--', '--test-threads=1'],
'list': prefix + ['--', '--list'],
'clippy': ['cargo', 'clippy', '--locked', '--offline', '-p', 'oa-core', '--all-targets', '--', '-D', 'warnings'],
'fmt': ['cargo', 'fmt', '--all', '--', '--check'],
}
verified = {}
all_receipts = {}
for mode, command in commands.items():
name = f'carried-{mode}-{stem}-1'
data, raw = receipt(directory, name)
assert data['source'] == data['head_after'] == source
assert data['mode'] == mode and data['command'] == command
assert not data['changed_inputs'] and not data['verification_failures']
manifest_raw = (directory / data['inputs']).read_bytes()
assert sha(manifest_raw) == data['inputs_sha256']
assert json.loads(manifest_raw) == {'source': source, 'inputs': expected_inputs}
launcher = (directory / data['launcher_copy']).read_bytes()
assert sha(launcher) == data['launcher_sha256'] == data['launcher_sha256_after']
assert source.encode() in launcher
env = data['environment']
assert env['CARGO_BUILD_JOBS'] == '1' and env['CARGO_INCREMENTAL'] == '0'
assert env['ARCADIA_CODEC_LIFECYCLE_PHASE'] is None and env['RUST_MIN_STACK'] is None
assert data['cwd'] == str(root)
text = raw.decode()
outcomes = re.findall(r'^test ([^\r\n]+) \.\.\. (ok|FAILED|ignored)\r?$', text, re.M)
assert outcomes == [tuple(x) for x in data['outcomes']]
assert len(outcomes) == len(dict(outcomes))
members = re.findall(r'^([^\r\n]+): test\r?$', text, re.M) if mode == 'list' else []
assert members == data['listing_members'] and len(members) == data['listing_count']
assert len(members) == len(set(members))
if mode == 'list':
assert len(members) == 246 + expected_added
if mode in ('focused', 'full'):
counts = tuple(sum(v == state for _, v in outcomes) for state in ('ok', 'FAILED', 'ignored'))
summary = re.findall(r'^test result: (ok|FAILED)\. (\d+) passed; (\d+) failed; (\d+) ignored; 0 measured; (\d+) filtered out;', text, re.M)
assert len(summary) == 1 and tuple(map(int, summary[0][1:4])) == counts
assert summary[0][0] == ('FAILED' if counts[1] else 'ok')
assert int(summary[0][4]) == (246 if mode == 'focused' else 0)
assert data['exit'] == (101 if counts[1] else 0)
assert len(data['artifacts']) == 1
for artifact in data['artifacts']:
actual = Path(artifact['path']).read_bytes()
assert len(actual) == artifact['bytes'] and sha(actual) == artifact['sha256']
assert str(Path(artifact['path'])).replace('\\', '/') in text.replace('\\', '/')
all_receipts[mode] = data
verified[name] = {'source': source, 'exit': data['exit'], 'outcomes': len(outcomes), 'listing': len(members), 'log_sha256': sha(raw), 'result_sha256': sha((directory / (name + '.result.json')).read_bytes())}
old, old_raw = receipt(prior, 'rename-full-18073a6-1')
assert old['source'] == '18073a6f2eabce83fc83997f094e331eec835a16'
old_actual = re.findall(r'^test ([^\r\n]+) \.\.\. (ok|FAILED|ignored)\r?$', old_raw.decode(), re.M)
assert old_actual == [tuple(x) for x in old['outcomes']]
assert len(old_actual) == len(dict(old_actual)) == 246
old_out = dict(old['outcomes'])
new_out = dict(all_receipts['full']['outcomes'])
assert len(old_out) == 246 and len(new_out) == 246 + expected_added
assert all(new_out.get(k) == v for k, v in old_out.items())
added = set(new_out) - set(old_out)
assert len(added) == expected_added and all(new_out[k] == 'ok' and k.startswith(focus) for k in added)
assert set(dict(all_receipts['focused']['outcomes'])) == added
assert all(status == 'ok' for _, status in all_receipts['focused']['outcomes'])
assert set(all_receipts['list']['listing_members']) == set(new_out)
assert all_receipts['clippy']['exit'] == all_receipts['list']['exit'] == all_receipts['focused']['exit'] == 0
assert all_receipts['fmt']['exit'] == 1
def failure_blocks(raw):
text = raw.decode().replace('\r\n', '\n')
return {m[1]: re.sub(r"(?m)^(thread '[^\n]*') \(\d+\) panicked", r'\1 (<PID>) panicked', m[2]).strip()
for m in re.finditer(r'^---- ([^\n]+) stdout ----\n(.*?)(?=^---- |^failures:|\Z)', text, re.M | re.S)}
new_raw = (directory / f'carried-full-{stem}-1.log').read_bytes()
old_blocks, new_blocks = failure_blocks(old_raw), failure_blocks(new_raw)
assert len(old_blocks) == len(new_blocks) == 16 and old_blocks == new_blocks
old_fmt, old_fmt_raw = receipt(prior, 'rename-fmt-18073a6-1')
fmt_raw = (directory / f'carried-fmt-{stem}-1.log').read_bytes()
assert fmt_raw == old_fmt_raw
result = {'source': source, 'baseline': old['source'], 'inputs': len(expected_inputs),
'unchanged_old_outcomes': 246, 'added_passed': expected_added,
'full_passed': sum(v == 'ok' for v in new_out.values()),
'identical_failure_blocks_after_pid_only_normalization': 16,
'identical_fmt_sha256': sha(fmt_raw), 'receipts': verified,
'scope': 'Read-only committed-input/raw-log/artifact comparison; no Cargo execution.'}
destination = Path(__file__).with_name('CARRIED-PHASE-RUNTIME-READBACK.json')
assert not destination.exists(), 'Preserve previous readback; use a separately named checker for another source.'
destination.write_text(json.dumps(result, indent=2) + '\n', encoding='utf-8')
print(json.dumps(result, indent=2))