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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user