#!/usr/bin/env python3 # exercise syntax injection, isolated workers, typed graph copying and regressions. from pathlib import Path import argparse import subprocess import time parser = argparse.ArgumentParser() parser.add_argument('vm', nargs='?', default='build/bin/zy') parser.add_argument('--case', default='') parser.add_argument('--library', default='') args = parser.parse_args() root = Path(__file__).resolve().parents[2] expected = {'parallel': '0 0\n11 21\n', 'state': '0 5 7\n4\n', 'graphs': '25 a 5\n', 'results': 'ok\n', 'plain': '3\n', 'module_helpers': '10\n', 'safepoint': '8\n', 'values': '1\n', 'functions': '12\n', 'pointer_scalar': '1\n', 'declaration': '5 7 0 0\n', 'lifecycle': '-1 3\n', 'generic_extensions': '3\n', 'failed_worker': '-1 -1 3\n', 'generic_declaration': '5 7 4 0\n', 'generic_typed_method': '7 2\n', 'drop_closes': '1 0 11 0 1\n'} count = 0 for case in sorted((root / 'tests/actor').glob('*/*.zc')): if args.case and args.case not in str(case): continue start = time.monotonic() source = case.read_text() if args.library: source = source.replace('include rt, actor;', f'include rt; include \"{args.library}\"; include actor;') proc = subprocess.run([str(root / args.vm)], input=source, text=True, capture_output=True, cwd=root, timeout=15) elapsed = time.monotonic() - start if case.parent.name == 'reject': required = {'no_include': "actor: isn't a type", 'input_type': 'type error:', 'output_type': 'type error:', 'explicit_this': 'this is implicit', 'nested_missing_import': 'module access requires `include rt;`', 'generic_input': 'type error:', 'generic_method_return': 'type error:', 'drop_message': "r: has drop and can't be copied into a message", 'drop_value': "p: has drop and can't be copied into a message"}[case.stem] assert required in proc.stdout, f'{case}: expected {required!r}, got {proc.stdout!r}' else: actual = proc.stdout if case.stem == 'parallel': lines = actual.splitlines(keepends=True) assert len(lines) == 3, f'invalid parallel output: {actual!r}' runtime_ms = int(lines[-1]) assert 280 <= runtime_ms < 580, f'workers did not overlap: {runtime_ms}ms' actual = ''.join(lines[:-1]) assert proc.returncode == 0 and actual == expected[case.stem], f'{case}: stdout={proc.stdout!r}, stderr={proc.stderr!r}' print(f'ok {case.relative_to(root)} ({elapsed:.3f}s)') count += 1 assert count, 'no actor fixtures selected' print(f'{count} actor fixtures passed')