tinymux/tests/codiff
Stephen Dennis c7f064216d test(codiff): validate the host leg by running it, not by probing a symbol (#2055)
On a box with any libmux.so on its library path, test-codiff reported

  --- comparing 0 transcript lines ---
    interp  vs host   : DIFFER (1914 lines)
    dbt     vs host   : DIFFER (1914 lines)
  FAIL: routes disagree -- see above.

Nothing disagreed. The host leg never ran -- it died with an undefined
reference to co_delete_at, and run.sh discarded its stderr -- so the reference
transcript was empty and every route "differed" from it by its whole length.
That is exactly the inversion the script's own comment says it exists to
avoid, and it named the wrong culprit while doing it.

The guard written for that hazard did not close it, for two reasons:

  * The canary decays.  It probed for co_insert_at, which the months-old
    libmux in ~/lib still exports; the symbol that actually failed was
    co_delete_at.  Any hardcoded name stops discriminating as the library
    grows past it -- silently, with no build error to notice.

  * Choosing the right directory does not mean the right library LOADS.
    -Wl,-rpath emits RUNPATH under the default --enable-new-dtags, and the
    loader searches LD_LIBRARY_PATH BEFORE RUNPATH.  So the guard selected
    mux/lib correctly and the loader ignored it.

So stop asking what a candidate exports. Link against it, run it with the path
pinned, and keep the first that produces a transcript. "Does this work" cannot
decay, and it subsumes the canary question rather than restating it.

The host leg is now built and run during selection, so the duplicate build and
run further down are gone; the run that proved the choice is the transcript
that gets compared.

Note the run check is deliberately NOT a pipeline: `!` on `a | b` tests b, and
strip_marker is a grep that exits 1 when it selects nothing -- which would have
called a good host leg broken and an empty one fine.

Verified on Kagura, where LD_LIBRARY_PATH=/home/sdennis/lib is set from the
login profile -- the condition that caused this:

  * unpinned `make test-codiff`: PASS, 1914 lines, interp OK, dbt OK.
  * negative control -- the stale libmux copied over mux/lib/libmux.so:
    both candidates are reported as not linking, naming co_delete_at, and
    the run SKIPs (exit 0) instead of failing as a route disagreement.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 15:06:16 -06:00
..
repro test(codiff): add the chain-edge bisection that localised #2019 2026-08-03 20:02:59 -06:00
.gitignore test(codiff): run color_ops on every route that executes it, with qemu as oracle 2026-08-03 19:33:37 -06:00
cases.h test(codiff): cover cluster addressing before making scramble linear (#2045) 2026-08-04 12:58:06 -06:00
guest_main.c test(codiff): cover cluster addressing before making scramble linear (#2045) 2026-08-04 12:58:06 -06:00
host_main.c test(codiff): run color_ops on every route that executes it, with qemu as oracle 2026-08-03 19:33:37 -06:00
min_main.c test(codiff): run color_ops on every route that executes it, with qemu as oracle 2026-08-03 19:33:37 -06:00
run.sh test(codiff): validate the host leg by running it, not by probing a symbol (#2055) 2026-08-04 15:06:16 -06:00
runner.cpp test(codiff): make the harness run on macOS, not skip cleanly 2026-08-03 20:29:54 -06:00