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

View File

@@ -251,10 +251,12 @@ ImportName = ident .
ImportPath = ident { "." ident } .
```
- Every source file begins with a package clause. A directory of eligible
`.ww` files sharing one declared package name compiles as one package. The
declared name need not equal the directory name or the final component of its
canonical import identity.
- Every source file begins with a package clause. Within one semantic source
action, eligible `.ww` files share one declared package name. Ordinary
production and same-package test sources use `p`; external test sources may
use the related `p_test`, and the actions remain separate even though one
canonical directory owns their test product. The declared name need not equal
the directory name or the final component of its canonical import identity.
- Directory source eligibility uses Go 1.26.5 filename suffix semantics for
WW's fixed `linux/amd64` target. In the basename stem before the first dot, a
final `_test` token is ignored for platform matching. A final known OS or
@@ -286,10 +288,12 @@ ImportPath = ident { "." ident } .
initialization. Repeated blank occurrences and blank plus default/explicit
named occurrences of one path are valid; every named occurrence remains
independently subject to duplicate-binding and unused checks.
The package dependency graph is the sorted, deduplicated union of the real
imports in all eligible files. Occurrences retain their owning file and
position, but equal canonical targets create one graph edge/package action.
Self-import is rejected.
Each semantic action's package dependency graph is the sorted, deduplicated
union of real imports in that action's eligible source set. Occurrences retain
their owning file and position, but equal canonical targets create one graph
edge. Test-only occurrences never enter ordinary production. Self-import is
rejected, except that toolchain-owned external-test self wiring is rebound to
the effective augmented package action after ordinary per-site validation.
- An executable package is one declared `package main` and containing a
`fn main`; path and directory spelling do not classify commands. An ordinary
import of a package declared `main` is rejected, except for the toolchain's
@@ -606,13 +610,21 @@ the program. Two placements, following the Go `foo` / `foo_test` model:
```
Production, production-plus-white-box-test, external black-box-test, test
support, and generated test main are distinct package actions. Before a test
function runs, the generated test product initializes its exact reachable
variant graph dependency-first and once per canonical action. A white-box
variant replaces the colocated production task rather than initializing both;
an external variant depends on ordinary production. Imports, runtime lets, and
init declarations found only in `*_test.ww` never enter an ordinary production
build.
support, recompiled-for-test dependencies, and generated test main are distinct
package actions. One canonical selected directory owns one test product and one
generated main, which imports every applicable same-package and external target
and produces one binary/result. The external action's import of the package
under test binds to the augmented white-box action when it exists; affected
transitive importers are copied and rewired so ordinary and augmented package
state do not coexist in the linked closure.
Before a test function runs, the one generated product initializes its exact
effective graph dependency-first and once per canonical action. Imports,
runtime lets, and init declarations found only in `*_test.ww` never enter an
ordinary production build. Test-only same-package, external-package, and valid
mixed directories are accepted from their selected test files. A directory
with no selected test file validates ordinary production but creates no test
support, generated main, link, binary, result, or process.
---

View File

@@ -193,8 +193,9 @@ and nonempty-version-constant assertions.
`ww test` delegates directory package requests to the native package
coordinator. The coordinator owns request-pattern expansion, package grouping,
same-package and external-package variant selection, filtering, result
aggregation, and its internal temporary workspace. Test sources are exclusively
same-package and external-package action selection, one canonical
directory-owned product, filtering, result aggregation, and its internal
temporary workspace. Test sources are exclusively
`*_test.ww` (Go's `_test.go` contract): a line-leading `@test` declaration in
any other source is rejected loudly — by both driver stages at directory
enumeration and by the coordinator at source classification. A local spelling
@@ -204,8 +205,11 @@ directory prefix before the first wildcard. Recursive children beginning `.`
or `_` and exact `testdata` subtrees are pruned; child directory symlinks are
not followed. A wildcard cannot consume a non-terminal exact `vendor` element,
while an explicitly vendor-rooted pattern remains legal. Every selected
test-bearing directory becomes one package run, and selected source-bearing
directories without tests report the usual `?` line. The coordinator first
test-bearing directory becomes exactly one package run, binary, and result even
when both internal and external actions exist. Selected source-bearing
directories without selected test files report the usual `?` line after
ordinary production validation, with no support, generated main, link, binary,
result, or process. The coordinator first
launches one driver plan for the complete command-global package/action union.
After that shared build completes, `-j N` schedules up to N successful selected
test binaries concurrently under `os.exec` start/poll supervision (no threads);
@@ -213,10 +217,11 @@ 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` binary in the package directory; the first output owns the one
`<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 package:
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
@@ -256,8 +261,10 @@ archive/action ownership, one canonical direct edge for repeated occurrences,
stage-equal diagnostics and binaries, and clean rejection state.
The declared-name observer proves imports are file-scoped while dependency
edges are the package-wide sorted union; command and
production/internal/external/generated-main variants retain canonical action
ownership; vendor expansion changes identity but not the effective qualifier;
production/internal/external/directory-main actions retain canonical action
ownership while one canonical directory owns their product; external
self-imports bind the augmented internal action; vendor expansion changes
identity but not the effective qualifier;
compiler argv contains only direct `.wwi` inputs; and its named rejected
actions leave neither committed nor staged action artifacts or a published
binary. It also forces a request transaction to reject after dependency work
@@ -277,9 +284,15 @@ normalized compiler/assembler/linker argv, units, `.wwi`, assembly, objects,
archives, generated-main archives, binaries, runtime/test output, direct and
recursive behavior, reversed roots, ignored-edit reuse, selected private-change
propagation, and request rollback after a dependency has staged and the root
compiler fails. The existing bounded-memory package-initialization observer
continues to own allocation-failure parity for the shared dynamically grown
action universe.
compiler fails. Wrong-target test files cannot add a target to the directory
main or create one for an otherwise no-test directory. The bounded-memory
package-initialization observer now pressures the combined directory topology
itself: production, augmented internal test, external self-import, a transitive
recompile-for-test clone, support, and the two-target generated main. Each stage
searches its own bounded address-space ceiling, while the accepted failure must
have the same `ww: out of memory` diagnostic, invoke no compiler, assembler, or
linker, and leave an empty caller work directory with no output, status, or
staging path.
`test/sep/sepinit_test.ww` is the single focused package-initialization owner.
It generates all source trees temporarily and runs independent cold/persistent
@@ -287,15 +300,18 @@ Cstage and WWstage legs. Its matrix covers blank-only reachability; dependency,
diamond, and independent ready-task order; runtime call/allocation and aggregate
package lets; multiple init declarations and invalid forms; direct/qualified
init invisibility; initialization cycles and diagnostic order; command,
internal-test, external-test, support, and generated-main ownership; canonical
internal-test, external-test, support, and one directory-generated-main
ownership; canonical
task and dispatcher symbols; deterministic one- and two-member archives;
`.wwi` exclusion; byte-identical artifacts/binaries; init-only invalidation;
warm invalid-init rollback; direct/recursive variant equivalence; exact
production, support, and generated-main task ordering; complete normalized
production, support, ptest-before-pxtest-before-main task ordering, exactly-once
package/dependency initialization in one dispatcher; complete normalized
rejection diagnostics; dangling staging/rollback no-follow rejection; and
checked compiler-output failure/non-regular-destination rollback; and
bounded-memory allocation-failure parity under one shared ceiling supplied by
the repository-built `sep-limitexec` helper.
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
@@ -330,9 +346,11 @@ create false reuse or a mixed generation; a successful executable link still
reruns when required. One workdir serves one invocation at a time and may hold
the complete command-global action universe for all selected roots and isolated
variants; semantic identity, rather than request shape, controls reuse. Both
driver stages implement the identical contract. This is build staleness in the
driver stages implement the identical contract. Test-mode persistent workdirs
use format 19. This is build staleness in the
Make/mk/Go sense, not a result cache:
tests always run, and the byte-identity and bootstrap gates keep building on
real directory test products always run, while no-selected-test directories do
not create a process. The byte-identity and bootstrap gates keep building on
fresh scratch. `make clean` reclaims every workdir under `out/`.
On a package or tree target, `ww build/test -w DIR` forwards that exact caller

View File

@@ -3,7 +3,7 @@ package pass_test;
import test;
@test fn alpha_pass() void = {
assert(test.current() == "pass_test.alpha_pass");
assert(test.current() == "pass.alpha_pass");
};
@test fn beta_skip() void = {

File diff suppressed because it is too large Load Diff

View File

@@ -736,7 +736,11 @@ fn rejectrow(td: str, label: str, src: str, expected: str) void = {
let td: str = testenv.fresh();
let tree: str = strings.concat(td, "/tree");
assert(os.mkdir(tree, 493) == 0);
let body: str = "package main;\n";
let target: str = strings.concat(tree, "/target");
let bridge: str = strings.concat(tree, "/bridge");
assert(os.mkdir(target, 493) == 0);
assert(os.mkdir(bridge, 493) == 0);
let body: str = "package target;\n";
let i: i32 = 0;
for (i < 600) {
let name: str = allocpkgname(i);
@@ -747,63 +751,98 @@ fn rejectrow(td: str, label: str, src: str, expected: str) void = {
body = strings.concat(body, "import _ ", name, ";\n");
i += 1;
};
body = strings.concat(body, "fn main() i32 = { return 0; };\n");
let src: str = strings.concat(td, "/main.ww");
testenv.writefile(src, body);
let wrapper: str = strings.concat(td, "/w6c-trace.sh");
body = strings.concat(body,
"export fn value() i32 = { return 41; };\n");
testenv.writefile(strings.concat(target, "/target.ww"), body);
testenv.writefile(strings.concat(target, "/same_test.ww"), strings.concat(
"package target;\n",
"export fn internal_helper() i32 = { return value(); };\n",
"@test fn internal_runs() void = { assert(value() == 41); };\n"));
testenv.writefile(strings.concat(bridge, "/bridge.ww"), strings.concat(
"package bridge;\nimport target;\n",
"export fn helper() i32 = { return target.internal_helper(); };\n"));
testenv.writefile(strings.concat(target, "/external_test.ww"),
strings.concat("package target_test;\nimport bridge;\nimport target;\n",
"@test fn external_runs() void = {\n",
" assert(target.internal_helper() == 41);\n",
" assert(bridge.helper() == 41);\n};\n"));
let wrapper: str = strings.concat(td, "/tool-trace.sh");
testenv.writeexecutable(wrapper, strings.concat("#!/bin/sh\n",
"printf x >> \"$WW_SEPINIT_W6C_TRACE\"\nexit 99\n"));
"printf x >> \"$WW_SEPINIT_TOOL_TRACE\"\nexit 99\n"));
let stages: []str = ["ww", "ww_ww"];
let compilers: []str = ["w6c", "w6c_ww"];
let launcher: str = testenv.driver("sep-limitexec");
let found: bool = false;
let last: str = "";
let limit: i64 = 2621440i64;
let li: i32 = 0;
// Both implementations must reject under the same address-space ceiling.
// Search a bounded same-limit ladder because loader mappings differ across
// supported hosts; the 600-action graph makes the driver-allocation window
// broad, while the compiler trace pins failure before the first tool.
for (limit <= 16777216i64 && !found) {
let limitstr: str = strconv.i64tos(limit, strconv.base.DEC);
let good: [2]bool;
let diags: [2]str;
i = 0;
for (i < stages.len) {
let accepted: [2]str;
let stagei: i32 = 0;
// Address-space layouts differ, so each implementation searches its own
// bounded ceiling. The accepted point must fail while constructing the
// combined p/ptest/pxtest/pmain and transitive-clone graph, before any tool.
for (stagei < stages.len) {
let found: bool = false;
let last: str = "";
let limit: i64 = 2621440i64;
let li: i32 = 0;
for (limit <= 33554432i64 && !found) {
let tag: str = allocpkgname(li);
let trace: str = strings.concat(td, "/alloc-", stages[i], "-",
let trace: str = strings.concat(td, "/alloc-", stages[stagei], "-",
tag, ".trace");
let work: str = strings.concat(td, "/alloc-work-", stages[stagei],
"-", tag);
let output: str = strings.concat(td, "/alloc-output-",
stages[stagei], "-", tag);
let status: str = strings.concat(td, "/alloc-status-",
stages[stagei], "-", tag);
testenv.writefile(trace, "");
let env: []str = compilertraceenv(wrapper,
testenv.driver(compilers[i]), trace);
let output: str = strings.concat(td, "/alloc-", stages[i], "-",
tag);
let av: []str = [launcher, limitstr, testenv.driver(stages[i]),
"build", "-I", tree, "-o", output, src];
assert(os.mkdir(work, 493) == 0);
let base: []str = os.getenvs();
let env: []str = alloc([], (base.len + 4): u64)!;
i = 0;
for (i < base.len) {
if (!strings.hasprefix(base[i], "WW_W6C=")
&& !strings.hasprefix(base[i], "WW_W6A=")
&& !strings.hasprefix(base[i], "WW_W6L=")
&& !strings.hasprefix(base[i],
"WW_SEPINIT_TOOL_TRACE=")) {
append(env, base[i]);
};
i += 1;
};
append(env, strings.concat("WW_W6C=", wrapper));
append(env, strings.concat("WW_W6A=", wrapper));
append(env, strings.concat("WW_W6L=", wrapper));
append(env, strings.concat("WW_SEPINIT_TOOL_TRACE=", trace));
let limitstr: str = strconv.i64tos(limit, strconv.base.DEC);
let av: []str = [launcher, limitstr, testenv.driver(stages[stagei]),
"test", "-c", "-w", work, "-I", tree,
"--ww-package-test", "test", "target", "target", "target",
"target_test", target, output, status, target];
let out: testenv.commandout;
runenv(td, strings.concat("allocation-", stages[i], "-", tag),
runenv(td, strings.concat("allocation-", stages[stagei], "-", tag),
av, env, &out);
last = strings.dup(out.stderr);
good[i] = exitcode(&out) == 1 && testenv.same(out.stderr,
"ww: out of memory\n")
&& testenv.readfile(trace).len == 0;
diags[i] = strings.dup(out.stderr);
if (testenv.exists(output) || testenv.exists(strings.concat(output,
".sepwork"))) {
if (testenv.listdir(work).len != 0
|| nofollowexists(output)
|| nofollowexists(strings.concat(output, ".new"))
|| nofollowexists(strings.concat(output, ".sepwork"))
|| nofollowexists(status)
|| nofollowexists(strings.concat(status, ".new"))) {
fail("allocation", "failed pressure leg published state");
};
i += 1;
};
if (good[0] && good[1]) {
if (!testenv.same(diags[0], diags[1])) {
fail("allocation", "C/WW allocation diagnostic mismatch");
if (exitcode(&out) == 1 && out.stdout.len == 0
&& testenv.same(out.stderr, "ww: out of memory\n")
&& testenv.readfile(trace).len == 0) {
accepted[stagei] = strings.dup(out.stderr);
found = true;
};
found = true;
testenv.clean(work);
limit += 131072i64;
li += 1;
};
limit += 131072i64;
li += 1;
if (!found) { fail("allocation", last); };
stagei += 1;
};
if (!testenv.same(accepted[0], accepted[1])) {
fail("allocation", "C/WW allocation diagnostic mismatch");
};
if (!found) { fail("allocation", last); };
testenv.clean(td);
};
@@ -932,16 +971,12 @@ fn rejectrow(td: str, label: str, src: str, expected: str) void = {
let tags: []str = ["c", "ww"];
let reference: str = "";
let variantnames: []str = [
"widget-internal-test-main.init.unit.ww",
"widget-internal-test-main.init.s",
"widget-internal-test-main.init.o",
"widget-internal-test-main.a",
"widget_test-external-test-main.init.unit.ww",
"widget_test-external-test-main.init.s",
"widget_test-external-test-main.init.o",
"widget_test-external-test-main.a",
"widget-test-main.init.unit.ww",
"widget-test-main.init.s",
"widget-test-main.init.o",
"widget-test-main.a",
];
let variantrefs: []str = ["", "", "", "", "", "", "", ""];
let variantrefs: []str = ["", "", "", ""];
let i: i32 = 0;
for (i < 2) {
let work: str = strings.concat(td, "/test-work-", tags[i]);
@@ -967,61 +1002,45 @@ fn rejectrow(td: str, label: str, src: str, expected: str) void = {
let rr: i32 = testenv.pos(out.stdout, "<R>");
let ii: i32 = testenv.pos(out.stdout, "<I>");
let tt: i32 = testenv.pos(out.stdout, "<T>");
let tail: str = "";
if (tt >= 0) { tail = strings.sub(out.stdout, tt + 3, out.stdout.len); };
let de: i32 = testenv.pos(tail, "<D>");
let pe: i32 = testenv.pos(tail, "<P>");
let w: i32 = testenv.pos(tail, "<W>");
let e: i32 = testenv.pos(tail, "<E>");
let x: i32 = testenv.pos(tail, "<X>");
if (!(d >= 0 && d < q && q < rr && rr < p && p < ii && ii < tt
&& de >= 0 && de < pe && pe < w && w < e && e < x)) {
let w: i32 = testenv.pos(out.stdout, "<W>");
let e: i32 = testenv.pos(out.stdout, "<E>");
let x: i32 = testenv.pos(out.stdout, "<X>");
if (!(d >= 0 && d < q && q < rr && rr < p && p < ii && ii < w
&& w < e && e < tt && tt < x)) {
fail("variants", strings.concat("test init order: ", out.stdout));
};
if (testenv.occurrences(out.stdout, "<Q>") != 1
|| testenv.occurrences(out.stdout, "<D>") != 2
|| testenv.occurrences(out.stdout, "<D>") != 1
|| testenv.occurrences(out.stdout, "<R>") != 1
|| testenv.occurrences(out.stdout, "<W>") != 1
|| testenv.occurrences(out.stdout, "<I>") != 1
|| testenv.occurrences(out.stdout, "<E>") != 1
|| testenv.occurrences(out.stdout, "<P>") != 2) {
|| testenv.occurrences(out.stdout, "<P>") != 1) {
fail("variants", "variant initialization count");
};
let internal: str = testenv.readfile(strings.concat(work,
"/widget-internal-test-main.init.unit.ww"));
if (testenv.occurrences(internal,
let dispatcher: str = testenv.readfile(strings.concat(work,
"/widget-test-main.init.unit.ww"));
if (testenv.occurrences(dispatcher,
"__ww..pkg.p.testside.v0.r0.init") != 1
|| testenv.occurrences(internal,
|| testenv.occurrences(dispatcher,
"__ww..pkg.p.prodside.v0.r0.init") != 1
|| testenv.occurrences(internal,
|| testenv.occurrences(dispatcher,
"__ww..pkg.p.widget.v1.r0.init") != 1
|| testenv.occurrences(internal,
"__ww..pkg.p.test.v0.r0.init") != 1
|| testenv.occurrences(internal,
"//ww:init-call __ww..pkg.p.__wwtestmain.widget.internal.main.v3.r2.init") != 1
|| testenv.pos(internal, "__ww..pkg.p.test.v0.r0.init")
>= testenv.pos(internal,
"//ww:init-call __ww..pkg.p.__wwtestmain.widget.internal.main.v3.r2.init")
|| testenv.has(internal, "__ww..pkg.p.widget.v0.r0.init")) {
fail("variants", "internal variant dispatcher ownership");
};
let external: str = testenv.readfile(strings.concat(work,
"/widget_test-external-test-main.init.unit.ww"));
if (testenv.occurrences(external,
"__ww..pkg.p.widget.v0.r0.init") != 1
|| testenv.occurrences(external,
"__ww..pkg.p.prodside.v0.r0.init") != 1
|| testenv.occurrences(external,
|| testenv.occurrences(dispatcher,
"__ww..pkg.p.widget_test.v2.r0.init") != 1
|| testenv.occurrences(external,
|| testenv.occurrences(dispatcher,
"__ww..pkg.p.test.v0.r0.init") != 1
|| testenv.occurrences(external,
"//ww:init-call __ww..pkg.p.__wwtestmain.widget_test.external.main.v3.r2.init") != 1
|| testenv.pos(external, "__ww..pkg.p.test.v0.r0.init")
>= testenv.pos(external,
"//ww:init-call __ww..pkg.p.__wwtestmain.widget_test.external.main.v3.r2.init")
|| testenv.has(external, "testside")) {
fail("variants", "external variant dispatcher ownership");
|| testenv.occurrences(dispatcher,
"//ww:init-call __ww..pkg.p.__wwtestmain.widget.main.v3.r2.init") != 1
|| testenv.pos(dispatcher, "__ww..pkg.p.widget.v1.r0.init")
>= testenv.pos(dispatcher,
"__ww..pkg.p.widget_test.v2.r0.init")
|| testenv.pos(dispatcher,
"__ww..pkg.p.widget_test.v2.r0.init")
>= testenv.pos(dispatcher,
"//ww:init-call __ww..pkg.p.__wwtestmain.widget.main.v3.r2.init")
|| testenv.has(dispatcher, "__ww..pkg.p.widget.v0.r0.init")) {
fail("variants", "directory test dispatcher ownership");
};
let directstdout: str = strings.dup(out.stdout);
let recursivework: str = strings.concat(td, "/test-recursive-work-",
@@ -1100,7 +1119,7 @@ fn rejectrow(td: str, label: str, src: str, expected: str) void = {
av, env, tmo(), &out);
if (exitcode(&out) == 0
|| !testenv.has(out.stderr,
"ww: dependency cycle in initialization closure")
"ww: dependency cycle: p -> q -> r -> p")
|| testenv.readfile(trace).len != 0
|| testenv.listdir(work).len != 0) {
fail("test-cycle", out.stderr);