Every section banner dies (103 -> 0) across test/lang, the observer suites, the C carriers, and the five comment-heavy corpus fixtures; banner provenance (#N cites, carrier numbers, repair-cluster labels) folded into headers or adjacent WHY comments. Narration deleted; row provenance, ref cites, divergence pins, and layout contracts kept (fwd-ref decl-order guards and bootstrap-gate corpus rationale restored where the sweep over-cut). Comment-only proven: all 3742 wwbuild workdir .s byte-identical before/after; test-commit and test-byteid (161 lang + 1399 data, 0 pinned-divergent) green.
160 lines
5.2 KiB
Plaintext
160 lines
5.2 KiB
Plaintext
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;
|
|
};
|
|
|
|
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);
|
|
};
|