test: prove canonical directory test products

This commit is contained in:
2026-08-15 02:50:00 +09:00
parent 8dad2755b3
commit 7d73d31b38
6 changed files with 2935 additions and 1806 deletions

View File

@@ -2829,7 +2829,8 @@ and every component of the canonical import path. A selected command directory
declares `package main` while retaining its complete canonical import identity.
A source import of a command package from a
different directory is rejected; the one same-directory exception is an
external `main_test` variant's canonical import of its production action. Two
external `main_test` variant's canonical import of its effective augmented
test action. Two
ordinary logical identities for one physical directory are rejected rather
than compiled twice; section 11.16 records the deliberate exception for
distinct expanded vendor routes that converge through symlinks.
@@ -2948,54 +2949,57 @@ supported manifest-free forms include `ww build DIR...`, `ww build DIR/...`,
`ww test DIR...`, and `ww test DIR/...`, with overlapping direct and recursive
roots. Test retains its existing `-run`, `-filter`, `-list`, `-timeout-ms`,
`-j`, `-c`, and `-w` forms. `ww test -c -o test.bin DIR` names the result when
the selected directory has one test variant; the coordinator rejects one output
name for a multi-variant or recursive test request. Explicit `ww test FILE`
retains its compatibility path.
the request selects one canonical directory, including a directory with both
same-package and external-package test sources. The coordinator rejects one
output name only when it would fan out over multiple directory products.
Explicit `ww test FILE` retains its compatibility path.
The test coordinator still discovers requested directories, enumerates the
test package names, selects variants, executes independent binaries, and emits
captured results in byte-sorted package order. It no longer concatenates a
The test coordinator still discovers requested directories, classifies the
selected test package names, executes one binary per test-bearing canonical
directory, and emits captured results in byte-sorted directory order. It no
longer concatenates a
generated production/test root, resolves imports, or starts one package graph
per binary or directory. Instead it sends one ordered build request containing
every selected directory/variant root to the Cstage or WWstage command. Its
semantic selections are only the directory and selected variant/package
identities; it also carries output destinations, coordinator-private completion
paths, import search roots, and the optional command-scoped work-directory
policy. The command owns source selection, package loading, compiler inputs,
archive construction, generated-main construction, and linking for every
package variant:
per declared test package. Instead it sends one ordered build request containing
one product descriptor per selected directory, with optional production,
same-package, and external-package selectors, to the Cstage or WWstage command.
It also carries output destinations, coordinator-private completion paths,
import search roots, and the optional command-scoped work-directory policy.
The command owns source selection, package loading, substitution, compiler
inputs, archive construction, the single generated main, and linking:
- The ordinary production action selects the directory's byte-sorted non-test
files. A no-test requested product uses this action directly, and every
ordinary, internal-test, or external-test import of that package reuses it.
files. A no-test request uses this action directly. Ordinary builds and
dependencies outside a tested closure continue to use it.
- The internal production-plus-test variant selects the byte-sorted production
files followed by byte-sorted matching `package p` test files. It is distinct
from production so its private production declarations and test declarations
remain isolated to that test product.
from production, exports declarations contributed by internal test files, and
replaces the ordinary action throughout the applicable tested closure.
- When production sources establish `p`, the external variant selects only
matching `package p_test` files, where `p` is the production declaration
rather than an import-path leaf. A test-only directory may establish its own
one consistent test package name, matching pinned `go/build` classification.
A real source import of the production package uses its canonical import
path and is a direct edge to the same ordinary production action used by
ordinary products and transitive imports; there is no external-production
role or artifact.
`p`, `p_test`, or valid `p`/`p_test` pair, matching pinned `go/build`
classification. The external action's import of the package under test binds
to the augmented internal action when it exists. Importers affected by that
replacement are copied and rewired transitively; an ordinary and augmented
instance of one canonical package never coexist in the linked test closure.
- Generated main is a separate package action whose owner-only generated unit
declares `package main` and imports exactly the selected variant and test
support. It consumes those direct `.wwi` files, emits its own `.wwi/.o/.a`,
and alone receives compiler `-T --entry`. Its target edge also receives the
compiler-private `--test-target-package <canonical-path>` binding. That
private canonical-path qualifier prevents a tested command declared `main`
from colliding with generated main; it is not user alias syntax.
declares `package main` and imports every applicable internal/external target
plus test support. It consumes those direct `.wwi` files, emits its own
`.wwi/.o/.a`, and alone receives compiler `-T --entry`. Repeated byte-sorted
`--test-target-package <canonical-path>` arguments identify the target set.
Those compiler-private canonical qualifiers prevent declared-name collisions;
they are not user alias syntax.
The authoritative directory-action identity is the triple **(canonical
filesystem directory, canonical ordinary import path, semantic variant)**.
The semantic variants are production, internal production-plus-test, and
external `_test`; generated main and the reserved test-support alias are
explicit non-directory action classes. The declared package name is stored
separately and is not part of canonical directory/path interning. Requested-root
state, discovery role, product ordinal, output path, persistent artifact key,
and discovery order never enter the triple.
The coordinator groups one test product by canonical directory, but physical
location is not a compiler/package identity. The authoritative action key uses
the finalized canonical dotted import identity, semantic variant, role, and,
for a copy made by recompile-for-test, the owning canonical directory product's
stable test identity. The semantic variants are production,
production-plus-same-package-test, external `_test`, directory generated main,
and recompiled-for-test. The declared package name, local import binding,
request spelling, path leaf, source filename, artifact basename, product
ordinal, output path, and discovery order are presentation or source-location
state and never substitute for that key.
A literal directory root may enter the interner before its full import spelling
is known. It is provisionally interned by canonical directory and variant, and
@@ -3059,19 +3063,19 @@ introduces a package registry.
Artifact publication follows the semantic action instead of product order:
production uses the full finalized ordinary identity, internal appends
`-internal-test`, external appends `_test-external-test`, and their generated
mains append `-main`. Generated package identities are likewise derived from
the full variant identity, for example `__wwtestmain.a.foo.internal.main` and
`__wwtestmain.b.foo_test.external.main`. Equivalent products therefore reuse an
already-interned directory action and generated-main action and publish through
the same persistent-workdir slots regardless of discovery or product order.
`-internal-test`, external appends `_test-external-test`, and the one
directory-owned generated main appends `-test-main`. Its package identity is
`__wwtestmain.<canonical-directory-product-base>.main`, independent of either
declared test name. Equivalent roots therefore converge on one directory
product and reuse already interned actions and persistent-workdir slots
regardless of discovery or request order.
The narrow raw single-file compatibility path alone retains `__root`.
A deterministic dependency-first traversal of the complete command union
invokes the compiler, assembler, and in-driver deterministic archiver once per
interned action. This is compile-time interning, not linker-argument
deduplication. Each product is then linked separately from its generated-main
or executable root archive and the complete reachable archive closure. The
deduplication. Each canonical directory product is linked once from its single
generated-main root archive and the complete reachable archive closure. The
shared plan remains package-test-specific; it is not a generalized scheduler,
action schema, cache, or protocol.
@@ -3095,15 +3099,19 @@ a rejected union build. After one successful union build, the completed test
products share the coordinator's existing `-j` process bound; captured output
is still emitted only in byte-sorted directory/package order.
Every source-imported dependency is 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 internal or external variant. Each compiler
unit contains only its action's owned source set, while its invocation receives
only the byte-sorted direct dependency `.wwi` artifacts as separate inputs.
Ordinary production loading never selects dependency `*_test.ww` files.
Imports that occur only in selected test files add edges only to the applicable
internal or external action. Recompile-for-test may create a product-scoped copy
of an ordinary transitive importer, but that copy retains the importer's
production source unit and changes only canonical dependency targets. Each
compiler unit contains only its action's owned source set, while its invocation
receives only the byte-sorted direct dependency `.wwi` artifacts as separate
inputs.
Variant compiles receive `--test-package`, which validates and retains private
`@test` declarations as compiler-only export metadata without synthesizing an
entry point. The distinct generated-main action consumes that metadata from its
direct variant export and synthesizes the dispatcher with `-T`.
entry point. The distinct directory generated-main action consumes that
metadata from every direct target export and synthesizes one dispatcher with
`-T`.
The generated-main action, rather than the tested variant, owns the implicit
direct test-runtime support edge. The command-scoped plan compiles the common
@@ -3125,22 +3133,23 @@ coexist only because the former is explicitly rebound to the compiler-only
qualifier `__wwtest`. This is the sole role-based directory alias and cannot be
created by a source import. The separate expanded-vendor-route exception in
section 11.16 is canonical source-tree identity, not a role alias. All ordinary
production actions, including an external test's colocated production
dependency, use canonical directory identity and the global bidirectional
import-path checks above. There is no role-based tolerance for duplicate
ordinary import identities and no late product-closure ambiguity to resolve.
and test actions use canonical action identity and the global bidirectional
import-path checks above. External self-import substitution changes the target
action, never the source spelling or file-local binding. There is no role-based
tolerance for duplicate ordinary import identities and no late product-closure
ambiguity to resolve.
The selected internal/external variants and a production action reached by
their imports or test-runtime closure are the sanctioned graph nodes that may
share a physical directory. This also lets a toolchain package's own tests
coexist with the production action required by the test runtime. An internal
variant already defines those production symbols, so the colocated production
archive is omitted from that product's final link while the production action's
dependency archives remain in the closure. The external product includes the
production archive. Variant-only archives are never linked into another
product. All ordinary logical and physical package-identity collision checks
remain unchanged; only distinct expanded vendor routes receive the section
11.16 symlink-convergence exception.
Production, internal, and external actions may select source from one physical
directory, but the final directory test closure is strict: wherever the
augmented internal action substitutes for production, every affected direct and
transitive edge is rewired before tools. A closure containing both ordinary
`p` and its augmented `ptest` is rejected rather than hidden by initialization
or linker filtering. The external action therefore sees internal-test exports
through `ptest`, and the one linked process owns exactly one package state.
Variant-only archives never leak into an unrelated directory product. All
ordinary logical and physical package-identity collision checks remain
unchanged; only distinct expanded vendor routes receive the section 11.16
symlink-convergence exception.
Both stage linkers receive the generated-main archive first, followed by the
complete reverse-topological reachable package-archive closure, runtime, and
@@ -3155,10 +3164,13 @@ one stable escape of the canonical discovery directory names the persistent
command work directory. It contains neither a declared package leaf nor a
product ordinal, so equivalent path spellings and reordered products select the
same request state.
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]`.
Every selected `*_test.ww` package variant is built even when its files only
declare helpers and contain no `@test`, so its package clause and imports are
still checked; that is a real zero-test package and runs one empty combined
harness. A directory with no selected test files instead follows the no-real-run
path: validate/compile ordinary production as needed, publish status only, and
create no support action, generated main, link, binary, result, or process. The
coordinator alone emits its `[no tests]` report.
Persistent workdirs keep a global driver/compiler/assembler/stamp identity and
per-action committed units. When that global identity is stale, the command
@@ -3175,12 +3187,9 @@ stops as soon as a regenerated importer export is byte-identical. Stable
semantic artifact keys make that behavior independent of which ordinary or
test product first discovered the action.
This ownership split follows the pinned Go 1.26.5 implementation cited in
section 11.12: its loader reuses canonical cached package objects, its work
builder interns actions by mode and package, and its test loader reuses ordinary
production while constructing only the required internal, external, and
generated-main variants. WW borrows that command-global ownership boundary
without adding Go's build cache, import configuration format, or module system.
The completed topology and its pinned Go 1.26.5 evidence are specified in
section 11.22. WW borrows that command-global action boundary without adding
Go's build cache, import-configuration format, or module system.
### 11.8 Implemented exact package-tool invocation slice
@@ -3389,7 +3398,8 @@ imports use their explicit compiler-owned bindings. Executable linking
independently walks the full reachable package
closure and passes archives, never interfaces. The same path handles an
ordinary package, the production-plus-internal-test variant, the external test
package and its reused production package, compiler-generated test main, and
package and its effective production-or-augmented self dependency,
compiler-generated directory test main, and
the reserved test-support package. Persistent workdirs compare a newly emitted
export with its committed predecessor before allowing a direct importer to
reuse owner-identical artifacts, retaining correctness without a new cache
@@ -3411,8 +3421,9 @@ its non-`main` canonical identity in the unit, export, archive, compiler argv,
and linker argv; the bootstrap self-rebuild independently proves the same rule
for the real `w6a` and `w6l` command directories. A focused command-test row
proves distinct production, internal, external, and generated-main actions,
colocated external-production reuse, parser-only command markers, stage-equal
unit/export/archive bytes, both test binaries' runtime behavior, and pre-tool
colocated external-to-augmented substitution, parser-only command markers,
stage-equal unit/export/archive bytes, the one combined test binary's runtime
behavior, and pre-tool
rejection when another directory tries to import the command.
The exact-argv regression uses the real diamond
@@ -3424,9 +3435,9 @@ and byte-identical units, exports, archives, executables, and tool argument
vectors across two clean
Cstage builds and two clean WWstage builds. The existing directory-package
variant regression checks separate production, internal, external, and
generated-main actions, exact generated-main direct variant/support exports,
canonical production reuse across ordinary and test products, and archive-only
link closures. It also reverses equivalent product descriptors and compares
directory-generated-main actions, exact generated-main direct target/support
exports, canonical recompile-for-test substitution, and one archive-only link
closure. It also reverses equivalent product descriptors and compares
exact compiler and linker trace bytes, then changes a shared direct export in
persistent workdirs to prove propagation through direct importers stops at the
first byte-identical regenerated export. Both stages compile and run those
@@ -3661,9 +3672,10 @@ over 255 bytes. They inspect the complete owner in units and exports, exact
direct sorted/deduplicated `.wwi` compiler inputs, long mangled assembler
symbols, complete archive-only link closures, runtime results, and independent
Cstage/WWstage artifact bytes. Two deep outside-root directories declaring
the same leaf coexist under distinct reversible identities. A long command
package and its production, internal, external, and two generated-main actions
remain distinct. Logical and literal roots, dependency-first and root-first
the same leaf coexist under distinct reversible identities. A long command
package's internal, external, and one directory generated-main actions remain
distinct while retaining its canonical package identity. Logical and literal
roots, dependency-first and root-first
discovery, equivalent and symlink spellings, reordered products, and warm
requests reuse the same production action and persistent slot. The persistent
diamond observer also changes a shared dependency export, proves rebuilding of
@@ -3757,7 +3769,7 @@ lazily zero-extended `contextstate: []u8`.
Products, load frames, and topological frames use typed dynamically allocated
slices. `internal/wwpackage` continues to construct one union command for all
selected directory-test groups, but now checks the complete
`12 + 6*products + 2*includes` builder argument count before allocating or
`12 + 9*products + 2*includes` builder argument count before allocating or
starting the driver.
All graph and product growth starts at capacity 8 and doubles until it covers
@@ -3819,30 +3831,26 @@ byte-identical export. Closing the chain at `p299 -> p000` produces the complete
stage-identical 300-node cycle diagnostic with empty compiler, assembler, and
linker traces.
`dynamic_package_universe_crosses_former_boundary` first selects 309 package-test
products through 257 directory spellings in one direct request per stage.
Fifty-two real directories each produce ordinary production, internal
production-plus-test, external `_test`, and two generated-main actions; the
shared support closure brings that command-global universe to 270 actions. Two
hundred five explicit symlink spellings of `p000` add distinct valid products
and resolution contexts while reusing its one canonical internal action. The
observer reverses product and variant order between stages, proves one compile
per action, checks all 309 binaries exist, runs boundary products, validates
variant-owned units, and compares every action artifact plus representative
binaries byte-for-byte.
`dynamic_package_universe_crosses_former_boundary` selects 257 canonical
directory products in one direct request per stage. Fifty-two directories have
combined same/external tests and each produces `ptest`, `pxtest`, and one
directory `pmain`; 205 production-only directories take the no-test path. The
shared support closure brings the command-global universe to exactly 370
compile actions and 422 assembler invocations, with 52 generated dispatchers,
links, binaries, and results. The 205 no-test products have only ordinary
production actions and statuses: no support-owned target, main, link, binary,
or result. The observer reverses all directory descriptors between stages,
proves one compile per action, runs a boundary combined binary, validates
variant-owned units and external self substitution, and compares representative
action artifacts, normalized traces, and binaries byte-for-byte.
The same observer then exercises the public `ww test <tree>/...` coordinator
path. The generated tree has 257 real directories: the 52 test-bearing
directories above plus 205 production-only directories. The coordinator forms
and passes 309 products and 258 contexts (including support) in one driver
request. Reusing the direct request's persistent semantic-action store preserves all 270
existing actions and adds exactly 410 production/generated-main actions, for 680
distinct actions. Both stages run every product, produce byte-identical ordered
coordinator output and all 680 action artifacts, and perform no compilation on a
second equivalent public request. It checks all 104 test-bearing result labels
and all 205 no-test result labels, while a builder-boundary observer records
exactly one invocation containing all 309 descriptors for each cold and warm
public request. Existing focused observers continue to prove
The same observer exercises the public `ww test <tree>/...` coordinator path
against that persistent action store. The coordinator passes exactly 257
directory descriptors in one driver request, prints 52 combined `ok` reports
and 205 no-test `?` reports, and performs no new compilation. An unchanged warm
request again invokes no compiler or assembler; the 52 real products follow the
existing explicit-output relink convention while no-test products still create
no linker work. Existing focused observers continue to prove
dependency-first/root-first canonical reuse, root-only/combined artifact
identity, exact reordered-product trace bytes, and request-shape-independent
persistent action reuse.
@@ -4351,8 +4359,9 @@ selected test-only directory remains an unusable build root and fails. Build
creates one production product per remaining directory. Test retains test-only
directories and, after selection, constructs the already specified isolated
production/no-test, internal production-plus-test, external `_test`, support,
and generated-main actions. Pattern expansion does not create those variants
and cannot make one variant visible to another.
recompiled-for-test, and one directory-generated-main action. Pattern expansion
does not create those actions; graph-owned substitution alone makes the
augmented package visible through applicable external and transitive edges.
Vendor selection remains distinct from vendor import resolution. Selecting a
directory below `vendor`, literally or through an explicitly vendor-rooted
@@ -4592,14 +4601,14 @@ directory may establish one consistent package name from its test files, as in
pinned `go/build`. External action identity remains the canonical production
identity plus the existing external variant suffix where that production
exists. Imports found only in internal or external test files belong only to
that variant. Support and generated-main actions retain their isolated
that action. Support and the directory generated-main retain isolated action
identities and archive closures. A generated dispatcher privately binds its
tested target through
`--test-target-package <canonical-path>` so a command variant declared `main`
tested targets through repeated, byte-sorted
`--test-target-package <canonical-path>` arguments so a command variant declared `main`
does not collide with the dispatcher's own synthesized `main`; this is
compiler-generated wiring distinct from ordinary source aliases. Zero-test
dispatchers mark their compiler-owned target/support metadata imports consumed.
That private binding is installed or marked consumed only in the generated
compiler-generated wiring distinct from ordinary source aliases. A real
zero-test directory product marks all compiler-owned target/support metadata
imports consumed. Those private bindings are installed or marked consumed only in the generated
dispatcher's source section; an import from an earlier test-file section
neither supplies nor satisfies it.
@@ -5117,14 +5126,15 @@ the reachable archive closure and runtime/native inputs; no `.wwi`, alias,
blank spelling, or dispatcher sidecar appears.
Production, production-plus-internal-test, external `_test`, test support, and
generated main retain separate action identities. An internal product replaces
the colocated production task with its combined variant and includes test-only
blank edges/init declarations exactly once. An external product initializes
ordinary production and its production dependencies before the external task.
Support is an ordinary dependency task; generated main owns only the final
dispatcher call and cannot duplicate a tested task. Test-file-only imports,
runtime lets, and init functions never enter production. A blank import cannot
bypass imported-`main` rejection, including through vendor expansion.
directory generated main retain separate action identities. One canonical
directory product replaces colocated production with `ptest` wherever internal
tests augment it, rewires `pxtest` self-import and affected transitive importers
to that action, and includes test-only blank edges/init declarations exactly
once. Support is an ordinary dependency task; the one generated main owns only
the final dispatcher call and cannot duplicate a tested task. Test-file-only
imports, runtime lets, and init functions never enter production. A blank
import cannot bypass imported-`main` rejection, including through vendor
expansion.
`.wwi` contains neither blank-only spelling, init declarations/bodies, hidden
variable helpers, slice backing symbols, package tasks, nor dispatcher facts.
@@ -5139,7 +5149,7 @@ first regenerated byte-identical semantic export.
The owner source voucher remains `<action>.unit.ww`; a linked product root also
owns `<root>.init.unit.ww` for its dispatcher unit, `.init.s`, `.init.o`, and
two-member archive. Current persistent formats are build 18 and test 17. Warm
two-member archive. Current persistent formats are build 18 and test 19. Warm
consumers select a dependency's staged `.wwi.new` or `.a.new` when that exact
action changed in the same request. All action artifacts, init artifacts, tool
identity copies, stamp, library/executable publications, and test statuses are
@@ -5184,9 +5194,10 @@ diamonds, independent lexical ties, aggregate and allocation initialization,
multiple-cycle diagnostics, special-init rejection, test-variant isolation,
canonical task/dispatcher/archive bytes, init-only invalidation, and warm
invalid-init rollback across independent Cstage and WWstage roots. Direct and
recursive test legs compare variant dispatcher/archive bytes and observable
production-dependency order; exact task counts include support and generated
main. Rejection rows compare complete normalized diagnostics and prove cold
recursive test legs compare the one directory dispatcher/archive and observable
dependency, `ptest`, `pxtest`, then `pmain` order; every production and
dependency task runs exactly once. Exact task counts include support and the
single generated main. Rejection rows compare complete normalized diagnostics and prove cold
scratch absence. The observer also uses a repository-built `setrlimit` launcher
to find one shared bounded-memory ceiling at which both drivers fail before a
producer, and proves no-follow atomic rejection of dangling driver staging and
@@ -5305,7 +5316,7 @@ binary effect, or test execution.
#### Persistence, rejection, and stage responsibility
Persistent formats are build 18 and test 17 so a pre-slice workdir performs one
Persistent formats are build 18 and test 19 so a pre-slice workdir performs one
complete reachable-action refresh under the new membership contract. Thereafter
an excluded-file add, removal, or content edit changes no unit voucher, `.wwi`,
assembly, object, archive, dispatcher, test status, or reverse action. Existing
@@ -5340,9 +5351,242 @@ observers retain their broader ownership.
Source-level `//go:build`/`+build` equivalents, arbitrary tags, cross-target
selection, grouped/quoted/dot imports, modules, manifests, registries, and a
programmable build language remain deliberately unsupported. Go's `UseAllFiles`
escape is also not exposed. The separate remaining Go test-product topology
divergence—one generated main for combined internal and external variants—is
not hidden or changed by this slice.
escape is also not exposed. Section 11.22 closes the formerly separate
directory test-product topology divergence without changing these filename
eligibility boundaries.
### 11.22 Implemented one canonical directory package-test product
`ww test` now owns one practical test product per canonical selected directory,
not one product per declared test package. Production, augmented internal test,
external test, support, recompiled dependency, and generated-main actions stay
separate compilation units; only their execution/publication ownership is
unified. This is the applicable Go 1.26.5 topology for WW's local, dotted,
manifest-free package model.
#### Pinned Go evidence and pre-fix divergence
The reference is official Go 1.26.5 at commit
`c19862e5f8415b4f24b189d065ed739517c548ba`:
- `TestPackagesFor` defines one `pmain` test binary running `ptest` and optional
`pxtest`, with `ptest` equal to production plus same-package test files
([`cmd/go/internal/load/test.go`, lines 85101 and 175226](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/test.go#L85-L101)).
- External self-import is recognized before the external package is formed and
is rebound to `ptest`, not ordinary `p`
([lines 144161 and 228266](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/test.go#L144-L161)).
- One `pmain` receives both applicable targets, one sorted import set, and then
`recompileForTest` copy-on-write rewires every affected transitive importer
from ordinary production to the augmented package
([lines 272293, 342376, and 421490](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/test.go#L272-L293)).
- The generated source scans both target classes into one function set and one
`testing.MainStart`/`Run`
([lines 595638 and 790860](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/load/test.go#L595-L638)).
- A directory with no selected test files takes the early ordinary-production
compile path and creates no test support, generated main, link, executable,
or subprocess; its print action reports `[no test files]`
([`cmd/go/internal/test/test.go`, lines 11331170 and 15241557](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/test/test.go#L1133-L1170)).
- A real test package creates one generated source, one link action, and one
output-copy/install or run action, including `-c`/`-o`
([lines 12001364](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/test/test.go#L1200-L1364)).
- Go's action cache distinguishes cloned package objects even when their import
paths match, compiler inputs come from the selected action's direct
dependencies, and the link closure selects one archive per import path
([`cmd/go/internal/work/action.go`, lines 202206, 437447, and 628658](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/action.go#L202-L206),
[`exec.go`, lines 410438 and 864884](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/exec.go#L410-L438)).
- `go/build` classifies same-package and `_test` external files independently
and accepts directories containing only either class
([`go/build/build.go`, lines 948953, 10051036, and 10761082](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L948-L953)).
Official command testdata closes the observable cases. `test_empty.txt` lines
324 and 3053 accepts production-only, internal-only, external-only, combined,
test-only internal, test-only external, and mixed test-only directories
([source](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/test_empty.txt#L3-L24)).
`vendor_test_issue11864.txt` lines 89 and 6480 proves an external test can use
an export declared only in an internal test source
([source](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/vendor_test_issue11864.txt#L64-L80)).
`list_test_imports.txt` lines 321 proves transitive rebuilding when a helper
imports the package under test
([source](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/list_test_imports.txt#L3-L21)).
`toolexec.txt` lines 2750 observes distinct `ptest`, `pxtest`, and `pmain`
compiles but one main and linker call
([source](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/toolexec.txt#L27-L50)).
`test_no_tests.txt` lines 114 uses a panicking production initializer to prove
that no-test reporting does not execute a test process
([source](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/test_no_tests.txt#L1-L14)).
Before this slice WW constructed one generated main, link, binary, result, and
report for each declared same/external test package. A combined directory ran
two processes, initialized production state twice, hid internal-test exports
from the external package, and made `-c -o` fail as a multi-product request.
Even a directory with no selected tests manufactured support, a main, a link,
and a temporary executable merely to print `[no tests]`. Test-only external
directories were mislabeled, a valid mixed test-only directory was rejected,
and a transitive importer was compiled against ordinary production.
#### Final product and action topology
For canonical directory product `P`, the action graph is:
- `p`: ordinary production sources only;
- `ptest`: production plus same-package selected `*_test.ww` sources;
- `pxtest`: external-package selected `*_test.ww` sources only;
- product-scoped recompiled actions: unchanged source units whose direct target
set was rewritten by the `p -> ptest` substitution;
- support: one command-global production support action (or the reserved
`__wwtest` compiler binding when user `test` occupies that spelling);
- `pmain`: one directory-owned generated-main action importing every applicable
target and support.
The source shapes produce these reachable roots:
| Directory shape | Test closure and externally visible product |
| --- | --- |
| production, no selected tests | ordinary `p`; no support/main/link/run/output/result |
| production + internal | `ptest` + `pmain`; one binary/result |
| production + external | unaugmented `p` + `pxtest` + `pmain`; one binary/result |
| production + both | `ptest` + `pxtest -> ptest` + `pmain`; one binary/result |
| test-only same package | `ptest` + `pmain`; one binary/result |
| test-only external package | `pxtest` + `pmain`; one binary/result |
| test-only same + external | `ptest` + `pxtest -> ptest` + `pmain`; one binary/result |
A selected helper-only `*_test.ww` file is still a real test source: it is
loaded and may yield an empty harness. The no-real-run branch is specifically
the absence of selected test files after platform filtering. Ordinary
`ww build` excludes test filenames before reading even their package clauses,
so malformed test-only content and test-only imports cannot affect production.
The coordinator in `internal/wwpackage/package.ww` classifies all selected
files into one directory group. Classification is production-name-relative,
so a legitimate production package literally named `foo_test` has external
name `foo_test_test`; without production, a valid `p`/`p_test` pair is retained
as same/external rather than blindly stripping every suffix. The private driver
descriptor is an ordered directory record:
```
--ww-package-test KIND FAMILY PRODUCTION INTERNAL EXTERNAL DIR OUTPUT STATUS
```
Missing action selectors are `-`. One descriptor owns at most one output and
one status. Canonically duplicate products and pairwise output/status/staging
collisions reject before producer execution. Declared names and output stems do
not identify products or actions.
The Cstage and WWstage drivers first load and validate the ordinary production
root. They form `ptest` and `pxtest` as separate source actions, bind external
self-import to `ptest`, seed `p -> ptest`, and copy/rewrite the affected
dependency closure. Both deduplicated dependency edges and every original
file-local import binding target are rewritten through action identity. The
strict closure validator rejects any leaked ordinary/augmented duplicate; no
initialization or archive-order fallback can hide an incomplete substitution.
`pmain` stores a checked, byte-sorted unique target action set. Its generated
unit imports each target once plus support. The compiler argv repeats
`--test-target-package` in that same order, followed by the exact byte-sorted
direct `--import PATH WWI` set. Thus a combined shape has the essential form:
```
w6c --test-package ... -I PTEST.wwi -o PTEST.s PTEST.unit.ww
w6c --test-package ... --import P PTEST.wwi ... -I PXTEST.wwi ...
w6c -T --entry --test-support-module test \
--test-target-package P --test-target-package P_test \
--import P PTEST.wwi --import P_test PXTEST.wwi --import test TEST.wwi \
-I PMAIN.wwi -o PMAIN.s PMAIN.unit.ww
```
Actual arguments also contain action-owned init and dispatcher symbols. The
assembler receives one source object per compiled action and exactly one
`pmain.init.s -> pmain.init.o` dispatcher. Test target archives contain only
their deterministic `pkg.o` member; the main archive contains `pkg.o` then
`init.o`. Link argv is root plus reachable archives only:
```
w6l -o OUTPUT.new PMAIN.a [PXTEST.a] [PTEST-or-P.a] ... TEST.a libwwrt.a
```
No `.wwi`, source filename, standalone semantic object, or linker-order choice
participates. Both native linkers already resolve archive members by symbols;
they required no topology-specific change.
#### Import, export, initialization, and execution ownership
Default, explicit-alias, and blank imports remain file-local source
occurrences. The package graph still uses one canonical edge per target and
preserves every occurrence for usage and legality diagnostics. Substitution
changes only the chosen canonical action. Consequently an external source
continues to spell `import P`, but its direct compiler export input is
`ptest.wwi`; an exported helper in an internal test source is ordinary augmented
package export data and needs no special reader format. Per-owner `@test`
metadata in `.wwi` remains sufficient. The writer/reader format did not change.
`cmd/w6c/main.c`, `cmd/wcc/ww.h`, and `cmd/wcc/check.c`, with their self-hosted
twins, changed singular generated-target state into a target set. Every target
import is marked used, and every imported `@test` declaration receives its
canonical target qualifier. The coordinator controls target order; the checker
does not resolve directories. `wwdump` passes an empty target set on its
non-test path.
One dependency-first dispatcher is generated from the substituted closure.
Each reachable canonical action contributes one initialization task; `pmain`
is the sole entry package that calls the dispatcher. A combined directory
therefore initializes dependencies, augmented production, external tests,
support, and main exactly once in one process. Filtering and listing operate on
the single deterministic enumeration containing both target sets; output has
one accounting block and one directory report. `ww test -c -o OUTPUT DIR`
publishes the one directory binary even when both target classes exist.
#### Artifacts, persistence, invalidation, and rejection
Semantic action artifacts remain separate: `.unit.ww`, `.wwi`, `.s`, `.o`, and
`.a` for each production/test/recompiled/main/support action, plus main init
unit/assembly/object. The directory product alone owns the binary, status, and
result. Test persistent-work format is `19`; semantic package storage is format
`3` and includes the product-scoped `for_test` identity for recompiled actions.
There is still no cache, CAS, manifest, registry, database, or result cache.
Warm reuse compares owner-unit bytes and exact direct export bytes. An internal
helper body edit with stable `.wwi` rebuilds only `ptest` and relinks; external
and reverse compilation stop. An external body-only edit rebuilds only
`pxtest`. Adding or changing an exported internal helper changes `ptest.wwi`,
then rebuilds exactly affected recompiled importers, `pxtest`, and `pmain`.
Adding or removing a target class changes only the owning directory product and
newly reachable actions. Request/root order and equivalent directory spelling
do not change action bytes, target order, output, or reuse.
Loader-owned source classification, import legality, canonical-product,
duplicate-closure, cycle, command-kind, and publication-path errors reject
before compiler, assembler, linker, support, or main work. Production failure
is diagnosed once even though an augmented action would contain the same
sources. Later compiler, assembler, generated-main, archive, link, staging, or
commit failure remains one request-wide transaction: no sibling product runs,
no status/result/binary or mixed generation is published, prior committed
bytes remain unchanged, and every staged `.new` is discarded. Both drivers use
checked dynamic allocation and transactional clone construction; allocation
failure cannot publish a partial action or leave cleanup to traverse
uninitialized storage.
The native proof is primarily
`directory_package_graph_variants`,
`multi_directory_shared_package_plan`,
`empty_and_invalid_package_classes`,
`dynamic_package_universe_crosses_former_boundary`,
`platform_filename_source_selection`,
`vendor_directory_import_resolution`, and
`test_variant_initialization`, with late transaction ownership in
`sibling_test_variant_failures_are_isolated`. Together they compare
cold/persistent Cstage and WWstage units, exports, assembly, objects, exact
archive members, mains, binaries, diagnostics, runtime order, literal and
normalized compiler/assembler/linker argv, both root orders in each stage,
precise body/export and target-removal/re-addition invalidation, combined-graph
allocation failure, repeated late internal/external/main/link rollback, and a
complete work-directory sweep for staged residue.
Deliberately unchanged or unsupported behavior includes the raw single-file
compatibility path, WW's `[no tests]` presentation text, Go modules and build
cache, network resolution, manifests, coverage/vet/fuzz/benchmark generation,
source-level build expressions, quoted/grouped/dot imports, and targets other
than the separately specified fixed `linux/amd64` filename selection. None is
used to define canonical package or directory-product identity.
## 12. Candidate architectures and hard-gate decision