from pathlib import Path import subprocess, os, signal, json, sys, time root = Path('/mnt/storage/src/mosaic-stack-rocko-178') out = Path(__file__).resolve().parent logdir = out/'mutants'; logdir.mkdir(exist_ok=True) env = {**os.environ, 'TMPDIR':'/mnt/storage/scratch/rocko-178/tmp', 'DOCKER_HOST':'unix:///nonexistent.sock', 'MOSAIC_CONFIG':'/mnt/storage/scratch/rocko-178/no-live-config.json'} results = [] for c in json.loads((out/'mutant-sites.json').read_text()): p = root/c['path']; original = p.read_bytes(); text = original.decode() assert text.count(c['before']) == 1, c['name'] try: p.write_text(text.replace(c['before'], c['after'], 1)) syntax = ['bash','-n',str(p)] if p.suffix == '.sh' else ['node','--check',str(p)] subprocess.run(syntax,check=True,stdout=subprocess.DEVNULL,stderr=subprocess.PIPE) with (logdir/(c['name']+'.log')).open('w') as f: ch = subprocess.Popen(c.get('command',['node','--test','--test-name-pattern='+c['pattern'],c['test']]),cwd=root,env=env,stdout=f,stderr=subprocess.STDOUT,start_new_session=True) try: rc=ch.wait(timeout=180) except subprocess.TimeoutExpired: os.killpg(ch.pid,signal.SIGKILL);ch.wait();rc=124 status = 'killed' if rc == 1 else 'survived' if rc == 0 else 'invalid-or-timeout' results.append({k:c[k] for k in ['name','test','pattern','check']} | {'exit':rc,'status':status}) print(c['name'], status, flush=True) finally: p.write_bytes(original) (logdir/'results.json').write_text(json.dumps(results,indent=2)+'\n') sys.exit(any(r['status']!='killed' for r in results))