from pathlib import Path from hashlib import sha256 import subprocess, json, os, tempfile, re, signal, time out=Path(__file__).resolve().parent root=Path('/mnt/storage/src/mosaic-stack-rocko-124-r2') rows=json.loads((out/'mutants/results.json').read_text()) assert len(rows)==66 and all(r['result']=='KILLED' for r in rows) paths=(out/'changed-paths.txt').read_text().splitlines() expected={p:h for h,p in (line.split(' ',1) for line in (out/'candidate-manifest.sha256').read_text().splitlines())} assert set(paths)==set(expected) for p,h in expected.items(): assert sha256((root/p).read_bytes()).hexdigest()==h,p assert sha256(subprocess.check_output(['git','show',':'+p],cwd=root)).hexdigest()==h,p fd,index=tempfile.mkstemp(prefix='rocko-124-r2-index-',dir='/mnt/storage/scratch/rocko-124/tmp');os.close(fd) try: env={**os.environ,'GIT_INDEX_FILE':index} base=(out/'base.txt').read_text().strip() subprocess.run(['git','read-tree',base],cwd=root,env=env,check=True) subprocess.run(['git','apply','--cached',str(out/'build.patch')],cwd=root,env=env,check=True) actual=subprocess.check_output(['git','diff','--cached','--name-only',base],cwd=root,env=env,text=True).splitlines() assert set(actual)==set(paths) for p,h in expected.items():assert sha256(subprocess.check_output(['git','show',':'+p],cwd=root,env=env)).hexdigest()==h,p finally:Path(index).unlink(missing_ok=True) markers=['/mnt/storage/src/mosaic-stack-rocko-124','/mnt/storage/scratch/rocko-124'] def own(): found=[] for p in Path('/proc').glob('[0-9]*'): try: cwd=os.readlink(p/'cwd');args=(p/'cmdline').read_bytes().split(b'\0');exe=Path(args[0].decode()).name if not (exe=='node' or 'chrom' in exe):continue if any(cwd.startswith(m) or any(m.encode() in a for a in args) for m in markers):found.append({'pid':int(p.name),'exe':exe,'cwd':cwd}) except (OSError,UnicodeError):pass return found before=own() for p in before: try:os.kill(p['pid'],signal.SIGTERM) except ProcessLookupError:pass if before:time.sleep(1) for p in own(): try:os.kill(p['pid'],signal.SIGKILL) except ProcessLookupError:pass if before:time.sleep(.2) after=own();assert not after,after stamp=subprocess.check_output(['date','-u','+%Y-%m-%dT%H:%M:%SZ'],text=True).strip() verification={'at':stamp,'package_suites':json.loads((out/'suite-counts.json').read_text()),'mutants_killed':66,'candidate_files_restored':len(paths),'staged_blobs_restored':True,'reconstructed_files':len(paths),'process_sweep_before':before,'process_sweep_after':after,'Docker':'not used; dead DOCKER_HOST','TMPDIR':'/mnt/storage/scratch/rocko-124/tmp','live_actions':False} (out/'verification.json').write_text(json.dumps(verification,indent=2)+'\n') with (out/'BUILD.md').open('a') as f: f.write('\n## Final verification\n\n'+stamp+'\n\n| Suite | Passed | Failed | Skipped |\n| --- | ---: | ---: | ---: |\n') for pkg,s in verification['package_suites'].items():f.write(f"| {pkg} | {s['pass']} | {s['fail']} | {s['skipped']} |\n") f.write('\n927 package tests passed; land-work 86/0, config 24/0. No tracked flake recurrence.\n\n| Mutant | Owning killing test file | Result |\n| --- | --- | --- |\n') for r in rows:f.write(f"| {r['check']} | {r['test']} | {r['result']} |\n") f.write('\n66/66 killed; no survivors, timeouts or invalid runs. All 38 hashes and staged\nblobs restored; clean-index reconstruction matches all 38 paths. Final cwd/argv\nnode/chromium sweep is empty; every runner has exited. No Docker network was\ncreated. Candidate manifest SHA-256: '+sha256((out/'candidate-manifest.sha256').read_bytes()).hexdigest()+'.\n') print(json.dumps({'stamp':stamp,'reconstruction':len(paths),'process_sweep':after,'mutants':len(rows)}))