| 1 | #!/usr/bin/env python3 |
| 2 | """Cold-open a batch of disposable section candidates in isolated OneNote caches.""" |
| 3 | import argparse |
| 4 | import hashlib |
| 5 | import json |
| 6 | from pathlib import Path |
| 7 | import signal |
| 8 | import zipfile |
| 9 | from native_runner import ROOT, clone, command, windows, collect_artifacts |
| 10 | |
| 11 | |
| 12 | def run(inputs, output, scripts=None): |
| 13 | output.mkdir(parents=True, exist_ok=False) |
| 14 | files = sorted(inputs.glob('*.one')) |
| 15 | assert files, 'No section candidates' |
| 16 | if scripts is None: |
| 17 | (output / 'scripts').mkdir() |
| 18 | scripts = [output / 'scripts' / name for name in ('cold.ps1', 'probe.ps1')] |
| 19 | for path in scripts: path.write_bytes((ROOT / 'tools/native' / path.name).read_bytes()) |
| 20 | (output / 'run.json').write_text(json.dumps({'inputs': {p.name: hashlib.sha256(p.read_bytes()).hexdigest() for p in files}, |
| 21 | 'scripts': {p.name: hashlib.sha256(p.read_bytes()).hexdigest() for p in scripts}}, indent=2)) |
| 22 | archive = output / 'inputs.zip' |
| 23 | try: |
| 24 | with zipfile.ZipFile(archive, 'w', zipfile.ZIP_DEFLATED) as packed: |
| 25 | for path in files: |
| 26 | packed.writestr(path.name, path.read_bytes()) |
| 27 | with clone(output) as name: |
| 28 | for local, remote in [(archive, r'C:\one-tests\inputs.zip'), (scripts[0], r'C:\one-tests\cold-current.ps1'), |
| 29 | (scripts[1], r'C:\one-tests\probe.ps1')]: |
| 30 | result = windows.do_put(local, remote, name) |
| 31 | if result.get('error'): raise RuntimeError(result['error']) |
| 32 | command(name, r'powershell -NoProfile -Command "Expand-Archive C:\one-tests\inputs.zip C:\one-tests\runs\capture\inputs"', output) |
| 33 | command(name, r'powershell -NoProfile -NonInteractive -ExecutionPolicy Bypass -File C:\one-tests\probe.ps1 -Root C:\one-tests\runs\capture -CloneHost ONE-' + name.upper(), output, (len(files) * 60 + 120) * 1000) |
| 34 | collect_artifacts(name, output, r'results, C:\one-tests\runs\capture\results.json, C:\one-tests\runs\capture\progress.jsonl') |
| 35 | finally: |
| 36 | archive.unlink(missing_ok=True) |
| 37 | |
| 38 | |
| 39 | if __name__ == '__main__': |
| 40 | parser = argparse.ArgumentParser(description=__doc__) |
| 41 | parser.add_argument('inputs', type=Path) |
| 42 | parser.add_argument('output', type=Path) |
| 43 | args = parser.parse_args() |
| 44 | def interrupted(_signum, _frame): |
| 45 | raise KeyboardInterrupt |
| 46 | signal.signal(signal.SIGTERM, interrupted) |
| 47 | run(args.inputs.resolve(), args.output.resolve()) |