/* * 989_zerotest_run (#64, F15 c7) — `ww test ` over a directory with no * *_test.ww files must fail loud, not return rc=0 with a silent false-green. * * THE BUG (wwstage driver only, cat-A silent false-green under rc=0): * rundirtests had no zero-count check — a directory with no *_test.ww files * yielded pass=0 fail=0 → `return 0` with no output at all. A typo'd or empty * test dir got a silent green from the wwstage driver, while cstage do_test * errors "ww test: no *_test.ww files in %s" rc=1 (cmd/ww/main.c:945). THE FIX: * count *_test.ww matches and loud-fail (rc=1 + the same message) when zero. * * row | dir contents | result (cs==ww) * --------+---------------------------+---------------------------- * empty | no files | rc != 0 (loud "no *_test.ww") * nomatch | foo.ww (not *_test.ww) | rc != 0 (loud) * healthy | foo_test.ww (1 @test) | rc == 0 (control) * * empty / nomatch were RED pre-c7 on wwstage (rc=0, no output, false-green). * healthy pins the real-test path: both stages run it and exit 0. */ #include #include #include #include #include #include static int runwait(const char *cmd) { int rc = system(cmd); if (rc == -1) return -1; if (WIFEXITED(rc)) return WEXITSTATUS(rc); return -1; } /* Set up a fresh dir; optionally drop a file with `body` named `fname`. * Returns the dir path in `dir`. */ static void make_dir(char *dir, size_t dsz, const char *tag, const char *fname, const char *body) { char cmd[256], fp[256]; snprintf(dir, dsz, "/tmp/zt_%d_%s", getpid(), tag); snprintf(cmd, sizeof cmd, "rm -rf %s && mkdir -p %s", dir, dir); system(cmd); if (fname) { snprintf(fp, sizeof fp, "%s/%s", dir, fname); FILE *f = fopen(fp, "wb"); if (f) { fputs(body, f); fclose(f); } } } /* ` test ` rc. */ static int run_test(const char *driver, const char *dir) { char cmd[1024]; snprintf(cmd, sizeof cmd, "%s test %s >/dev/null 2>&1", driver, dir); return runwait(cmd); } int main(void) { const char *bin = getenv("BIN"); if (!bin) bin = "out/bin"; char absbin[1024]; if (bin[0] != '/') { char cwd[1024]; if (getcwd(cwd, sizeof cwd) == NULL) return 1; snprintf(absbin, sizeof absbin, "%s/%s", cwd, bin); bin = absbin; } char cdrv[1024], wdrv[1024]; snprintf(cdrv, sizeof cdrv, "%s/ww", bin); snprintf(wdrv, sizeof wdrv, "%s/ww_ww", bin); int have_ww = (access(wdrv, X_OK) == 0); if (!have_ww) fprintf(stderr, "zerotest: skip wwstage (no %s)\n", wdrv); struct row { const char *tag; const char *fname; const char *body; int want_loud; }; struct row rows[] = { { "empty", NULL, NULL, 1 }, { "nomatch", "foo.ww", "package main;\nexport fn main() i32 = { return 0; };\n", 1 }, { "healthy", "foo_test.ww", "package zt_test;\n@test fn t_ok() void = { };\n", 0 }, }; int n = (int)(sizeof rows / sizeof rows[0]); int fail = 0, total = 0; for (int i = 0; i < n; i++) { total++; char dir[128]; make_dir(dir, sizeof dir, rows[i].tag, rows[i].fname, rows[i].body); int crc = run_test(cdrv, dir); if (rows[i].want_loud) { if (crc == 0) { fprintf(stderr, "zerotest[cstage][%s]: rc=0, expected loud " "no-tests failure\n", rows[i].tag); fail++; } } else if (crc != 0) { fprintf(stderr, "zerotest[cstage][%s]: rc=%d, expected 0\n", rows[i].tag, crc); fail++; } if (have_ww) { int wrc = run_test(wdrv, dir); if (rows[i].want_loud) { if (wrc == 0) { fprintf(stderr, "zerotest[wwstage][%s]: rc=0 on a dir with " "no *_test.ww (silent false-green — #64)\n", rows[i].tag); fail++; } if ((crc == 0) != (wrc == 0)) { fprintf(stderr, "zerotest[%s]: loud divergence cs_rc=%d " "ww_rc=%d (#64)\n", rows[i].tag, crc, wrc); fail++; } } else { if (wrc != 0) { fprintf(stderr, "zerotest[wwstage][%s]: rc=%d, expected 0\n", rows[i].tag, wrc); fail++; } } } char cmd[160]; snprintf(cmd, sizeof cmd, "rm -rf %s", dir); system(cmd); } if (fail) { fprintf(stderr, "zerotest_run: %d/%d check(s) failed\n", fail, total); return 1; } printf("zerotest_run: %d/%d ok\n", total, total); return 0; }