test: prove canonical directory package identity

This commit is contained in:
2026-08-13 02:48:17 +09:00
parent 0aff801def
commit cc6799c3b1
5 changed files with 530 additions and 149 deletions

View File

@@ -88,6 +88,7 @@ fn samefile(a: str, b: str, why: str) void = {
let cwork: str = strings.concat(stems[0], ".sepwork/");
let cwork2: str = strings.concat(stems[1], ".sepwork/");
let wwork: str = strings.concat(stems[2], ".sepwork/");
let appidentity: str = testenv.localpackageidentity(app, "main");
let foounit: str = testenv.readfile(strings.concat(cwork,
"example.foo.unit.ww"));
let wantfoo: str = strings.concat("//ww:module-reset example.foo\n", afoosrc,
@@ -97,14 +98,15 @@ fn samefile(a: str, b: str, why: str) void = {
|| testenv.has(foounit, "//ww:module ")) {
fail("foo unit is not exactly its sorted, owned source set");
};
let wantroot: str = strings.concat("//ww:module-reset main\n", appsrc,
let wantroot: str = strings.concat("//ww:module-reset ", appidentity,
"\n", appsrc,
"\n");
if (!testenv.same(wantroot, testenv.readfile(strings.concat(cwork,
"main.unit.ww")))) {
appidentity, ".unit.ww")))) {
fail("root unit is not exactly its owned source");
};
let keys: []str = ["example.base", "example.bar", "example.foo",
"main"];
appidentity];
let suffixes: []str = [".unit.ww", ".wwi", ".a"];
i = 0;
for (i < keys.len) {
@@ -122,6 +124,47 @@ fn samefile(a: str, b: str, why: str) void = {
samefile(stems[0], stems[1], "C executables are not deterministic");
samefile(stems[0], stems[2], "C/WW executables differ");
// The same canonical directory is now observed as an imported dependency,
// a literal root, an explicit logical root, an equivalent path spelling,
// and a symlink spelling. Every route must publish the one example.foo
// action with byte-identical owner unit, export, and archive.
let fooalias: str = strings.concat(td, "/foo-alias");
assert(os.symlink(foo, fooalias) == 0);
let rootouts: []str = [strings.concat(td, "/foo-root-c"),
strings.concat(td, "/foo-root-w"),
strings.concat(td, "/foo-logical-c"),
strings.concat(td, "/foo-logical-w"),
strings.concat(td, "/foo-equivalent-c"),
strings.concat(td, "/foo-equivalent-w"),
strings.concat(td, "/foo-relative-c"),
strings.concat(td, "/foo-relative-w"),
strings.concat(td, "/foo-alias-c"),
strings.concat(td, "/foo-alias-w")];
let rootdrivers: []str = ["ww", "ww_ww", "ww", "ww_ww", "ww",
"ww_ww", "ww", "ww_ww", "ww", "ww_ww"];
let roottags: []str = ["literal-c", "literal-w", "logical-c",
"logical-w", "equivalent-c", "equivalent-w", "relative-c",
"relative-w", "alias-c", "alias-w"];
let roottargets: []str = [foo, foo, "example.foo", "example.foo",
strings.concat(foo, "/../foo"), strings.concat(foo, "/../foo"),
"late/example/foo", "late/example/foo", fooalias, fooalias];
i = 0;
for (i < rootouts.len) {
let rav: []str = [testenv.driver(rootdrivers[i]), "build", "-p",
"-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/");
let rsuffixes: []str = [".unit.ww", ".wwi", ".a"];
let ri: i32 = 0;
for (ri < rsuffixes.len) {
let artifact: str = strings.concat("example.foo", rsuffixes[ri]);
samefile(strings.concat(cwork, artifact), strings.concat(rw, artifact),
"canonical foo action changed across root spellings");
ri += 1;
};
i += 1;
};
let cerr: testenv.commandout;
let werr: testenv.commandout;
let cav: []str = [testenv.driver("ww"), "build", "-I", early,

View File

@@ -132,7 +132,7 @@ fn rejectstable(dir: str, label: str, target: str, needle: str) void = {
@test fn standalone_and_package_artifact() void = {
let td: str = testenv.fresh();
let app: str = strings.concat(td, "/app");
let app: str = strings.concat(td, "/main");
mkdir(app);
testenv.writefile(strings.concat(app, "/main.ww"), strings.concat(
"package main;\n",
@@ -459,11 +459,11 @@ fn writediamond(td: str, reverse: bool) str = {
@test fn toolchain_library_root_stage_parity() void = {
let td: str = testenv.fresh();
let source: str = strings.concat(td, "/source library");
let app: str = strings.concat(source, "/app");
let app: str = strings.concat(source, "/main");
let dep: str = strings.concat(source, "/dep");
let leaf: str = strings.concat(source, "/leaf");
let runtime: str = strings.concat(td, "/runtime library");
let decoy: str = strings.concat(runtime, "/app");
let decoy: str = strings.concat(runtime, "/main");
let tools: str = strings.concat(td, "/tool wrappers");
let cwd: str = strings.concat(td, "/isolated cwd");
let defaultapp: str = strings.concat(td, "/default app");
@@ -556,7 +556,7 @@ fn writediamond(td: str, reverse: bool) str = {
testenv.driver(assemblers[si]),
testenv.driver(linkers[si]));
let av: []str = [testenv.driver(stages[si]), "build", "-o", bin,
"app"];
"main"];
let out: testenv.commandout;
testenv.runcommandenv(cwd, td, strings.concat("library-root-", prefix),
av, env, tmo(), &out);
@@ -701,6 +701,7 @@ fn writediamond(td: str, reverse: bool) str = {
let emptyassemblerreference: str = "";
let emptylinkerreference: str = "";
let emptyout: str = strings.concat(td, "/empty published binary");
let emptyidentity: str = testenv.localpackageidentity(defaultapp, "main");
let si: i32 = 0;
for (si < stages.len) {
let outpath: str = emptyout;
@@ -727,7 +728,7 @@ fn writediamond(td: str, reverse: bool) str = {
testenv.runcommandenv(cwd, td, strings.concat("empty-library-",
tags[si]), av, emptyenv, tmo(), &out);
let rootunit: str = testenv.readfile(strings.concat(emptywork,
"main.unit.ww"));
emptyidentity, ".unit.ww"));
let ctrace: str = testenv.readfile(compilertrace);
let atrace: str = testenv.readfile(assemblertrace);
let ltrace: str = testenv.readfile(linkertrace);
@@ -738,7 +739,8 @@ fn writediamond(td: str, reverse: bool) str = {
runav) != 42) {
fail("library-roots", "empty override did not use default roots");
};
if (!testenv.has(rootunit, "//ww:module-reset main\npackage main;")
if (!testenv.has(rootunit, strings.concat("//ww:module-reset ",
emptyidentity, "\npackage main;"))
|| testenv.has(rootunit, "//ww:module ")
|| !testenv.exists(strings.concat(emptywork, "types.wwi"))
|| !testenv.exists(strings.concat(emptywork, "types.a"))
@@ -789,7 +791,7 @@ fn writediamond(td: str, reverse: bool) str = {
@test fn persistent_build_reuse_tracks_driver_identity() void = {
let td: str = testenv.fresh();
let source: str = strings.concat(td, "/source tree");
let app: str = strings.concat(source, "/app");
let app: str = strings.concat(source, "/main");
let dep: str = strings.concat(source, "/dep");
let leaf: str = strings.concat(source, "/leaf");
let tools: str = strings.concat(td, "/tool wrappers");
@@ -871,7 +873,7 @@ fn writediamond(td: str, reverse: bool) str = {
testenv.driver(assemblers[si]),
testenv.driver(linkers[si]));
let av: []str = [copied[si], "build", "-w", work,
"-o", bin, "app"];
"-o", bin, "main"];
let out: testenv.commandout;
testenv.runcommandenv(cwd, td, strings.concat("driver-cold-",
tags[si]), av, env, tmo(), &out);
@@ -905,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 7 mode build asm 0\n")) {
"ww workdir fmt 8 mode build asm 0\n")) {
fail("driver-identity", "persistent artifacts or identities are incomplete");
};
let coldwwi: str = testenv.readfile(strings.concat(work, "/dep.wwi"));
@@ -1049,7 +1051,7 @@ fn writediamond(td: str, reverse: bool) str = {
let missingwork: str = strings.concat(td, "/missing workdir");
let missingbin: str = strings.concat(td, "/missing binary");
let badav: []str = [copied[si], "build", "-w", missingwork,
"-o", missingbin, "app"];
"-o", missingbin, "main"];
testenv.runcommandenv(cwd, td, strings.concat("driver-missing-",
tags[si]), badav, env, tmo(), &out);
let wantdiag: str = strings.concat("ww: workdir ", missingwork,