test: cover shared directory test build plans

This commit is contained in:
2026-08-12 11:42:29 +09:00
parent dd975d195c
commit 02574c88f1
2 changed files with 326 additions and 72 deletions

View File

@@ -2849,11 +2849,16 @@ has one test variant; the coordinator rejects one output name for a multi-varian
or recursive request. Explicit `ww test FILE` retains its compatibility path.
The test coordinator still discovers requested directories, enumerates the
test package names, schedules independent binaries, executes them, and emits
test package names, selects variants, executes independent binaries, and emits
captured results in byte-sorted package order. It no longer concatenates a
generated production/test root or resolves imports. Instead it asks the Cstage
or WWstage command to build one of two non-importable root variants from the
real directory:
generated production/test root, resolves imports, or starts one package graph
per binary. Instead it sends one ordered build request per directory to the
Cstage or WWstage command. Its semantic selections are only the directory and
the selected variant/package identities; it also carries output destinations,
coordinator-private completion paths, import search roots, and the optional
shared work-directory policy. The command owns source selection,
package loading, compiler inputs, archive construction, and linking for both
non-importable roots:
- `same-test` selects the byte-sorted production files followed by the
byte-sorted matching `package p` test files. They form one compiler unit, so
@@ -2863,32 +2868,55 @@ real directory:
directory. That node selects every production file, emits `p.wwi` and `p.a`,
and exposes no private declaration to the external root.
The command loads those roots into one command-scoped package universe. The
roots retain distinct artifact keys (`__ww-test-same` and
`__ww-test-external`) that cannot collide with a legal import identity,
while imports of the same canonical production directory intern to one
production node. A deterministic dependency-first traversal of the union
therefore invokes the compiler and archiver once for every reachable canonical
production package, even when both test products need it. Each root is still
compiled once with its own selected sources and linked separately. The shared
plan is deliberately package-test-specific: it is not a generalized scheduler,
action schema, cache, or protocol.
A production action failure blocks exactly the roots that reach it. A
root-local compile or link failure does not suppress a successfully built
sibling product: the command records completion per product, and the
coordinator can run and report successful siblings while attributing each
missing product as a build failure. Directory builds and completed test
products share the coordinator's existing `-j` process bound; captured output
is still emitted only in byte-sorted directory/package order.
Every non-root dependency is always a production variant, so dependency
`*_test.ww` files never enter the graph. Imports that occur only in selected
test files add edges only to that test root. The compiler unit for each package
contains only its byte-sorted direct dependency `.wwi` artifacts; the final
test link still receives the root object and the complete reverse-topological
archive closure. The compiler-generated `-T` dispatcher owns the implicit
direct test-runtime support edge and remains embedded in each independent test
root. The command resolves that edge from the selected toolchain source tree,
not the user search path. Normally its graph qualifier is `test`, so an explicit
source `import test` coalesces with the same canonical package. When a real user
package occupies that identity, the command presents the runtime edge to the
compiler under the reserved `__wwtest` qualifier. This keeps a production
package named `test` available to external tests while preserving raw `w6c -T`
compatibility, whose default unresolved qualifier remains `test`.
direct test-runtime support edge and remains embedded in each independently
compiled test root; it is the narrow test-main variant, not a
coordinator-generated graph package. The shared plan compiles the common
runtime production package once. The command resolves that edge from the
selected toolchain source tree, not the user search path. Normally its graph
qualifier is `test`, so an explicit source `import test` coalesces with the same
canonical package. When a real user package occupies that identity, the command
presents the runtime edge to the compiler under the reserved `__wwtest`
qualifier. This keeps a production package named `test` available to external
tests while preserving raw `w6c -T` compatibility, whose default unresolved
qualifier remains `test`.
The selected test root and a production variant reached by its imports or test
runtime closure are the only sanctioned pair of graph nodes that may share a
The selected test roots and a production variant reached by their imports or
test-runtime closure are the only sanctioned graph nodes that may share a
physical directory. This also lets a toolchain package's own tests coexist with
the production variant required by the test runtime. A same-package root
already defines those production symbols, so the duplicate production archive
is omitted from its final link while that node's dependency archives remain in
the closure. All ordinary logical and physical package-identity collision
checks remain unchanged. Recursive
discovery groups by physical directory before sorting filenames, and persistent
coordinator work directories use an injective escaped `(directory, test
package)` key. Every `*_test.ww` package variant is built even when a file only
already defines those production symbols, so the production archive is omitted
from that product's final link while the production node's dependency archives
remain in its closure. The external product includes the production archive.
Variant-only archives are never linked into the other product. All ordinary
logical and physical package-identity collision checks remain unchanged.
Recursive discovery groups by physical directory before sorting filenames, and
persistent coordinator work directories use one injective escaped directory
plan key. Every `*_test.ww` package variant is built even when a file only
declares helpers and contains no `@test`, so its package clause and imports are
still checked by the shared loader. Every built variant is run, and a successful
compiler-owned dispatcher with empty output is reported as `[no tests]`.
@@ -2896,9 +2924,15 @@ compiler-owned dispatcher with empty output is reported as `[no tests]`.
This ownership split follows Go 1.26.5's separation of production,
same-package-test, external-test, and generated test-main inputs in
[`cmd/go/internal/load/test.go`](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/load/test.go),
while retaining WW's compiler-owned dispatcher. Direct compile dependencies and
the separately expanded link closure follow the boundary in
[`cmd/go/internal/work/action.go`](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/action.go).
while retaining WW's compiler-owned dispatcher. Go's loader returns the same
cached package pointer for repeated imports, and its command-scoped builder
deduplicates compile actions by package identity; WW borrows that one-universe,
multi-root ownership boundary without borrowing Go's cache machinery. Direct
compile dependencies and the separately expanded link closure follow the
boundary in
[`cmd/go/internal/work/action.go`](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/action.go),
with compiler and linker import configurations emitted separately in
[`cmd/go/internal/work/exec.go`](https://go.googlesource.com/go/+/refs/tags/go1.26.5/src/cmd/go/internal/work/exec.go).
## 12. Candidate architectures and hard-gate decision