diff --git a/Makefile b/Makefile index fc7c4c3f..f67fa328 100644 --- a/Makefile +++ b/Makefile @@ -421,7 +421,8 @@ MISC_WW_TARGETS = $(MISC_WW_TESTS:%=wwtest/%) # test/sep: they run under test-compiler. TOOL_WW_TESTS = test/tool/rejects_test.ww test/tool/driver_test.ww \ test/tool/wwdump_test.ww test/tool/ffi_test.ww \ - test/tool/attest_test.ww test/tool/wwirune_test.ww + test/tool/attest_test.ww test/tool/wwirune_test.ww \ + test/tool/c6soak_test.ww TOOL_WW_TARGETS = $(TOOL_WW_TESTS:%=wwtest/%) BOOTSTRAP_WRAPPER_SOURCES = test/wcc/950_selfcheck.c \ test/wcc/991_w6a_ww.c \ diff --git a/test/tool/c6soak_test.ww b/test/tool/c6soak_test.ww new file mode 100644 index 00000000..f28f4535 --- /dev/null +++ b/test/tool/c6soak_test.ww @@ -0,0 +1,160 @@ +package c6soak_test; + +// M3-tail commit-6 separate-compilation soak gate (#46 c6, +// rob-c6-spec.md Tier-A/B + section-3 collision). Port of the retired +// native carrier test/wcc/989_c6soak_run.c; every assertion +// preserved at the carrier's own scale (real library chains, both +// driver stages, full per-file artifact compare). +// +// utf8 — a root importing encoding.utf8 (DOTTED path #57) + strings +// counts the runes of "héllo" via a decode/next match loop: +// build+run exit 5 on both stages. The C fixture embedded the e-acute +// as raw UTF-8 bytes; the generated source uses the \u00e9 escape, +// the same string bytes after lexing (escape decode owned by +// test/lang). +// +// collide — strings.contains AND bytes.contains, the SAME leaf +// exported by two packages (rob-c6-spec section 3, the #48/#49 class +// on real code): both true, exit 7 on both stages. +// +// cs==ww (rule 10) — EVERY per-package .s and .wwi in the cstage +// sepwork must be byte-identical to the wwstage same-named file, and +// at least ONE file must be compared (an empty sepwork would pass the +// loop vacuously). +// +// section-3 non-vacuity (collide only) — the cstage strings.s defines +// `TEXT strings.contains` and bytes.s `TEXT bytes.contains`: two +// genuinely DISTINCT path-qualified symbols, disambiguation real, not +// luck. +// +// The heavy Tier-C capstone (tool self-compile equivalence) stays +// folded into the 990-997 bootstrap oracle (994_w6c_ww), not here +// (rob-c6-spec section 2 / amendment-B). + +import os; +import os.exec; +import strings; +import testenv; +import time; + +fn fail(label: str, why: str) void = { + let m: str = strings.concat("c6soak FAIL: ", label, " -- ", why, + "\n"); + os.write(2, m.ptr, m.len: u64); + assert(false); +}; + +fn tmo() time.duration = { + return (240i64 * (time.second: i64)): time.duration; +}; + +fn runcode(dir: str, name: str, argv: []str) i32 = { + let co: testenv.commandout; + testenv.runcommand(dir, dir, name, argv, tmo(), &co); + if (co.termination != exec.termination.EXIT) { return -1; }; + return co.code; +}; + +// every .s/.wwi in csdir byte-identical in wwdir; at least one seen +fn cmpsepwork(label: str, csdir: str, wwdir: str) void = { + 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; + }; + if (seen == 0) { + fail(label, "no .s/.wwi in the cs sepwork (vacuous compare)"); + }; +}; + +fn soak(label: str, src: str, expect: i32, collide: bool) void = { + let td: str = testenv.fresh(); + let rootww: str = strings.concat(td, "/", label, ".ww"); + testenv.writefile(rootww, src); + // the real include set the sep producer needs for the lib + + // frontend package graph + let libinc: str = strings.concat(testenv.repo(), "/lib"); + let wwinc: str = strings.concat(testenv.repo(), "/lib/ww"); + let wccinc: str = strings.concat(testenv.repo(), "/selfhost/cmd/wcc"); + let drvs: []str = ["ww", "ww_ww"]; + let tags: []str = ["cs", "ww"]; + let s: i32 = 0; + for (s < 2) { + // `.bin` infix keeps the stage-`ww` output distinct from the + //