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:
@@ -12,11 +12,12 @@
|
||||
* module nears 256 files). THE FIX (CAP-SEMANTICS rule: the cstage twin grows,
|
||||
* so grow-dynamic): mirror the realloc-doubling growth in enumeratedir.
|
||||
*
|
||||
* #94 sep layout: the flip stops emitting a single <stem>.combined.ww; under
|
||||
* `--sep` each package is enumerated into its OWN <stem>.sepwork/<pkg>.unit.ww
|
||||
* #94 sep layout: separate compilation stops emitting a single
|
||||
* <stem>.combined.ww; each package is enumerated into its OWN
|
||||
* <stem>.sepwork/<pkg>.unit.ww
|
||||
* (the bigmod dir → bigmod.unit.ww, holding one `package bigmod;` clause per
|
||||
* enumerated source file — the exact set the combined.ww used to hold for that
|
||||
* package). So the gate now drives `ww build --sep` / `ww_ww build --sep` and
|
||||
* package). So the gate now drives `ww build` / `ww_ww build` and
|
||||
* re-targets the enumeration check onto bigmod.unit.ww: each stage must enroll
|
||||
* `nfiles` package clauses, and the two stages' bigmod.unit.ww must be byte-
|
||||
* identical. A cap-drop on one side shrinks that stage's bigmod.unit.ww — the
|
||||
@@ -30,13 +31,13 @@
|
||||
* big_300 was RED pre-c3 (ww enrolled 256, cs 300 — divergent unit).
|
||||
* small_5 pins the common ≤cap path stays byte-identical.
|
||||
*
|
||||
* All intermediates redirect under each stage's -o stem and WW_PKGCACHE is
|
||||
* pinned to the /tmp scratch, so out/.pkgcache and the source tree stay clean
|
||||
* and the gate runs parallel-safe.
|
||||
* All intermediates redirect under each stage's -o stem in /tmp, so out/
|
||||
* and the source tree stay clean and the gate runs parallel-safe.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
@@ -64,32 +65,60 @@ count_pkgs(const char *path)
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Returns 0 if both --sep driver builds enrolled `nfiles` package clauses into
|
||||
/* Returns 0 if both driver builds enrolled `nfiles` package clauses into
|
||||
* their bigmod.unit.ww AND the two units are byte-identical; non-zero
|
||||
* (and prints) otherwise. */
|
||||
static int
|
||||
one_row(const char *label, const char *cdrv, const char *wdrv, int nfiles,
|
||||
int have_ww)
|
||||
{
|
||||
char dir[64], main_ww[128], cstem[128], wstem[128];
|
||||
char dir[64], bigdir[128], main_ww[128], cstem[128], wstem[128];
|
||||
char cunit[192], wunit[192], cmd[1024], fn[160];
|
||||
snprintf(dir, sizeof dir, "/tmp/encap_%d_%s", getpid(), label);
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s && mkdir -p %s/bigmod", dir, dir);
|
||||
system(cmd);
|
||||
if (mkdir(dir, 0755) != 0) {
|
||||
perror(dir);
|
||||
return 1;
|
||||
}
|
||||
int fail = 0, have_bigdir = 0;
|
||||
snprintf(bigdir, sizeof bigdir, "%s/bigmod", dir);
|
||||
if (mkdir(bigdir, 0755) != 0) {
|
||||
perror(bigdir);
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
have_bigdir = 1;
|
||||
|
||||
for (int i = 0; i < nfiles; i++) {
|
||||
snprintf(fn, sizeof fn, "%s/bigmod/f%03d.ww", dir, i);
|
||||
FILE *f = fopen(fn, "wb");
|
||||
if (!f) return 1;
|
||||
fprintf(f, "package bigmod;\nexport fn f%03d() i32 = "
|
||||
"{ return %d; };\n", i, i);
|
||||
fclose(f);
|
||||
if (!f) {
|
||||
perror(fn);
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
int werr = fprintf(f, "package bigmod;\nexport fn f%03d() i32 = "
|
||||
"{ return %d; };\n", i, i) < 0;
|
||||
if (fclose(f) != 0) werr = 1;
|
||||
if (werr) {
|
||||
perror(fn);
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
snprintf(main_ww, sizeof main_ww, "%s/main.ww", dir);
|
||||
FILE *mf = fopen(main_ww, "wb");
|
||||
if (!mf) return 1;
|
||||
fputs("package main;\nimport bigmod;\nfn main() void = {};\n", mf);
|
||||
fclose(mf);
|
||||
if (!mf) {
|
||||
perror(main_ww);
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
int werr = fputs("package main;\nimport bigmod;\nfn main() void = {};\n", mf) == EOF;
|
||||
if (fclose(mf) != 0) werr = 1;
|
||||
if (werr) {
|
||||
perror(main_ww);
|
||||
fail++;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
snprintf(cstem, sizeof cstem, "%s/X_c", dir);
|
||||
snprintf(wstem, sizeof wstem, "%s/X_w", dir);
|
||||
@@ -97,10 +126,9 @@ one_row(const char *label, const char *cdrv, const char *wdrv, int nfiles,
|
||||
snprintf(cunit, sizeof cunit, "%s.sepwork/bigmod.unit.ww", cstem);
|
||||
snprintf(wunit, sizeof wunit, "%s.sepwork/bigmod.unit.ww", wstem);
|
||||
|
||||
int fail = 0;
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"WW_PKGCACHE=%s/pc %s build --sep -o %s %s 2>/dev/null",
|
||||
dir, cdrv, cstem, main_ww);
|
||||
"%s build -o %s %s 2>/dev/null",
|
||||
cdrv, cstem, main_ww);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "enumcap[cstage][%s]: build failed\n", label);
|
||||
fail++;
|
||||
@@ -114,8 +142,8 @@ one_row(const char *label, const char *cdrv, const char *wdrv, int nfiles,
|
||||
|
||||
if (have_ww) {
|
||||
snprintf(cmd, sizeof cmd,
|
||||
"WW_PKGCACHE=%s/pw %s build --sep -o %s %s 2>/dev/null",
|
||||
dir, wdrv, wstem, main_ww);
|
||||
"%s build -o %s %s 2>/dev/null",
|
||||
wdrv, wstem, main_ww);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "enumcap[wwstage][%s]: build failed\n", label);
|
||||
fail++;
|
||||
@@ -136,8 +164,52 @@ one_row(const char *label, const char *cdrv, const char *wdrv, int nfiles,
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s", dir);
|
||||
system(cmd);
|
||||
cleanup:
|
||||
if (have_bigdir) {
|
||||
for (int i = 0; i < nfiles; i++) {
|
||||
snprintf(fn, sizeof fn, "%s/bigmod/f%03d.ww", dir, i);
|
||||
if (unlink(fn) != 0 && errno != ENOENT) {
|
||||
perror(fn);
|
||||
fail++;
|
||||
}
|
||||
}
|
||||
}
|
||||
snprintf(main_ww, sizeof main_ww, "%s/main.ww", dir);
|
||||
if (unlink(main_ww) != 0 && errno != ENOENT) {
|
||||
perror(main_ww);
|
||||
fail++;
|
||||
}
|
||||
snprintf(cstem, sizeof cstem, "%s/X_c", dir);
|
||||
snprintf(wstem, sizeof wstem, "%s/X_w", dir);
|
||||
if (unlink(cstem) != 0 && errno != ENOENT) {
|
||||
perror(cstem);
|
||||
fail++;
|
||||
}
|
||||
if (unlink(wstem) != 0 && errno != ENOENT) {
|
||||
perror(wstem);
|
||||
fail++;
|
||||
}
|
||||
char work[192];
|
||||
snprintf(work, sizeof work, "%s.sepwork", cstem);
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s", work);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "enumcap[%s]: cleanup failed: %s\n", label, work);
|
||||
fail++;
|
||||
}
|
||||
snprintf(work, sizeof work, "%s.sepwork", wstem);
|
||||
snprintf(cmd, sizeof cmd, "rm -rf %s", work);
|
||||
if (runwait(cmd) != 0) {
|
||||
fprintf(stderr, "enumcap[%s]: cleanup failed: %s\n", label, work);
|
||||
fail++;
|
||||
}
|
||||
if (have_bigdir && rmdir(bigdir) != 0) {
|
||||
perror(bigdir);
|
||||
fail++;
|
||||
}
|
||||
if (rmdir(dir) != 0) {
|
||||
perror(dir);
|
||||
fail++;
|
||||
}
|
||||
return fail;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user