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

@@ -49,6 +49,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/wait.h>
@@ -69,25 +70,51 @@ run_neg(const char *driver, const char *fixdir, const char *tag)
snprintf(src, sizeof src, "neg_%s.ww", tag);
char td[128];
snprintf(td, sizeof td, "/tmp/psm_neg_%d_%s", getpid(), tag);
mkdir(td, 0755);
if (mkdir(td, 0755) != 0) {
fprintf(stderr, "param_shadow_mod[neg_%s]: mkdir %s: %s\n",
tag, td, strerror(errno));
return 1;
}
char out[160], sepdir[192], rmcmd[224];
snprintf(out, sizeof out, "%s/out", td);
snprintf(sepdir, sizeof sepdir, "%s.sepwork", out);
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", sepdir);
char cmd[2048];
/* cd into the fixture dir so the driver's source-dir-first
* import search resolves `use shadowmod;`; -o moves the binary
* and its <stem>.sepwork OUT of the tracked fixture tree. */
* and caller-owned out.sepwork out of the tracked fixture tree. */
snprintf(cmd, sizeof cmd,
"cd %s && %s build -o %s/out %s >/dev/null 2>&1",
fixdir, driver, td, src);
"cd %s && %s build -o %s %s >/dev/null 2>&1",
fixdir, driver, out, src);
int rc = runwait(cmd);
char rmcmd[256];
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", td);
runwait(rmcmd);
int failed = 0;
if (rc == 0) {
fprintf(stderr,
"param_shadow_mod[neg_%s]: build unexpectedly succeeded "
"— shadow rule did not fire\n", tag);
return 1;
failed = 1;
}
return 0;
{
int cleanup_failed = 0;
if (runwait(rmcmd) != 0) {
fprintf(stderr, "param_shadow_mod[neg_%s]: remove %s failed\n",
tag, sepdir);
cleanup_failed = 1;
}
if (unlink(out) != 0 && errno != ENOENT) {
fprintf(stderr, "param_shadow_mod[neg_%s]: unlink %s: %s\n",
tag, out, strerror(errno));
cleanup_failed = 1;
}
if (rmdir(td) != 0) {
fprintf(stderr, "param_shadow_mod[neg_%s]: rmdir %s: %s\n",
tag, td, strerror(errno));
cleanup_failed = 1;
}
if (!failed && cleanup_failed) failed = 1;
}
return failed;
}
static int
@@ -95,32 +122,57 @@ run_pos(const char *driver, const char *fixdir)
{
char td[128];
snprintf(td, sizeof td, "/tmp/psm_pos_%d", getpid());
mkdir(td, 0755);
char rmcmd[256];
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", td);
if (mkdir(td, 0755) != 0) {
fprintf(stderr, "param_shadow_mod[pos_rename]: mkdir %s: %s\n",
td, strerror(errno));
return 1;
}
char out[160], sepdir[192], rmcmd[224];
snprintf(out, sizeof out, "%s/out", td);
snprintf(sepdir, sizeof sepdir, "%s.sepwork", out);
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", sepdir);
char cmd[2048];
/* keep cd for sibling-import resolution; -o moves the binary and
* its pos_rename.sepwork OUT of the tracked fixture tree. */
/* Keep cd for sibling-import resolution; -o moves the binary and
* caller-owned out.sepwork out of the tracked fixture tree. */
snprintf(cmd, sizeof cmd,
"cd %s && %s build -o %s/out pos_rename.ww >/dev/null 2>&1",
fixdir, driver, td);
"cd %s && %s build -o %s pos_rename.ww >/dev/null 2>&1",
fixdir, driver, out);
int failed = 0, got;
if (runwait(cmd) != 0) {
runwait(rmcmd);
fprintf(stderr,
"param_shadow_mod[pos_rename]: build failed — rule "
"over-triggered on the rename\n");
return 1;
failed = 1;
goto cleanup;
}
char bin[2048];
snprintf(bin, sizeof bin, "%s/out", td);
int got = runwait(bin);
runwait(rmcmd);
got = runwait(out);
if (got != 42) {
fprintf(stderr,
"param_shadow_mod[pos_rename]: exit=%d want=42\n", got);
return 1;
failed = 1;
}
return 0;
cleanup:
{
int cleanup_failed = 0;
if (runwait(rmcmd) != 0) {
fprintf(stderr, "param_shadow_mod[pos_rename]: remove %s failed\n",
sepdir);
cleanup_failed = 1;
}
if (unlink(out) != 0 && errno != ENOENT) {
fprintf(stderr, "param_shadow_mod[pos_rename]: unlink %s: %s\n",
out, strerror(errno));
cleanup_failed = 1;
}
if (rmdir(td) != 0) {
fprintf(stderr, "param_shadow_mod[pos_rename]: rmdir %s: %s\n",
td, strerror(errno));
cleanup_failed = 1;
}
if (!failed && cleanup_failed) failed = 1;
}
return failed;
}
/*
@@ -134,34 +186,61 @@ run_pos(const char *driver, const char *fixdir)
static int
run_neg_selfimp(const char *comp, const char *fixdir, const char *tag)
{
char errp[96], cmd[2048];
snprintf(errp, sizeof errp, "/tmp/psm_selfimp_%s_%d.err", tag, getpid());
char td[128];
snprintf(td, sizeof td, "/tmp/psm_selfimp_%d_%s", getpid(), tag);
if (mkdir(td, 0755) != 0) {
fprintf(stderr, "param_shadow_mod[neg_selfimp-%s]: mkdir %s: %s\n",
tag, td, strerror(errno));
return 1;
}
char errp[160], cmd[2048];
snprintf(errp, sizeof errp, "%s/stderr", td);
snprintf(cmd, sizeof cmd,
"cd %s && %s selfimp/selfimptest.ww -o /dev/null 2>%s",
fixdir, comp, errp);
int rc = runwait(cmd);
int failed = 0, found = 0;
FILE *f;
if (rc == 0) {
fprintf(stderr, "param_shadow_mod[neg_selfimp-%s]: accepted "
"self-import (expected reject)\n", tag);
unlink(errp);
return 1;
failed = 1;
goto cleanup;
}
FILE *f = fopen(errp, "rb");
int found = 0;
f = fopen(errp, "rb");
if (f) {
char buf[4096];
size_t n = fread(buf, 1, sizeof buf - 1, f);
fclose(f);
buf[n] = '\0';
found = strstr(buf, "self-import") != NULL;
if (!ferror(f)) {
buf[n] = '\0';
found = strstr(buf, "self-import") != NULL;
}
if (fclose(f) != 0) found = 0;
}
unlink(errp);
if (!found) {
fprintf(stderr, "param_shadow_mod[neg_selfimp-%s]: rejected "
"but no 'self-import' on stderr\n", tag);
return 1;
failed = 1;
}
return 0;
cleanup:
{
int cleanup_failed = 0;
if (unlink(errp) != 0 && errno != ENOENT) {
fprintf(stderr,
"param_shadow_mod[neg_selfimp-%s]: unlink %s: %s\n",
tag, errp, strerror(errno));
cleanup_failed = 1;
}
if (rmdir(td) != 0) {
fprintf(stderr,
"param_shadow_mod[neg_selfimp-%s]: rmdir %s: %s\n",
tag, td, strerror(errno));
cleanup_failed = 1;
}
if (!failed && cleanup_failed) failed = 1;
}
return failed;
}
/*
@@ -177,32 +256,57 @@ run_pos_crossmod(const char *driver, const char *fixdir)
{
char td[128];
snprintf(td, sizeof td, "/tmp/psm_crossmod_%d", getpid());
mkdir(td, 0755);
char rmcmd[256];
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", td);
if (mkdir(td, 0755) != 0) {
fprintf(stderr, "param_shadow_mod[pos_crossmod]: mkdir %s: %s\n",
td, strerror(errno));
return 1;
}
char out[160], sepdir[192], rmcmd[224];
snprintf(out, sizeof out, "%s/out", td);
snprintf(sepdir, sizeof sepdir, "%s.sepwork", out);
snprintf(rmcmd, sizeof rmcmd, "rm -rf %s", sepdir);
char cmd[2048];
/* keep cd for sibling-import resolution; -o moves the binary and
* its pos_crossmod.sepwork OUT of the tracked fixture tree. */
/* Keep cd for sibling-import resolution; -o moves the binary and
* caller-owned out.sepwork out of the tracked fixture tree. */
snprintf(cmd, sizeof cmd,
"cd %s && %s build -o %s/out pos_crossmod.ww >/dev/null 2>&1",
fixdir, driver, td);
"cd %s && %s build -o %s pos_crossmod.ww >/dev/null 2>&1",
fixdir, driver, out);
int failed = 0, got;
if (runwait(cmd) != 0) {
runwait(rmcmd);
fprintf(stderr,
"param_shadow_mod[pos_crossmod]: build failed — shadow "
"rule over-triggered on a cross-module param\n");
return 1;
failed = 1;
goto cleanup;
}
char bin[2048];
snprintf(bin, sizeof bin, "%s/out", td);
int got = runwait(bin);
runwait(rmcmd);
got = runwait(out);
if (got != 2) {
fprintf(stderr,
"param_shadow_mod[pos_crossmod]: exit=%d want=2\n", got);
return 1;
failed = 1;
}
return 0;
cleanup:
{
int cleanup_failed = 0;
if (runwait(rmcmd) != 0) {
fprintf(stderr, "param_shadow_mod[pos_crossmod]: remove %s failed\n",
sepdir);
cleanup_failed = 1;
}
if (unlink(out) != 0 && errno != ENOENT) {
fprintf(stderr, "param_shadow_mod[pos_crossmod]: unlink %s: %s\n",
out, strerror(errno));
cleanup_failed = 1;
}
if (rmdir(td) != 0) {
fprintf(stderr, "param_shadow_mod[pos_crossmod]: rmdir %s: %s\n",
td, strerror(errno));
cleanup_failed = 1;
}
if (!failed && cleanup_failed) failed = 1;
}
return failed;
}
int