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:
@@ -10,7 +10,7 @@
|
||||
* (task #21, FC0). This gate closes the class: each lib test fixture is
|
||||
* sep-built through BOTH driver stages and the per-package asm compared.
|
||||
*
|
||||
* #94 sep layout: the gate drives `ww --sep` (cstage) and `ww_ww --sep`
|
||||
* #94 sep layout: the gate drives `ww` (cstage) and `ww_ww`
|
||||
* (wwstage) instead of feeding a single .combined.ww to raw w6c/w6c_ww.
|
||||
* Under sep EACH package compiles to its OWN <stem>.sepwork/<pkg>.s — the
|
||||
* lib body lands in <pkg>.s, NOT in __root.s (which holds only the test
|
||||
@@ -27,7 +27,7 @@
|
||||
* the concatenated asm must still DIFFER: when a fix lands,
|
||||
* the entry fails loudly demanding graduation to ID rather
|
||||
* than silently widening or narrowing coverage.
|
||||
* WWREJECT — cstage --sep compiles, wwstage --sep errors (front-end
|
||||
* WWREJECT — cstage compiles, wwstage errors (front-end
|
||||
* gap, task #59). Graduation is pinned the same way.
|
||||
*
|
||||
* Modules with no test fixture and no embedding (sort/path/endian/net/
|
||||
@@ -39,9 +39,8 @@
|
||||
* fails loudly on any lib/ dir not enrolled here, so new modules can't
|
||||
* ship uncovered.
|
||||
*
|
||||
* Compile+cmp only (--sep -o redirects every artifact to a getpid-keyed
|
||||
* /tmp dir; WW_PKGCACHE pinned there so out/.pkgcache is untouched), so
|
||||
* this stays phase-1 parallel-safe next to the 9xx _run tests.
|
||||
* Compile+cmp only; -o redirects every artifact to a getpid-keyed
|
||||
* /tmp directory for isolation.
|
||||
*
|
||||
* 9xx is full; shares the 989 prefix per the 989_sha256 precedent (the
|
||||
* `short` name keys the binary).
|
||||
@@ -53,7 +52,7 @@
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
enum { M_ID, M_DIVERGE, M_WWREJECT, NENT_EXPECT = 42 };
|
||||
enum { M_ID, M_DIVERGE, M_WWREJECT, NENT_EXPECT = 43 };
|
||||
|
||||
struct ent {
|
||||
const char *fixture; /* repo-relative .ww; NULL → probe entry */
|
||||
@@ -94,6 +93,8 @@ static const struct ent ents[] = {
|
||||
{ .fixture = "lib/math/random/random_test.ww", .mode = M_ID },
|
||||
{ .fixture = "lib/memio/memiotest.ww", .mode = M_ID },
|
||||
{ .fixture = "lib/os/ostest.ww", .mode = M_ID },
|
||||
{ .probe = "package main;\nimport os.exec;\nfn main() i32 = { return 0; };\n",
|
||||
.mode = M_ID, .sentinel = "package exec;", .moddir = "lib/os/exec" },
|
||||
{ .fixture = "lib/regex/regex_test.ww", .mode = M_ID },
|
||||
{ .fixture = "lib/strconv/test/ftostest.ww", .mode = M_ID },
|
||||
/* graduated from #59.10 DIVERGE by the #62 float-literal fold fix
|
||||
@@ -227,9 +228,10 @@ check_one(const char *bin, const char *cwd, const struct ent *e, int idx)
|
||||
int rc = -1;
|
||||
|
||||
snprintf(td, sizeof td, "/tmp/wwlbi_%d_%d", getpid(), idx);
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s", td);
|
||||
runwait(cmd);
|
||||
mkdir(td, 0755);
|
||||
if (mkdir(td, 0755) != 0) {
|
||||
perror(td);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char base[256];
|
||||
if (e->fixture) {
|
||||
@@ -271,34 +273,34 @@ check_one(const char *bin, const char *cwd, const struct ent *e, int idx)
|
||||
char *sd = strrchr(stem, '.');
|
||||
if (sd) *sd = '\0';
|
||||
|
||||
/* Two sep driver builds. @test fixtures are main-less, so `test -c
|
||||
* --sep` carries -T (synthesizes the entry + keeps @test fns + auto-
|
||||
/* Two compiler-only sep driver builds. @test fixtures are main-less,
|
||||
* so `test -S ` carries -T (synthesizes the entry + keeps @test fns + auto-
|
||||
* bundles lib/test's run() callee) and emits per-package asm without
|
||||
* a harness run; import-probes carry their own `fn main()`, which -T
|
||||
* loud-rejects (910), so they `build --sep` (non-T). Each stage's
|
||||
* loud-rejects (910), so they `build -S ` (non-T). Each stage's
|
||||
* artifacts land under its own -o stem so out/ and the source tree
|
||||
* stay clean; WW_PKGCACHE is pinned to td. */
|
||||
const char *sub = e->fixture ? "test -c --sep" : "build --sep";
|
||||
* stay clean. */
|
||||
const char *sub = e->fixture ? "test -S " : "build -S ";
|
||||
char stemc[600], stemw[600];
|
||||
snprintf(stemc, sizeof stemc, "%s/c_%s", td, stem);
|
||||
snprintf(stemw, sizeof stemw, "%s/w_%s", td, stem);
|
||||
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && WW_PKGCACHE=%s/pc timeout 180 %s/ww %s %s -o %s %s "
|
||||
">/dev/null 2>&1", td, td, bin, sub, incs, stemc, base);
|
||||
"cd %s && timeout 180 %s/ww %s %s -o %s %s "
|
||||
">/dev/null 2>&1", td, bin, sub, incs, stemc, base);
|
||||
int ce = runwait(cmd);
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"cd %s && WW_PKGCACHE=%s/pw timeout 180 %s/ww_ww %s %s -o %s %s "
|
||||
">/dev/null 2>&1", td, td, bin, sub, incs, stemw, base);
|
||||
"cd %s && timeout 180 %s/ww_ww %s %s -o %s %s "
|
||||
">/dev/null 2>&1", td, bin, sub, incs, stemw, base);
|
||||
int we = runwait(cmd);
|
||||
|
||||
/* the cstage --sep build resolves the units (root + each package);
|
||||
/* the cstage build resolves the units (root + each package);
|
||||
* its __root.unit.ww proves resolution ran. WWREJECT still requires
|
||||
* cstage to compile, so this holds for every mode. */
|
||||
char rootu[760];
|
||||
snprintf(rootu, sizeof rootu, "%s.sepwork/__root.unit.ww", stemc);
|
||||
if (ce != 0 || access(rootu, 0) != 0) {
|
||||
fprintf(stderr, "lib_byteid FAIL: %s — cstage --sep produced "
|
||||
fprintf(stderr, "lib_byteid FAIL: %s — cstage produced "
|
||||
"no resolved unit\n", label);
|
||||
goto out;
|
||||
}
|
||||
@@ -322,7 +324,7 @@ check_one(const char *bin, const char *cwd, const struct ent *e, int idx)
|
||||
|
||||
if (e->mode == M_WWREJECT) {
|
||||
if (we == 0) {
|
||||
fprintf(stderr, "lib_byteid FAIL: %s — wwstage --sep now "
|
||||
fprintf(stderr, "lib_byteid FAIL: %s — wwstage now "
|
||||
"compiles this; graduate the %s pin to ID or "
|
||||
"DIVERGE\n", label, e->cite);
|
||||
goto out;
|
||||
@@ -331,7 +333,7 @@ check_one(const char *bin, const char *cwd, const struct ent *e, int idx)
|
||||
goto out;
|
||||
}
|
||||
if (we != 0) {
|
||||
fprintf(stderr, "lib_byteid FAIL: %s — wwstage --sep rejected\n",
|
||||
fprintf(stderr, "lib_byteid FAIL: %s — wwstage rejected\n",
|
||||
label);
|
||||
goto out;
|
||||
}
|
||||
@@ -345,10 +347,18 @@ check_one(const char *bin, const char *cwd, const struct ent *e, int idx)
|
||||
snprintf(ws, sizeof ws, "%s/all_w.s", td);
|
||||
snprintf(cmd, sizeof cmd, "cat %s.sepwork/*.s > %s 2>/dev/null",
|
||||
stemc, cs);
|
||||
if (system(cmd)) {}
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "lib_byteid FAIL: %s — cstage .s concat "
|
||||
"failed (no per-package .s)\n", label);
|
||||
goto out;
|
||||
}
|
||||
snprintf(cmd, sizeof cmd, "cat %s.sepwork/*.s > %s 2>/dev/null",
|
||||
stemw, ws);
|
||||
if (system(cmd)) {}
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "lib_byteid FAIL: %s — wwstage .s concat "
|
||||
"failed (no per-package .s)\n", label);
|
||||
goto out;
|
||||
}
|
||||
|
||||
char *bc = NULL, *bw = NULL;
|
||||
size_t nc = 0, nw = 0;
|
||||
@@ -359,6 +369,12 @@ check_one(const char *bin, const char *cwd, const struct ent *e, int idx)
|
||||
}
|
||||
int same = (nc == nw && memcmp(bc, bw, nc) == 0);
|
||||
free(bc); free(bw);
|
||||
/* two empty concats compare equal — that green covers nothing */
|
||||
if (nc == 0 || nw == 0) {
|
||||
fprintf(stderr, "lib_byteid FAIL: %s — empty .s concat "
|
||||
"(cs %zu, ww %zu bytes)\n", label, nc, nw);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (e->mode == M_ID && !same) {
|
||||
fprintf(stderr, "lib_byteid FAIL: %s — cs %zu vs ww %zu bytes "
|
||||
@@ -373,7 +389,10 @@ check_one(const char *bin, const char *cwd, const struct ent *e, int idx)
|
||||
rc = 0;
|
||||
out:
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s", td);
|
||||
runwait(cmd);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "lib_byteid: cleanup rm -rf %s failed\n", td);
|
||||
if (rc == 0) rc = -1;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user