138 lines
7.4 KiB
Python
138 lines
7.4 KiB
Python
"""Admit only the prepared desktop listing, focused suites, full suite or clippy."""
|
|
from pathlib import Path
|
|
from datetime import datetime, timezone
|
|
import hashlib
|
|
import json
|
|
import re
|
|
import subprocess
|
|
import sys
|
|
|
|
if not __debug__:
|
|
raise SystemExit('Refusing optimized Python: admission assertions are required')
|
|
here = Path(__file__).resolve().parent
|
|
base = here.parents[1]
|
|
root = base / '.local/rs'
|
|
folder = base / '.local/rename-scroll-gates-20260913'
|
|
watched = {}
|
|
def read(path):
|
|
raw = path.read_bytes()
|
|
if path in watched:
|
|
assert watched[path] == raw, path
|
|
watched[path] = raw
|
|
return raw
|
|
def digest(path):
|
|
return hashlib.sha256(read(path)).hexdigest()
|
|
def value(path):
|
|
return json.loads(read(path))
|
|
assert digest(here / 'expected.json') == '7c104d5b9409b70dd4c0a38ddac45d8d9f910f49342084cdabe2b780b085f9f3'
|
|
config = value(here / 'expected.json')
|
|
source = config['source']
|
|
assert subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=root).decode().strip() == source
|
|
for path, sha in config['baseline_and_original_helper_pins'].items():
|
|
assert digest(base / path) == sha, path
|
|
baseline = value(base / '.local/navigation-palette-gates-20260913/list-44095f7.result.json')
|
|
baseline_admission = value(base / '.local/navigation-palette-gates-20260913/list-44095f7.admission.json')
|
|
assert baseline['exit'] == 0 and baseline_admission['verified_inputs'] == 581
|
|
assert baseline['source'] == baseline_admission['source'] == '44095f78c28b79d6d085863dc928adba8e24d955'
|
|
expected = config['listing_members']
|
|
assert len(expected) == len(set(expected)) == 1099
|
|
new = 'app::source_rename::tests::preview_scroll_tests::details_remount_restores_wheel_offset_before_any_rescroll'
|
|
assert len(baseline['listing_members']) == 1098
|
|
assert set(expected) == set(baseline['listing_members']) | {new}
|
|
name, mode = sys.argv[1:3]
|
|
assert re.fullmatch(r'[a-zA-Z0-9-]+', name)
|
|
record_path = folder / (name + '.result.json')
|
|
record = value(record_path)
|
|
assert record['source'] == record['head_after'] == source
|
|
assert type(record['exit']) is int and record['exit'] == 0
|
|
assert record['changed_inputs'] == [] and record['status_after'] == ''
|
|
assert datetime.fromisoformat(record['end']) >= datetime.fromisoformat(record['start'])
|
|
assert record['launcher_sha256'] == digest(here / 'run-fixed.py')
|
|
assert record['inputs'] == name + '.inputs.json'
|
|
inputs_path = folder / record['inputs']
|
|
manifest = value(inputs_path)
|
|
assert manifest['source'] == source
|
|
scopes = ['Cargo.toml', 'Cargo.lock', 'rust-toolchain.toml', '.cargo', 'build', 'crates', 'assets', 'docs', 'examples', 'harness/fixtures']
|
|
paths = subprocess.check_output(['git', 'ls-tree', '-r', '--name-only', source, *scopes], cwd=root).decode().splitlines()
|
|
assert len(paths) == 581 == config['gate_inputs']
|
|
assert [item['path'] for item in manifest['inputs']] == paths
|
|
blobs = subprocess.check_output(['git', 'cat-file', '--batch'], cwd=root,
|
|
input=''.join(f'{source}:{p}\n' for p in paths).encode())
|
|
offset = 0
|
|
for item in manifest['inputs']:
|
|
end = blobs.index(b'\n', offset)
|
|
_, kind, size = blobs[offset:end].split()
|
|
assert kind == b'blob'
|
|
size = int(size)
|
|
raw = blobs[end + 1:end + 1 + size]
|
|
assert read(root / item['path']) == raw
|
|
assert item == {'path': item['path'], 'bytes': size, 'sha256': hashlib.sha256(raw).hexdigest()}
|
|
offset = end + size + 2
|
|
assert offset == len(blobs)
|
|
log_path = folder / (name + '.log')
|
|
log = read(log_path).decode('utf-8', errors='strict')
|
|
prefix = ['cargo', 'test', '--locked', '-p', 'oa-desktop', '--bin', 'arcadia-studio']
|
|
names, artifact = [], None
|
|
if mode != 'clippy':
|
|
assert len(record['artifacts']) == 1
|
|
artifact = record['artifacts'][0]
|
|
raw = Path(artifact['path']).read_bytes()
|
|
assert len(raw) == artifact['bytes'] and hashlib.sha256(raw).hexdigest() == artifact['sha256']
|
|
launches = re.findall(r'Running unittests [^\r\n]+ \(([^\r\n]+\.exe)\)', log)
|
|
assert len(launches) == 1
|
|
launched = Path(launches[0])
|
|
assert (launched if launched.is_absolute() else root / launched).resolve() == Path(artifact['path']).resolve()
|
|
if mode == 'list':
|
|
assert record['command'] == prefix + ['--', '--list']
|
|
names = re.findall(r'^([^\r\n]+): test\r?$', log, re.M)
|
|
assert names == record['listing_members']
|
|
assert record['listing_count'] == len(names) == len(set(names)) == 1099
|
|
assert set(names) == set(expected)
|
|
assert re.findall(r'^(\d+) tests, (\d+) benchmarks\s*$', log, re.M) == [('1099', '0')]
|
|
elif mode in ('focused', 'full'):
|
|
listing_name = sys.argv[3]
|
|
assert re.fullmatch(r'[a-zA-Z0-9-]+', listing_name)
|
|
listed = value(folder / (listing_name + '.result.json'))
|
|
admitted = value(folder / (listing_name + '.admission.json'))
|
|
assert admitted['source'] == source and admitted['mode'] == 'list'
|
|
assert admitted['helper_sha256'] == digest(Path(__file__))
|
|
for suffix, field in [('result.json', 'result_sha256'), ('inputs.json', 'inputs_sha256'), ('log', 'log_sha256')]:
|
|
assert admitted[field] == digest(folder / (listing_name + '.' + suffix))
|
|
assert admitted['config_sha256'] == digest(here / 'expected.json')
|
|
assert admitted['artifact'] == artifact == listed['artifacts'][0]
|
|
assert admitted['inputs_sha256'] == digest(inputs_path)
|
|
assert set(listed['listing_members']) == set(expected)
|
|
if mode == 'focused':
|
|
selector = sys.argv[4]
|
|
names = config['focused_groups'][selector]
|
|
assert record['command'] == prefix + [selector, '--', '--test-threads=1']
|
|
ignored = []
|
|
else:
|
|
names, ignored = expected, config['ignored']
|
|
assert record['command'] == prefix + ['--', '--test-threads=1']
|
|
outcomes = re.findall(r'^test ([^\r\n]+) \.\.\. (ok|FAILED|ignored)(?:, [^\r\n]*)?\r?$', log, re.M)
|
|
actual = [n for n, _ in outcomes]
|
|
assert len(actual) == len(set(actual)) == len(names) and set(actual) == set(names)
|
|
assert {n for n, outcome in outcomes if outcome == 'ignored'} == set(ignored)
|
|
assert all(outcome == ('ignored' if n in ignored else 'ok') for n, outcome in outcomes)
|
|
totals = re.findall(r'^test result: ok\. (\d+) passed; (\d+) failed; (\d+) ignored; (\d+) measured; (\d+) filtered out;', log, re.M)
|
|
assert totals == [(str(len(names)-len(ignored)), '0', str(len(ignored)), '0', str(1099-len(names)))], totals
|
|
elif mode == 'clippy':
|
|
assert record['command'] == ['cargo', 'clippy', '--locked', '-p', 'oa-desktop', '--all-targets', '--', '-D', 'warnings']
|
|
assert record['artifacts'] == []
|
|
assert re.search(r'Finished `dev` profile', log)
|
|
else:
|
|
raise AssertionError('Unsupported admission mode')
|
|
assert subprocess.check_output(['git', 'rev-parse', 'HEAD'], cwd=root).decode().strip() == source
|
|
assert not subprocess.check_output(['git', 'status', '--porcelain', '--untracked-files=all', '--', *scopes], cwd=root)
|
|
receipt = {'source': source, 'mode': mode, 'names': names, 'artifact': artifact,
|
|
'utc': datetime.now(timezone.utc).isoformat(), 'verified_inputs': 581,
|
|
'result_sha256': digest(record_path), 'inputs_sha256': digest(inputs_path),
|
|
'log_sha256': digest(log_path), 'config_sha256': digest(here / 'expected.json'),
|
|
'helper_sha256': digest(Path(__file__)), 'boundary': 'Desktop source gate only; native/package acceptance is separate.'}
|
|
for path, raw in watched.items():
|
|
assert path.read_bytes() == raw, path
|
|
with (folder / (name + '.admission.json')).open('x', encoding='utf-8', newline='\n') as stream:
|
|
stream.write(json.dumps(receipt, indent=2) + '\n')
|
|
print(json.dumps({'admitted': name, 'mode': mode, 'names': len(names), 'source': source}))
|