ww test: retain directory test binaries like Go

This commit is contained in:
2026-08-20 20:13:08 +09:00
parent f28843f2f5
commit db5782eff9
10 changed files with 1014 additions and 213 deletions

View File

@@ -216,18 +216,28 @@ test binaries concurrently under `os.exec` start/poll supervision (no threads);
emission stays strictly in group order, so the byte stream is identical at
every `-j` level, and `-j 1` — the default — matches the former sequential
run loop exactly. Measured on the 31-package `lib/...` walk:
7.0s sequential, 2.4s at `-j 4`. With `-c`, it publishes each exact
`<package>.test` directory binary; the first output owns the one
shared cold sepwork containing the command-global action universe. Those become
caller-owned artifacts. `-c -o <name>`
names that artifact instead of the fixed stem for exactly one directory,
including a combined internal/external directory:
the coordinator rejects a multi-package fan-out ("cannot use -o with
multiple packages", Go's `go test -o` rule), and `-o` without `-c` is
rejected at the driver ("needs -c for a package target") because a plain
run leaves no caller-owned artifact for `-o` to name. Without `-c`, it removes the
temporary binary and scratch with its workspace. The language runtime
owns individual `@test` functions.
7.0s sequential, 2.4s at `-j 4`.
Directory test binaries are always linked under the coordinator's temporary
product root. `-c` independently requests a caller-visible executable copy and
suppresses execution. `-o` independently requests a copy and still runs the
temporary binary unless `-c` is also present. Without `-o`, `-c` publishes
`<import-leaf>.test` in the invocation directory; an output ending in `/` or
naming an existing directory receives one such name per selected package and
missing parents are created. A single non-directory output is legal for one
package only. Multi-package non-directory output and duplicate visible binary
names reject before tools; exact `/dev/null` discards every copy and permits
duplicate names. A package with no selected test source validates production
but publishes nothing and does not create an otherwise unneeded output
directory. Successful `-c` output is silent apart from no-test reporting.
The retained executable is byte-identical to the temporary runnable and has
executable mode `0777` filtered by the caller's umask, but it is never the path
executed by the coordinator. Publication participates in the driver's one
request-wide transaction: producer, linker, staging, or installation failure
preserves every prior destination and removes stages and newly created output
prefixes. A runtime failure occurs after commit and therefore leaves the saved
binary. The language runtime owns individual `@test` functions.
Every actually executed directory product gives its single generated binary
the product's canonical absolute physical source directory as child cwd. A
@@ -409,16 +419,19 @@ bounded-memory Cstage/WWstage allocation-failure parity across the complete
combined package-test graph, under independently discovered ceilings supplied
by the repository-built `sep-limitexec` helper.
`ww build`, an explicit single-file `ww test -o <stem>`, and each successful
directory-package `ww test -c` build publish `<stem>.sepwork` as a caller-owned
artifact directory. The driver acquires it with one fresh `mkdir` and refuses
an existing path; it never clears a collision. A caller keeps only the exact
artifacts it observes and removes that exact tree on every later success or
failure. `ww run` and no-output single-file `ww test` use driver-owned scratch
instead; both driver stages place that scratch and their temporary executable
beneath one freshly acquired directory, remove both after every build result,
and make cleanup failure fail the command. Make recipes build driver-produced
tools in invocation-owned directories and apply the same exact cleanup rule.
`ww build` and an explicit single-file `ww test -o <stem>` publish
`<stem>.sepwork` as a caller-owned artifact directory. The driver acquires it
with one fresh `mkdir` and refuses an existing path; it never clears a
collision. A caller keeps only the exact artifacts it observes and removes
that exact tree on every later success or failure. Directory-package test
plans instead keep their cold semantic-action scratch and runnable binary
inside the coordinator's temporary root; only the optional retained executable
escapes through the transaction above. `ww run` and no-output single-file
`ww test` use driver-owned scratch instead; both driver stages place that
scratch and their temporary executable beneath one freshly acquired directory,
remove both after every build result, and make cleanup failure fail the
command. Make recipes build driver-produced tools in invocation-owned
directories and apply the same exact cleanup rule.
`ww build -w DIR` and single-file `ww test -w DIR` replace that scratch with a
caller-owned persistent package-artifact workdir: for these direct routes the
@@ -561,8 +574,8 @@ timeout policy in this architecture.
## Open driver work
None; the package-level `-o` contract (the last carried bullet) landed as
`-c -o <name>` for exactly one package.
None; directory-package `-c` and `-o` now have the applicable Go 1.26.5
retention, naming, fan-out, execution, and publication behavior.
## Validation policy