ww test: fork-isolated record-and-continue harness (lib/test, both stages)

lib/test/run.ww: fork+wait4 runner; each @test runs in its own child,
abort/SEGV/FPE decoded from wait-status, failures recorded and the run
continues; exit = fail count. Tests are hermetic: module globals do not
persist test-to-test (fresh fork image; sanctioned divergence from
harec's shared-process __test_main, no setjmp/signal layer needed).
-T synth (both stages) emits a module-global (str,*fn() void) table +
return run(table) instead of straight-line calls. Driver twins bundle
lib/test under test mode and gain ww test -c/-o (go test -c) so the
byte-id gates diff the same artifact the real path builds. Gates
989/910/997 rewired onto it; new 911 pins record-and-continue across
all three fault classes; 949 +3 rows. (#17-team commit-2)
This commit is contained in:
2026-06-11 00:08:39 +09:00
parent 08a76cf4c8
commit 16c83e70d3
15 changed files with 961 additions and 194 deletions

View File

@@ -254,18 +254,29 @@ check_one(const char *bin, const char *cwd, const struct ent *e, int idx)
}
/* exit deliberately ignored: the combined unit is written before
* codegen (cf 990 resolveunit) and only it matters here. */
snprintf(cmd, sizeof cmd,
"cd %s && timeout 180 %s/ww build %s %s >/dev/null 2>&1",
td, bin, incs, base);
* codegen (cf 990 resolveunit) and only it matters here. A @test
* fixture builds via `ww test -c -o <stem>` (compile-only) so the
* resolved unit AUTO-BUNDLES lib/test — the #17 synth's `run()` callee
* must resolve when w6c/w6c_ww -T compile the combined below. Both the
* `-o <stem>` (test) and the next-to-source (build) paths land the
* combined at <stem>.combined.ww. Import-probes carry their own main
* and stay a plain non-test build. */
char stem[512];
snprintf(stem, sizeof stem, "%s", base);
char *sd = strrchr(stem, '.');
if (sd) *sd = '\0';
if (e->fixture)
snprintf(cmd, sizeof cmd,
"cd %s && timeout 180 %s/ww test -c -o %s %s %s >/dev/null 2>&1",
td, bin, stem, incs, base);
else
snprintf(cmd, sizeof cmd,
"cd %s && timeout 180 %s/ww build %s %s >/dev/null 2>&1",
td, bin, incs, base);
runwait(cmd);
char comb[512];
snprintf(comb, sizeof comb, "%s/%s", td, base);
char *dot = strrchr(comb, '.');
if (dot) *dot = '\0';
size_t cn = strlen(comb);
snprintf(comb + cn, sizeof comb - cn, ".combined.ww");
snprintf(comb, sizeof comb, "%s/%s.combined.ww", td, stem);
if (access(comb, 0) != 0) {
fprintf(stderr, "lib_byteid FAIL: %s — no resolved unit\n", label);
goto out;
@@ -357,6 +368,10 @@ static const char *covered[] = {
"lib/io", "lib/math", "lib/rt", "lib/types", "lib/ww/parse",
/* module body dragged into the lib/strconv/test fixtures */
"lib/strconv",
/* #17: the @test runner is AUTO-BUNDLED into every -T combined, so
* every @test fixture above byte-ids it cs/ww; 911_attest_record also
* compares it directly. It has no _test.ww of its own. */
"lib/test",
NULL,
};