ww: select build action from package declaration
This commit is contained in:
@@ -150,7 +150,7 @@ fn samefile(a: str, b: str, why: str) void = {
|
||||
"late/example/foo", "late/example/foo", fooalias, fooalias];
|
||||
i = 0;
|
||||
for (i < rootouts.len) {
|
||||
let rav: []str = [testenv.driver(rootdrivers[i]), "build", "-p",
|
||||
let rav: []str = [testenv.driver(rootdrivers[i]), "build",
|
||||
"-I", early, "-I", late, "-o", rootouts[i], roottargets[i]];
|
||||
expectcode(td, strings.concat("foo_root_", roottags[i]), rav, 0);
|
||||
let rw: str = strings.concat(rootouts[i], ".sepwork/");
|
||||
|
||||
@@ -166,9 +166,9 @@ fn rejectstable(dir: str, label: str, target: str, needle: str) void = {
|
||||
"fn hidden() i32 = { return 99; };\n"));
|
||||
let ca: str = strings.concat(td, "/libonly-c.a");
|
||||
let wa: str = strings.concat(td, "/libonly-w.a");
|
||||
let cav: []str = [testenv.driver("ww"), "build", "-p", "-I", td,
|
||||
let cav: []str = [testenv.driver("ww"), "build", "-I", td,
|
||||
"-o", ca, lib];
|
||||
let wav: []str = [testenv.driver("ww_ww"), "build", "-p", "-I", td,
|
||||
let wav: []str = [testenv.driver("ww_ww"), "build", "-I", td,
|
||||
"-o", wa, lib];
|
||||
if (code(td, "build_package_c", cav) != 0
|
||||
|| code(td, "build_package_w", wav) != 0) {
|
||||
@@ -302,10 +302,10 @@ fn rejectstable(dir: str, label: str, target: str, needle: str) void = {
|
||||
strings.concat(td, "/api-c2.a"), strings.concat(td, "/api-w.a")];
|
||||
i = 0;
|
||||
for (i < packages.len) {
|
||||
let pav: []str = [testenv.driver(drivers[i]), "build", "-p", "-I", td,
|
||||
let pav: []str = [testenv.driver(drivers[i]), "build", "-I", td,
|
||||
"-o", packages[i], api];
|
||||
if (code(td, strings.concat("package_", tags[i]), pav) != 0) {
|
||||
fail("self-contained", "ww build -p api failed");
|
||||
fail("self-contained", "ww build api failed");
|
||||
};
|
||||
i += 1;
|
||||
};
|
||||
@@ -907,7 +907,7 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
"/.wwtool.w6a")), testenv.readfile(assembler))
|
||||
|| !testenv.same(testenv.readfile(strings.concat(work,
|
||||
"/.wwtool.stamp")),
|
||||
"ww workdir fmt 10 mode build asm 0\n")) {
|
||||
"ww workdir fmt 12 mode build asm 0\n")) {
|
||||
fail("driver-identity", "persistent artifacts or identities are incomplete");
|
||||
};
|
||||
let coldwwi: str = testenv.readfile(strings.concat(work, "/dep.wwi"));
|
||||
@@ -1224,9 +1224,9 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
"export fn nestedvalue() i32 = { return 41; };\n"));
|
||||
let ca: str = strings.concat(td, "/nested-c.a");
|
||||
let wa: str = strings.concat(td, "/nested-w.a");
|
||||
let cav: []str = [testenv.driver("ww"), "build", "-p", "-I", root,
|
||||
let cav: []str = [testenv.driver("ww"), "build", "-I", root,
|
||||
"-o", ca, "foo.bar"];
|
||||
let wav: []str = [testenv.driver("ww_ww"), "build", "-p", "-I", root,
|
||||
let wav: []str = [testenv.driver("ww_ww"), "build", "-I", root,
|
||||
"-o", wa, "foo.bar"];
|
||||
if (code(td, "nested_package_c", cav) != 0
|
||||
|| code(td, "nested_package_w", wav) != 0) {
|
||||
@@ -1247,22 +1247,575 @@ fn writediamond(td: str, reverse: bool) str = {
|
||||
let i: i32 = 0;
|
||||
for (i < drivers.len) {
|
||||
let badout: str = strings.concat(td, "/bad-flags-", drivers[i]);
|
||||
let av: []str = [testenv.driver(drivers[i]), "build", "-p", "-S",
|
||||
let av: []str = [testenv.driver(drivers[i]), "build", "-p",
|
||||
"-I", root, "-o", badout, "foo.bar"];
|
||||
let co: testenv.commandout;
|
||||
command(td, strings.concat("package_flag_contract_", drivers[i]),
|
||||
av, &co);
|
||||
if (co.termination != exec.termination.EXIT || co.code == 0
|
||||
|| !testenv.has(co.stderr,
|
||||
"ww build: -p and -S cannot be combined")) {
|
||||
|| !testenv.has(co.stderr, "ww build: unknown flag")) {
|
||||
fail("package-flags", strings.concat(drivers[i],
|
||||
" accepted -p -S"));
|
||||
" accepted the removed package-action flag"));
|
||||
};
|
||||
i += 1;
|
||||
};
|
||||
testenv.clean(td);
|
||||
};
|
||||
|
||||
@test fn package_kind_selects_build_action() void = {
|
||||
let td: str = testenv.fresh();
|
||||
let source: str = strings.concat(td, "/source");
|
||||
let foo: str = strings.concat(source, "/foo");
|
||||
let dep: str = strings.concat(foo, "/dep");
|
||||
let bar: str = strings.concat(foo, "/bar");
|
||||
let commanddir: str = strings.concat(foo, "/cmd");
|
||||
let cyclea: str = strings.concat(foo, "/cyclea");
|
||||
let cycleb: str = strings.concat(foo, "/cycleb");
|
||||
let tools: str = strings.concat(td, "/tools");
|
||||
mkdir(source); mkdir(foo); mkdir(dep); mkdir(bar); mkdir(commanddir);
|
||||
mkdir(cyclea); mkdir(cycleb); mkdir(tools);
|
||||
let depsrc: str = strings.concat(dep, "/dep.ww");
|
||||
let depbase: str = strings.concat(
|
||||
"package dep;\n",
|
||||
"// DEP_SOURCE\n",
|
||||
"fn hidden() i32 = { return 40; };\n",
|
||||
"export fn value() i32 = { return hidden(); };\n");
|
||||
let depprivate: str = strings.concat(
|
||||
"package dep;\n",
|
||||
"// DEP_SOURCE\n",
|
||||
"fn hidden() i32 = { return 41; };\n",
|
||||
"export fn value() i32 = { return hidden(); };\n");
|
||||
let depexported: str = strings.concat(depprivate,
|
||||
"export fn additional() i32 = { return 1; };\n");
|
||||
testenv.writefile(depsrc, depbase);
|
||||
testenv.writefile(strings.concat(bar, "/a.ww"), strings.concat(
|
||||
"package bar;\nimport foo.dep;\n",
|
||||
"// ROOT_A\n",
|
||||
"export fn value() i32 = { return dep.value() + 2; };\n"));
|
||||
testenv.writefile(strings.concat(bar, "/z.ww"), strings.concat(
|
||||
"package bar;\nimport foo.dep;\n",
|
||||
"// ROOT_Z\n",
|
||||
"export fn other() i32 = { return 9; };\n"));
|
||||
testenv.writefile(strings.concat(commanddir, "/main.ww"), strings.concat(
|
||||
"package main;\nimport foo.bar;\n",
|
||||
"// COMMAND_OWNER\n",
|
||||
"fn main() i32 = { return bar.value(); };\n"));
|
||||
testenv.writefile(strings.concat(cyclea, "/a.ww"), strings.concat(
|
||||
"package cyclea;\nimport foo.cycleb;\n",
|
||||
"export fn value() i32 = { return cycleb.value(); };\n"));
|
||||
testenv.writefile(strings.concat(cycleb, "/b.ww"), strings.concat(
|
||||
"package cycleb;\nimport foo.cyclea;\n",
|
||||
"export fn value() i32 = { return cyclea.value(); };\n"));
|
||||
|
||||
let compiler: str = strings.concat(tools, "/w6c.sh");
|
||||
let assembler: str = strings.concat(tools, "/w6a.sh");
|
||||
let linker: str = strings.concat(tools, "/w6l.sh");
|
||||
testenv.writeexecutable(compiler, strings.concat(
|
||||
"#!/bin/sh\n",
|
||||
"printf 'BEGIN' >> \"$WW_ROOT_COMPILER_TRACE\"\n",
|
||||
"for arg in \"$@\"; do printf '<%s>' \"$arg\" >> ",
|
||||
"\"$WW_ROOT_COMPILER_TRACE\"; done\n",
|
||||
"printf '\\n' >> \"$WW_ROOT_COMPILER_TRACE\"\n",
|
||||
"exec \"$WW_ROOT_REAL_COMPILER\" \"$@\"\n"));
|
||||
testenv.writeexecutable(assembler, strings.concat(
|
||||
"#!/bin/sh\n",
|
||||
"printf 'BEGIN' >> \"$WW_ROOT_ASSEMBLER_TRACE\"\n",
|
||||
"for arg in \"$@\"; do printf '<%s>' \"$arg\" >> ",
|
||||
"\"$WW_ROOT_ASSEMBLER_TRACE\"; done\n",
|
||||
"printf '\\n' >> \"$WW_ROOT_ASSEMBLER_TRACE\"\n",
|
||||
"exec \"$WW_ROOT_REAL_ASSEMBLER\" \"$@\"\n"));
|
||||
testenv.writeexecutable(linker, strings.concat(
|
||||
"#!/bin/sh\n",
|
||||
"printf 'BEGIN' >> \"$WW_ROOT_LINKER_TRACE\"\n",
|
||||
"for arg in \"$@\"; do printf '<%s>' \"$arg\" >> ",
|
||||
"\"$WW_ROOT_LINKER_TRACE\"; done\n",
|
||||
"printf '\\n' >> \"$WW_ROOT_LINKER_TRACE\"\n",
|
||||
"exec \"$WW_ROOT_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 tags: []str = ["c", "ww"];
|
||||
let suffixes: []str = [".unit.ww", ".wwi", ".s", ".o", ".a"];
|
||||
let rootreference: []str = ["", "", "", "", ""];
|
||||
let depreference: []str = ["", "", "", "", ""];
|
||||
let commandreference: []str = ["", "", "", "", ""];
|
||||
let nooutrootreference: []str = ["", "", "", "", ""];
|
||||
let nooutdepreference: []str = ["", "", "", "", ""];
|
||||
let publishreference: str = "";
|
||||
let exportreference: str = "";
|
||||
let binaryreference: str = "";
|
||||
let diagnosticreference: str = "";
|
||||
let cyclediagreference: str = "";
|
||||
let cyclepathdiagreference: str = "";
|
||||
let pathdiagreference: str = "";
|
||||
let runtime: str = strings.concat(testenv.repo(), "/out/lib");
|
||||
let si: i32 = 0;
|
||||
for (si < stages.len) {
|
||||
let work: str = strings.concat(td, "/work-", tags[si]);
|
||||
let outpath: str = strings.concat(td, "/libbar-", tags[si], ".a");
|
||||
let compilertrace: str = strings.concat(td, "/compiler-", tags[si]);
|
||||
let assemblertrace: str = strings.concat(td, "/assembler-", tags[si]);
|
||||
let linkertrace: str = strings.concat(td, "/linker-", tags[si]);
|
||||
mkdir(work);
|
||||
testenv.writefile(compilertrace, "");
|
||||
testenv.writefile(assemblertrace, "");
|
||||
testenv.writefile(linkertrace, "");
|
||||
let env: []str = roottraceenv(source, runtime,
|
||||
compiler, assembler, linker,
|
||||
compilertrace, assemblertrace, linkertrace,
|
||||
testenv.driver(compilers[si]),
|
||||
testenv.driver(assemblers[si]),
|
||||
testenv.driver(linkers[si]));
|
||||
let av: []str = [testenv.driver(stages[si]), "build",
|
||||
"-w", work, "-I", source, "-o", outpath, "foo.bar"];
|
||||
let out: testenv.commandout;
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-cold-", tags[si]),
|
||||
av, env, tmo(), &out);
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| out.stderr.len != 0) {
|
||||
fail("package-autoaction", strings.concat(tags[si],
|
||||
" cold library build failed: ", out.stderr));
|
||||
};
|
||||
let ctrace: str = testenv.readfile(compilertrace);
|
||||
let atrace: str = testenv.readfile(assemblertrace);
|
||||
let wantcompiler: str = strings.concat(
|
||||
"BEGIN<-c><-I><", work,
|
||||
"/foo.dep.wwi.new><-o><", work,
|
||||
"/foo.dep.s.new><", work, "/foo.dep.unit.new>\n",
|
||||
"BEGIN<-c><--import><foo.dep><", work,
|
||||
"/foo.dep.wwi><-I><", work,
|
||||
"/foo.bar.wwi.new><-o><", work,
|
||||
"/foo.bar.s.new><", work, "/foo.bar.unit.new>\n");
|
||||
let wantassembler: str = strings.concat(
|
||||
"BEGIN<-o><", work, "/foo.dep.o.new><", work,
|
||||
"/foo.dep.s.new>\n",
|
||||
"BEGIN<-o><", work, "/foo.bar.o.new><", work,
|
||||
"/foo.bar.s.new>\n");
|
||||
if (!testenv.same(ctrace, wantcompiler)
|
||||
|| !testenv.same(atrace, wantassembler)
|
||||
|| testenv.readfile(linkertrace).len != 0) {
|
||||
fail("package-autoaction",
|
||||
"library action tool arguments are not compile-only/direct");
|
||||
};
|
||||
let rootunit: str = testenv.readfile(strings.concat(work,
|
||||
"/foo.bar.unit.ww"));
|
||||
if (testenv.pos(rootunit, "// ROOT_A") < 0
|
||||
|| testenv.pos(rootunit, "// ROOT_Z")
|
||||
<= testenv.pos(rootunit, "// ROOT_A")
|
||||
|| testenv.has(rootunit, "DEP_SOURCE")
|
||||
|| testenv.occurrences(rootunit,
|
||||
"//ww:module-reset foo.bar\n") != 2) {
|
||||
fail("package-autoaction",
|
||||
"library unit is not owner-only and byte-sorted");
|
||||
};
|
||||
if (!testenv.exists(outpath)
|
||||
|| !testenv.exists(strings.concat(outpath, ".wwi"))
|
||||
|| !testenv.same(testenv.readfile(outpath),
|
||||
testenv.readfile(strings.concat(work, "/foo.bar.a")))
|
||||
|| !testenv.same(testenv.readfile(strings.concat(outpath, ".wwi")),
|
||||
testenv.readfile(strings.concat(work, "/foo.bar.wwi")))) {
|
||||
fail("package-autoaction", "explicit package publication changed bytes");
|
||||
};
|
||||
let ai: i32 = 0;
|
||||
for (ai < suffixes.len) {
|
||||
let rootbytes: str = testenv.readfile(strings.concat(work,
|
||||
"/foo.bar", suffixes[ai]));
|
||||
let depbytes: str = testenv.readfile(strings.concat(work,
|
||||
"/foo.dep", suffixes[ai]));
|
||||
if (si == 0) {
|
||||
rootreference[ai] = strings.dup(rootbytes);
|
||||
depreference[ai] = strings.dup(depbytes);
|
||||
} else { if (!testenv.same(rootreference[ai], rootbytes)
|
||||
|| !testenv.same(depreference[ai], depbytes)) {
|
||||
fail("package-autoaction",
|
||||
"Cstage and WWstage package artifacts differ");
|
||||
}; };
|
||||
ai += 1;
|
||||
};
|
||||
if (si == 0) {
|
||||
publishreference = strings.dup(testenv.readfile(outpath));
|
||||
exportreference = strings.dup(testenv.readfile(strings.concat(
|
||||
outpath, ".wwi")));
|
||||
} else { if (!testenv.same(publishreference,
|
||||
testenv.readfile(outpath)) || !testenv.same(exportreference,
|
||||
testenv.readfile(strings.concat(outpath, ".wwi")))) {
|
||||
fail("package-autoaction", "published stage artifacts differ");
|
||||
}; };
|
||||
|
||||
// The other AutoAction half remains declaration-selected: package main
|
||||
// alone receives --entry and its complete archive-only link closure.
|
||||
testenv.clean(compilertrace); testenv.writefile(compilertrace, "");
|
||||
testenv.clean(assemblertrace); testenv.writefile(assemblertrace, "");
|
||||
testenv.clean(linkertrace); testenv.writefile(linkertrace, "");
|
||||
let commandwork: str = strings.concat(td, "/command-work-", tags[si]);
|
||||
let commandbin: str = strings.concat(td, "/command-", tags[si]);
|
||||
mkdir(commandwork);
|
||||
let commandav: []str = [testenv.driver(stages[si]), "build",
|
||||
"-w", commandwork, "-I", source, "-o", commandbin, "foo.cmd"];
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-command-", tags[si]),
|
||||
commandav, env, tmo(), &out);
|
||||
ctrace = testenv.readfile(compilertrace);
|
||||
atrace = testenv.readfile(assemblertrace);
|
||||
let commandlink: str = testenv.readfile(linkertrace);
|
||||
let wantcommandcompiler: str = strings.concat(
|
||||
"BEGIN<-c><-I><", commandwork,
|
||||
"/foo.dep.wwi.new><-o><", commandwork,
|
||||
"/foo.dep.s.new><", commandwork, "/foo.dep.unit.new>\n",
|
||||
"BEGIN<-c><--import><foo.dep><", commandwork,
|
||||
"/foo.dep.wwi><-I><", commandwork,
|
||||
"/foo.bar.wwi.new><-o><", commandwork,
|
||||
"/foo.bar.s.new><", commandwork, "/foo.bar.unit.new>\n",
|
||||
"BEGIN<--entry><-c><--import><foo.bar><", commandwork,
|
||||
"/foo.bar.wwi><-I><", commandwork,
|
||||
"/foo.cmd.wwi.new><-o><", commandwork,
|
||||
"/foo.cmd.s.new><", commandwork, "/foo.cmd.unit.new>\n");
|
||||
let wantcommandassembler: str = strings.concat(
|
||||
"BEGIN<-o><", commandwork, "/foo.dep.o.new><", commandwork,
|
||||
"/foo.dep.s.new>\n",
|
||||
"BEGIN<-o><", commandwork, "/foo.bar.o.new><", commandwork,
|
||||
"/foo.bar.s.new>\n",
|
||||
"BEGIN<-o><", commandwork, "/foo.cmd.o.new><", commandwork,
|
||||
"/foo.cmd.s.new>\n");
|
||||
let wantcommandlink: str = strings.concat("BEGIN<-o><", commandbin,
|
||||
"><", commandwork, "/foo.cmd.a><", commandwork,
|
||||
"/foo.bar.a><", commandwork, "/foo.dep.a><", runtime,
|
||||
"/libwwrt.a>\n");
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| out.stderr.len != 0
|
||||
|| !testenv.same(ctrace, wantcommandcompiler)
|
||||
|| !testenv.same(atrace, wantcommandassembler)
|
||||
|| !testenv.same(commandlink, wantcommandlink)
|
||||
|| testenv.has(commandlink, ".wwi>")) {
|
||||
fail("package-autoaction",
|
||||
"main action arguments or archive closure changed");
|
||||
};
|
||||
let commandunit: str = testenv.readfile(strings.concat(commandwork,
|
||||
"/foo.cmd.unit.ww"));
|
||||
if (!testenv.has(commandunit, "// COMMAND_OWNER")
|
||||
|| testenv.has(commandunit, "// ROOT_A")
|
||||
|| testenv.has(commandunit, "// DEP_SOURCE")) {
|
||||
fail("package-autoaction", "command unit contains foreign sources");
|
||||
};
|
||||
ai = 0;
|
||||
for (ai < suffixes.len) {
|
||||
let commandbytes: str = testenv.readfile(strings.concat(commandwork,
|
||||
"/foo.cmd", suffixes[ai]));
|
||||
if (si == 0) { commandreference[ai] = strings.dup(commandbytes); }
|
||||
else { if (!testenv.same(commandreference[ai], commandbytes)) {
|
||||
fail("package-autoaction",
|
||||
"Cstage and WWstage command artifacts differ");
|
||||
}; };
|
||||
ai += 1;
|
||||
};
|
||||
let commandrun: []str = [commandbin];
|
||||
if (code(td, strings.concat("auto-command-run-", tags[si]),
|
||||
commandrun) != 42) {
|
||||
fail("package-autoaction", "main action binary returned wrong value");
|
||||
};
|
||||
// The public run command must make the same declaration-driven choice;
|
||||
// its private temp paths make exact argv intentionally inapplicable here.
|
||||
let drivercommandrun: []str = [testenv.driver(stages[si]), "run",
|
||||
"-I", source, "foo.cmd"];
|
||||
testenv.runcommand(td, td, strings.concat("auto-driver-command-run-",
|
||||
tags[si]), drivercommandrun, tmo(), &out);
|
||||
if (out.termination != exec.termination.EXIT || out.code != 42
|
||||
|| out.stdout.len != 0 || out.stderr.len != 0) {
|
||||
fail("package-autoaction", "ww run rejected or misran package main");
|
||||
};
|
||||
if (si == 0) {
|
||||
binaryreference = strings.dup(testenv.readfile(commandbin));
|
||||
} else { if (!testenv.same(binaryreference,
|
||||
testenv.readfile(commandbin))) {
|
||||
fail("package-autoaction", "linked stage binaries differ");
|
||||
}; };
|
||||
|
||||
testenv.clean(compilertrace); testenv.writefile(compilertrace, "");
|
||||
testenv.clean(assemblertrace); testenv.writefile(assemblertrace, "");
|
||||
testenv.clean(linkertrace); testenv.writefile(linkertrace, "");
|
||||
let nooutwork: str = strings.concat(td, "/no-output-work-", tags[si]);
|
||||
mkdir(nooutwork);
|
||||
let noout: []str = [testenv.driver(stages[si]), "build",
|
||||
"-w", nooutwork, "-I", source, "foo.bar"];
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-no-output-", tags[si]),
|
||||
noout, env, tmo(), &out);
|
||||
ctrace = testenv.readfile(compilertrace);
|
||||
atrace = testenv.readfile(assemblertrace);
|
||||
let wantnooutcompiler: str = strings.concat(
|
||||
"BEGIN<-c><-I><", nooutwork,
|
||||
"/foo.dep.wwi.new><-o><", nooutwork,
|
||||
"/foo.dep.s.new><", nooutwork, "/foo.dep.unit.new>\n",
|
||||
"BEGIN<-c><--import><foo.dep><", nooutwork,
|
||||
"/foo.dep.wwi><-I><", nooutwork,
|
||||
"/foo.bar.wwi.new><-o><", nooutwork,
|
||||
"/foo.bar.s.new><", nooutwork, "/foo.bar.unit.new>\n");
|
||||
let wantnooutassembler: str = strings.concat(
|
||||
"BEGIN<-o><", nooutwork, "/foo.dep.o.new><", nooutwork,
|
||||
"/foo.dep.s.new>\n",
|
||||
"BEGIN<-o><", nooutwork, "/foo.bar.o.new><", nooutwork,
|
||||
"/foo.bar.s.new>\n");
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| out.stderr.len != 0 || testenv.exists(strings.concat(td, "/bar"))
|
||||
|| !testenv.same(ctrace, wantnooutcompiler)
|
||||
|| !testenv.same(atrace, wantnooutassembler)
|
||||
|| testenv.readfile(linkertrace).len != 0) {
|
||||
fail("package-autoaction",
|
||||
"cold no-output library build did not remain compile-only");
|
||||
};
|
||||
ai = 0;
|
||||
for (ai < suffixes.len) {
|
||||
let nooutroot: str = testenv.readfile(strings.concat(nooutwork,
|
||||
"/foo.bar", suffixes[ai]));
|
||||
let nooutdep: str = testenv.readfile(strings.concat(nooutwork,
|
||||
"/foo.dep", suffixes[ai]));
|
||||
if (!testenv.same(nooutroot, rootreference[ai])
|
||||
|| !testenv.same(nooutdep, depreference[ai])) {
|
||||
fail("package-autoaction",
|
||||
"publication request changed package artifact bytes");
|
||||
};
|
||||
if (si == 0) {
|
||||
nooutrootreference[ai] = strings.dup(nooutroot);
|
||||
nooutdepreference[ai] = strings.dup(nooutdep);
|
||||
} else { if (!testenv.same(nooutrootreference[ai], nooutroot)
|
||||
|| !testenv.same(nooutdepreference[ai], nooutdep)) {
|
||||
fail("package-autoaction",
|
||||
"cold no-output artifacts differ by stage");
|
||||
}; };
|
||||
ai += 1;
|
||||
};
|
||||
// An explicitly empty -o is observably the same no-publication request
|
||||
// in both drivers and therefore reuses the same semantic actions.
|
||||
testenv.clean(compilertrace); testenv.writefile(compilertrace, "");
|
||||
testenv.clean(assemblertrace); testenv.writefile(assemblertrace, "");
|
||||
testenv.clean(linkertrace); testenv.writefile(linkertrace, "");
|
||||
let emptyout: []str = [testenv.driver(stages[si]), "build",
|
||||
"-w", nooutwork, "-I", source, "-o", "", "foo.bar"];
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-empty-output-",
|
||||
tags[si]), emptyout, env, tmo(), &out);
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| out.stderr.len != 0
|
||||
|| testenv.readfile(compilertrace).len != 0
|
||||
|| testenv.readfile(assemblertrace).len != 0
|
||||
|| testenv.readfile(linkertrace).len != 0) {
|
||||
fail("package-autoaction",
|
||||
"empty -o changed no-publication action semantics");
|
||||
};
|
||||
|
||||
// Publication is not semantic action identity: an already-populated
|
||||
// package workdir is reusable when the next request omits -o.
|
||||
testenv.clean(compilertrace); testenv.writefile(compilertrace, "");
|
||||
testenv.clean(assemblertrace); testenv.writefile(assemblertrace, "");
|
||||
testenv.clean(linkertrace); testenv.writefile(linkertrace, "");
|
||||
let warmnoout: []str = [testenv.driver(stages[si]), "build",
|
||||
"-w", work, "-I", source, "foo.bar"];
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-warm-no-output-",
|
||||
tags[si]), warmnoout, env, tmo(), &out);
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| out.stderr.len != 0
|
||||
|| testenv.readfile(compilertrace).len != 0
|
||||
|| testenv.readfile(assemblertrace).len != 0
|
||||
|| testenv.readfile(linkertrace).len != 0) {
|
||||
fail("package-autoaction",
|
||||
"publication request entered persistent action identity");
|
||||
};
|
||||
|
||||
testenv.clean(compilertrace); testenv.writefile(compilertrace, "");
|
||||
testenv.clean(assemblertrace); testenv.writefile(assemblertrace, "");
|
||||
testenv.clean(linkertrace); testenv.writefile(linkertrace, "");
|
||||
let pathwork: str = strings.concat(td, "/path-work-", tags[si]);
|
||||
mkdir(pathwork);
|
||||
let longout: str = strings.concat(td, "/");
|
||||
for (longout.len < 4090) { longout = strings.concat(longout, "x"); };
|
||||
let pathav: []str = [testenv.driver(stages[si]), "build",
|
||||
"-w", pathwork, "-I", source, "-o", longout, "foo.bar"];
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-output-path-", tags[si]),
|
||||
pathav, env, tmo(), &out);
|
||||
let wantpathdiag: str = "ww: package output path is too long\n";
|
||||
if (out.termination != exec.termination.EXIT || out.code != 1
|
||||
|| !testenv.same(out.stderr, wantpathdiag)
|
||||
|| testenv.readfile(compilertrace).len != 0
|
||||
|| testenv.readfile(assemblertrace).len != 0
|
||||
|| testenv.readfile(linkertrace).len != 0
|
||||
|| testenv.exists(strings.concat(pathwork, "/foo.dep.unit.ww"))
|
||||
|| testenv.exists(strings.concat(pathwork, "/foo.bar.unit.ww"))) {
|
||||
fail("package-autoaction",
|
||||
"package publication path failed after the tool boundary");
|
||||
};
|
||||
if (si == 0) { pathdiagreference = strings.dup(out.stderr); }
|
||||
else { if (!testenv.same(pathdiagreference, out.stderr)) {
|
||||
fail("package-autoaction", "output path diagnostics differ by stage");
|
||||
}; };
|
||||
|
||||
// Output publication is unused under -S, so even this spelling must not
|
||||
// participate in an assembly-only action or its failure behavior.
|
||||
testenv.clean(compilertrace); testenv.writefile(compilertrace, "");
|
||||
testenv.clean(assemblertrace); testenv.writefile(assemblertrace, "");
|
||||
testenv.clean(linkertrace); testenv.writefile(linkertrace, "");
|
||||
let asmwork: str = strings.concat(td, "/asm-work-", tags[si]);
|
||||
mkdir(asmwork);
|
||||
let asmav: []str = [testenv.driver(stages[si]), "build", "-S",
|
||||
"-w", asmwork, "-I", source, "-o", longout, "foo.bar"];
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-asm-long-output-",
|
||||
tags[si]), asmav, env, tmo(), &out);
|
||||
let wantasmcompiler: str = strings.concat(
|
||||
"BEGIN<-c><-I><", asmwork,
|
||||
"/foo.dep.wwi.new><-o><", asmwork,
|
||||
"/foo.dep.s.new><", asmwork, "/foo.dep.unit.new>\n",
|
||||
"BEGIN<-c><--import><foo.dep><", asmwork,
|
||||
"/foo.dep.wwi><-I><", asmwork,
|
||||
"/foo.bar.wwi.new><-o><", asmwork,
|
||||
"/foo.bar.s.new><", asmwork, "/foo.bar.unit.new>\n");
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| out.stderr.len != 0
|
||||
|| !testenv.same(testenv.readfile(compilertrace), wantasmcompiler)
|
||||
|| testenv.readfile(assemblertrace).len != 0
|
||||
|| testenv.readfile(linkertrace).len != 0
|
||||
|| testenv.exists(strings.concat(asmwork, "/foo.dep.o"))
|
||||
|| testenv.exists(strings.concat(asmwork, "/foo.dep.a"))
|
||||
|| testenv.exists(strings.concat(asmwork, "/foo.bar.o"))
|
||||
|| testenv.exists(strings.concat(asmwork, "/foo.bar.a"))) {
|
||||
fail("package-autoaction",
|
||||
"assembly-only action consumed an unused publication path");
|
||||
};
|
||||
|
||||
testenv.clean(compilertrace); testenv.writefile(compilertrace, "");
|
||||
testenv.clean(assemblertrace); testenv.writefile(assemblertrace, "");
|
||||
testenv.clean(linkertrace); testenv.writefile(linkertrace, "");
|
||||
let runav: []str = [testenv.driver(stages[si]), "run",
|
||||
"-I", source, "foo.bar"];
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-run-reject-", tags[si]),
|
||||
runav, env, tmo(), &out);
|
||||
let wantdiag: str = "ww: package foo.bar is not a main package\n";
|
||||
if (out.termination != exec.termination.EXIT || out.code != 1
|
||||
|| !testenv.same(out.stderr, wantdiag)
|
||||
|| testenv.readfile(compilertrace).len != 0
|
||||
|| testenv.readfile(assemblertrace).len != 0
|
||||
|| testenv.readfile(linkertrace).len != 0) {
|
||||
fail("package-autoaction", "run crossed the non-main tool boundary");
|
||||
};
|
||||
if (si == 0) { diagnosticreference = strings.dup(out.stderr); }
|
||||
else { if (!testenv.same(diagnosticreference, out.stderr)) {
|
||||
fail("package-autoaction", "run diagnostics differ by stage");
|
||||
}; };
|
||||
|
||||
let cyclerun: []str = [testenv.driver(stages[si]), "run",
|
||||
"-I", source, "foo.cyclea"];
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-run-cycle-", tags[si]),
|
||||
cyclerun, env, tmo(), &out);
|
||||
if (out.termination != exec.termination.EXIT || out.code != 1
|
||||
|| !testenv.has(out.stderr,
|
||||
"ww: dependency cycle: foo.cyclea -> foo.cycleb -> foo.cyclea\n")
|
||||
|| testenv.has(out.stderr, "is not a main package")
|
||||
|| testenv.readfile(compilertrace).len != 0
|
||||
|| testenv.readfile(assemblertrace).len != 0
|
||||
|| testenv.readfile(linkertrace).len != 0) {
|
||||
fail("package-autoaction",
|
||||
"run command-kind validation masked a graph failure");
|
||||
};
|
||||
if (si == 0) { cyclediagreference = strings.dup(out.stderr); }
|
||||
else { if (!testenv.same(cyclediagreference, out.stderr)) {
|
||||
fail("package-autoaction", "run cycle diagnostics differ by stage");
|
||||
}; };
|
||||
|
||||
let cyclepathwork: str = strings.concat(td, "/cycle-path-work-",
|
||||
tags[si]);
|
||||
mkdir(cyclepathwork);
|
||||
let cyclepathav: []str = [testenv.driver(stages[si]), "build",
|
||||
"-w", cyclepathwork, "-I", source, "-o", longout,
|
||||
"foo.cyclea"];
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-cycle-path-", tags[si]),
|
||||
cyclepathav, env, tmo(), &out);
|
||||
if (out.termination != exec.termination.EXIT || out.code != 1
|
||||
|| !testenv.has(out.stderr, "ww: dependency cycle: ")
|
||||
|| !testenv.has(out.stderr, "foo.cyclea")
|
||||
|| !testenv.has(out.stderr, "foo.cycleb")
|
||||
|| testenv.has(out.stderr, "package output path is too long")
|
||||
|| testenv.readfile(compilertrace).len != 0
|
||||
|| testenv.readfile(assemblertrace).len != 0
|
||||
|| testenv.readfile(linkertrace).len != 0) {
|
||||
fail("package-autoaction",
|
||||
strings.concat("publication path validation masked a graph failure: ",
|
||||
out.stderr));
|
||||
};
|
||||
if (si == 0) { cyclepathdiagreference = strings.dup(out.stderr); }
|
||||
else { if (!testenv.same(cyclepathdiagreference, out.stderr)) {
|
||||
fail("package-autoaction",
|
||||
"cycle/output-path diagnostic differs by stage");
|
||||
}; };
|
||||
|
||||
assert(os.remove(depsrc) == 0);
|
||||
testenv.writefile(depsrc, depprivate);
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-private-", tags[si]),
|
||||
av, env, tmo(), &out);
|
||||
ctrace = testenv.readfile(compilertrace);
|
||||
atrace = testenv.readfile(assemblertrace);
|
||||
let wantprivatecompiler: str = strings.concat(
|
||||
"BEGIN<-c><-I><", work,
|
||||
"/foo.dep.wwi.new><-o><", work,
|
||||
"/foo.dep.s.new><", work, "/foo.dep.unit.new>\n");
|
||||
let wantprivateassembler: str = strings.concat(
|
||||
"BEGIN<-o><", work, "/foo.dep.o.new><", work,
|
||||
"/foo.dep.s.new>\n");
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| !testenv.same(ctrace, wantprivatecompiler)
|
||||
|| !testenv.same(atrace, wantprivateassembler)
|
||||
|| testenv.readfile(linkertrace).len != 0
|
||||
|| !testenv.same(rootreference[4], testenv.readfile(strings.concat(
|
||||
work, "/foo.bar.a")))) {
|
||||
fail("package-autoaction",
|
||||
"private dependency change escaped its export boundary");
|
||||
};
|
||||
|
||||
testenv.clean(compilertrace); testenv.writefile(compilertrace, "");
|
||||
testenv.clean(assemblertrace); testenv.writefile(assemblertrace, "");
|
||||
testenv.clean(linkertrace); testenv.writefile(linkertrace, "");
|
||||
assert(os.remove(depsrc) == 0);
|
||||
testenv.writefile(depsrc, depexported);
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-export-", tags[si]),
|
||||
av, env, tmo(), &out);
|
||||
ctrace = testenv.readfile(compilertrace);
|
||||
atrace = testenv.readfile(assemblertrace);
|
||||
let wantexportcompiler: str = strings.concat(
|
||||
"BEGIN<-c><-I><", work,
|
||||
"/foo.dep.wwi.new><-o><", work,
|
||||
"/foo.dep.s.new><", work, "/foo.dep.unit.new>\n",
|
||||
"BEGIN<-c><--import><foo.dep><", work,
|
||||
"/foo.dep.wwi><-I><", work,
|
||||
"/foo.bar.wwi.new><-o><", work,
|
||||
"/foo.bar.s.new><", work, "/foo.bar.unit.new>\n");
|
||||
let wantexportassembler: str = strings.concat(
|
||||
"BEGIN<-o><", work, "/foo.dep.o.new><", work,
|
||||
"/foo.dep.s.new>\n",
|
||||
"BEGIN<-o><", work, "/foo.bar.o.new><", work,
|
||||
"/foo.bar.s.new>\n");
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| !testenv.same(ctrace, wantexportcompiler)
|
||||
|| !testenv.same(atrace, wantexportassembler)
|
||||
|| testenv.readfile(linkertrace).len != 0) {
|
||||
fail("package-autoaction",
|
||||
"exported dependency change did not reach its direct importer");
|
||||
};
|
||||
|
||||
testenv.clean(compilertrace); testenv.writefile(compilertrace, "");
|
||||
testenv.clean(assemblertrace); testenv.writefile(assemblertrace, "");
|
||||
testenv.clean(linkertrace); testenv.writefile(linkertrace, "");
|
||||
testenv.runcommandenv(td, td, strings.concat("auto-warm-", tags[si]),
|
||||
av, env, tmo(), &out);
|
||||
if (out.termination != exec.termination.EXIT || out.code != 0
|
||||
|| out.stderr.len != 0
|
||||
|| testenv.readfile(compilertrace).len != 0
|
||||
|| testenv.readfile(assemblertrace).len != 0
|
||||
|| testenv.readfile(linkertrace).len != 0) {
|
||||
fail("package-autoaction", "warm library build did not fully reuse");
|
||||
};
|
||||
assert(os.remove(depsrc) == 0);
|
||||
testenv.writefile(depsrc, depbase);
|
||||
si += 1;
|
||||
};
|
||||
testenv.clean(td);
|
||||
};
|
||||
|
||||
@test fn generated_test_hook_is_not_a_user_exemption() void = {
|
||||
let td: str = testenv.fresh();
|
||||
let src: str = strings.concat(td, "/case.ww");
|
||||
|
||||
Reference in New Issue
Block a user