check-compiler.py (2977B)
1 """Correctness/security controls for the opt-in prepared-input benchmark.""" 2 import json 3 import pathlib 4 import shutil 5 import struct 6 import subprocess 7 import sys 8 import tempfile 9 10 root = pathlib.Path(sys.argv[1]) 11 data = root / 'compiler-data' 12 manifest = json.loads((data/'manifest.json').read_text()) 13 14 def commands(directory, case): 15 return [ 16 [str(root/'bin/compiler-native'),str(directory),str(directory/str(case))], 17 [str(root/'bin/wasmtime'),'run','--dir',f'{directory}::/data',str(root/'bin/compiler.wasm'),'/data','/data/'+str(case)], 18 [str(root/'bin/node'),str(root/'bin/node-wasi.mjs'),str(root/'bin/compiler.wasm'),str(directory),str(case)], 19 ] 20 21 def check(command, error=None, rts=True): 22 result = subprocess.run(command + (['+RTS','-T','-M512m','-K8m','-RTS'] if rts else []), 23 capture_output=True,text=True,timeout=120) 24 if error is None: 25 assert result.returncode == 0, result.stderr 26 if rts: 27 metrics=json.loads(result.stdout) 28 assert metrics['allocated_bytes']>0 29 else: 30 assert result.returncode != 0, 'negative control unexpectedly succeeded' 31 assert error in result.stderr, result.stderr 32 33 for case in manifest['cases']: 34 for command in commands(data,case['id']): 35 check(command) 36 # TS oracle smoke is not a timing gate. 37 check([str(root/'bin/node'),str(root/'bin/ts-compiler.mjs'),str(root/'site'),'0'],rts=False) 38 with tempfile.TemporaryDirectory() as tmp: 39 tmp=pathlib.Path(tmp) 40 bad=tmp/'bad'; shutil.copytree(data,bad) 41 (bad/'0/expected').write_text('ok\nid\t0\n') 42 for command in commands(bad,0): check(command,'compiler golden mismatch') 43 shutil.copyfile(data/'0/expected',bad/'0/expected') 44 b=bytearray((bad/'compiler.dag').read_bytes()) 45 b[8]=1; struct.pack_into('<I',b,9,0) # node zero referring to itself 46 (bad/'compiler.dag').write_bytes(b) 47 for command in commands(bad,0): check(command,'invalid DAG record') 48 (bad/'compiler.dag').write_bytes(b'bad') 49 for command in commands(bad,0): check(command,'truncated DAG') 50 site=tmp/'site'; site.mkdir() 51 original=root/'site' 52 for name in ['dist','bundles','test']: 53 (site/name).symlink_to((original/name).resolve(),target_is_directory=True) 54 descriptor=json.loads((original/'compiler.json').read_text()) 55 # Corrupt bytes under the correct pinned filename: authentication must fail. 56 (site/'bundles').unlink(); (site/'bundles').mkdir() 57 (site/'bundles'/(descriptor['hash']+'.arboricx')).write_bytes(b'corrupt') 58 (site/'compiler.json').write_text(json.dumps(descriptor)) 59 check([str(root/'bin/node'),str(root/'bin/prepare-compiler.mjs'),str(site),str(tmp/'prepared')], 60 'AssertionError',rts=False) 61 # No preopen: cannot reach the compiler inputs. 62 check([str(root/'bin/wasmtime'),'run',str(root/'bin/compiler.wasm'),'/data','/data/0'], 63 'does not exist') 64 print('compiler goldens and negative controls passed')