tricu

An interpreted language for exploring Tree Calculus
Log | Files | Refs | README | LICENSE

io_v2_clock.py (3267B)


      1 #!/usr/bin/env python3
      2 """Actual source timing, scoped waits/cancellation, and migrated async demos."""
      3 import argparse
      4 import json
      5 from pathlib import Path
      6 import subprocess
      7 from source_order import Runner
      8 from http_headers import number, result, tree_list
      9 from io_v2_objects import text
     10 from io_v2_directory import parse_tree, natural
     11 
     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('--directory',type=Path,required=True)
     17     a=p.parse_args();root=a.directory.resolve();root.mkdir(parents=True,exist_ok=False)
     18     runner=Runner(a.tricu,root);checks=[]
     19     def compile(label,path):
     20         bundle=root/(label+'.arboricx')
     21         runner.run(label+'-compile',['compile','--file',path,'--store',runner.store,'--output',bundle,'--compile-timeout','600'],seconds=660)
     22         return runner.imported(bundle,label+'-import')
     23     pin=compile('clock',ROOT/'demos/io-v2/clock.tri')
     24     def invoke(label,name,value=None):
     25         args=['--io']
     26         if value is not None:
     27             path=root/(label+'.tree');path.write_bytes(value);args+=['--arg-tree-file',path]
     28         return runner.invoke(label,pin,name,args)
     29     assert invoke('yield','yielded')==result(True,b'\0');checks.append('yield-unit')
     30     assert invoke('cancelled','cancelledWait')==tree_list([text('cancelled'),text('timer-stop'),b'\0']);checks.append('cancel-max-duration')
     31     for milliseconds in [0,1,20]:
     32         raw=invoke(f'elapsed-{milliseconds}','elapsed',number(milliseconds))
     33         # Decode the binary kernel tree with the existing reader; compare to an
     34         # independent host duration bound, never a self-derived expected value.
     35         elapsed=natural(parse_tree(raw))
     36         assert elapsed>=milliseconds*1000000,(milliseconds,elapsed)
     37         checks.append(f'elapsed-{milliseconds}')
     38     assert natural(parse_tree(invoke('scope-wait','scopeWait')))>=20000000
     39     checks.append('normal-scope-waits')
     40     problem=tree_list([text('invalid-argument'),text('clock/sleep'),b'\0',text('none')])
     41     for i,value in enumerate([number(9223372036854775808),b'\1\0',b'\2\0\0']):
     42         assert invoke(f'invalid-{i}','invalidSleep',value)==result(False,problem)
     43         checks.append(f'invalid-{i}')
     44     for label,path,wanted in [
     45       ('async',ROOT/'demos/interactionTrees.tri',b'Parent first!\n2000ms done sleeping!\n5000ms done sleeping!\n'),
     46       ('yield-demo',ROOT/'demos/interactionTrees/yield.tri',b'A says 1\nA says 2\nA says 3\nB says 1\nB says 2\nB says 3\nFinished: doneA doneB\n')]:
     47         demo=compile(label,path)
     48         command=[str(runner.exe),'arboricx','run','--module',demo,'--name','main','--store',str(runner.store),'--io','--no-result']
     49         run=subprocess.run(command,stdout=subprocess.PIPE,stderr=subprocess.PIPE,timeout=30)
     50         (root/(label+'.stdout')).write_bytes(run.stdout);(root/(label+'.stderr')).write_bytes(run.stderr)
     51         assert run.returncode==0,(label,run.stderr)
     52         assert run.stdout==wanted,(label,run.stdout)
     53         checks.append(label)
     54     (root/'report.json').write_text(json.dumps(dict(passed=checks,records=runner.records),indent=2)+'\n')
     55     print(f'PASS {len(checks)} clock/caller controls')
     56 if __name__=='__main__':main()