Files

87 lines
4.3 KiB
Python

#!/usr/bin/env python3
"""Row278 commands prepared for Sage CLEAR. No execution on import."""
import argparse
import hashlib
import importlib.util
import json
import os
from pathlib import Path
import subprocess
import sys
sys.dont_write_bytecode = True
HERE = Path(__file__).resolve().parent
spec = importlib.util.spec_from_file_location('row278_checks', HERE/'checks.py')
checks = importlib.util.module_from_spec(spec)
spec.loader.exec_module(checks)
def totals(path):
result = {}
for line in path.read_text(errors='replace').splitlines():
for key in ['tests', 'pass', 'fail', 'skipped']:
prefix = '# '+key+' '
if line.startswith(prefix) and line[len(prefix):].isdigit():
result[key] = int(line[len(prefix):])
return result
def main():
ap = argparse.ArgumentParser()
ap.add_argument('--grant', required=True)
ap.add_argument('--stage', choices=['syntax', 'red', 'focused', 'whole'], required=True)
ap.add_argument('--out', type=Path, required=True)
args = ap.parse_args()
if not os.environ.get('TMPDIR', '').startswith('/mnt/storage/scratch/tmp/g'):
raise RuntimeError('use the granted scratch TMPDIR')
expected = json.loads((HERE/'CANDIDATE-SHAS.json').read_text())
for name, sha in expected.items():
assert hashlib.sha256((checks.REPO/name).read_bytes()).hexdigest() == sha, name
args.out.mkdir(parents=True, exist_ok=True)
results = dict(grant=args.grant, stage=args.stage, steps=[])
def step(name, command, red=False, seconds=1200):
r = checks.run(command, args.out/(name+'.log'), seconds=seconds)
r.update(name=name, expected_red=red, counts=totals(Path(r['log'])))
results['steps'].append(r)
(args.out/'results.json').write_text(json.dumps(results, indent=2)+'\n')
if r['timeout']:
raise RuntimeError('timeout: stop and report')
if red and r['code'] == 0:
raise RuntimeError('expected RED did not fail: stop and report')
if not red and r['code'] != 0:
raise RuntimeError('unexpected failure: stop and report')
tests = ['packages/webui/tests/thread-claims.test.mjs', 'packages/webui/tests/thread-claims-browser.test.mjs', 'packages/webui/tests/shell.test.mjs']
if args.stage == 'syntax':
for index, name in enumerate(expected):
if name.endswith(('.js', '.mjs')):
step('syntax-'+str(index), ['node', '--check', name])
elif args.stage == 'red':
targets = ['packages/webui/src/cli.mjs', 'packages/webui/src/serve.mjs', 'packages/webui/src/public/bus.js']
saved = {name: (checks.REPO/name).read_bytes() for name in targets}
status = subprocess.check_output(['git', 'status', '--porcelain', '--untracked-files=no'], cwd=checks.REPO)
try:
for name in targets:
(checks.REPO/name).write_bytes(subprocess.check_output(['git', 'show', '6af85df4b:'+name], cwd=checks.REPO))
for index, (name, pattern) in enumerate(zip(tests, ['row278 HTTP read returns held claims', 'row278 browser lists held claims'])):
step('red-'+str(index), ['node', '--test', '--test-reporter=tap', '--test-name-pattern', pattern, name], red=True)
finally:
for name, data in saved.items():
(checks.REPO/name).write_bytes(data)
assert (checks.REPO/name).read_bytes() == data
assert subprocess.check_output(['git', 'status', '--porcelain', '--untracked-files=no'], cwd=checks.REPO) == status
elif args.stage == 'focused':
for index, name in enumerate(tests):
step('focused-'+str(index), ['node', '--test', '--test-reporter=tap', name])
else:
step('bus', ['node', '--test', '--test-reporter=tap', 'packages/bus/tests/'])
step('webui', ['node', '--test', '--test-reporter=tap', 'packages/webui/tests/'])
files = sorted((checks.REPO/'scripts').glob('test-*.sh'))
assert len(files) == 10
limits = json.loads((HERE/'SHELL-LIMITS.json').read_text())['scripts']
for path in files:
script = str(path.relative_to(checks.REPO))
limit = limits[script]['limit_seconds']
step(path.stem, ['timeout', '-k', '10', str(limit), 'bash', script], seconds=limit+30)
print(json.dumps(results, indent=2))
if __name__ == '__main__':
main()