test: prove canonical directory test products
This commit is contained in:
@@ -736,7 +736,11 @@ fn rejectrow(td: str, label: str, src: str, expected: str) void = {
|
||||
let td: str = testenv.fresh();
|
||||
let tree: str = strings.concat(td, "/tree");
|
||||
assert(os.mkdir(tree, 493) == 0);
|
||||
let body: str = "package main;\n";
|
||||
let target: str = strings.concat(tree, "/target");
|
||||
let bridge: str = strings.concat(tree, "/bridge");
|
||||
assert(os.mkdir(target, 493) == 0);
|
||||
assert(os.mkdir(bridge, 493) == 0);
|
||||
let body: str = "package target;\n";
|
||||
let i: i32 = 0;
|
||||
for (i < 600) {
|
||||
let name: str = allocpkgname(i);
|
||||
@@ -747,63 +751,98 @@ fn rejectrow(td: str, label: str, src: str, expected: str) void = {
|
||||
body = strings.concat(body, "import _ ", name, ";\n");
|
||||
i += 1;
|
||||
};
|
||||
body = strings.concat(body, "fn main() i32 = { return 0; };\n");
|
||||
let src: str = strings.concat(td, "/main.ww");
|
||||
testenv.writefile(src, body);
|
||||
let wrapper: str = strings.concat(td, "/w6c-trace.sh");
|
||||
body = strings.concat(body,
|
||||
"export fn value() i32 = { return 41; };\n");
|
||||
testenv.writefile(strings.concat(target, "/target.ww"), body);
|
||||
testenv.writefile(strings.concat(target, "/same_test.ww"), strings.concat(
|
||||
"package target;\n",
|
||||
"export fn internal_helper() i32 = { return value(); };\n",
|
||||
"@test fn internal_runs() void = { assert(value() == 41); };\n"));
|
||||
testenv.writefile(strings.concat(bridge, "/bridge.ww"), strings.concat(
|
||||
"package bridge;\nimport target;\n",
|
||||
"export fn helper() i32 = { return target.internal_helper(); };\n"));
|
||||
testenv.writefile(strings.concat(target, "/external_test.ww"),
|
||||
strings.concat("package target_test;\nimport bridge;\nimport target;\n",
|
||||
"@test fn external_runs() void = {\n",
|
||||
" assert(target.internal_helper() == 41);\n",
|
||||
" assert(bridge.helper() == 41);\n};\n"));
|
||||
let wrapper: str = strings.concat(td, "/tool-trace.sh");
|
||||
testenv.writeexecutable(wrapper, strings.concat("#!/bin/sh\n",
|
||||
"printf x >> \"$WW_SEPINIT_W6C_TRACE\"\nexit 99\n"));
|
||||
"printf x >> \"$WW_SEPINIT_TOOL_TRACE\"\nexit 99\n"));
|
||||
let stages: []str = ["ww", "ww_ww"];
|
||||
let compilers: []str = ["w6c", "w6c_ww"];
|
||||
let launcher: str = testenv.driver("sep-limitexec");
|
||||
let found: bool = false;
|
||||
let last: str = "";
|
||||
let limit: i64 = 2621440i64;
|
||||
let li: i32 = 0;
|
||||
// Both implementations must reject under the same address-space ceiling.
|
||||
// Search a bounded same-limit ladder because loader mappings differ across
|
||||
// supported hosts; the 600-action graph makes the driver-allocation window
|
||||
// broad, while the compiler trace pins failure before the first tool.
|
||||
for (limit <= 16777216i64 && !found) {
|
||||
let limitstr: str = strconv.i64tos(limit, strconv.base.DEC);
|
||||
let good: [2]bool;
|
||||
let diags: [2]str;
|
||||
i = 0;
|
||||
for (i < stages.len) {
|
||||
let accepted: [2]str;
|
||||
let stagei: i32 = 0;
|
||||
// Address-space layouts differ, so each implementation searches its own
|
||||
// bounded ceiling. The accepted point must fail while constructing the
|
||||
// combined p/ptest/pxtest/pmain and transitive-clone graph, before any tool.
|
||||
for (stagei < stages.len) {
|
||||
let found: bool = false;
|
||||
let last: str = "";
|
||||
let limit: i64 = 2621440i64;
|
||||
let li: i32 = 0;
|
||||
for (limit <= 33554432i64 && !found) {
|
||||
let tag: str = allocpkgname(li);
|
||||
let trace: str = strings.concat(td, "/alloc-", stages[i], "-",
|
||||
let trace: str = strings.concat(td, "/alloc-", stages[stagei], "-",
|
||||
tag, ".trace");
|
||||
let work: str = strings.concat(td, "/alloc-work-", stages[stagei],
|
||||
"-", tag);
|
||||
let output: str = strings.concat(td, "/alloc-output-",
|
||||
stages[stagei], "-", tag);
|
||||
let status: str = strings.concat(td, "/alloc-status-",
|
||||
stages[stagei], "-", tag);
|
||||
testenv.writefile(trace, "");
|
||||
let env: []str = compilertraceenv(wrapper,
|
||||
testenv.driver(compilers[i]), trace);
|
||||
let output: str = strings.concat(td, "/alloc-", stages[i], "-",
|
||||
tag);
|
||||
let av: []str = [launcher, limitstr, testenv.driver(stages[i]),
|
||||
"build", "-I", tree, "-o", output, src];
|
||||
assert(os.mkdir(work, 493) == 0);
|
||||
let base: []str = os.getenvs();
|
||||
let env: []str = alloc([], (base.len + 4): u64)!;
|
||||
i = 0;
|
||||
for (i < base.len) {
|
||||
if (!strings.hasprefix(base[i], "WW_W6C=")
|
||||
&& !strings.hasprefix(base[i], "WW_W6A=")
|
||||
&& !strings.hasprefix(base[i], "WW_W6L=")
|
||||
&& !strings.hasprefix(base[i],
|
||||
"WW_SEPINIT_TOOL_TRACE=")) {
|
||||
append(env, base[i]);
|
||||
};
|
||||
i += 1;
|
||||
};
|
||||
append(env, strings.concat("WW_W6C=", wrapper));
|
||||
append(env, strings.concat("WW_W6A=", wrapper));
|
||||
append(env, strings.concat("WW_W6L=", wrapper));
|
||||
append(env, strings.concat("WW_SEPINIT_TOOL_TRACE=", trace));
|
||||
let limitstr: str = strconv.i64tos(limit, strconv.base.DEC);
|
||||
let av: []str = [launcher, limitstr, testenv.driver(stages[stagei]),
|
||||
"test", "-c", "-w", work, "-I", tree,
|
||||
"--ww-package-test", "test", "target", "target", "target",
|
||||
"target_test", target, output, status, target];
|
||||
let out: testenv.commandout;
|
||||
runenv(td, strings.concat("allocation-", stages[i], "-", tag),
|
||||
runenv(td, strings.concat("allocation-", stages[stagei], "-", tag),
|
||||
av, env, &out);
|
||||
last = strings.dup(out.stderr);
|
||||
good[i] = exitcode(&out) == 1 && testenv.same(out.stderr,
|
||||
"ww: out of memory\n")
|
||||
&& testenv.readfile(trace).len == 0;
|
||||
diags[i] = strings.dup(out.stderr);
|
||||
if (testenv.exists(output) || testenv.exists(strings.concat(output,
|
||||
".sepwork"))) {
|
||||
if (testenv.listdir(work).len != 0
|
||||
|| nofollowexists(output)
|
||||
|| nofollowexists(strings.concat(output, ".new"))
|
||||
|| nofollowexists(strings.concat(output, ".sepwork"))
|
||||
|| nofollowexists(status)
|
||||
|| nofollowexists(strings.concat(status, ".new"))) {
|
||||
fail("allocation", "failed pressure leg published state");
|
||||
};
|
||||
i += 1;
|
||||
};
|
||||
if (good[0] && good[1]) {
|
||||
if (!testenv.same(diags[0], diags[1])) {
|
||||
fail("allocation", "C/WW allocation diagnostic mismatch");
|
||||
if (exitcode(&out) == 1 && out.stdout.len == 0
|
||||
&& testenv.same(out.stderr, "ww: out of memory\n")
|
||||
&& testenv.readfile(trace).len == 0) {
|
||||
accepted[stagei] = strings.dup(out.stderr);
|
||||
found = true;
|
||||
};
|
||||
found = true;
|
||||
testenv.clean(work);
|
||||
limit += 131072i64;
|
||||
li += 1;
|
||||
};
|
||||
limit += 131072i64;
|
||||
li += 1;
|
||||
if (!found) { fail("allocation", last); };
|
||||
stagei += 1;
|
||||
};
|
||||
if (!testenv.same(accepted[0], accepted[1])) {
|
||||
fail("allocation", "C/WW allocation diagnostic mismatch");
|
||||
};
|
||||
if (!found) { fail("allocation", last); };
|
||||
testenv.clean(td);
|
||||
};
|
||||
|
||||
@@ -932,16 +971,12 @@ fn rejectrow(td: str, label: str, src: str, expected: str) void = {
|
||||
let tags: []str = ["c", "ww"];
|
||||
let reference: str = "";
|
||||
let variantnames: []str = [
|
||||
"widget-internal-test-main.init.unit.ww",
|
||||
"widget-internal-test-main.init.s",
|
||||
"widget-internal-test-main.init.o",
|
||||
"widget-internal-test-main.a",
|
||||
"widget_test-external-test-main.init.unit.ww",
|
||||
"widget_test-external-test-main.init.s",
|
||||
"widget_test-external-test-main.init.o",
|
||||
"widget_test-external-test-main.a",
|
||||
"widget-test-main.init.unit.ww",
|
||||
"widget-test-main.init.s",
|
||||
"widget-test-main.init.o",
|
||||
"widget-test-main.a",
|
||||
];
|
||||
let variantrefs: []str = ["", "", "", "", "", "", "", ""];
|
||||
let variantrefs: []str = ["", "", "", ""];
|
||||
let i: i32 = 0;
|
||||
for (i < 2) {
|
||||
let work: str = strings.concat(td, "/test-work-", tags[i]);
|
||||
@@ -967,61 +1002,45 @@ fn rejectrow(td: str, label: str, src: str, expected: str) void = {
|
||||
let rr: i32 = testenv.pos(out.stdout, "<R>");
|
||||
let ii: i32 = testenv.pos(out.stdout, "<I>");
|
||||
let tt: i32 = testenv.pos(out.stdout, "<T>");
|
||||
let tail: str = "";
|
||||
if (tt >= 0) { tail = strings.sub(out.stdout, tt + 3, out.stdout.len); };
|
||||
let de: i32 = testenv.pos(tail, "<D>");
|
||||
let pe: i32 = testenv.pos(tail, "<P>");
|
||||
let w: i32 = testenv.pos(tail, "<W>");
|
||||
let e: i32 = testenv.pos(tail, "<E>");
|
||||
let x: i32 = testenv.pos(tail, "<X>");
|
||||
if (!(d >= 0 && d < q && q < rr && rr < p && p < ii && ii < tt
|
||||
&& de >= 0 && de < pe && pe < w && w < e && e < x)) {
|
||||
let w: i32 = testenv.pos(out.stdout, "<W>");
|
||||
let e: i32 = testenv.pos(out.stdout, "<E>");
|
||||
let x: i32 = testenv.pos(out.stdout, "<X>");
|
||||
if (!(d >= 0 && d < q && q < rr && rr < p && p < ii && ii < w
|
||||
&& w < e && e < tt && tt < x)) {
|
||||
fail("variants", strings.concat("test init order: ", out.stdout));
|
||||
};
|
||||
if (testenv.occurrences(out.stdout, "<Q>") != 1
|
||||
|| testenv.occurrences(out.stdout, "<D>") != 2
|
||||
|| testenv.occurrences(out.stdout, "<D>") != 1
|
||||
|| testenv.occurrences(out.stdout, "<R>") != 1
|
||||
|| testenv.occurrences(out.stdout, "<W>") != 1
|
||||
|| testenv.occurrences(out.stdout, "<I>") != 1
|
||||
|| testenv.occurrences(out.stdout, "<E>") != 1
|
||||
|| testenv.occurrences(out.stdout, "<P>") != 2) {
|
||||
|| testenv.occurrences(out.stdout, "<P>") != 1) {
|
||||
fail("variants", "variant initialization count");
|
||||
};
|
||||
let internal: str = testenv.readfile(strings.concat(work,
|
||||
"/widget-internal-test-main.init.unit.ww"));
|
||||
if (testenv.occurrences(internal,
|
||||
let dispatcher: str = testenv.readfile(strings.concat(work,
|
||||
"/widget-test-main.init.unit.ww"));
|
||||
if (testenv.occurrences(dispatcher,
|
||||
"__ww..pkg.p.testside.v0.r0.init") != 1
|
||||
|| testenv.occurrences(internal,
|
||||
|| testenv.occurrences(dispatcher,
|
||||
"__ww..pkg.p.prodside.v0.r0.init") != 1
|
||||
|| testenv.occurrences(internal,
|
||||
|| testenv.occurrences(dispatcher,
|
||||
"__ww..pkg.p.widget.v1.r0.init") != 1
|
||||
|| testenv.occurrences(internal,
|
||||
"__ww..pkg.p.test.v0.r0.init") != 1
|
||||
|| testenv.occurrences(internal,
|
||||
"//ww:init-call __ww..pkg.p.__wwtestmain.widget.internal.main.v3.r2.init") != 1
|
||||
|| testenv.pos(internal, "__ww..pkg.p.test.v0.r0.init")
|
||||
>= testenv.pos(internal,
|
||||
"//ww:init-call __ww..pkg.p.__wwtestmain.widget.internal.main.v3.r2.init")
|
||||
|| testenv.has(internal, "__ww..pkg.p.widget.v0.r0.init")) {
|
||||
fail("variants", "internal variant dispatcher ownership");
|
||||
};
|
||||
let external: str = testenv.readfile(strings.concat(work,
|
||||
"/widget_test-external-test-main.init.unit.ww"));
|
||||
if (testenv.occurrences(external,
|
||||
"__ww..pkg.p.widget.v0.r0.init") != 1
|
||||
|| testenv.occurrences(external,
|
||||
"__ww..pkg.p.prodside.v0.r0.init") != 1
|
||||
|| testenv.occurrences(external,
|
||||
|| testenv.occurrences(dispatcher,
|
||||
"__ww..pkg.p.widget_test.v2.r0.init") != 1
|
||||
|| testenv.occurrences(external,
|
||||
|| testenv.occurrences(dispatcher,
|
||||
"__ww..pkg.p.test.v0.r0.init") != 1
|
||||
|| testenv.occurrences(external,
|
||||
"//ww:init-call __ww..pkg.p.__wwtestmain.widget_test.external.main.v3.r2.init") != 1
|
||||
|| testenv.pos(external, "__ww..pkg.p.test.v0.r0.init")
|
||||
>= testenv.pos(external,
|
||||
"//ww:init-call __ww..pkg.p.__wwtestmain.widget_test.external.main.v3.r2.init")
|
||||
|| testenv.has(external, "testside")) {
|
||||
fail("variants", "external variant dispatcher ownership");
|
||||
|| testenv.occurrences(dispatcher,
|
||||
"//ww:init-call __ww..pkg.p.__wwtestmain.widget.main.v3.r2.init") != 1
|
||||
|| testenv.pos(dispatcher, "__ww..pkg.p.widget.v1.r0.init")
|
||||
>= testenv.pos(dispatcher,
|
||||
"__ww..pkg.p.widget_test.v2.r0.init")
|
||||
|| testenv.pos(dispatcher,
|
||||
"__ww..pkg.p.widget_test.v2.r0.init")
|
||||
>= testenv.pos(dispatcher,
|
||||
"//ww:init-call __ww..pkg.p.__wwtestmain.widget.main.v3.r2.init")
|
||||
|| testenv.has(dispatcher, "__ww..pkg.p.widget.v0.r0.init")) {
|
||||
fail("variants", "directory test dispatcher ownership");
|
||||
};
|
||||
let directstdout: str = strings.dup(out.stdout);
|
||||
let recursivework: str = strings.concat(td, "/test-recursive-work-",
|
||||
@@ -1100,7 +1119,7 @@ fn rejectrow(td: str, label: str, src: str, expected: str) void = {
|
||||
av, env, tmo(), &out);
|
||||
if (exitcode(&out) == 0
|
||||
|| !testenv.has(out.stderr,
|
||||
"ww: dependency cycle in initialization closure")
|
||||
"ww: dependency cycle: p -> q -> r -> p")
|
||||
|| testenv.readfile(trace).len != 0
|
||||
|| testenv.listdir(work).len != 0) {
|
||||
fail("test-cycle", out.stderr);
|
||||
|
||||
Reference in New Issue
Block a user