io_v2_zig_paths.py (3334B)
1 #!/usr/bin/env python3 2 """Private Zig path/directory operations: independent results, Haskell comparison.""" 3 import argparse 4 import hashlib 5 import json 6 import os 7 from pathlib import Path 8 from source_order import Runner 9 from http_headers import tree_list, number 10 from stable_bundle import byte_tree 11 from process_rss import run_guarded 12 ROOT = Path(__file__).resolve().parent.parent 13 14 def main(): 15 p = argparse.ArgumentParser(description=__doc__) 16 p.add_argument('tricu', type=Path); p.add_argument('probe', type=Path) 17 p.add_argument('--directory', type=Path, required=True) 18 args = p.parse_args(); d = args.directory.resolve(); d.mkdir(parents=True, exist_ok=False) 19 r = Runner(args.tricu, d); bundle = d/'paths.arboricx' 20 r.run('compile', ['compile', '--file', ROOT/'test/io-v2/zig-paths.tri', '--store', r.store, '--output', bundle]) 21 pin = r.imported(bundle, 'import'); checks = [] 22 def run(name, paths, expected, label, haskell=True): 23 output, peak = run_guarded([str(args.probe.resolve()), str(bundle), name, *['text:'+str(path) for path in paths]], memory_mib=128, seconds=60) 24 (d/(label+'.log')).write_text(output) 25 assert bytes(map(int, output.strip())) == expected, label 26 if haskell: 27 flags = ['--io'] 28 for i, path in enumerate(paths): 29 arg = d/f'{label}-{i}.tree'; arg.write_bytes(tree_list([number(ord(c)) for c in str(path)])) 30 flags += ['--arg-tree-file', arg] 31 assert r.invoke(label+'-haskell', pin, name, flags) == expected, label 32 checks.append(dict(label=label, peak_kib=peak)) 33 regular = tree_list([byte_tree(b'file'), number(3)]) 34 for case in ('ascii', 'é😀'): 35 directory, source = d/(case+'-dir'), d/(case+'-source') 36 target = directory/'target' 37 run('paths', [directory, source, target], tree_list([regular, tree_list([byte_tree(b'directory')]), regular, byte_tree(b'not-found')]), case) 38 assert not directory.exists() and not source.exists() and not target.exists() 39 source = d/'source'; source.write_bytes(b'abc') 40 link = d/'link'; link.symlink_to(source) 41 run('observe', [link], tree_list([tree_list([byte_tree(b'symlink')]), regular]), 'symlink') 42 run('observe', [source], tree_list([regular, regular]), 'regular') 43 directory_status = tree_list([byte_tree(b'directory')]) 44 run('observe', [d], tree_list([directory_status, directory_status]), 'directory') 45 fifo = d/'fifo'; os.mkfifo(fifo) 46 other = tree_list([byte_tree(b'other')]) 47 run('observe', [fifo], tree_list([other, other]), 'fifo-observation') 48 run('badDirectory', [source], byte_tree(b'not-directory'), 'sync-regular') 49 run('badDirectory', [fifo], byte_tree(b'not-directory'), 'sync-fifo') 50 target = d/'missing-parent'/'out' 51 run('failedRename', [source, target], byte_tree(b'not-found'), 'rename-missing-parent') 52 assert source.read_bytes() == b'abc' and not target.exists() 53 (d/'report.json').write_text(json.dumps(dict(checks=checks, haskell=r.records, source_sha256=hashlib.sha256((ROOT/'test/io-v2/zig-paths.tri').read_bytes()).hexdigest(), probe_sha256=hashlib.sha256(args.probe.read_bytes()).hexdigest()), indent=2)+'\n') 54 print(f'PASS {len(checks)} path/directory controls on private Zig and Haskell') 55 if __name__ == '__main__': main()