test: prove platform filename selection

This commit is contained in:
2026-08-14 21:44:26 +09:00
parent f138844737
commit 5c0e468f53
4 changed files with 857 additions and 34 deletions

View File

@@ -5118,6 +5118,637 @@ fn hexbytes(value: str) str = {
clean(root);
};
@test fn platform_filename_source_selection() void = {
let root: str = fresh();
let source: str = strings.concat(root, "/source");
let app: str = strings.concat(source, "/app");
let good: str = strings.concat(source, "/dep/good");
let pkg: str = strings.concat(source, "/pkg");
let testgood: str = strings.concat(source, "/test/good");
let wrongonly: str = strings.concat(source, "/wrongonly");
let notests: str = strings.concat(source, "/notests");
let internal: str = strings.concat(source, "/foreign/internal/secret");
let command: str = strings.concat(source, "/command");
let vendored: str = strings.concat(app, "/vendor/vendored");
let order: str = strings.concat(root, "/order");
let tools: str = strings.concat(root, "/tools");
mkdirall(app); mkdirall(good); mkdirall(pkg); mkdirall(testgood);
mkdirall(wrongonly); mkdirall(notests); mkdirall(internal);
mkdirall(command); mkdirall(vendored); mkdirall(order); mkdirall(tools);
let good5: str = strings.concat("package good;\n",
"export fn value() i32 = { return 5; };\n");
let good6: str = strings.concat("package good;\n",
"export fn value() i32 = { return 6; };\n");
let good7: str = strings.concat("package good;\n",
"export fn value() i32 = { return 7; };\n");
let appmain: str = strings.concat(
"package main;\nimport dep.good;\n",
"fn main() i32 = { return good.value() + wholelinux() + ",
"afterdot() + arch() + reversed() + future() + osname() + pair(); };\n");
let wholelinux: str =
"package main;\nfn wholelinux() i32 = { return 1; };\n";
let afterdot: str =
"package main;\nfn afterdot() i32 = { return 1; };\n";
let arch: str =
"package main;\nfn arch() i32 = { return 1; };\n";
let reversed: str =
"package main;\nfn reversed() i32 = { return 1; };\n";
let future: str =
"package main;\nfn future() i32 = { return 1; };\n";
let osname: str = strings.concat(
"package main;\nimport _ dep.good;\n",
"fn osname() i32 = { return 1; };\n");
let pair: str =
"package main;\nfn pair() i32 = { return 1; };\n";
let ignoredparse: str =
"this wrong-target source is deliberately malformed\n";
let ignoredparseedit: str =
"a different malformed wrong-target edit {\n";
let ignoreddep: str = strings.concat(
"package main;\nimport dep.wrong;\n",
"fn wrong_dep() i32 = { return wrong.value(); };\n");
let ignoredinternal: str = strings.concat(
"package main;\nimport foreign.internal.secret;\n",
"fn wrong_internal() i32 = { return secret.value(); };\n");
let ignoredmain: str = strings.concat(
"package main;\nimport command;\n",
"fn wrong_main() i32 = { return 0; };\n");
let ignoredvendor: str = strings.concat(
"package main;\nimport vendored;\n",
"fn wrong_vendor() i32 = { return vendored.value(); };\n");
writefile(strings.concat(good, "/good.ww"), good5);
writefile(strings.concat(app, "/main.ww"), appmain);
writefile(strings.concat(app, "/linux.ww"), wholelinux);
writefile(strings.concat(app, "/platform.extra_windows.ww"), afterdot);
writefile(strings.concat(app, "/platform_amd64.ww"), arch);
writefile(strings.concat(app, "/platform_amd64_linux.ww"), reversed);
writefile(strings.concat(app, "/platform_future.ww"), future);
writefile(strings.concat(app, "/platform_linux.ww"), osname);
writefile(strings.concat(app, "/platform_linux_amd64.ww"), pair);
writefile(strings.concat(app, "/badparse_windows.ww"), ignoredparse);
writefile(strings.concat(app, "/baddep_arm64.ww"), ignoreddep);
writefile(strings.concat(app, "/badinternal_windows_amd64.ww"),
ignoredinternal);
writefile(strings.concat(app, "/badmain_linux_arm64.ww"), ignoredmain);
writefile(strings.concat(app, "/badvendor_windows.ww"), ignoredvendor);
writefile(strings.concat(internal, "/secret.ww"), strings.concat(
"package secret;\n",
"export fn value() i32 = { return 19; };\n"));
writefile(strings.concat(command, "/main.ww"),
"package main;\nfn main() i32 = { return 0; };\n");
writefile(strings.concat(vendored, "/vendored.ww"), strings.concat(
"package vendored;\n",
"export fn value() i32 = { return 23; };\n"));
let pkgbase: str = strings.concat("package pkg;\n",
"export fn value() i32 = { return 7; };\n");
let samepair: str = strings.concat(
"package pkg;\nimport test.good;\n",
"@test fn selected_internal_pair() void = { ",
"assert(value() + good.value() == 18); };\n");
let samewhole: str = strings.concat(
"package pkg;\n",
"@test fn selected_whole_plan9_name() void = { assert(value() == 7); };\n");
let samereversed: str = strings.concat(
"package pkg;\n",
"@test fn selected_reversed_suffix() void = { assert(value() == 7); };\n");
let externalpair: str = strings.concat(
"package pkg_test;\nimport pkg;\nimport test.good;\n",
"@test fn selected_external_pair() void = { ",
"assert(pkg.value() + good.value() == 18); };\n");
let externaldot: str = strings.concat(
"package pkg_test;\nimport pkg;\n",
"@test fn selected_external_after_dot() void = { ",
"assert(pkg.value() == 7); };\n");
let wrongtest: str = strings.concat(
"package pkg;\nimport test.wrong;\n",
"@test fn wrong_target_test() void = { abort(\"wrong test ran\"); };\n");
let wrongtestedit: str =
"this edited wrong-target test remains deliberately malformed\n";
writefile(strings.concat(pkg, "/base.ww"), pkgbase);
writefile(strings.concat(pkg, "/internal_linux_amd64_test.ww"), samepair);
writefile(strings.concat(pkg, "/plan9_test.ww"), samewhole);
writefile(strings.concat(pkg, "/reverse_amd64_linux_test.ww"),
samereversed);
writefile(strings.concat(pkg, "/external_linux_amd64_test.ww"),
externalpair);
writefile(strings.concat(pkg, "/external.extra_windows_test.ww"),
externaldot);
writefile(strings.concat(pkg, "/internal_windows_amd64_test.ww"),
wrongtest);
writefile(strings.concat(pkg, "/external_linux_arm64_test.ww"),
wrongtest);
writefile(strings.concat(pkg, "/x_plan9_test.ww"), wrongtest);
writefile(strings.concat(testgood, "/good.ww"), strings.concat(
"package good;\n",
"export fn value() i32 = { return 11; };\n"));
writefile(strings.concat(wrongonly, "/only_windows.ww"), ignoredparse);
writefile(strings.concat(notests, "/base.ww"),
"package notests;\nexport fn value() i32 = { return 1; };\n");
writefile(strings.concat(notests, "/only_windows_test.ww"), ignoredparse);
// Creation order is deliberately the inverse of byte order.
writefile(strings.concat(order, "/z_linux.ww"),
"package order;\n@test fn z() void = { };\n");
writefile(strings.concat(order, "/a_linux.ww"),
"package order;\n@test fn a() void = { };\n");
let compilerwrapper: str = strings.concat(tools, "/w6c.sh");
let assemblerwrapper: str = strings.concat(tools, "/w6a.sh");
let linkerwrapper: str = strings.concat(tools, "/w6l.sh");
writeexecutable(compilerwrapper, strings.concat(
"#!/bin/sh\nprintf 'BEGIN' >> \"$WW_PLATFORM_COMPILER_TRACE\"\n",
"for arg in \"$@\"; do printf '<%s>' \"$arg\" >> ",
"\"$WW_PLATFORM_COMPILER_TRACE\"; done\n",
"printf '\\n' >> \"$WW_PLATFORM_COMPILER_TRACE\"\n",
"exec \"$WW_PLATFORM_REAL_COMPILER\" \"$@\"\n"));
writeexecutable(assemblerwrapper, strings.concat(
"#!/bin/sh\nprintf 'BEGIN' >> \"$WW_PLATFORM_ASSEMBLER_TRACE\"\n",
"for arg in \"$@\"; do printf '<%s>' \"$arg\" >> ",
"\"$WW_PLATFORM_ASSEMBLER_TRACE\"; done\n",
"printf '\\n' >> \"$WW_PLATFORM_ASSEMBLER_TRACE\"\n",
"exec \"$WW_PLATFORM_REAL_ASSEMBLER\" \"$@\"\n"));
writeexecutable(linkerwrapper, strings.concat(
"#!/bin/sh\nprintf 'BEGIN' >> \"$WW_PLATFORM_LINKER_TRACE\"\n",
"for arg in \"$@\"; do printf '<%s>' \"$arg\" >> ",
"\"$WW_PLATFORM_LINKER_TRACE\"; done\n",
"printf '\\n' >> \"$WW_PLATFORM_LINKER_TRACE\"\n",
"exec \"$WW_PLATFORM_REAL_LINKER\" \"$@\"\n"));
let stages: []str = ["ww", "ww_ww"];
let compilers: []str = ["w6c", "w6c_ww"];
let assemblers: []str = ["w6a", "w6a_ww"];
let linkers: []str = ["w6l", "w6l_ww"];
let labels: []str = ["c", "ww"];
let artifactnames: []str = ["app.unit.ww", "app.wwi", "app.s",
"app.o", "app.a", "app.init.unit.ww", "app.init.s", "app.init.o",
"dep.good.unit.ww", "dep.good.wwi", "dep.good.s", "dep.good.o",
"dep.good.a"];
let artifactrefs: []str = ["", "", "", "", "", "", "", "", "",
"", "", "", ""];
let testartifactnames: []str = ["pkg.unit.ww", "pkg.wwi", "pkg.a",
"pkg-internal-test.unit.ww", "pkg-internal-test.wwi",
"pkg-internal-test.a", "pkg_test-external-test.unit.ww",
"pkg_test-external-test.wwi", "pkg_test-external-test.a",
"pkg-internal-test-main.a", "pkg_test-external-test-main.a"];
let testartifactrefs: []str = ["", "", "", "", "", "", "", "",
"", "", ""];
let binref: str = "";
let compilerref: str = "";
let assemblerref: str = "";
let linkerref: str = "";
let prodarchiveref: str = "";
let prodwwiref: str = "";
let testoutref: str = "";
let testerrref: str = "";
let faildiagref: str = "";
let recursiveoutref: str = "";
let recursiveerrref: str = "";
let baseenv: []str = os.getenvs();
let si: i32 = 0;
for (si < stages.len) {
rewritefile(strings.concat(good, "/good.ww"), good5);
rewritefile(strings.concat(app, "/platform_future.ww"), future);
rewritefile(strings.concat(app, "/badparse_windows.ww"), ignoredparse);
rewritefile(strings.concat(pkg, "/internal_windows_amd64_test.ww"),
wrongtest);
let work: str = strings.concat(root, "/", labels[si], "-work");
let reversework: str = strings.concat(root, "/", labels[si],
"-reverse-work");
let outdir: str = strings.concat(root, "/", labels[si], "-out");
let reverseout: str = strings.concat(root, "/", labels[si],
"-reverse-out");
let compilertrace: str = strings.concat(root, "/", labels[si],
"-compiler");
let assemblertrace: str = strings.concat(root, "/", labels[si],
"-assembler");
let linkertrace: str = strings.concat(root, "/", labels[si],
"-linker");
assert(os.mkdir(work, 448i32) == 0);
assert(os.mkdir(reversework, 448i32) == 0);
assert(os.mkdir(outdir, 448i32) == 0);
assert(os.mkdir(reverseout, 448i32) == 0);
writefile(compilertrace, ""); writefile(assemblertrace, "");
writefile(linkertrace, "");
let env: []str = alloc([], (baseenv.len + 9): u64)!;
let ei: i32 = 0;
for (ei < baseenv.len) {
if (!strings.hasprefix(baseenv[ei], "WW_W6C=")
&& !strings.hasprefix(baseenv[ei], "WW_W6A=")
&& !strings.hasprefix(baseenv[ei], "WW_W6L=")
&& !strings.hasprefix(baseenv[ei],
"WW_PLATFORM_COMPILER_TRACE=")
&& !strings.hasprefix(baseenv[ei],
"WW_PLATFORM_ASSEMBLER_TRACE=")
&& !strings.hasprefix(baseenv[ei],
"WW_PLATFORM_LINKER_TRACE=")
&& !strings.hasprefix(baseenv[ei],
"WW_PLATFORM_REAL_COMPILER=")
&& !strings.hasprefix(baseenv[ei],
"WW_PLATFORM_REAL_ASSEMBLER=")
&& !strings.hasprefix(baseenv[ei],
"WW_PLATFORM_REAL_LINKER=")) {
append(env, baseenv[ei]);
};
ei += 1;
};
append(env, strings.concat("WW_W6C=", compilerwrapper));
append(env, strings.concat("WW_W6A=", assemblerwrapper));
append(env, strings.concat("WW_W6L=", linkerwrapper));
append(env, strings.concat("WW_PLATFORM_COMPILER_TRACE=", compilertrace));
append(env, strings.concat("WW_PLATFORM_ASSEMBLER_TRACE=", assemblertrace));
append(env, strings.concat("WW_PLATFORM_LINKER_TRACE=", linkertrace));
append(env, strings.concat("WW_PLATFORM_REAL_COMPILER=",
driver(compilers[si])));
append(env, strings.concat("WW_PLATFORM_REAL_ASSEMBLER=",
driver(assemblers[si])));
append(env, strings.concat("WW_PLATFORM_REAL_LINKER=",
driver(linkers[si])));
let forward: []str = [driver(stages[si]), "build", "-w", work,
"-I", source, "-o", strings.concat(outdir, "/"), app, good];
let reverse: []str = [driver(stages[si]), "build", "-w", reversework,
"-I", source, "-o", strings.concat(reverseout, "/"), good, app];
let out: commandout;
runcommandenv(root, strings.concat("platform-cold-", labels[si]),
forward, env, (120i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(out.stdout.len == 0 && out.stderr.len == 0);
let ctrace: str = readfile(compilertrace);
let atrace: str = readfile(assemblertrace);
let ltrace: str = readfile(linkertrace);
assert(occurrences(ctrace, "\n") == 2);
assert(occurrences(atrace, "\n") == 3);
assert(occurrences(ltrace, "\n") == 1);
let appline: str = linecontaining(ctrace, "/app.unit.new");
assert(occurrences(appline, "<--import><dep.good>") == 1);
assert(occurrences(appline, "/dep.good.wwi.new>") == 1);
assert(!has(ctrace, "dep.wrong"));
assert(!has(ctrace, "foreign.internal.secret"));
assert(!has(ctrace, "vendored"));
assert(!has(ctrace, "command.wwi"));
assert(occurrences(ltrace, strings.concat(work, "/app.a.new")) == 1);
assert(occurrences(ltrace, strings.concat(work,
"/dep.good.a.new")) == 1);
assert(!has(ltrace, ".wwi"));
assert(!has(ltrace, "dep.wrong"));
let unitprefix: str = strings.concat(
"//ww:module-reset app\n", wholelinux, "\n",
"//ww:module-reset app\n", appmain, "\n",
"//ww:module-reset app\n", afterdot, "\n",
"//ww:module-reset app\n", arch, "\n",
"//ww:module-reset app\n", reversed, "\n",
"//ww:module-reset app\n", future, "\n",
"//ww:module-reset app\n", osname, "\n",
"//ww:module-reset app\n", pair, "\n");
let appunit: str = readfile(strings.concat(work, "/app.unit.ww"));
assert(strings.hasprefix(appunit, unitprefix));
assert(has(appunit, "//ww:direct-export dep.good "));
assert(!has(appunit, "wrong_dep"));
assert(!has(appunit, "wrong_internal"));
assert(!has(appunit, "wrong_main"));
assert(!has(appunit, "wrong_vendor"));
assert(!os.exists(strings.concat(work, "/dep.wrong.unit.ww")));
let bin: str = strings.concat(outdir, "/app");
let runav: []str = [bin];
runcommand(root, strings.concat("platform-run-", labels[si]), runav,
(60i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 12);
let ai: i32 = 0;
for (ai < artifactnames.len) {
let bytes: str = readfile(strings.concat(work, "/",
artifactnames[ai]));
if (si == 0) { artifactrefs[ai] = strings.dup(bytes); }
else { assert(same(artifactrefs[ai], bytes)); };
ai += 1;
};
let normalizedcompiler: str = normalizedtrace(ctrace,
strings.concat(work, "/"), outdir);
let normalizedassembler: str = normalizedtrace(atrace,
strings.concat(work, "/"), outdir);
let normalizedlinker: str = normalizedtrace(ltrace,
strings.concat(work, "/"), outdir);
if (si == 0) {
compilerref = strings.dup(normalizedcompiler);
assemblerref = strings.dup(normalizedassembler);
linkerref = strings.dup(normalizedlinker);
binref = strings.dup(readfile(bin));
} else {
assert(same(compilerref, normalizedcompiler));
assert(same(assemblerref, normalizedassembler));
assert(same(linkerref, normalizedlinker));
assert(same(binref, readfile(bin)));
};
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
runcommandenv(root, strings.concat("platform-reverse-", labels[si]),
reverse, env, (120i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(same(readfile(bin), readfile(strings.concat(reverseout, "/app"))));
assert(same(normalizedcompiler, normalizedtrace(readfile(compilertrace),
strings.concat(reversework, "/"), reverseout)));
assert(same(normalizedassembler, normalizedtrace(readfile(assemblertrace),
strings.concat(reversework, "/"), reverseout)));
assert(same(normalizedlinker, normalizedtrace(readfile(linkertrace),
strings.concat(reversework, "/"), reverseout)));
ai = 0;
for (ai < artifactnames.len) {
assert(same(readfile(strings.concat(work, "/", artifactnames[ai])),
readfile(strings.concat(reversework, "/", artifactnames[ai]))));
ai += 1;
};
let stableunit: str = strings.dup(readfile(strings.concat(work,
"/app.unit.ww")));
let stablewwi: str = strings.dup(readfile(strings.concat(work,
"/app.wwi")));
let stablearchive: str = strings.dup(readfile(strings.concat(work,
"/app.a")));
let stabledepwwi: str = strings.dup(readfile(strings.concat(work,
"/dep.good.wwi")));
let stablebin: str = strings.dup(readfile(bin));
let stablestamp: str = strings.dup(readfile(strings.concat(work,
"/.wwtool.stamp")));
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
runcommandenv(root, strings.concat("platform-warm-", labels[si]),
forward, env, (120i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(readfile(compilertrace).len == 0);
assert(readfile(assemblertrace).len == 0);
assert(occurrences(readfile(linkertrace), "\n") == 1);
rewritefile(strings.concat(app, "/badparse_windows.ww"),
ignoredparseedit);
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
runcommandenv(root, strings.concat("platform-ignored-edit-", labels[si]),
forward, env, (120i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(readfile(compilertrace).len == 0);
assert(readfile(assemblertrace).len == 0);
assert(occurrences(readfile(linkertrace), "\n") == 1);
assert(same(stableunit, readfile(strings.concat(work, "/app.unit.ww"))));
assert(same(stablewwi, readfile(strings.concat(work, "/app.wwi"))));
assert(same(stablearchive, readfile(strings.concat(work, "/app.a"))));
assert(same(stabledepwwi, readfile(strings.concat(work,
"/dep.good.wwi"))));
assert(same(stablebin, readfile(bin)));
assert(same(stablestamp, readfile(strings.concat(work,
"/.wwtool.stamp"))));
rewritefile(strings.concat(good, "/good.ww"), good6);
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
runcommandenv(root, strings.concat("platform-private-edit-", labels[si]),
forward, env, (120i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(occurrences(readfile(compilertrace), "\n") == 1);
assert(has(readfile(compilertrace), "/dep.good.unit.new"));
assert(!has(readfile(compilertrace), "/app.unit.new"));
assert(occurrences(readfile(assemblertrace), "\n") == 1);
assert(occurrences(readfile(linkertrace), "\n") == 1);
assert(same(stabledepwwi, readfile(strings.concat(work,
"/dep.good.wwi"))));
assert(same(stableunit, readfile(strings.concat(work, "/app.unit.ww"))));
assert(same(stablewwi, readfile(strings.concat(work, "/app.wwi"))));
assert(same(stablearchive, readfile(strings.concat(work, "/app.a"))));
assert(!same(stablebin, readfile(bin)));
let runchanged: []str = [bin];
runcommand(root, strings.concat("platform-run-edited-", labels[si]),
runchanged, (60i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 13);
let committeddepunit: str = strings.dup(readfile(strings.concat(work,
"/dep.good.unit.ww")));
let committeddepa: str = strings.dup(readfile(strings.concat(work,
"/dep.good.a")));
let committedbin: str = strings.dup(readfile(bin));
rewritefile(strings.concat(good, "/good.ww"), good7);
rewritefile(strings.concat(app, "/platform_future.ww"),
"package main;\nfn future() i32 = { return missing_name; };\n");
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
runcommandenv(root, strings.concat("platform-late-failure-", labels[si]),
forward, env, (120i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 1);
assert(has(out.stderr, "undefined: missing_name"));
let normalizedfailure: str = normalizedtrace(out.stderr,
strings.concat(work, "/"), bin);
if (si == 0) { faildiagref = strings.dup(normalizedfailure); }
else { assert(same(faildiagref, normalizedfailure)); };
assert(occurrences(readfile(compilertrace), "\n") == 2);
assert(occurrences(readfile(assemblertrace), "\n") == 1);
assert(readfile(linkertrace).len == 0);
assert(same(committeddepunit, readfile(strings.concat(work,
"/dep.good.unit.ww"))));
assert(same(committeddepa, readfile(strings.concat(work,
"/dep.good.a"))));
assert(same(committedbin, readfile(bin)));
assert(same(stablestamp, readfile(strings.concat(work,
"/.wwtool.stamp"))));
assert(!os.exists(strings.concat(work, "/dep.good.unit.new")));
assert(!os.exists(strings.concat(work, "/dep.good.wwi.new")));
assert(!os.exists(strings.concat(work, "/dep.good.a.new")));
assert(!os.exists(strings.concat(work, "/app.unit.new")));
assert(!os.exists(strings.concat(work, "/app.wwi.new")));
assert(!os.exists(strings.concat(work, "/app.a.new")));
rewritefile(strings.concat(good, "/good.ww"), good6);
rewritefile(strings.concat(app, "/platform_future.ww"), future);
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
runcommandenv(root, strings.concat("platform-restored-", labels[si]),
forward, env, (120i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(readfile(compilertrace).len == 0);
assert(readfile(assemblertrace).len == 0);
assert(occurrences(readfile(linkertrace), "\n") == 1);
assert(same(committedbin, readfile(bin)));
rewritefile(strings.concat(good, "/good.ww"), good5);
rewritefile(strings.concat(app, "/badparse_windows.ww"), ignoredparse);
let prodwork: str = strings.concat(root, "/", labels[si], "-prod-work");
let prodout: str = strings.concat(root, "/", labels[si], "-pkg.a");
assert(os.mkdir(prodwork, 448i32) == 0);
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
let prodav: []str = [driver(stages[si]), "build", "-w", prodwork,
"-I", source, "-o", prodout, pkg];
runcommandenv(root, strings.concat("platform-production-", labels[si]),
prodav, env, (120i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(occurrences(readfile(compilertrace), "\n") == 1);
assert(!has(readfile(compilertrace), "test.good"));
assert(!has(readfile(strings.concat(prodwork, "/pkg.unit.ww")),
"selected_internal"));
if (si == 0) {
prodarchiveref = strings.dup(readfile(prodout));
prodwwiref = strings.dup(readfile(strings.concat(prodout, ".wwi")));
} else {
assert(same(prodarchiveref, readfile(prodout)));
assert(same(prodwwiref, readfile(strings.concat(prodout, ".wwi"))));
};
let testwork: str = strings.concat(root, "/", labels[si], "-test-work");
assert(os.mkdir(testwork, 448i32) == 0);
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
let testav: []str = [driver(stages[si]), "test", "-w", testwork,
"-I", source, pkg];
runcommandenv(root, strings.concat("platform-test-", labels[si]), testav,
env, (180i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(has(out.stdout, "selected_internal_pair ... ok\n"));
assert(has(out.stdout, "selected_whole_plan9_name ... ok\n"));
assert(has(out.stdout, "selected_reversed_suffix ... ok\n"));
assert(has(out.stdout, "selected_external_pair ... ok\n"));
assert(has(out.stdout, "selected_external_after_dot ... ok\n"));
assert(!has(out.stdout, "wrong_target_test"));
assert(!has(out.stderr, "wrong-target"));
let testctrace: str = readfile(compilertrace);
let testltrace: str = readfile(linkertrace);
assert(!has(testctrace, "test.wrong"));
let sameline: str = linecontaining(testctrace,
"/pkg-internal-test.unit.new");
let externalline: str = linecontaining(testctrace,
"/pkg_test-external-test.unit.new");
assert(occurrences(sameline, "<--import><test.good>") == 1);
assert(occurrences(externalline, "<--import><pkg>") == 1);
assert(occurrences(externalline, "<--import><test.good>") == 1);
assert(!has(testltrace, ".wwi"));
let sameunit: str = readfile(strings.concat(testwork,
"/pkg-internal-test.unit.ww"));
let externalunit: str = readfile(strings.concat(testwork,
"/pkg_test-external-test.unit.ww"));
assert(has(sameunit, "selected_internal_pair"));
assert(has(sameunit, "selected_whole_plan9_name"));
assert(has(sameunit, "selected_reversed_suffix"));
assert(!has(sameunit, "wrong_target_test"));
assert(has(externalunit, "selected_external_pair"));
assert(has(externalunit, "selected_external_after_dot"));
assert(!has(externalunit, "wrong_target_test"));
ai = 0;
for (ai < testartifactnames.len) {
let bytes: str = readfile(strings.concat(testwork, "/",
testartifactnames[ai]));
if (si == 0) { testartifactrefs[ai] = strings.dup(bytes); }
else { assert(same(testartifactrefs[ai], bytes)); };
ai += 1;
};
if (si == 0) {
testoutref = strings.dup(out.stdout);
testerrref = strings.dup(out.stderr);
} else {
assert(same(testoutref, out.stdout));
assert(same(testerrref, out.stderr));
};
let stabletestunit: str = strings.dup(sameunit);
rewritefile(strings.concat(pkg, "/internal_windows_amd64_test.ww"),
wrongtestedit);
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
runcommandenv(root, strings.concat("platform-test-warm-", labels[si]),
testav, env, (180i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(same(testoutref, out.stdout));
assert(readfile(compilertrace).len == 0);
assert(readfile(assemblertrace).len == 0);
assert(occurrences(readfile(linkertrace), "\n") == 2);
assert(same(stabletestunit, readfile(strings.concat(testwork,
"/pkg-internal-test.unit.ww"))));
rewritefile(strings.concat(pkg, "/internal_windows_amd64_test.ww"),
wrongtest);
let onlywork: str = strings.concat(root, "/", labels[si], "-only-work");
let onlyout: str = strings.concat(root, "/", labels[si], "-only-bin");
assert(os.mkdir(onlywork, 448i32) == 0);
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
let onlyav: []str = [driver(stages[si]), "build", "-w", onlywork,
"-o", onlyout, wrongonly];
runcommandenv(root, strings.concat("platform-only-", labels[si]), onlyav,
env, (60i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 1);
assert(same(out.stderr, strings.concat("ww: ", wrongonly,
": directory contains no WW package sources\n")));
assert(readfile(compilertrace).len == 0);
assert(readfile(assemblertrace).len == 0);
assert(readfile(linkertrace).len == 0);
assert(!os.exists(onlyout));
assert(!os.exists(strings.concat(onlywork, "/.wwtool.stamp")));
let orderwork: str = strings.concat(root, "/", labels[si],
"-order-work");
assert(os.mkdir(orderwork, 448i32) == 0);
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
let orderav: []str = [driver(stages[si]), "build", "-w", orderwork,
"-o", strings.concat(root, "/", labels[si], "-order.a"), order];
runcommandenv(root, strings.concat("platform-order-", labels[si]),
orderav, env, (60i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 1);
assert(same(out.stderr, strings.concat("ww: ", order,
"/a_linux.ww: @test declaration outside *_test.ww\n")));
assert(readfile(compilertrace).len == 0);
assert(readfile(assemblertrace).len == 0);
assert(readfile(linkertrace).len == 0);
assert(!os.exists(strings.concat(orderwork, "/.wwtool.stamp")));
let recursivework: str = strings.concat(root, "/", labels[si],
"-recursive-work");
let recursiveout: str = strings.concat(root, "/", labels[si],
"-recursive-out");
assert(os.mkdir(recursivework, 448i32) == 0);
assert(os.mkdir(recursiveout, 448i32) == 0);
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
let recursiveav: []str = [driver(stages[si]), "build", "-w",
recursivework, "-I", source, "-o", strings.concat(recursiveout,
"/"), strings.concat(source, "/...")];
runcommandenv(root, strings.concat("platform-recursive-build-",
labels[si]), recursiveav, env,
(180i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(out.stdout.len == 0 && out.stderr.len == 0);
assert(!has(readfile(compilertrace), "wrongonly"));
assert(!has(readfile(compilertrace), "dep.wrong"));
let recbin: str = strings.concat(recursiveout, "/app");
let recrun: []str = [recbin];
runcommand(root, strings.concat("platform-recursive-run-", labels[si]),
recrun, (60i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 12);
assert(same(binref, readfile(recbin)));
let recursivetestwork: str = strings.concat(root, "/", labels[si],
"-recursive-test-work");
assert(os.mkdir(recursivetestwork, 448i32) == 0);
rewritefile(compilertrace, ""); rewritefile(assemblertrace, "");
rewritefile(linkertrace, "");
let recursivetestav: []str = [driver(stages[si]), "test", "-w",
recursivetestwork, "-I", source, strings.concat(source, "/...")];
runcommandenv(root, strings.concat("platform-recursive-test-",
labels[si]), recursivetestav, env,
(240i64 * (time.second: i64)): time.duration, &out);
expectexit(&out, 0);
assert(has(out.stdout, "selected_internal_pair ... ok\n"));
assert(has(out.stdout, "selected_external_pair ... ok\n"));
assert(has(out.stdout, strings.concat("? ", notests,
" [no tests]\n")));
assert(!has(out.stdout, "wrong_target_test"));
assert(!has(out.stderr, "only_windows"));
assert(!has(readfile(compilertrace), "dep.wrong"));
if (si == 0) {
recursiveoutref = strings.dup(out.stdout);
recursiveerrref = strings.dup(out.stderr);
} else {
assert(same(recursiveoutref, out.stdout));
assert(same(recursiveerrref, out.stderr));
};
si += 1;
};
clean(root);
};
// Invalid @test attribute shapes reject at build with stable text on
// BOTH frontends (the -T synth checker owns them; the fixture corpus
// cannot reach -T, so these rows live here). Fragments only — the