aboutsummaryrefslogtreecommitdiffstats
path: root/research/experiments/029-across-machines/each_check.py
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-10-02 06:21:48 +0100
committereunhhu <[email protected]>2026-10-02 06:21:48 +0100
commit2be6928a4367ff35209484becad6627e34ac9768 (patch)
treee3af41b1611cdc064607553f33f3b82106164ffc /research/experiments/029-across-machines/each_check.py
parent28e51430cc860adc8d8f384d7662d85ab09dc5c7 (diff)
downloadpure-2be6928a4367ff35209484becad6627e34ac9768.tar.gz
pure-2be6928a4367ff35209484becad6627e34ac9768.zip
Run Pure and aup on an x86_64 WSL2 and an M3 Mac against the Pi (029)
Every pure-run of aup's check (1,053 runs of 667 modules) gives the same output, errors and exit on the Pi, the WSL2 (x86_64, 4 KiB pages, gcc 13) and the Mac (Apple clang 21); the same events make byte-identical stores on the Pi and the Mac, and either opens the other's and goes on the same. Pure's checks pass one at a time in WSL (each_check.py); its wall clock is set back about 2 s every 32 s (clock.py). stores.py streams pure-run's output, whose size grows with the square of the events.
Diffstat (limited to 'research/experiments/029-across-machines/each_check.py')
-rw-r--r--research/experiments/029-across-machines/each_check.py49
1 files changed, 49 insertions, 0 deletions
diff --git a/research/experiments/029-across-machines/each_check.py b/research/experiments/029-across-machines/each_check.py
new file mode 100644
index 0000000..8876cba
--- /dev/null
+++ b/research/experiments/029-across-machines/each_check.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+"""Pure's tests/check.py one check at a time (research 029): the statements
+of its main, each run alone in a temporary directory of its own, going on
+past one that fails, with its time. A JSON line each.
+
+each_check.py AUP [NAME ...] all, or the checks whose report key has a
+ NAME in it; each line says when it began and
+ ended on the system's monotonic clock (as
+ clock.py's lines do)"""
+import argparse
+import ast
+import json
+import sys
+import tempfile
+import time
+import traceback
+from pathlib import Path
+
+PURE = Path(__file__).resolve().parents[3]
+sys.path.insert(0, str(PURE / 'tests'))
+import check # noqa: E402
+
+tree = ast.parse((PURE / 'tests' / 'check.py').read_text())
+main = next(node for node in tree.body if isinstance(node, ast.FunctionDef) and node.name == 'main')
+block = next(node for node in ast.walk(main) if isinstance(node, ast.With))
+aup = Path(sys.argv[1]).resolve()
+check.EDITOR = aup.parents[1] / 'examples' / 'editor.aup'
+wanted = sys.argv[2:]
+for statement in block.body:
+ if not isinstance(statement, ast.Assign):
+ continue
+ names = [ast.unparse(target) for target in statement.targets]
+ if not any('report[' in n for n in names): # the check's own (its directory), not a check
+ continue
+ if wanted and not any(w in n for w in wanted for n in names):
+ continue
+ began = time.monotonic()
+ with tempfile.TemporaryDirectory(prefix='pure-check-') as directory:
+ space = dict(vars(check), aup=aup, pure=PURE, work=Path(directory), report={},
+ args=argparse.Namespace(seeds=4))
+ try:
+ exec(compile(ast.Module(body=[statement], type_ignores=[]), 'check.py', 'exec'), space)
+ line = {'check': names[0], 'passed': True, 'report': space['report']}
+ except Exception as failure: # noqa: BLE001 - every failure is reported, and the next check runs
+ line = {'check': names[0], 'passed': False, 'failure': repr(failure)[:600],
+ 'where': traceback.format_exc().splitlines()[-3][:300]}
+ line['seconds'] = round(time.monotonic() - began, 1)
+ line['monotonic'] = [round(began, 2), round(time.monotonic(), 2)]
+ print(json.dumps(line, ensure_ascii=False), flush=True)