test: accept empty skip reasons
This commit is contained in:
@@ -18689,3 +18689,355 @@ fn runtimepath(relative: str) str = {
|
||||
&& !directoryhasfragment(root, ".install"));
|
||||
clean(root);
|
||||
};
|
||||
|
||||
// A skip is an outcome even when it carries no explanatory bytes. Keep that
|
||||
// boundary identical through every directory-package test descriptor and the
|
||||
// retained-binary route; an empty payload must not become a harness error.
|
||||
@test fn empty_skip_reason_is_a_successful_skip() void = {
|
||||
let root: str = fresh();
|
||||
let mixed: str = strings.concat(root, "/mixed");
|
||||
let only: str = strings.concat(root, "/only");
|
||||
let raw: str = strings.concat(root, "/raw_test.ww");
|
||||
let oversized: str = strings.concat(root, "/oversized");
|
||||
let outside: str = strings.concat(root, "/outside");
|
||||
mkdirall(mixed);
|
||||
mkdirall(only);
|
||||
mkdirall(oversized);
|
||||
mkdirall(outside);
|
||||
writefile(strings.concat(mixed, "/prod.ww"), strings.concat(
|
||||
"package skipmix;\n",
|
||||
"import test;\n",
|
||||
"export fn value() i32 = { return 7; };\n",
|
||||
"export fn skip_from_production() never = { test.skip(\"\"); };\n"));
|
||||
writefile(strings.concat(mixed, "/same_test.ww"), strings.concat(
|
||||
"package skipmix;\n",
|
||||
"import test;\n",
|
||||
"@test fn aa_empty_production() void = { skip_from_production(); };\n",
|
||||
"@test fn aa_empty_same() void = { test.skip(\"\"); };\n",
|
||||
"@test fn ab_same_peer() void = { assert(value() == 7); };\n",
|
||||
"@test fn ac_named_same() void = { test.skip(\"named reason\"); };\n"));
|
||||
writefile(strings.concat(mixed, "/external_test.ww"), strings.concat(
|
||||
"package skipmix_test;\n",
|
||||
"import skipmix;\n",
|
||||
"import test;\n",
|
||||
"@test fn ad_empty_external() void = {\n",
|
||||
" assert(skipmix.value() == 7); test.skip(\"\");\n",
|
||||
"};\n",
|
||||
"@test fn ae_external_peer() void = {\n",
|
||||
" assert(skipmix.value() == 7);\n",
|
||||
"};\n"));
|
||||
writefile(strings.concat(only, "/only_test.ww"), strings.concat(
|
||||
"package skiponly;\n",
|
||||
"import test;\n",
|
||||
"@test fn aa_empty_test_only() void = { test.skip(\"\"); };\n",
|
||||
"@test fn ab_test_only_peer() void = { assert(true); };\n"));
|
||||
writefile(raw, strings.concat(
|
||||
"package rawskip;\n",
|
||||
"import test;\n",
|
||||
"@test fn aa_empty_raw() void = { test.skip(\"\"); };\n",
|
||||
"@test fn ab_raw_peer() void = { assert(true); };\n"));
|
||||
writefile(strings.concat(oversized, "/oversized_test.ww"), strings.concat(
|
||||
"package skipoversized;\n",
|
||||
"import strings;\n",
|
||||
"import test;\n",
|
||||
"@test fn too_large() void = {\n",
|
||||
" let reason: []u8 = alloc([], 4094u64)!; reason.len = 4094;\n",
|
||||
" let i: i32 = 0; for (i < reason.len) { reason[i] = 'x'; i += 1; };\n",
|
||||
" test.skip(strings.frombytes(reason));\n",
|
||||
"};\n"));
|
||||
writefile(strings.concat(outside, "/main.ww"), strings.concat(
|
||||
"package main;\n",
|
||||
"import test;\n",
|
||||
"fn main() void = { test.skip(\"\"); };\n"));
|
||||
|
||||
let stages: []str = ["ww", "ww_ww"];
|
||||
let tags: []str = ["c", "ww"];
|
||||
let works: []str = [strings.concat(root, "/work-c"),
|
||||
strings.concat(root, "/work-ww")];
|
||||
let oversizedworks: []str = [strings.concat(root, "/oversized-work-c"),
|
||||
strings.concat(root, "/oversized-work-ww")];
|
||||
let outsideworks: []str = [strings.concat(root, "/outside-work-c"),
|
||||
strings.concat(root, "/outside-work-ww")];
|
||||
let outsidebins: []str = [strings.concat(root, "/outside-c"),
|
||||
strings.concat(root, "/outside-ww")];
|
||||
let retained: []str = [strings.concat(root, "/retained-c.test"),
|
||||
strings.concat(root, "/retained-ww.test")];
|
||||
let runningretained: []str = [strings.concat(root, "/running-c.test"),
|
||||
strings.concat(root, "/running-ww.test")];
|
||||
let ordinaryout: []str = ["", ""];
|
||||
let ordinaryerr: []str = ["", ""];
|
||||
let emptyout: []str = ["", ""];
|
||||
let emptyerr: []str = ["", ""];
|
||||
let passout: []str = ["", ""];
|
||||
let passerr: []str = ["", ""];
|
||||
let listout: []str = ["", ""];
|
||||
let listerr: []str = ["", ""];
|
||||
let rawout: []str = ["", ""];
|
||||
let rawerr: []str = ["", ""];
|
||||
let oversizedout: []str = ["", ""];
|
||||
let oversizederr: []str = ["", ""];
|
||||
let runningout: []str = ["", ""];
|
||||
let runningerr: []str = ["", ""];
|
||||
let compileout: []str = ["", ""];
|
||||
let compileerr: []str = ["", ""];
|
||||
let directout: []str = ["", ""];
|
||||
let directerr: []str = ["", ""];
|
||||
let outsideout: []str = ["", ""];
|
||||
let outsideerr: []str = ["", ""];
|
||||
let out: commandout;
|
||||
let si: i32 = 0;
|
||||
for (si < stages.len) {
|
||||
mkdirall(outsideworks[si]);
|
||||
// An ordinary product may import the shared test library. Its artifact
|
||||
// therefore participates in normal content invalidation, while invoking
|
||||
// skip without an active test retains the preexisting abort boundary.
|
||||
let outsidebuildav: []str = [driver(stages[si]), "build", "-w",
|
||||
outsideworks[si], "-o", outsidebins[si], outside];
|
||||
runcommand(root, strings.concat("empty-skip-outside-build-", tags[si]),
|
||||
outsidebuildav, (120i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 0);
|
||||
assert(out.stdout.len == 0 && out.stderr.len == 0
|
||||
&& os.exists(outsidebins[si]));
|
||||
let outsiderunav: []str = [outsidebins[si]];
|
||||
runcommand(root, strings.concat("empty-skip-outside-run-", tags[si]),
|
||||
outsiderunav, (30i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 1);
|
||||
assert(out.stdout.len == 0
|
||||
&& same(out.stderr, "test.skip called outside a test"));
|
||||
outsideout[si] = strings.dup(out.stdout);
|
||||
outsideerr[si] = strings.dup(out.stderr);
|
||||
assert(!directoryhasnew(outsideworks[si])
|
||||
&& !directoryhasfragment(outsideworks[si], ".wwtxn.")
|
||||
&& !directoryhasfragment(outsideworks[si], ".install"));
|
||||
|
||||
let ordinaryav: []str = [driver(stages[si]), "test", "-w",
|
||||
works[si], "-I", root, mixed, only];
|
||||
runcommand(root, strings.concat("empty-skip-ordinary-cold-", tags[si]),
|
||||
ordinaryav, (120i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 0);
|
||||
assert(out.stderr.len == 0);
|
||||
assert(occurrences(out.stdout,
|
||||
"skipmix.aa_empty_production ... SKIP: \n") == 1);
|
||||
assert(occurrences(out.stdout,
|
||||
"skipmix.aa_empty_same ... SKIP: \n") == 1);
|
||||
assert(occurrences(out.stdout,
|
||||
"skipmix.ad_empty_external ... SKIP: \n") == 1);
|
||||
assert(occurrences(out.stdout,
|
||||
"skiponly.aa_empty_test_only ... SKIP: \n") == 1);
|
||||
assert(occurrences(out.stdout,
|
||||
"skipmix.ac_named_same ... SKIP: named reason\n") == 1);
|
||||
assert(occurrences(out.stdout,
|
||||
"skipmix.ab_same_peer ... ok\n") == 1);
|
||||
assert(occurrences(out.stdout,
|
||||
"skipmix.ae_external_peer ... ok\n") == 1);
|
||||
assert(occurrences(out.stdout,
|
||||
"skiponly.ab_test_only_peer ... ok\n") == 1);
|
||||
assert(pos(out.stdout, "skipmix.aa_empty_same ... SKIP: \n")
|
||||
< pos(out.stdout, "skipmix.ab_same_peer ... ok\n"));
|
||||
assert(occurrences(out.stdout,
|
||||
"2 passed, 0 failed, 4 skipped, 0 harness errors\n") == 1);
|
||||
assert(occurrences(out.stdout,
|
||||
"6 discovered, 6 selected, 6 started, 6 completed\n") == 1);
|
||||
assert(occurrences(out.stdout,
|
||||
"1 passed, 0 failed, 1 skipped, 0 harness errors\n") == 1);
|
||||
assert(occurrences(out.stdout,
|
||||
"2 discovered, 2 selected, 2 started, 2 completed\n") == 1);
|
||||
assert(occurrences(out.stdout, strings.concat("ok ", mixed,
|
||||
" [skipmix]\n")) == 1);
|
||||
assert(occurrences(out.stdout, strings.concat("ok ", only,
|
||||
" [skiponly]\n")) == 1);
|
||||
assert(!has(out.stdout, "HARNESS"));
|
||||
ordinaryout[si] = strings.dup(out.stdout);
|
||||
ordinaryerr[si] = strings.dup(out.stderr);
|
||||
|
||||
// Exact repetition against persisted work preserves the externally
|
||||
// visible result and leaves no transactional residue.
|
||||
runcommand(root, strings.concat("empty-skip-ordinary-warm-", tags[si]),
|
||||
ordinaryav, (120i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 0);
|
||||
assert(same(out.stdout, ordinaryout[si]));
|
||||
assert(same(out.stderr, ordinaryerr[si]));
|
||||
assert(!directoryhasnew(works[si])
|
||||
&& !directoryhasfragment(works[si], ".wwtxn.")
|
||||
&& !directoryhasfragment(works[si], ".install"));
|
||||
|
||||
let emptyav: []str = [driver(stages[si]), "test", "-w",
|
||||
works[si], "-I", root, "-run", "aa_empty_same", mixed];
|
||||
runcommand(root, strings.concat("empty-skip-filter-empty-", tags[si]),
|
||||
emptyav, (120i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 0);
|
||||
assert(out.stderr.len == 0
|
||||
&& occurrences(out.stdout,
|
||||
"skipmix.aa_empty_same ... SKIP: \n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"0 passed, 0 failed, 1 skipped, 0 harness errors\n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"6 discovered, 1 selected, 1 started, 1 completed\n") == 1
|
||||
&& !has(out.stdout, "ab_same_peer ...")
|
||||
&& !has(out.stdout, "HARNESS"));
|
||||
emptyout[si] = strings.dup(out.stdout);
|
||||
emptyerr[si] = strings.dup(out.stderr);
|
||||
|
||||
let passav: []str = [driver(stages[si]), "test", "-w",
|
||||
works[si], "-I", root, "-run", "ab_same_peer", mixed];
|
||||
runcommand(root, strings.concat("empty-skip-filter-pass-", tags[si]),
|
||||
passav, (120i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 0);
|
||||
assert(out.stderr.len == 0
|
||||
&& occurrences(out.stdout, "skipmix.ab_same_peer ... ok\n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"1 passed, 0 failed, 0 skipped, 0 harness errors\n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"6 discovered, 1 selected, 1 started, 1 completed\n") == 1
|
||||
&& !has(out.stdout, "SKIP:") && !has(out.stdout, "HARNESS"));
|
||||
passout[si] = strings.dup(out.stdout);
|
||||
passerr[si] = strings.dup(out.stderr);
|
||||
|
||||
let listav: []str = [driver(stages[si]), "test", "-w", works[si],
|
||||
"-I", root, "-list", mixed, only];
|
||||
runcommand(root, strings.concat("empty-skip-list-", tags[si]), listav,
|
||||
(120i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 0);
|
||||
assert(out.stderr.len == 0);
|
||||
assert(occurrences(out.stdout, "skipmix.aa_empty_same\n") == 1
|
||||
&& occurrences(out.stdout, "skipmix.ad_empty_external\n") == 1
|
||||
&& occurrences(out.stdout, "skiponly.aa_empty_test_only\n") == 1
|
||||
&& !has(out.stdout, " ... ") && !has(out.stdout, "SKIP:")
|
||||
&& !has(out.stdout, " discovered, ") && !has(out.stdout, "HARNESS"));
|
||||
listout[si] = strings.dup(out.stdout);
|
||||
listerr[si] = strings.dup(out.stderr);
|
||||
|
||||
// The raw single-file compatibility route wraps the same runtime and
|
||||
// therefore accepts the same zero-byte skip payload before continuing.
|
||||
let rawav: []str = [driver(stages[si]), "test", raw];
|
||||
runcommand(root, strings.concat("empty-skip-raw-", tags[si]), rawav,
|
||||
(120i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 0);
|
||||
assert(out.stderr.len == 0
|
||||
&& occurrences(out.stdout,
|
||||
"aa_empty_raw ... SKIP: \n") == 1
|
||||
&& occurrences(out.stdout, "ab_raw_peer ... ok\n") == 1
|
||||
&& pos(out.stdout, "aa_empty_raw ... SKIP: \n")
|
||||
< pos(out.stdout, "ab_raw_peer ... ok\n")
|
||||
&& occurrences(out.stdout,
|
||||
"1 passed, 0 failed, 1 skipped, 0 harness errors\n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"2 discovered, 2 selected, 2 started, 2 completed\n") == 1
|
||||
&& !has(out.stdout, "HARNESS"));
|
||||
rawout[si] = strings.dup(out.stdout);
|
||||
rawerr[si] = strings.dup(out.stderr);
|
||||
|
||||
// The empty-payload correction does not broaden the framed protocol:
|
||||
// an oversized reason remains an isolated harness error.
|
||||
let oversizedav: []str = [driver(stages[si]), "test", "-w",
|
||||
oversizedworks[si], oversized];
|
||||
runcommand(root, strings.concat("empty-skip-oversized-", tags[si]),
|
||||
oversizedav, (120i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 1);
|
||||
assert(out.stderr.len == 0
|
||||
&& occurrences(out.stdout, strings.concat(
|
||||
"skipoversized.too_large ... ",
|
||||
"HARNESS (malformed or contradictory result)\n")) == 1
|
||||
&& occurrences(out.stdout,
|
||||
"0 passed, 0 failed, 0 skipped, 1 harness errors\n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"1 discovered, 1 selected, 1 started, 1 completed\n") == 1
|
||||
&& !has(out.stdout, "SKIP:"));
|
||||
oversizedout[si] = strings.dup(out.stdout);
|
||||
oversizederr[si] = strings.dup(out.stderr);
|
||||
assert(!directoryhasnew(oversizedworks[si])
|
||||
&& !directoryhasfragment(oversizedworks[si], ".wwtxn.")
|
||||
&& !directoryhasfragment(oversizedworks[si], ".install"));
|
||||
|
||||
// Running retention consumes the same result before guarded publication.
|
||||
let runningav: []str = [driver(stages[si]), "test", "-w",
|
||||
works[si], "-o", runningretained[si], "-I", root, mixed];
|
||||
runcommand(root, strings.concat("empty-skip-running-retained-", tags[si]),
|
||||
runningav, (120i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 0);
|
||||
assert(out.stderr.len == 0
|
||||
&& occurrences(out.stdout,
|
||||
"skipmix.aa_empty_production ... SKIP: \n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"skipmix.aa_empty_same ... SKIP: \n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"skipmix.ad_empty_external ... SKIP: \n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"skipmix.ac_named_same ... SKIP: named reason\n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"2 passed, 0 failed, 4 skipped, 0 harness errors\n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"6 discovered, 6 selected, 6 started, 6 completed\n") == 1
|
||||
&& !has(out.stdout, "HARNESS")
|
||||
&& os.exists(runningretained[si])
|
||||
&& !os.exists(strings.concat(runningretained[si], ".new"))
|
||||
&& !os.exists(strings.concat(runningretained[si], ".sepwork")));
|
||||
runningout[si] = strings.dup(out.stdout);
|
||||
runningerr[si] = strings.dup(out.stderr);
|
||||
|
||||
let compileav: []str = [driver(stages[si]), "test", "-c", "-w",
|
||||
works[si], "-o", retained[si], "-I", root, mixed];
|
||||
runcommand(root, strings.concat("empty-skip-compile-", tags[si]),
|
||||
compileav, (120i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 0);
|
||||
assert(out.stdout.len == 0 && out.stderr.len == 0
|
||||
&& os.exists(retained[si])
|
||||
&& !os.exists(strings.concat(retained[si], ".new"))
|
||||
&& !os.exists(strings.concat(retained[si], ".sepwork")));
|
||||
compileout[si] = strings.dup(out.stdout);
|
||||
compileerr[si] = strings.dup(out.stderr);
|
||||
|
||||
let directav: []str = [retained[si], "-package=skipmix"];
|
||||
runcommand(root, strings.concat("empty-skip-direct-", tags[si]),
|
||||
directav, (30i64 * (time.second: i64)): time.duration, &out);
|
||||
expectexit(&out, 0);
|
||||
assert(out.stderr.len == 0
|
||||
&& occurrences(out.stdout,
|
||||
"skipmix.aa_empty_production ... SKIP: \n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"skipmix.aa_empty_same ... SKIP: \n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"skipmix.ad_empty_external ... SKIP: \n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"skipmix.ac_named_same ... SKIP: named reason\n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"2 passed, 0 failed, 4 skipped, 0 harness errors\n") == 1
|
||||
&& occurrences(out.stdout,
|
||||
"6 discovered, 6 selected, 6 started, 6 completed\n") == 1
|
||||
&& !has(out.stdout, "HARNESS"));
|
||||
directout[si] = strings.dup(out.stdout);
|
||||
directerr[si] = strings.dup(out.stderr);
|
||||
assert(!directoryhasnew(works[si])
|
||||
&& !directoryhasfragment(works[si], ".wwtxn.")
|
||||
&& !directoryhasfragment(works[si], ".install"));
|
||||
si += 1;
|
||||
};
|
||||
|
||||
assert(same(ordinaryout[0], ordinaryout[1])
|
||||
&& same(ordinaryerr[0], ordinaryerr[1]));
|
||||
assert(same(emptyout[0], emptyout[1])
|
||||
&& same(emptyerr[0], emptyerr[1]));
|
||||
assert(same(passout[0], passout[1])
|
||||
&& same(passerr[0], passerr[1]));
|
||||
assert(same(listout[0], listout[1])
|
||||
&& same(listerr[0], listerr[1]));
|
||||
assert(same(rawout[0], rawout[1])
|
||||
&& same(rawerr[0], rawerr[1]));
|
||||
assert(same(oversizedout[0], oversizedout[1])
|
||||
&& same(oversizederr[0], oversizederr[1]));
|
||||
assert(same(runningout[0], runningout[1])
|
||||
&& same(runningerr[0], runningerr[1]));
|
||||
assert(same(readfile(runningretained[0]), readfile(runningretained[1])));
|
||||
assert(same(compileout[0], compileout[1])
|
||||
&& same(compileerr[0], compileerr[1]));
|
||||
assert(same(readfile(retained[0]), readfile(retained[1])));
|
||||
assert(same(directout[0], directout[1])
|
||||
&& same(directerr[0], directerr[1]));
|
||||
assert(same(outsideout[0], outsideout[1])
|
||||
&& same(outsideerr[0], outsideerr[1]));
|
||||
assert(same(readfile(outsidebins[0]), readfile(outsidebins[1])));
|
||||
assert(!directoryhasnew(root)
|
||||
&& !directoryhasfragment(root, ".wwtxn.")
|
||||
&& !directoryhasfragment(root, ".install"));
|
||||
clean(root);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user