228 lines
8.1 KiB
Plaintext
228 lines
8.1 KiB
Plaintext
package direnum_test;
|
|
|
|
// Directory-package loader observers on both driver stages. Port of
|
|
// the retired native carrier test/wcc/737_direnum.c; every assertion
|
|
// preserved, the bad/bad-deep rows strengthened with the stderr
|
|
// parity leg the C carrier reserved for the reject table.
|
|
//
|
|
// okrun — the in-repo tree test/wcc/data/direnum/ (entry imports
|
|
// multi-file dir ok/ with a.ww+b.ww both package ok, cross-pkg
|
|
// bare-leaf calls): `ww run` exits 0 on BOTH stages.
|
|
//
|
|
// conflict — bad_entry.ww imports a dir with conflicting `package`
|
|
// clauses; bad_deep_entry.ww the same with one clause behind a
|
|
// >2048-byte comment header (the loader's whole-source header read).
|
|
// Both stages must FAIL with "conflicting package names", and the
|
|
// two stages' diagnostics must be byte-identical.
|
|
//
|
|
// rootorder — a private rootok/ command dir built DIRECTLY (z.ww ORDER-Z
|
|
// value()=17 vs a.ww ORDER-A leading comment + main): build exit 0,
|
|
// the binary exits 17, and the driver's local-identity owner unit
|
|
// stores ORDER-A strictly before ORDER-Z (byte-sorted deterministic
|
|
// source order); the two stages' units are byte-identical.
|
|
//
|
|
// rejects — the authoritative loader-reject table over private trees:
|
|
// root-conflict ("conflicting package names"), root-missing and
|
|
// root-invalid ("invalid or missing package clause"), attest-noncanon
|
|
// ("@test declaration outside *_test.ww" — Go's test-file contract);
|
|
// per row both stages fail, carry the needle, and their captured stderr is
|
|
// byte-identical. The former import-leaf rejection is now an accepted
|
|
// path/name-decoupling case and uses the imported declaration as qualifier.
|
|
//
|
|
// Dropped C machinery, not assertions: the ww_ww-absent skip gate
|
|
// (the Make target declares both drivers) and the unlink/rmdir
|
|
// accounting (testenv.clean asserts the removal).
|
|
|
|
import os;
|
|
import os.exec;
|
|
import strings;
|
|
import testenv;
|
|
import time;
|
|
|
|
fn fail(label: str, why: str) void = {
|
|
let m: str = strings.concat("direnum 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;
|
|
};
|
|
|
|
// -1 encodes an abnormal (non-EXIT) termination, never a valid code.
|
|
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 datasrc(name: str) str = {
|
|
return strings.concat(testenv.repo(), "/test/wcc/data/direnum/",
|
|
name);
|
|
};
|
|
|
|
@test fn okrun() void = {
|
|
let td: str = testenv.fresh();
|
|
let src: str = datasrc("entry.ww");
|
|
let drvs: []str = ["ww", "ww_ww"];
|
|
let s: i32 = 0;
|
|
for (s < 2) {
|
|
let av: []str = [testenv.driver(drvs[s]), "run", src];
|
|
if (runcode(td, strings.concat("run_", drvs[s]), av) != 0) {
|
|
fail("okrun", strings.concat(drvs[s], " run failed on the ",
|
|
"multi-file imported dir (cross-pkg bare-leaf calls)"));
|
|
};
|
|
s += 1;
|
|
};
|
|
testenv.clean(td);
|
|
};
|
|
|
|
// A build expected to FAIL with `needle` on both stages, diagnostics
|
|
// byte-identical across stages.
|
|
fn rejectpair(label: str, td: str, target: str, needle: str) void = {
|
|
let drvs: []str = ["ww", "ww_ww"];
|
|
let errs: []str = ["", ""];
|
|
let s: i32 = 0;
|
|
for (s < 2) {
|
|
let out: str = strings.concat(td, "/", label, "-", drvs[s]);
|
|
let co: testenv.commandout;
|
|
let av: []str = [testenv.driver(drvs[s]), "build", "-o", out,
|
|
target];
|
|
testenv.runcommand(td, td,
|
|
strings.concat(label, "_", drvs[s]), av, tmo(), &co);
|
|
if (co.termination != exec.termination.EXIT || co.code == 0) {
|
|
fail(label, strings.concat(drvs[s],
|
|
" expected build failure, succeeded"));
|
|
};
|
|
if (!testenv.has(co.stderr, needle)) {
|
|
fail(label, strings.concat(drvs[s], " stderr missing '",
|
|
needle, "'"));
|
|
};
|
|
errs[s] = co.stderr;
|
|
s += 1;
|
|
};
|
|
if (!testenv.same(errs[0], errs[1])) {
|
|
fail(label, "C/WW diagnostics differ");
|
|
};
|
|
};
|
|
|
|
@test fn conflict() void = {
|
|
let td: str = testenv.fresh();
|
|
rejectpair("bad", td, datasrc("bad_entry.ww"),
|
|
"conflicting package names");
|
|
rejectpair("bad-deep", td, datasrc("bad_deep_entry.ww"),
|
|
"conflicting package names");
|
|
testenv.clean(td);
|
|
};
|
|
|
|
@test fn rootorder() void = {
|
|
let td: str = testenv.fresh();
|
|
let rootok: str = strings.concat(td, "/rootok");
|
|
assert(os.mkdir(rootok, 493) == 0);
|
|
testenv.writefile(strings.concat(rootok, "/z.ww"), strings.concat(
|
|
"package main;\n// ORDER-Z\n",
|
|
"fn value() i32 = { return 17; };\n"));
|
|
testenv.writefile(strings.concat(rootok, "/a.ww"), strings.concat(
|
|
"// leading comment is part of the loader grammar\n",
|
|
"package main;\n// ORDER-A\n",
|
|
"fn main() i32 = { return value(); };\n"));
|
|
let drvs: []str = ["ww", "ww_ww"];
|
|
let identity: str = testenv.localpackageidentity(rootok, "main");
|
|
let units: []str = ["", ""];
|
|
let s: i32 = 0;
|
|
for (s < 2) {
|
|
let out: str = strings.concat(td, "/root-", drvs[s]);
|
|
let av: []str = [testenv.driver(drvs[s]), "build", "-o", out,
|
|
rootok];
|
|
if (runcode(td, strings.concat("build_", drvs[s]), av) != 0) {
|
|
fail("rootorder", strings.concat(drvs[s],
|
|
" direct dir build failed"));
|
|
};
|
|
let rav: []str = [out];
|
|
if (runcode(td, strings.concat("run_", drvs[s]), rav) != 17) {
|
|
fail("rootorder", strings.concat(drvs[s], " exit != 17"));
|
|
};
|
|
units[s] = testenv.readfile(strings.concat(out,
|
|
".sepwork/", identity, ".unit.ww"));
|
|
let a: i32 = testenv.pos(units[s], "ORDER-A");
|
|
let z: i32 = testenv.pos(units[s], "ORDER-Z");
|
|
if (a < 0 || z < 0 || a >= z) {
|
|
fail("rootorder", strings.concat(drvs[s],
|
|
" stored sources are not byte-sorted"));
|
|
};
|
|
s += 1;
|
|
};
|
|
if (!testenv.same(units[0], units[1])) {
|
|
fail("rootorder", "C/WW local root units differ");
|
|
};
|
|
testenv.clean(td);
|
|
};
|
|
|
|
@test fn rejects() void = {
|
|
let td: str = testenv.fresh();
|
|
let rootbad: str = strings.concat(td, "/rootbad");
|
|
let importbad: str = strings.concat(td, "/importbad");
|
|
let wanted: str = strings.concat(importbad, "/wanted");
|
|
let missing: str = strings.concat(td, "/missing");
|
|
let invalid: str = strings.concat(td, "/invalid");
|
|
let attbad: str = strings.concat(td, "/attbad");
|
|
assert(os.mkdir(rootbad, 493) == 0);
|
|
assert(os.mkdir(importbad, 493) == 0);
|
|
assert(os.mkdir(wanted, 493) == 0);
|
|
assert(os.mkdir(missing, 493) == 0);
|
|
assert(os.mkdir(invalid, 493) == 0);
|
|
assert(os.mkdir(attbad, 493) == 0);
|
|
testenv.writefile(strings.concat(rootbad, "/a.ww"),
|
|
"package rootbad;\nfn main() i32 = { return 0; };\n");
|
|
testenv.writefile(strings.concat(rootbad, "/b.ww"),
|
|
"package other;\nfn spare() i32 = { return 0; };\n");
|
|
testenv.writefile(strings.concat(importbad, "/entry.ww"),
|
|
strings.concat("package main;\nimport wanted;\n",
|
|
"fn main() i32 = { return other.value(); };\n"));
|
|
testenv.writefile(strings.concat(wanted, "/a.ww"),
|
|
"package other;\nexport fn value() i32 = { return 0; };\n");
|
|
testenv.writefile(strings.concat(missing, "/a.ww"),
|
|
"fn main() i32 = { return 0; };\n");
|
|
testenv.writefile(strings.concat(invalid, "/a.ww"),
|
|
"package 7bad;\nfn main() i32 = { return 0; };\n");
|
|
testenv.writefile(strings.concat(attbad, "/a.ww"),
|
|
"package attbad;\nfn main() i32 = { return 0; };\n");
|
|
testenv.writefile(strings.concat(attbad, "/t.ww"), strings.concat(
|
|
"package attbad;\n",
|
|
"@test fn hidden() void = { assert(false); };\n"));
|
|
|
|
let drvs: []str = ["ww", "ww_ww"];
|
|
let s: i32 = 0;
|
|
for (s < drvs.len) {
|
|
let out: str = strings.concat(td, "/import-name-", drvs[s]);
|
|
let av: []str = [testenv.driver(drvs[s]), "build", "-o", out,
|
|
strings.concat(importbad, "/entry.ww")];
|
|
if (runcode(td, strings.concat("import-name-build-", drvs[s]), av)
|
|
!= 0) {
|
|
fail("import-name", strings.concat(drvs[s], " build failed"));
|
|
};
|
|
let rav: []str = [out];
|
|
if (runcode(td, strings.concat("import-name-run-", drvs[s]), rav)
|
|
!= 0) {
|
|
fail("import-name", strings.concat(drvs[s], " run failed"));
|
|
};
|
|
s += 1;
|
|
};
|
|
|
|
let tags: []str = ["root-conflict", "root-missing",
|
|
"root-invalid", "attest-noncanon"];
|
|
let targets: []str = [rootbad, missing, invalid, attbad];
|
|
let needles: []str = ["conflicting package names",
|
|
"invalid or missing package clause",
|
|
"invalid or missing package clause",
|
|
"@test declaration outside *_test.ww"];
|
|
let r: i32 = 0;
|
|
for (r < tags.len) {
|
|
rejectpair(tags[r], td, targets[r], needles[r]);
|
|
r += 1;
|
|
};
|
|
testenv.clean(td);
|
|
};
|