test/wcc: carrier ownership repair and driver-contract adaptation
Every surviving carrier now owns its artifacts: checked mkdir/mkdtemp/ fopen acquisition, one all-exit cleanup funnel per carrier, ENOENT- tolerant checked unlinks, exact-path deletion (rm -rf only for an owned pid-keyed dir or a .sepwork beneath one), and cleanup failure fails a passing carrier without overwriting its diagnostic. In the same pass the carriers adapt to the driver contract this branch lands: --sep and WW_PKGCACHE are gone, -S and the /tmp/ww_run_<pid> scratch contract are asserted, and rows whose runtime or reject coverage moved to test/wcc/data fixtures or test/lang @test owners are trimmed to the byte/artifact/diagnostic observations only they can make. Repair and adaptation ride together because most files interleave both in the same hunks; splitting would manufacture intermediate carrier states that never existed and cannot run against either driver.
This commit is contained in:
@@ -1,41 +1,39 @@
|
||||
/*
|
||||
* 989_septest_run — M4 E1 (#79-B) regression gate: `ww test --sep`.
|
||||
* 989_septest_run — M4 E1 (#79-B) regression gate: `ww test`.
|
||||
*
|
||||
* E1 makes `ww test` work under the separate-compilation producer as an
|
||||
* ADDITIVE opt-in (combined stays default; 910/997 untouched). The synth
|
||||
* `ww test` uses the separate-compilation producer. The synthesized
|
||||
* test-main emits `test.run(__wwtests)` (N_DOT, qualified) + injects a
|
||||
* synthetic `use test;`; the driver injects `test` as a graph dep of the
|
||||
* root, passes `-T` to the root producer only, and routes a single-file
|
||||
* `ww test --sep` through build_one_sep(is_test=1). This gate is the
|
||||
* STANDING regression for that capability until E2 migrates 997.
|
||||
* `ww test` through build_one_sep(is_test=1). This gate is the standing
|
||||
* regression for that capability.
|
||||
*
|
||||
* Asserts (all COLD — fresh per-(case,stage) WW_PKGCACHE, scratch wiped):
|
||||
* 1. RUN-EXIT: `ww test --sep <fixture>` exits with the expected code for
|
||||
* Asserts (all COLD — direct per-(case,stage) builds):
|
||||
* 1. RUN-EXIT: `ww test <fixture>` exits with the expected code for
|
||||
* BOTH driver stages — 0 when every @test passes, non-zero when one
|
||||
* fails. The failing row is the non-vacuity teeth: it proves the @tests
|
||||
* genuinely RUN under sep (a no-op --sep that linked an empty main would
|
||||
* genuinely run (a vacuous path that linked an empty main would
|
||||
* exit 0 on the failing fixture and the gate would catch it).
|
||||
* This same RUN-EXIT path also hosts the @test user-facing reject +
|
||||
* coexist legs ported from 910/997 (C2a, #83), which die at the M4 flip
|
||||
* that deletes 910/997: `userman` (explicit user main collides with the
|
||||
* -T synth entry) and `badsig` (non-`fn() void` @test) must reject
|
||||
* (exit != 0) on both stages; `collide_run` (user `fn run` coexists with
|
||||
* lib/test's bound runner) must accept and run to exit 0 — under sep the
|
||||
* lib/test's bound runner) must accept and run to exit 0 — the
|
||||
* two land in distinct units, so a regressed collision fails the link.
|
||||
* 2. cs==ww (rule 10): the cstage `ww` and wwstage `ww_ww` sep-drivers emit
|
||||
* byte-identical per-package .s/.wwi for the passing fixture — including
|
||||
* __root.s, which carries the synth `CALL test.run`.
|
||||
* 3. SYNTH PRESENCE (non-vacuity on the -T path): the passing fixture's
|
||||
* __root.s defines `TEXT main` and emits `CALL test.run(SB)` — proving
|
||||
* the qualified-synth -T path fired under sep, not a stray combined fall-
|
||||
* back.
|
||||
* the qualified-synth -T path fired.
|
||||
*
|
||||
* Light wwstage-driver test (CLAUDE.md rule 14): every intermediate is
|
||||
* `-o`-redirected to /tmp, so it is phase-1 parallel-safe. Models
|
||||
* Every intermediate is `-o`-redirected to /tmp for isolation. Models
|
||||
* 989_c6soak_run.c conventions; 989 prefix per the sep-gate precedent.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
@@ -116,8 +114,7 @@ write_file(const char *path, const char *body)
|
||||
FILE *f = fopen(path, "wb");
|
||||
if (!f) return -1;
|
||||
wwtest_fputs(body, f);
|
||||
fclose(f);
|
||||
return 0;
|
||||
return fclose(f);
|
||||
}
|
||||
|
||||
/* cs==ww over a sep test build's per-package output: every .s/.wwi the
|
||||
@@ -162,7 +159,7 @@ struct tcase {
|
||||
const char *label;
|
||||
const char *src; /* inline fixture written to <td>/<label>.ww */
|
||||
const char *path; /* when set, use this on-disk fixture instead of src */
|
||||
int expect; /* expected `ww test --sep` run-exit (when !reject) */
|
||||
int expect; /* expected `ww test` run-exit (when !reject) */
|
||||
int byteid; /* run the cs==ww + synth-presence checks */
|
||||
int reject; /* @test user-facing reject: assert run-exit != 0 */
|
||||
};
|
||||
@@ -187,7 +184,7 @@ static struct tcase cases[] = {
|
||||
" if (1 + 1 == 2) { abort(); };\n"
|
||||
"};\n", NULL, 1, 0, 0 },
|
||||
/* C2a (#83): the @test user-facing reject + coexist paths, re-hosted
|
||||
* from 910/997 (deleted at the M4 flip) onto the live `ww test --sep`
|
||||
* from 910/997 (deleted at the M4 flip) onto the live `ww test`
|
||||
* gate. Fixtures are the unchanged 910/997 flat @test fixtures, reused
|
||||
* in place (single source of truth) — they survive the flip; only the
|
||||
* .c gates move. */
|
||||
@@ -216,12 +213,10 @@ main(void)
|
||||
const char *bin = absbin();
|
||||
if (!bin) return 1;
|
||||
|
||||
char td[64], cmd[8192];
|
||||
int fail = 0;
|
||||
snprintf(td, sizeof td, "/tmp/wwseptest_%d", getpid());
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s", td);
|
||||
runwait(cmd);
|
||||
mkdir(td, 0755);
|
||||
char td[] = "/tmp/wwseptest_XXXXXX";
|
||||
char cmd[8192];
|
||||
int fail = 0, cleanup_fail = 0;
|
||||
if (mkdtemp(td) == NULL) return 1;
|
||||
|
||||
for (int i = 0; cases[i].label; i++) {
|
||||
struct tcase *t = &cases[i];
|
||||
@@ -241,13 +236,12 @@ main(void)
|
||||
* `<label>.ww` SOURCE; -o leaves <prog>.sepwork for the
|
||||
* byte-id compare and runs the binary (exit = test result). */
|
||||
snprintf(prog, sizeof prog, "%s/%s.%s.bin", td, t->label, stg[s].tag);
|
||||
/* COLD per-(case,stage) cache so every package compiles fresh
|
||||
* (a warm cache would skip the per-pkg .s/.wwi this gate
|
||||
* inspects — mirrors 989_c6soak / 989_pkgcache). */
|
||||
/* Each direct build produces the per-package .s/.wwi artifacts
|
||||
* this gate inspects. */
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"WW_PKGCACHE='%s/cache.%s.%s' %s/%s test --sep -o %s %s "
|
||||
"%s/%s test -o %s %s "
|
||||
">/dev/null 2>&1",
|
||||
td, t->label, stg[s].tag, bin, stg[s].drv, prog, rootww);
|
||||
bin, stg[s].drv, prog, rootww);
|
||||
stg[s].rc = runwait(cmd);
|
||||
}
|
||||
|
||||
@@ -292,13 +286,34 @@ main(void)
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s", td);
|
||||
runwait(cmd);
|
||||
for (int i = 0; cases[i].label; i++) {
|
||||
for (int s = 0; s < 2; s++) {
|
||||
const char *tag = s == 0 ? "cs" : "ww";
|
||||
char path[1200];
|
||||
snprintf(path, sizeof path, "%s/%s.%s.bin.sepwork",
|
||||
td, cases[i].label, tag);
|
||||
snprintf(cmd, sizeof cmd, "rm -rf -- '%s'", path);
|
||||
if (runwait(cmd) != 0) cleanup_fail = 1;
|
||||
snprintf(path, sizeof path, "%s/%s.%s.bin",
|
||||
td, cases[i].label, tag);
|
||||
if (unlink(path) != 0 && errno != ENOENT) cleanup_fail = 1;
|
||||
}
|
||||
if (cases[i].src) {
|
||||
char path[1200];
|
||||
snprintf(path, sizeof path, "%s/%s.ww", td, cases[i].label);
|
||||
if (unlink(path) != 0 && errno != ENOENT) cleanup_fail = 1;
|
||||
}
|
||||
}
|
||||
if (rmdir(td) != 0) cleanup_fail = 1;
|
||||
if (cleanup_fail) {
|
||||
fprintf(stderr, "septest FAIL: cleanup incomplete under %s\n", td);
|
||||
fail++;
|
||||
}
|
||||
if (fail) {
|
||||
fprintf(stderr, "septest: %d check(s) failed\n", fail);
|
||||
return 1;
|
||||
}
|
||||
printf("septest: `ww test --sep` run-exit (pass=0, fail=1) on both driver "
|
||||
printf("septest: `ww test` run-exit (pass=0, fail=1) on both driver "
|
||||
"stages + cs==ww per-pkg .s/.wwi + synth `CALL test.run` in __root.s\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user