refactor(termtris): one shared harness for the six tests #12

Merged
arti merged 1 commits from opencode.siil.arti.ee/vt1200:fix/issue-6-7-termtris-harness into master 2026-11-13 11:56:50 +02:00
Collaborator

Closes #6, #7.

What changed

apps/termtris/tests/harness.lua is now the one copy of the debugger-assisted
loader harness: COFF parse/poke, .bss prefill, descriptor, create_process
entry, LOADER_END result polling, snapshot and exit. The six tests are
configuration plus hooks — input sequences, the app's result cells, and the
app-specific result line. tests/*.sh and verify.sh are untouched.

harness.lua returns a table with H.config{...}, H.key(...),
H.message(...), H.sequence(...), H.on_frame(fn), H.result_dump(fn),
H.on_done(fn) and H.run(). The exit is still the fixed LOADER_END frame;
no early-completion path was imported, because these tests read
loader_frame<LOADER_END>.png (3200/3300/3400).

Removed per #7: LOADER_MODE / LOADER_A8_DESC / RETURN_STUB /
RETURN_SP, the marker / xhello result branches and
base_contains_marker polling, the LOADER_TRACE / ld1.tr path (no
tests/*.sh used it, so it was dropped rather than renamed), the empty status
block, and the unused key_p.

One DIAG format for all six, a superset of both old ones:

DIAG: loops=%d events=%d last=%d focus=%08X rev=%d quit=%d
DIAG: tick=%d quit=%d

Unconfigured cells print -1. play.sh still finds DIAG: tick= and
play_keys.sh / verify.sh still find DIAG: loops=.

Baseline (unmodified tests, separate worktree)

$ git worktree add /tmp/opencode/t5-baseline-wt 772311b
$ HOME=/tmp/opencode/t5-old-home apps/termtris/verify.sh --skip-mame
== smoke     PASS
== fmt       PASS
== render    PASS
== input     PASS
== play      PASS
== play_keys PASS
== play acceptance
   move  DIAG: loops=650 events=18 last=3 focus=00400001 rev=0 quit=0
   panels  DIAG: loops=648 events=12 last=3 focus=00400001 rev=0 quit=0
   quit  DIAG: loops=555 events=10 last=3 focus=00400001 rev=0 quit=1
verify: PASS

Old play.lua's own DIAG line (pre-refactor script run against the same
termtris.coff, same env as play.sh):

$ git show 772311b:apps/termtris/tests/play.lua > /tmp/opencode/t5-old-play.lua
$ HOME=/tmp/opencode/t5-oldplay-home VT1200_SKIP_LEVEL1=1 LOADER_SNAP=1 \
    DIAG_TICK=0x01a08980 DIAG_QUIT=0x01a08960 LOADER_AT=2500 LOADER_END=3300 \
    LOADER_BIN=$PWD/dwt/loader/build/loader.bin \
    LOADER_COFF=$PWD/apps/termtris/build/termtris.coff \
    LOADER_OUT=/tmp/opencode/t5-oldplay-ev \
    $M vt1200 -rompath harness/mame/roms -video none -sound none -nothrottle \
    -skip_gameinfo -debug -debugger none \
    -autoboot_script /tmp/opencode/t5-old-play.lua -autoboot_delay 0
$ grep -a -E 'DIAG:|LOADER: result' /tmp/opencode/t5-old-play.log
LOADER: result status=0 (OK) entry=018A0000 text=018A0000/84576 bits data=018B4A60/4816 bits bss=01A00000/125984 bits relocs=0 pcb=003FEE50 nscns=4 len=15186
DIAG: tick=887 quit=0

Old play_keys.lua quit mode (same method, PLAY_MODE=quit,
LOADER_END=3200):

$ grep -a 'DIAG:' /tmp/opencode/t5-old-play_keys.log
DIAG: loops=555 events=10 last=3 focus=00400001 rev=0 quit=1
DIAG: tick=887

smoke, fmt, render and input printed no DIAG line at all.

After

$ HOME=/tmp/opencode/t5-new-home apps/termtris/verify.sh --skip-mame
== smoke     PASS
== fmt       PASS
== render    PASS
== input     PASS
== play      PASS
== play_keys PASS
== play acceptance
   move  DIAG: loops=650 events=18 last=3 focus=00400001 rev=0 quit=0
   panels  DIAG: loops=648 events=12 last=3 focus=00400001 rev=0 quit=0
   quit  DIAG: loops=555 events=10 last=3 focus=00400001 rev=0 quit=1
== ROM checksum (after the suite)
ok: b46a3e442ccb86134d2356bd70d22fd2
verify: PASS

Per-test DIAG, from the final run's logs:

$ grep -a 'DIAG:' apps/termtris/build/play.log
DIAG: loops=-1 events=-1 last=-1 focus=-1 rev=-1 quit=0
DIAG: tick=887 quit=0
$ grep -a 'DIAG:' apps/termtris/build/play_move.log
DIAG: loops=650 events=18 last=3 focus=00400001 rev=0 quit=0
DIAG: tick=887 quit=0
$ grep -a 'DIAG:' apps/termtris/build/play_panels.log
DIAG: loops=648 events=12 last=3 focus=00400001 rev=0 quit=0
DIAG: tick=887 quit=0
$ grep -a 'DIAG:' apps/termtris/build/play_quit.log
DIAG: loops=555 events=10 last=3 focus=00400001 rev=0 quit=1
DIAG: tick=887 quit=1
$ for f in smoke fmt render input; do grep -a 'DIAG:' apps/termtris/build/$f.log; done
DIAG: loops=-1 events=-1 last=-1 focus=-1 rev=-1 quit=-1
DIAG: tick=-1 quit=-1
DIAG: loops=-1 events=-1 last=-1 focus=-1 rev=-1 quit=-1
DIAG: tick=-1 quit=-1
DIAG: loops=-1 events=-1 last=-1 focus=-1 rev=-1 quit=-1
DIAG: tick=-1 quit=-1
DIAG: loops=-1 events=-1 last=-1 focus=-1 rev=-1 quit=-1
DIAG: tick=-1 quit=-1

Every configured value is identical to the baseline. The only DIAG changes are
the superset: the loops line now also appears for play/smoke/fmt/render/
input (with -1 for cells those tests do not configure), and the tick line
gains quit= for play_keys (play.sh parses DIAG: tick= and both
play_keys.sh and verify.sh parse DIAG: loops=, so both still work).

Log diff, old vs new

diff -u of each test log, with the worktree path normalised and MAME's
wall-clock Average speed line removed — the -/+ path lines below are only
the two different checkouts:

=== play_move
-LOADER: payload <TREE>/dwt/loader/build/loader.bin (1220 B) -> bit 01880000
+LOADER: payload <TREE>/dwt/loader/build/loader.bin (1220 B) -> bit 01880000
-LOADER: COFF <TREE>/apps/termtris/build/termtris.coff (15186 B) -> bit 01900000
+LOADER: COFF <TREE>/apps/termtris/build/termtris.coff (15186 B) -> bit 01900000
-DIAG: tick=887
+DIAG: tick=887 quit=0
-LOADER: snapshot <TREE>/apps/termtris/evidence/loader_frame3200.png ok=true
+LOADER: snapshot <TREE>/apps/termtris/evidence/loader_frame3200.png ok=true

The other logs differ the same way: only the DIAG: lines and the checkout
path in the LOADER: payload/COFF/snapshot lines.

Evidence

The five committed PNGs are byte-identical to what both the old and the new run
produce (old tree, new tree, and git show HEAD:):

render_frame3400.png      b06a240e20a9d63b1a29e5af62fcd558
termtris_frame3300.png    7164d01bd0b6d27bf88c9904692c31e5
termtris_move_3200.png    7f60c07676146e5c70a1a16b639d4fde
termtris_panels_3200.png  3f9fe2687ee6916ce0e270dcc37daf1d
termtris_quit_3200.png    5cd103b73aa683e1e1a563e38e470f19

Counts and dead paths

$ wc -l apps/termtris/tests/*.lua          # before (772311b)
   354 fmt.lua   387 input.lua  350 play.lua  390 play_keys.lua
   347 render.lua 355 smoke.lua
  2183 total
$ wc -l apps/termtris/tests/*.lua          # after
    24 fmt.lua
   354 harness.lua
    30 input.lua
     8 play.lua
    34 play_keys.lua
    17 render.lua
    19 smoke.lua
   486 total
$ grep -rnE 'LOADER_MODE|LOADER_A8_DESC|RETURN_STUB|RETURN_SP|xhello|ld1\.tr' apps/termtris/tests/
$ echo $?
1

2183 → 486 (−78%). The plan's "around 380" was an estimate: the actual is
higher because the harness keeps the full loader diagnostics the six copies
carried (payload/COFF/section header lines, poke read-backs, .bss prefill,
placement check, result block) so the log lines stay identical, and every test
keeps a short comment header. There is now one copy of the machinery.

rg is not installed in this environment, so the grep used the same pattern
with grep -rnE.

The .sh files are untouched (diffed against upstream/master at push time,
0b3db19; this branch was rebased onto it):

$ git diff --name-only 0b3db19..HEAD | grep '\.sh$'
$ echo $?
1
$ git diff --stat 0b3db19..HEAD
 apps/termtris/tests/fmt.lua       | 350 +------------------------------
 apps/termtris/tests/harness.lua   | 354 +++++++++++++++++++++++++++++++
 apps/termtris/tests/input.lua     | 411 +++---------------------------------
 apps/termtris/tests/play.lua      | 354 +-------------------------------
 apps/termtris/tests/play_keys.lua | 424 +++-----------------------------------
 apps/termtris/tests/render.lua    | 354 ++-----------------------------
 apps/termtris/tests/smoke.lua     | 364 ++-----------------------------
 7 files changed, 457 insertions(+), 2154 deletions(-)

ROM

$ md5sum vt1200_v22.bin
b46a3e442ccb86134d2356bd70d22fd2  vt1200_v22.bin

Not done

  • MAME was not rebuilt (--skip-mame was used, as the plan allows).
  • Each run used a private HOME (/tmp/opencode/t5-old-home,
    /tmp/opencode/t5-new-home, /tmp/opencode/t5-oldplay-home) so nvram/cfg
    were not shared with other threads.
Closes #6, #7. ## What changed `apps/termtris/tests/harness.lua` is now the one copy of the debugger-assisted loader harness: COFF parse/poke, `.bss` prefill, descriptor, `create_process` entry, `LOADER_END` result polling, snapshot and exit. The six tests are configuration plus hooks — input sequences, the app's result cells, and the app-specific result line. `tests/*.sh` and `verify.sh` are untouched. `harness.lua` returns a table with `H.config{...}`, `H.key(...)`, `H.message(...)`, `H.sequence(...)`, `H.on_frame(fn)`, `H.result_dump(fn)`, `H.on_done(fn)` and `H.run()`. The exit is still the fixed `LOADER_END` frame; no early-completion path was imported, because these tests read `loader_frame<LOADER_END>.png` (3200/3300/3400). Removed per #7: `LOADER_MODE` / `LOADER_A8_DESC` / `RETURN_STUB` / `RETURN_SP`, the `marker` / `xhello` result branches and `base_contains_marker` polling, the `LOADER_TRACE` / `ld1.tr` path (no `tests/*.sh` used it, so it was dropped rather than renamed), the empty status block, and the unused `key_p`. One DIAG format for all six, a superset of both old ones: DIAG: loops=%d events=%d last=%d focus=%08X rev=%d quit=%d DIAG: tick=%d quit=%d Unconfigured cells print `-1`. `play.sh` still finds `DIAG: tick=` and `play_keys.sh` / `verify.sh` still find `DIAG: loops=`. ## Baseline (unmodified tests, separate worktree) ``` $ git worktree add /tmp/opencode/t5-baseline-wt 772311b $ HOME=/tmp/opencode/t5-old-home apps/termtris/verify.sh --skip-mame == smoke PASS == fmt PASS == render PASS == input PASS == play PASS == play_keys PASS == play acceptance move DIAG: loops=650 events=18 last=3 focus=00400001 rev=0 quit=0 panels DIAG: loops=648 events=12 last=3 focus=00400001 rev=0 quit=0 quit DIAG: loops=555 events=10 last=3 focus=00400001 rev=0 quit=1 verify: PASS ``` Old `play.lua`'s own DIAG line (pre-refactor script run against the same `termtris.coff`, same env as `play.sh`): ``` $ git show 772311b:apps/termtris/tests/play.lua > /tmp/opencode/t5-old-play.lua $ HOME=/tmp/opencode/t5-oldplay-home VT1200_SKIP_LEVEL1=1 LOADER_SNAP=1 \ DIAG_TICK=0x01a08980 DIAG_QUIT=0x01a08960 LOADER_AT=2500 LOADER_END=3300 \ LOADER_BIN=$PWD/dwt/loader/build/loader.bin \ LOADER_COFF=$PWD/apps/termtris/build/termtris.coff \ LOADER_OUT=/tmp/opencode/t5-oldplay-ev \ $M vt1200 -rompath harness/mame/roms -video none -sound none -nothrottle \ -skip_gameinfo -debug -debugger none \ -autoboot_script /tmp/opencode/t5-old-play.lua -autoboot_delay 0 $ grep -a -E 'DIAG:|LOADER: result' /tmp/opencode/t5-old-play.log LOADER: result status=0 (OK) entry=018A0000 text=018A0000/84576 bits data=018B4A60/4816 bits bss=01A00000/125984 bits relocs=0 pcb=003FEE50 nscns=4 len=15186 DIAG: tick=887 quit=0 ``` Old `play_keys.lua` quit mode (same method, `PLAY_MODE=quit`, `LOADER_END=3200`): ``` $ grep -a 'DIAG:' /tmp/opencode/t5-old-play_keys.log DIAG: loops=555 events=10 last=3 focus=00400001 rev=0 quit=1 DIAG: tick=887 ``` `smoke`, `fmt`, `render` and `input` printed no DIAG line at all. ## After ``` $ HOME=/tmp/opencode/t5-new-home apps/termtris/verify.sh --skip-mame == smoke PASS == fmt PASS == render PASS == input PASS == play PASS == play_keys PASS == play acceptance move DIAG: loops=650 events=18 last=3 focus=00400001 rev=0 quit=0 panels DIAG: loops=648 events=12 last=3 focus=00400001 rev=0 quit=0 quit DIAG: loops=555 events=10 last=3 focus=00400001 rev=0 quit=1 == ROM checksum (after the suite) ok: b46a3e442ccb86134d2356bd70d22fd2 verify: PASS ``` Per-test DIAG, from the final run's logs: ``` $ grep -a 'DIAG:' apps/termtris/build/play.log DIAG: loops=-1 events=-1 last=-1 focus=-1 rev=-1 quit=0 DIAG: tick=887 quit=0 $ grep -a 'DIAG:' apps/termtris/build/play_move.log DIAG: loops=650 events=18 last=3 focus=00400001 rev=0 quit=0 DIAG: tick=887 quit=0 $ grep -a 'DIAG:' apps/termtris/build/play_panels.log DIAG: loops=648 events=12 last=3 focus=00400001 rev=0 quit=0 DIAG: tick=887 quit=0 $ grep -a 'DIAG:' apps/termtris/build/play_quit.log DIAG: loops=555 events=10 last=3 focus=00400001 rev=0 quit=1 DIAG: tick=887 quit=1 $ for f in smoke fmt render input; do grep -a 'DIAG:' apps/termtris/build/$f.log; done DIAG: loops=-1 events=-1 last=-1 focus=-1 rev=-1 quit=-1 DIAG: tick=-1 quit=-1 DIAG: loops=-1 events=-1 last=-1 focus=-1 rev=-1 quit=-1 DIAG: tick=-1 quit=-1 DIAG: loops=-1 events=-1 last=-1 focus=-1 rev=-1 quit=-1 DIAG: tick=-1 quit=-1 DIAG: loops=-1 events=-1 last=-1 focus=-1 rev=-1 quit=-1 DIAG: tick=-1 quit=-1 ``` Every configured value is identical to the baseline. The only DIAG changes are the superset: the loops line now also appears for `play`/`smoke`/`fmt`/`render`/ `input` (with `-1` for cells those tests do not configure), and the tick line gains `quit=` for `play_keys` (`play.sh` parses `DIAG: tick=` and both `play_keys.sh` and `verify.sh` parse `DIAG: loops=`, so both still work). ## Log diff, old vs new `diff -u` of each test log, with the worktree path normalised and MAME's wall-clock `Average speed` line removed — the `-`/`+` path lines below are only the two different checkouts: ``` === play_move -LOADER: payload <TREE>/dwt/loader/build/loader.bin (1220 B) -> bit 01880000 +LOADER: payload <TREE>/dwt/loader/build/loader.bin (1220 B) -> bit 01880000 -LOADER: COFF <TREE>/apps/termtris/build/termtris.coff (15186 B) -> bit 01900000 +LOADER: COFF <TREE>/apps/termtris/build/termtris.coff (15186 B) -> bit 01900000 -DIAG: tick=887 +DIAG: tick=887 quit=0 -LOADER: snapshot <TREE>/apps/termtris/evidence/loader_frame3200.png ok=true +LOADER: snapshot <TREE>/apps/termtris/evidence/loader_frame3200.png ok=true ``` The other logs differ the same way: only the `DIAG:` lines and the checkout path in the `LOADER:` payload/COFF/snapshot lines. ## Evidence The five committed PNGs are byte-identical to what both the old and the new run produce (old tree, new tree, and `git show HEAD:`): ``` render_frame3400.png b06a240e20a9d63b1a29e5af62fcd558 termtris_frame3300.png 7164d01bd0b6d27bf88c9904692c31e5 termtris_move_3200.png 7f60c07676146e5c70a1a16b639d4fde termtris_panels_3200.png 3f9fe2687ee6916ce0e270dcc37daf1d termtris_quit_3200.png 5cd103b73aa683e1e1a563e38e470f19 ``` ## Counts and dead paths ``` $ wc -l apps/termtris/tests/*.lua # before (772311b) 354 fmt.lua 387 input.lua 350 play.lua 390 play_keys.lua 347 render.lua 355 smoke.lua 2183 total $ wc -l apps/termtris/tests/*.lua # after 24 fmt.lua 354 harness.lua 30 input.lua 8 play.lua 34 play_keys.lua 17 render.lua 19 smoke.lua 486 total $ grep -rnE 'LOADER_MODE|LOADER_A8_DESC|RETURN_STUB|RETURN_SP|xhello|ld1\.tr' apps/termtris/tests/ $ echo $? 1 ``` 2183 → 486 (−78%). The plan's "around 380" was an estimate: the actual is higher because the harness keeps the full loader diagnostics the six copies carried (payload/COFF/section header lines, poke read-backs, `.bss` prefill, placement check, result block) so the log lines stay identical, and every test keeps a short comment header. There is now one copy of the machinery. `rg` is not installed in this environment, so the grep used the same pattern with `grep -rnE`. The `.sh` files are untouched (diffed against `upstream/master` at push time, `0b3db19`; this branch was rebased onto it): ``` $ git diff --name-only 0b3db19..HEAD | grep '\.sh$' $ echo $? 1 $ git diff --stat 0b3db19..HEAD apps/termtris/tests/fmt.lua | 350 +------------------------------ apps/termtris/tests/harness.lua | 354 +++++++++++++++++++++++++++++++ apps/termtris/tests/input.lua | 411 +++--------------------------------- apps/termtris/tests/play.lua | 354 +------------------------------- apps/termtris/tests/play_keys.lua | 424 +++----------------------------------- apps/termtris/tests/render.lua | 354 ++----------------------------- apps/termtris/tests/smoke.lua | 364 ++----------------------------- 7 files changed, 457 insertions(+), 2154 deletions(-) ``` ## ROM ``` $ md5sum vt1200_v22.bin b46a3e442ccb86134d2356bd70d22fd2 vt1200_v22.bin ``` ## Not done - MAME was not rebuilt (`--skip-mame` was used, as the plan allows). - Each run used a private `HOME` (`/tmp/opencode/t5-old-home`, `/tmp/opencode/t5-new-home`, `/tmp/opencode/t5-oldplay-home`) so nvram/cfg were not shared with other threads.
opencode.siil.arti.ee added 1 commit 2026-11-13 11:50:00 +02:00
arti merged commit 6ae2358ae6 into master 2026-11-13 11:56:50 +02:00
arti deleted branch fix/issue-6-7-termtris-harness 2026-11-13 11:56:51 +02:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: arti/vt1200#12