110 lines
3.5 KiB
Plaintext
110 lines
3.5 KiB
Plaintext
package enumcap_test;
|
|
|
|
// #65 (F13 c3) driver directory-enumerator capacity gate. Port of the
|
|
// retired native carrier test/wcc/989_enumcap_run.c; every assertion
|
|
// preserved. The module tree is GENERATED at runtime (301 files on the
|
|
// big row) -- it cannot be checked in as a fixture.
|
|
//
|
|
// Pre-c3 the wwstage enumeratedir silently capped at 256 files while
|
|
// cstage grows unbounded: a >256-file module dir bundled a silently
|
|
// divergent package unit under rc=0. Per row (big_300, small_5
|
|
// control), both driver builds must succeed, each stage's
|
|
// <stem>.sepwork/bigmod.unit.ww must hold EXACTLY nfiles
|
|
// line-anchored `package bigmod;` clauses, and the two units must be
|
|
// byte-identical (the decisive rule-10 leg -- a cap-drop on either
|
|
// side shrinks its unit).
|
|
//
|
|
// Dropped C machinery, not assertions: the ww_ww-absent skip gate
|
|
// (the Make target declares both drivers) and the per-file cleanup
|
|
// accounting (testenv.clean asserts the removal).
|
|
|
|
import os;
|
|
import os.exec;
|
|
import strconv;
|
|
import strings;
|
|
import testenv;
|
|
import time;
|
|
|
|
fn fail(label: str, why: str) void = {
|
|
let m: str = strings.concat("enumcap 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;
|
|
};
|
|
|
|
// itos returns a view into a static buffer; dup materializes it so two
|
|
// numbers can coexist in one concat.
|
|
fn dec(n: i32) str = {
|
|
return strings.dup(strconv.itos(n: int, strconv.base.DEC));
|
|
};
|
|
|
|
fn pad3(n: i32) str = {
|
|
let d: str = dec(n);
|
|
if (n < 10) { return strings.concat("00", d); };
|
|
if (n < 100) { return strings.concat("0", d); };
|
|
return d;
|
|
};
|
|
|
|
// line-anchored `package bigmod;` clause count; the '\n' prepend
|
|
// counts a file-leading clause too.
|
|
fn countpkg(path: str) i32 = {
|
|
let body: str = strings.concat("\n", testenv.readfile(path));
|
|
return testenv.occurrences(body, "\npackage bigmod;");
|
|
};
|
|
|
|
fn row(label: str, nfiles: i32) void = {
|
|
let td: str = testenv.fresh();
|
|
assert(os.mkdir(strings.concat(td, "/bigmod"), 493) == 0);
|
|
let i: i32 = 0;
|
|
for (i < nfiles) {
|
|
let nn: str = pad3(i);
|
|
testenv.writefile(strings.concat(td, "/bigmod/f", nn, ".ww"),
|
|
strings.concat("package bigmod;\nexport fn f", nn,
|
|
"() i32 = { return ", dec(i), "; };\n"));
|
|
i += 1;
|
|
};
|
|
let mainww: str = strings.concat(td, "/main.ww");
|
|
testenv.writefile(mainww,
|
|
"package main;\nimport bigmod;\nfn main() void = {};\n");
|
|
|
|
let drvs: []str = ["ww", "ww_ww"];
|
|
let stems: []str = ["X_c", "X_w"];
|
|
let units: []str = ["", ""];
|
|
let s: i32 = 0;
|
|
for (s < 2) {
|
|
let stem: str = strings.concat(td, "/", stems[s]);
|
|
let av: []str = [testenv.driver(drvs[s]), "build", "-o", stem,
|
|
mainww];
|
|
if (runcode(td, strings.concat("build_", stems[s]), av) != 0) {
|
|
fail(label, strings.concat(drvs[s], " build failed"));
|
|
};
|
|
units[s] = strings.concat(stem, ".sepwork/bigmod.unit.ww");
|
|
if (countpkg(units[s]) != nfiles) {
|
|
fail(label, strings.concat(drvs[s], " enrolled clause count ",
|
|
"!= nfiles (silent enumerator cap -- #65)"));
|
|
};
|
|
s += 1;
|
|
};
|
|
if (!testenv.same(testenv.readfile(units[0]),
|
|
testenv.readfile(units[1]))) {
|
|
fail(label, "cs/ww bigmod.unit.ww differ (#65)");
|
|
};
|
|
testenv.clean(td);
|
|
};
|
|
|
|
@test fn big_300() void = { row("big_300", 300); };
|
|
|
|
@test fn small_5() void = { row("small_5", 5); };
|