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:
2026-08-07 23:02:47 +09:00
parent b2899dd8d3
commit a95a7a316b
132 changed files with 7573 additions and 6172 deletions

View File

@@ -37,14 +37,15 @@
* w6a_ww/w6l_ww) -> cs==ww at the final-exe level + behavioral identity.
*
* COLD: a fresh getpid-keyed /tmp dir, `.wwi` materialized from scratch every
* run (no warm cache — a stale `.wwi` is a #110-class freshness hazard). No
* source-tree writes -> phase-1 parallel-safe. 9xx is full; shares the 989
* run (no warm cache — a stale `.wwi` is a #110-class freshness hazard). It
* writes nothing to the source tree. 9xx is full; shares the 989
* prefix per the 989_lib_byteid / 989_m2wwi precedent (the short name keys the
* binary). Models 989_m2wwi_run.c conventions.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
@@ -114,6 +115,17 @@ write_file(const char *path, const char *body)
return 0;
}
/* Remove one exact invocation-created child, accepting an uncreated path. */
static int
remove_child(const char *dir, const char *name)
{
char path[1024];
snprintf(path, sizeof path, "%s/%s", dir, name);
if (unlink(path) == 0 || errno == ENOENT) return 0;
perror(path);
return -1;
}
/* concat src files (verbatim bodies, each under a //ww:module directive or the
* //ww:module-reset root boundary) into one sep-unit. `pre` is the directive
* line (without trailing newline) to emit before `src`'s bytes; chained calls
@@ -255,9 +267,10 @@ main(void)
int fail = 0;
snprintf(td, sizeof td, "/tmp/wwm3_%d", getpid());
snprintf(cmd, sizeof cmd, "rm -rf %s", td);
runwait(cmd);
mkdir(td, 0755);
if (mkdir(td, 0755) != 0) {
perror(td);
return 1;
}
/* materialize the fixture cold */
snprintf(p, sizeof p, "%s/leaf.ww", td); if (write_file(p, leaf_src)) { fail++; goto out; }
@@ -670,8 +683,103 @@ main(void)
}
out:
snprintf(cmd, sizeof cmd, "rm -rf %s", td);
runwait(cmd);
{
int cleanfail = 0;
cleanfail |= remove_child(td, "leaf.ww");
cleanfail |= remove_child(td, "mid.ww");
cleanfail |= remove_child(td, "root.ww");
cleanfail |= remove_child(td, "sleaf.ww");
cleanfail |= remove_child(td, "smid.ww");
cleanfail |= remove_child(td, "sroot.ww");
cleanfail |= remove_child(td, "leaf.wwi");
cleanfail |= remove_child(td, "mid.wwi");
cleanfail |= remove_child(td, "mid.prod.ww");
cleanfail |= remove_child(td, "sleaf.wwi");
cleanfail |= remove_child(td, "smid.wwi");
cleanfail |= remove_child(td, "smid.prod.ww");
cleanfail |= remove_child(td, "mid.bodies.ww");
cleanfail |= remove_child(td, "mid.sep.ww");
cleanfail |= remove_child(td, "mid.bodies.cs.s");
cleanfail |= remove_child(td, "mid.sep.cs.s");
cleanfail |= remove_child(td, "mid.sep.ww.s");
cleanfail |= remove_child(td, "mid.sep.cs2.s");
cleanfail |= remove_child(td, "mid.bodies.ww.s");
cleanfail |= remove_child(td, "root.bodies.ww");
cleanfail |= remove_child(td, "root.sep.ww");
cleanfail |= remove_child(td, "root.bodies.cs.s");
cleanfail |= remove_child(td, "root.sep.cs.s");
cleanfail |= remove_child(td, "root.sep.ww.s");
cleanfail |= remove_child(td, "root.sep.cs2.s");
cleanfail |= remove_child(td, "root.bodies.ww.s");
cleanfail |= remove_child(td, "smid.bodies.ww");
cleanfail |= remove_child(td, "smid.sep.ww");
cleanfail |= remove_child(td, "smid.bodies.cs.s");
cleanfail |= remove_child(td, "smid.sep.cs.s");
cleanfail |= remove_child(td, "smid.sep.ww.s");
cleanfail |= remove_child(td, "smid.sep.cs2.s");
cleanfail |= remove_child(td, "smid.bodies.ww.s");
cleanfail |= remove_child(td, "leaf.cs.s");
cleanfail |= remove_child(td, "leaf.cs.o");
cleanfail |= remove_child(td, "mid.cs.s");
cleanfail |= remove_child(td, "mid.cs.o");
cleanfail |= remove_child(td, "root.cs.s");
cleanfail |= remove_child(td, "root.cs.o");
cleanfail |= remove_child(td, "prog.cs");
cleanfail |= remove_child(td, "leaf.ww.s");
cleanfail |= remove_child(td, "leaf.ww.o");
cleanfail |= remove_child(td, "mid.ww.s");
cleanfail |= remove_child(td, "mid.ww.o");
cleanfail |= remove_child(td, "root.ww.s");
cleanfail |= remove_child(td, "root.ww.o");
cleanfail |= remove_child(td, "prog.ww");
cleanfail |= remove_child(td, "sroot.sep.ww");
cleanfail |= remove_child(td, "sleaf.cs.s");
cleanfail |= remove_child(td, "sleaf.cs.o");
cleanfail |= remove_child(td, "smid.cs.s");
cleanfail |= remove_child(td, "smid.cs.o");
cleanfail |= remove_child(td, "sroot.cs.s");
cleanfail |= remove_child(td, "sroot.cs.o");
cleanfail |= remove_child(td, "sprog.cs");
cleanfail |= remove_child(td, "sleaf.ww.s");
cleanfail |= remove_child(td, "sleaf.ww.o");
cleanfail |= remove_child(td, "smid.ww.s");
cleanfail |= remove_child(td, "smid.ww.o");
cleanfail |= remove_child(td, "sroot.ww.s");
cleanfail |= remove_child(td, "sroot.ww.o");
cleanfail |= remove_child(td, "sprog.ww");
cleanfail |= remove_child(td, "cea.ww");
cleanfail |= remove_child(td, "ceb.ww");
cleanfail |= remove_child(td, "cxroot.ww");
cleanfail |= remove_child(td, "cea.wwi");
cleanfail |= remove_child(td, "ceb.wwi");
cleanfail |= remove_child(td, "cxroot.sep.ww");
cleanfail |= remove_child(td, "cea.cs.s");
cleanfail |= remove_child(td, "cea.cs.o");
cleanfail |= remove_child(td, "ceb.cs.s");
cleanfail |= remove_child(td, "ceb.cs.o");
cleanfail |= remove_child(td, "cxroot.cs.s");
cleanfail |= remove_child(td, "cxroot.cs.o");
cleanfail |= remove_child(td, "cxprog.cs");
cleanfail |= remove_child(td, "cea.ww.s");
cleanfail |= remove_child(td, "cea.ww.o");
cleanfail |= remove_child(td, "ceb.ww.s");
cleanfail |= remove_child(td, "ceb.ww.o");
cleanfail |= remove_child(td, "cxroot.ww.s");
cleanfail |= remove_child(td, "cxroot.ww.o");
cleanfail |= remove_child(td, "cxprog.ww");
if (rmdir(td) != 0) {
perror(td);
cleanfail = 1;
}
if (cleanfail) {
fprintf(stderr, "m3sep FAIL: temporary cleanup failed\n");
fail++;
}
}
if (fail) {
fprintf(stderr, "m3sep: %d check(s) failed\n", fail);
return 1;