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