test: port the c6 sep soak to ww; retire 989_c6soak_run
This commit is contained in:
160
test/tool/c6soak_test.ww
Normal file
160
test/tool/c6soak_test.ww
Normal file
@@ -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
|
||||
// <label>.ww SOURCE (else the build clobbers its own input)
|
||||
let prog: str = strings.concat(td, "/", label, ".", tags[s],
|
||||
".bin");
|
||||
let av: []str = [testenv.driver(drvs[s]), "build",
|
||||
"-I", libinc, "-I", wwinc, "-I", wccinc, "-o", prog, rootww];
|
||||
if (runcode(td, strings.concat("build_", tags[s]), av) != 0) {
|
||||
fail(label, strings.concat(drvs[s], " build failed"));
|
||||
};
|
||||
let rav: []str = [prog];
|
||||
if (runcode(td, strings.concat("run_", tags[s]), rav) != expect) {
|
||||
fail(label, strings.concat(drvs[s],
|
||||
" run exit != expected"));
|
||||
};
|
||||
s += 1;
|
||||
};
|
||||
|
||||
let csdir: str = strings.concat(td, "/", label, ".cs.bin.sepwork");
|
||||
let wwdir: str = strings.concat(td, "/", label, ".ww.bin.sepwork");
|
||||
cmpsepwork(label, csdir, wwdir);
|
||||
|
||||
if (collide) {
|
||||
if (!testenv.has(testenv.readfile(strings.concat(csdir,
|
||||
"/strings.s")), "TEXT strings.contains")) {
|
||||
fail(label, strings.concat("strings.s lacks `TEXT ",
|
||||
"strings.contains` (section-3 disambiguation)"));
|
||||
};
|
||||
if (!testenv.has(testenv.readfile(strings.concat(csdir,
|
||||
"/bytes.s")), "TEXT bytes.contains")) {
|
||||
fail(label, strings.concat("bytes.s lacks `TEXT ",
|
||||
"bytes.contains` (section-3 disambiguation)"));
|
||||
};
|
||||
};
|
||||
testenv.clean(td);
|
||||
};
|
||||
|
||||
@test fn utf8() void = {
|
||||
soak("utf8", strings.concat(
|
||||
"package main;\n",
|
||||
"import encoding.utf8;\n",
|
||||
"import strings;\n",
|
||||
"fn main() i32 = {\n",
|
||||
" let d = utf8.decode(strings.toutf8(\"h\\u00e9llo\"));\n",
|
||||
" let n: i32 = 0;\n",
|
||||
" for (true) {\n",
|
||||
" match (utf8.next(&d)) {\n",
|
||||
" case rune => n += 1;\n",
|
||||
" case => break;\n",
|
||||
" };\n",
|
||||
" };\n",
|
||||
" return n;\n",
|
||||
"};\n"), 5, false);
|
||||
};
|
||||
|
||||
@test fn collide() void = {
|
||||
soak("collide", strings.concat(
|
||||
"package main;\n",
|
||||
"import strings;\n",
|
||||
"import bytes;\n",
|
||||
"fn main() i32 = {\n",
|
||||
" let s = strings.contains(\"hello\", \"ell\");\n",
|
||||
" let b = bytes.contains(strings.toutf8(\"hello\"), ",
|
||||
"strings.toutf8(\"ell\"));\n",
|
||||
" if (s && b) { return 7; };\n",
|
||||
" return 1;\n",
|
||||
"};\n"), 7, true);
|
||||
};
|
||||
Reference in New Issue
Block a user