build: make executable and test roots package actions

This commit is contained in:
2026-08-12 22:00:02 +09:00
parent fc4bde703e
commit 1724ea086f
11 changed files with 722 additions and 364 deletions

View File

@@ -4,12 +4,11 @@ package seplink_test;
// retired native carriers test/wcc/989_separchive_run.c and
// 989_sepcycle_dup.c; every assertion preserved.
//
// archive (#46 commit-5a) — `ww build` wraps each DEP package's .o in
// a deterministic single-member .a and links the ROOT as a positional
// .o (force-loaded): build+run exit 7 both stages; __root.a absent,
// __root.o + helper.a present; cs helper.a == ww helper.a (rule 10,
// the .a byte-id substrate); 3 cold cstage rebuilds emit
// byte-identical helper.a (zeroed mtime/uid/gid, fixed mode/member —
// archive — `ww build` wraps every package action's .o in the existing
// deterministic single-member .a and links the root archive first:
// build+run exit 7 both stages; __root.a + helper.a present; both archives
// are byte-identical across stages; 3 cold cstage rebuilds emit
// byte-identical archives (zeroed mtime/uid/gid, fixed mode/member —
// a floating byte would poison the content cache key).
//
// archivedup (#31 PASS 3) — two dep packages force the same link
@@ -94,22 +93,20 @@ fn runcode(dir: str, name: str, argv: []str) i32 = {
s += 1;
};
// layout: root stays a positional force-loaded .o, deps become .a
if (testenv.exists(strings.concat(td, "/prog.cs.sepwork/__root.a"))) {
fail("archive", "root wrapped in .a (should stay positional .o)");
};
if (!testenv.exists(strings.concat(td, "/prog.cs.sepwork/__root.o"))) {
fail("archive", "missing root .o");
};
if (!testenv.exists(strings.concat(td, "/prog.cs.sepwork/helper.a"))) {
fail("archive", "missing dep helper.a");
// layout: root and dependency are both package archives.
if (!testenv.exists(strings.concat(td, "/prog.cs.sepwork/__root.a"))
|| !testenv.exists(strings.concat(td, "/prog.cs.sepwork/helper.a"))) {
fail("archive", "missing root or dependency archive");
};
// rule 10: the .a byte-id substrate
// rule 10: the complete .a byte-id substrate
if (!testenv.same(
testenv.readfile(strings.concat(td, "/prog.cs.sepwork/helper.a")),
testenv.readfile(strings.concat(td, "/prog.ww.sepwork/helper.a")))) {
fail("archive", "cs helper.a != ww helper.a (rule 10 .a byte-id)");
testenv.readfile(strings.concat(td, "/prog.ww.sepwork/helper.a")))
|| !testenv.same(
testenv.readfile(strings.concat(td, "/prog.cs.sepwork/__root.a")),
testenv.readfile(strings.concat(td, "/prog.ww.sepwork/__root.a")))) {
fail("archive", "cs package archives != ww package archives");
};
// determinism: 3 cold cstage rebuilds -> byte-identical .a
@@ -132,9 +129,18 @@ fn runcode(dir: str, name: str, argv: []str) i32 = {
let a2: str = testenv.readfile(strings.concat(det2,
".sepwork/helper.a"));
if (!testenv.same(a0, a1) || !testenv.same(a1, a2)) {
fail("archive", strings.concat(".a not deterministic across 3 ",
fail("archive", strings.concat("dependency .a not deterministic across 3 ",
"builds (floating bytes poison the cache key)"));
};
let r0: str = testenv.readfile(strings.concat(det0,
".sepwork/__root.a"));
let r1: str = testenv.readfile(strings.concat(det1,
".sepwork/__root.a"));
let r2: str = testenv.readfile(strings.concat(det2,
".sepwork/__root.a"));
if (!testenv.same(r0, r1) || !testenv.same(r1, r2)) {
fail("archive", "root .a not deterministic across 3 builds");
};
testenv.clean(td);
};