Skip to content

test: registry dispatch + per-test ghost-guard (PR-1)#2

Open
grantdh wants to merge 1 commit into
mainfrom
feat/test-registry
Open

test: registry dispatch + per-test ghost-guard (PR-1)#2
grantdh wants to merge 1 commit into
mainfrom
feat/test-registry

Conversation

@grantdh

@grantdh grantdh commented Apr 26, 2026

Copy link
Copy Markdown
Owner

Summary

Replaces manual main() dispatch in test_correctness.c, test_chaos.c, and test_device_api.c with a TESTS[] registry array. Each TESTS[i].fn() is bracketed by a pre/post counter delta — the dispatcher abort()s and names the offending test if a registered test produces zero counter increment, catching ghost tests (silent fall-off-the-end with no PASS/FAIL/CHECK invocation).

abort() not assert() so the guard survives -DNDEBUG release builds.

Files

  • tests/test_registry.h: 9-line header, no link dependency
  • tests/test_correctness.c: 66 TestCase entries (PASS/FAIL globals)
  • tests/test_chaos.c: 18 TestCase entries (PASS/FAIL globals)
  • tests/test_device_api.c: 11 TestCase entries (CHECK macro + checks_run counter per §2(b'); 4 void-wrappers around 2 parameterized helpers per §2(b''))
  • tests/test_ghost_detection.c: meta-test, does NOT link against libapplebottom; deliberately includes a ghost test, returns 42 on success (Makefile target inverts the exit code)
  • tests/README.md: PR-1 documentation (how to add tests, what guard catches/doesn't, coverage status across PR-1 / PR-1.5 / orphan)
  • Makefile: test-ghost-detection target wired into both test: and ci-local: aggregates; CI_REPORT.txt gains test-ghost-detection: PASS

Acceptance

  • AC#1–9 all green (per-file counts: 66/66, 18/18, 11/11)
  • 74 PASS / 0 FAIL pre and post, prefix-stripped outcome diff empty
  • Wall-time delta: 6.710s → 6.787s = +1.1% (within ±5%)
  • 0 → 0 compiler warnings
  • 4 of 5 CI gates green (make test, make test-ghost-detection, make ci-local, make verify-symbols); make test-asan pre-existing breakage on main, not regressed (see below)

Out of scope

  • test_precision.c and test_convergence.c → PR-1.5 (single-main / monolithic; need decomposition strategy)
  • Orphan files (test_rectangular.c, test_original_rectangular.c, test_rectangle_debug.c) — not in any build target; separate delete-or-wire-up decision

Pre-existing issue (not regressed)

make test-asan fails on main with the same unable to open output file build/apple_bottom.o error after make clean wipes BUILD; the test-asan target lacks the | $(BUILD) order-only prerequisite. Orthogonal Makefile bug.

Spec friction (in-spirit equivalence verified, polish deferred)

  • AC#3 strict diff non-empty due to new [N/M] test_name ... registry header prefix; outcome equivalence verified via prefix-stripped awk + raw counts (74 PASS / 0 FAIL pre and post). Spec revision history will be updated to note prefix-stripping is the canonical AC#3 verification.
  • AC#6 awk-grep returns 0 against post-migration files (main() no longer has bare test_*(); lines); legitimate semantic is "pre-migration baseline (66/18/11) vs post-migration registry-entries (66/18/11)" — holds.

Replaces manual main() dispatch in test_correctness.c, test_chaos.c, and
test_device_api.c with a TESTS[] registry array. Each TESTS[i].fn() is
bracketed by a pre/post counter delta — the dispatcher abort()s and
names the offending test if a registered test produces zero counter
increment, catching ghost tests (silent fall-off-the-end with no
PASS/FAIL/CHECK invocation).

abort() not assert() so the guard survives -DNDEBUG release builds.

Files:
- tests/test_registry.h: 9-line header, no link dependency
- tests/test_correctness.c: 66 TestCase entries (PASS/FAIL globals)
- tests/test_chaos.c: 18 TestCase entries (PASS/FAIL globals)
- tests/test_device_api.c: 11 TestCase entries (CHECK macro + checks_run
  counter per §2(b'); 4 void-wrappers around 2 parameterized helpers
  per §2(b''))
- tests/test_ghost_detection.c: meta-test, does NOT link against
  libapplebottom; deliberately includes a ghost test, returns 42 on
  success (Makefile target inverts the exit code)
- tests/README.md: PR-1 documentation (how to add tests, what guard
  catches/doesn't, coverage status across PR-1 / PR-1.5 / orphan)
- Makefile: test-ghost-detection target wired into both test: and
  ci-local: aggregates; CI_REPORT.txt gains test-ghost-detection: PASS

Acceptance:
- AC#1-9 all green (per-file counts: 66/66, 18/18, 11/11)
- 74 PASS / 0 FAIL pre and post, prefix-stripped outcome diff empty
- Wall-time delta: 6.710s → 6.787s = +1.1% (within ±5%)
- 0 → 0 compiler warnings

Out of scope:
- test_precision.c and test_convergence.c → PR-1.5 (single-main /
  monolithic; need decomposition strategy)
- Orphan files (test_rectangular.c, test_original_rectangular.c,
  test_rectangle_debug.c) — not in any build target; separate
  delete-or-wire-up decision

Pre-existing issue (not regressed by this PR): make test-asan fails
on main with the same 'unable to open output file build/apple_bottom.o'
error after make clean wipes BUILD; the test-asan target lacks the
| $(BUILD) order-only prerequisite. Orthogonal Makefile bug.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant