septest_test.ww keeps all five rows (pass/fail run-exits, the userman + badsig @test rejects, the collide_run user-fn-run coexist) plus the full-sepwork .s/.wwi byte-id sweep and the -T synth TEXT-main / CALL-test.run presence needles, both driver stages. The pass/fail run-exit rows overlap package_test ownership but stay: retiring them would drop audit-listed assertions from this gate. The attest_* data fixtures remain in test/wcc/data (also consumed by the 911_attest_* carriers).
156 lines
5.0 KiB
Plaintext
156 lines
5.0 KiB
Plaintext
package septest_test;
|
|
|
|
// `ww test` sep-driver gate (M4 E1, #79-B). Port of the retired native
|
|
// carrier test/wcc/989_septest_run.c; every assertion preserved.
|
|
//
|
|
// Rows (each drives `<drv> test -o` on BOTH stages):
|
|
// pass — two passing inline @tests -> run-exit 0; the byte-id
|
|
// + synth anchor.
|
|
// fail — one failing inline @test -> run-exit 1: proves the
|
|
// @tests genuinely RUN under sep (non-vacuity teeth).
|
|
// userman — explicit user `main` collides with the -T synth
|
|
// entry -> reject (exit != 0; exact code is a driver
|
|
// detail, deliberately unasserted).
|
|
// badsig — non-`fn() void` @test signature -> reject.
|
|
// collide_run — user `fn run` coexists with lib/test's bound runner
|
|
// (distinct units: main.run in __root.s, test.run in
|
|
// test.s) -> exit 0; a regressed collision re-mangles
|
|
// to duplicate test.run -> w6l dup-symbol -> non-zero.
|
|
//
|
|
// byteid rows (pass, collide_run): EVERY .s/.wwi in the cs sepwork
|
|
// byte-equals the wwstage same-named file, with seen>0 (an empty
|
|
// sepwork fails loudly); __root.s carries "TEXT main" AND
|
|
// "CALL\ttest.run(SB)" — the qualified -T synth path fired under sep.
|
|
//
|
|
// The three on-disk attest fixtures stay in test/wcc/data/ (also
|
|
// consumed by the 911_attest_* carriers).
|
|
|
|
import os;
|
|
import os.exec;
|
|
import strings;
|
|
import testenv;
|
|
import time;
|
|
|
|
fn fail(label: str, why: str) void = {
|
|
let m: str = strings.concat("septest FAIL: ", label, " -- ", why,
|
|
"\n");
|
|
os.write(2, m.ptr, m.len: u64);
|
|
assert(false);
|
|
};
|
|
|
|
fn tmo() time.duration = {
|
|
return (180i64 * (time.second: i64)): time.duration;
|
|
};
|
|
|
|
fn passsrc() str = {
|
|
return strings.concat(
|
|
"package septest;\n",
|
|
"@test fn t_arith() void = {\n",
|
|
" let a: i32 = 2;\n",
|
|
" if (a + 3 != 5) { abort(); };\n",
|
|
"};\n",
|
|
"@test fn t_again() void = {\n",
|
|
" let s: str = \"ok\";\n",
|
|
" if (len(s) != 2) { abort(); };\n",
|
|
"};\n");
|
|
};
|
|
|
|
fn failsrc() str = {
|
|
return strings.concat(
|
|
"package septest;\n",
|
|
"@test fn t_bad() void = {\n",
|
|
" if (1 + 1 == 2) { abort(); };\n",
|
|
"};\n");
|
|
};
|
|
|
|
// -1 encodes an abnormal (non-EXIT) termination, never a valid code.
|
|
fn teststage(td: str, label: str, drv: str, tag: str, fixture: str) i32 = {
|
|
let prog: str = strings.concat(td, "/", label, ".", tag, ".bin");
|
|
let av: []str = [testenv.driver(drv), "test", "-o", prog, fixture];
|
|
let co: testenv.commandout;
|
|
testenv.runcommand(td, td, strings.concat(label, "_", tag), av,
|
|
tmo(), &co);
|
|
if (co.termination != exec.termination.EXIT) { return -1; };
|
|
return co.code;
|
|
};
|
|
|
|
fn cmpsepwork(label: str, csdir: str, wwdir: str) void = {
|
|
if (!testenv.isdir(csdir)) { fail(label, "no cs sepwork"); };
|
|
let names: []str = testenv.listdir(csdir);
|
|
let seen: i32 = 0;
|
|
let i: i32 = 0;
|
|
for (i < names.len) {
|
|
if (strings.hassuffix(names[i], ".s")
|
|
|| strings.hassuffix(names[i], ".wwi")) {
|
|
seen += 1;
|
|
if (!testenv.same(
|
|
testenv.readfile(strings.concat(csdir, "/", names[i])),
|
|
testenv.readfile(strings.concat(wwdir, "/", names[i])))) {
|
|
fail(label, strings.concat("cs!=ww for ", names[i],
|
|
" (rule 10)"));
|
|
};
|
|
};
|
|
i += 1;
|
|
};
|
|
// an existing-but-empty sepwork would pass the loop vacuously
|
|
if (seen == 0) { fail(label, "no .s/.wwi in cs sepwork"); };
|
|
};
|
|
|
|
fn runrow(label: str, src: str, path: str, expect: i32, byteid: bool,
|
|
reject: bool) void = {
|
|
let td: str = testenv.fresh();
|
|
let fixture: str = "";
|
|
if (path.len != 0) {
|
|
fixture = strings.concat(testenv.repo(), "/", path);
|
|
} else {
|
|
fixture = strings.concat(td, "/", label, ".ww");
|
|
testenv.writefile(fixture, src);
|
|
};
|
|
let cs: i32 = teststage(td, label, "ww", "cs", fixture);
|
|
let ws: i32 = teststage(td, label, "ww_ww", "ww", fixture);
|
|
if (reject) {
|
|
if (cs == 0 || ws == 0) {
|
|
fail(label, "accepted (expected reject on both stages)");
|
|
};
|
|
} else {
|
|
if (cs != expect || ws != expect) {
|
|
fail(label, "run-exit differs from expected on a stage");
|
|
};
|
|
};
|
|
if (byteid) {
|
|
let csdir: str = strings.concat(td, "/", label, ".cs.bin.sepwork");
|
|
let wwdir: str = strings.concat(td, "/", label, ".ww.bin.sepwork");
|
|
cmpsepwork(label, csdir, wwdir);
|
|
let rs: str = testenv.readfile(strings.concat(csdir, "/__root.s"));
|
|
if (!testenv.has(rs, "TEXT main")) {
|
|
fail(label, "__root.s lacks `TEXT main` (synth -T main missing)");
|
|
};
|
|
if (!testenv.has(rs, "CALL\ttest.run(SB)")) {
|
|
fail(label, strings.concat("__root.s lacks `CALL test.run(SB)` ",
|
|
"(qualified synth call missing)"));
|
|
};
|
|
};
|
|
testenv.clean(td);
|
|
};
|
|
|
|
@test fn pass() void = {
|
|
runrow("pass", passsrc(), "", 0, true, false);
|
|
};
|
|
|
|
@test fn failing() void = {
|
|
runrow("fail", failsrc(), "", 1, false, false);
|
|
};
|
|
|
|
@test fn userman() void = {
|
|
runrow("userman", "", "test/wcc/data/attest_userman.ww", 0, false, true);
|
|
};
|
|
|
|
@test fn badsig() void = {
|
|
runrow("badsig", "", "test/wcc/data/attest_badsig.ww", 0, false, true);
|
|
};
|
|
|
|
@test fn colliderun() void = {
|
|
runrow("collide_run", "", "test/wcc/data/attest_userrun.ww", 0, true,
|
|
false);
|
|
};
|