ww: put selected toolchain first in test PATH
This commit is contained in:
@@ -5849,22 +5849,24 @@ reinterpret them. No runtime coordinator-global `chdir` was added; its cwd and
|
||||
`PWD` remain unchanged.
|
||||
|
||||
Each started product also receives a newly allocated run environment. It
|
||||
retains inherited entries in order except exact `TMPDIR=`, `LC_ALL=`, and
|
||||
uppercase `PWD=` entries, then appends `LC_ALL=C`, the product-local absolute
|
||||
`TMPDIR`, and `PWD=<pkggroup.dir>`. Removing prior `PWD` entries reproduces
|
||||
Go's observable last-wins result because WW's executor intentionally preserves
|
||||
retains inherited entries in order except exact `TMPDIR=`, `LC_ALL=`, uppercase
|
||||
`PATH=`, and uppercase `PWD=` entries, then appends `LC_ALL=C`, the
|
||||
product-local absolute `TMPDIR`, the selected toolchain `PATH`, and
|
||||
`PWD=<pkggroup.dir>`. Removing prior `PWD` and `PATH` entries reproduces Go's
|
||||
observable last-wins result because WW's executor intentionally preserves
|
||||
duplicates and WW `os.getenv` returns the first one. Case-distinct and malformed
|
||||
entries remain untouched. The product observes exactly one uppercase `PWD`, at
|
||||
the appended position.
|
||||
the appended position, and one effective uppercase `PATH`; section 11.32 owns
|
||||
the latter rule.
|
||||
|
||||
The vector and both generated strings are product-local, dynamically sized,
|
||||
The vector and its generated strings are product-local, dynamically sized,
|
||||
and published only after every checked allocation succeeds. Partial failure
|
||||
frees only initialized owned storage and never frees borrowed inherited
|
||||
strings. `exec.start` synchronously deep-copies the command before returning,
|
||||
after which the coordinator frees its run vector, generated `TMPDIR`, generated
|
||||
`PWD`, generated `-package` argument, and argv vector. Concurrent children
|
||||
therefore hold independent fork snapshots; no shared environment vector or
|
||||
process-global state is mutated.
|
||||
`PATH`, generated `PWD`, generated `-package` argument, and argv vector.
|
||||
Concurrent children therefore hold independent fork snapshots; no shared
|
||||
environment vector or process-global state is mutated.
|
||||
|
||||
All dependency initialization occurs inside that product process. A production
|
||||
or test-only dependency reached by package `p` sees `p`'s directory. If the
|
||||
@@ -5880,15 +5882,19 @@ emission remains byte-sorted and identical to `-j 1`.
|
||||
`-c -o`, builds or publishes but never enters `pkgstartrun`; no execution cwd
|
||||
or run environment is allocated. A published binary subsequently invoked by
|
||||
the user bypasses the coordinator and inherits the user's cwd and environment.
|
||||
The raw single-file test compatibility route is likewise unchanged. A
|
||||
directory with no selected test source still creates no support, generated
|
||||
main, link, run, result, or execution-context state.
|
||||
The raw single-file test compatibility route retains its caller cwd, `PWD`,
|
||||
stdin, and stream behavior, but section 11.32 applies the test-process `PATH`
|
||||
rule at its driver-owned launch. A directory with no selected test source still
|
||||
creates no support, generated main, link, run, result, or execution-context
|
||||
state.
|
||||
|
||||
Build-plan commands retain `dir=""` and their existing tool environment.
|
||||
Compiler, assembler, in-driver archiver, linker, support generation, generated
|
||||
main construction, the Cstage driver, and the WWstage driver therefore retain
|
||||
their exact prior cwd, argv, and environment. The runtime rule required no
|
||||
`lib/os/exec`, compiler, checker, writer, assembler, linker, or driver change.
|
||||
Compiler, assembler, in-driver archiver, linker, support generation, and
|
||||
generated-main construction therefore retain their exact prior cwd, argv, and
|
||||
environment. The directory cwd rule required no `lib/os/exec`, compiler,
|
||||
checker, writer, assembler, linker, or driver change; the later test-only PATH
|
||||
rule is isolated at launch and changes neither build-plan environment nor those
|
||||
tools.
|
||||
Independent Cstage/WWstage compile-only products remain byte-identical, and
|
||||
changing only `data.txt` or `testdata` changes no unit, `.wwi`, assembly,
|
||||
object, archive, generated-main, or binary bytes.
|
||||
@@ -5916,13 +5922,15 @@ The focused native owner is
|
||||
`directory_test_execution_working_directory` in
|
||||
`test/package/package_test.ww`. It creates only disposable source trees and
|
||||
compares Cstage and WWstage across duplicate and large environments; exact
|
||||
`getcwd`, effective/count/position of `PWD`; ordinary data, `testdata`, and
|
||||
`getcwd`, effective/count/position of `PWD`; absent, empty, nonempty, and
|
||||
duplicate inherited `PATH`; ordinary data, `testdata`, and
|
||||
relative writes; all production/internal/external/test-only shapes;
|
||||
production and test-only dependency initialization; recompiled external
|
||||
self-import; direct/recursive/redundant/absolute/symlink roots; reversed roots
|
||||
and creation order; `-j 1`/parallel execution; filters/list/no-match; failure
|
||||
and timeout; no-test and build paths; `-c`, `-c -o`, direct binaries, and raw
|
||||
single files; exact tool cwd/argv/locale/TMPDIR; persistent data-only reuse and
|
||||
and timeout; no-test and build paths; `-c`, `-c -o`, running retained tests,
|
||||
direct binaries, and raw single files; exact tool cwd/argv/locale/TMPDIR/PATH;
|
||||
persistent data-only reuse and
|
||||
artifact/binary identity; and a deterministic post-build directory removal
|
||||
where the affected product reports `ENOENT` while its sibling succeeds.
|
||||
Checked command-global allocation-failure parity remains owned by
|
||||
@@ -6904,6 +6912,141 @@ and retained-binary contracts. Existing request-transaction, timeout,
|
||||
interruption, and concurrent-driver owners continue to cover those unchanged
|
||||
dimensions.
|
||||
|
||||
### 11.32 Implemented selected toolchain first in test `PATH`
|
||||
|
||||
Every test binary actually started by `ww test` now receives one effective
|
||||
uppercase `PATH` beginning with the canonical absolute directory of the
|
||||
selected WW driver. An absent or empty inherited value produces only that
|
||||
directory. A nonempty first effective inherited value follows it after `:`;
|
||||
ordinary duplicate `PATH=` entries collapse to the one child value. This is
|
||||
test-process metadata only: build tools and every request that starts no test
|
||||
process retain their prior environment.
|
||||
|
||||
#### Pinned Go evidence and classification
|
||||
|
||||
The sole authority is official Go 1.26.5 at commit
|
||||
`c19862e5f8415b4f24b189d065ed739517c548ba`:
|
||||
|
||||
- The `go test` command documentation states that `$GOROOT/bin` is placed at
|
||||
the beginning of the test process's `PATH`, so an executed test resolves the
|
||||
`go` command from the invoking toolchain
|
||||
([`cmd/go/internal/test/test.go`, lines 87–94](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/test/test.go#L87-L94)).
|
||||
- `(*runTestActor).Act` begins with `cfg.OrigEnv`, applies
|
||||
`base.AppendPATH`, then `base.AppendPWD`, and assigns that environment to
|
||||
each test command
|
||||
([`cmd/go/internal/test/test.go`, lines 1661–1668](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/test/test.go#L1661-L1668)).
|
||||
`AppendPATH` appends `PATH=$GOROOT/bin` for an empty effective inherited
|
||||
value and `PATH=$GOROOT/bin:<old>` otherwise
|
||||
([`cmd/go/internal/base/env.go`, lines 29–45](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/base/env.go#L29-L45)).
|
||||
- `Cmd.environ` removes duplicate environment keys while preferring the later
|
||||
entry, making the appended value effective
|
||||
([`os/exec/exec.go`, lines 1231–1265](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/os/exec/exec.go#L1231-L1265)).
|
||||
On the supported Unix model, initial environment lookup uses the first
|
||||
inherited occurrence
|
||||
([`syscall/env_unix.go`, lines 20–44 and 66–84](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/syscall/env_unix.go#L20-L84)).
|
||||
- Official `test_goroot_PATH.txt` tests both an empty `PATH` and a nonempty
|
||||
directory containing no executable; the test must find the `go` executable
|
||||
in the current toolchain's `$GOROOT/bin`
|
||||
([lines 1–41](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/test_goroot_PATH.txt#L1-L41)).
|
||||
|
||||
Those source rules and official assertions are behavior directly implemented
|
||||
or asserted by pinned Go. Using the selected WW driver's sibling directory as
|
||||
the local toolchain-bin analogue is derived from that implementation: WW has
|
||||
no `GOROOT`, and that directory already supplies the driver's default compiler,
|
||||
assembler, linker, and package-test coordinator. Applying the rule to WW's raw
|
||||
single-file compatibility route is also derived; it is a local input extension,
|
||||
but it executes the same observable test and initialization code. Canonical
|
||||
absolute spelling is runtime metadata only and prevents a relative driver path
|
||||
from leaking the coordinator's later package cwd into `PATH`.
|
||||
|
||||
#### Fresh four-axis audit and direct pre-fix measurements
|
||||
|
||||
The bounded audit considered all four permanent axes and selected only this
|
||||
test-runtime gap:
|
||||
|
||||
- **Build:** pinned `runBuild` loads all roots and checks package errors before
|
||||
output/action construction
|
||||
([`cmd/go/internal/work/build.go`, lines 459–478](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/work/build.go#L459-L478)); official
|
||||
`build_json.txt` distinguishes load errors from compiler failures
|
||||
([lines 15–26 and 39–45](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/build_json.txt#L15-L45)).
|
||||
A direct missing-import probe made both WW stages exit `1` with the identical
|
||||
source diagnostic and no producer or public output. This candidate was
|
||||
aligned.
|
||||
- **Test:** direct Cstage and WWstage directory probes, each invoked with
|
||||
`PATH=/usr/bin:/bin`, both exited `0` while the test printed exactly that
|
||||
unchanged value. `/home/kimchi/src/ww/out/bin` was absent. These are directly
|
||||
measured pre-fix WW facts and establish the selected external difference.
|
||||
- **Package:** pinned `types2.(*Checker).initFiles` rejects package name `_`
|
||||
([`cmd/compile/internal/types2/check.go`, lines 311–355](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/compile/internal/types2/check.go#L311-L355)),
|
||||
with official anchors in
|
||||
[`internal/types/testdata/check/blank.go`](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/internal/types/testdata/check/blank.go#L1-L5)
|
||||
and [`test/blank1.go`](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/test/blank1.go#L1-L10).
|
||||
Direct production, imported, and test-only probes were rejected identically
|
||||
by both WW stages. This candidate was aligned.
|
||||
- **Import:** pinned `unusedImports` requires every nonblank import binding to
|
||||
be used
|
||||
([`cmd/compile/internal/types2/resolver.go`, lines 706–740](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/compile/internal/types2/resolver.go#L706-L740)); official
|
||||
`importdecl0` covers default, alias, dot, and blank forms
|
||||
([lines 5–31](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/internal/types/testdata/check/importdecl0/importdecl0a.go#L5-L31)).
|
||||
A direct unused default-import probe produced identical Cstage/WWstage
|
||||
diagnostics and no committed work. This candidate was aligned.
|
||||
|
||||
The build, package, and import observations above are directly measured WW
|
||||
behavior; the linked rules are behavior directly implemented or asserted by
|
||||
pinned Go. The conclusion that this slice crosses those axes only when code in
|
||||
a successfully loaded test variant or initialized dependency observes `PATH`
|
||||
is derived from the pinned launch placement.
|
||||
|
||||
#### Ownership, launch behavior, and preserved boundaries
|
||||
|
||||
The environment is synthesized at the three true test-process launch owners:
|
||||
`internal/wwpackage.pkgstartrun` for directory products, Cstage
|
||||
`run_test_bin`, and WWstage `runsingletest` for raw single-file tests. Each
|
||||
uses the selected driver directory's canonical absolute spelling. The first
|
||||
effective uppercase inherited value is the suffix; absent and empty values
|
||||
have no suffix; ordinary uppercase duplicates are removed. Unrelated entries,
|
||||
including case-distinct and malformed names, retain their previous order and
|
||||
bytes. Directory products retain their established appended locale, temporary
|
||||
directory, and final `PWD`; raw tests retain caller cwd, `PWD`, stdin, and split
|
||||
streams.
|
||||
|
||||
The rule covers internal, external, and combined directory products;
|
||||
dependency initialization; filters and list mode; running retained tests; and
|
||||
raw single-file tests. It is independently materialized for each concurrent
|
||||
product. `ww build`, `ww run`, compiler/assembler/linker and generated-main
|
||||
commands, compile-only and assembly-only tests, no-test products, rejected
|
||||
requests, and later direct execution of a retained binary receive no test
|
||||
environment transformation.
|
||||
|
||||
Loading, graph construction, compilation, assembly, linking, action keys, and
|
||||
artifact production are unchanged. A load, compile, or link failure starts no
|
||||
test process, so runtime `PATH` is inapplicable and the existing diagnostic
|
||||
precedence remains. A started test observes the new environment before normal
|
||||
success, assertion failure, signal, timeout, or interruption. Existing process
|
||||
groups, cancellation, output capture, and cleanup own those outcomes; the
|
||||
environment adds no global mutable state. A running retained request remains
|
||||
private build, private run, then guarded install, so any unsuccessful run
|
||||
publishes nothing and preserves prior bytes. Parallel products receive separate
|
||||
environment arrays and retain existing result isolation.
|
||||
|
||||
Canonical physical driver directories do not become package, import, graph,
|
||||
action, artifact, symbol, `.wwi`, publication, or persistence identity.
|
||||
Compiled units, interfaces, archives, executables, modes, diagnostics, and
|
||||
public-output disposition are unchanged. No stored key or byte changed, so
|
||||
build workdir format remains `18`, test workdir format remains `19`, and
|
||||
semantic storage format remains `3`.
|
||||
|
||||
The extended WW-native `directory_test_execution_working_directory` observer
|
||||
proves Cstage/WWstage equality for absent, empty, nonempty, and duplicate
|
||||
caller `PATH`; all directory test shapes and dependency initialization;
|
||||
filters, listing, raw single-file, and running retained tests; relative selected
|
||||
driver canonicalization; build/no-test/compile-only/rejection exclusions;
|
||||
unchanged compiler, assembler, and linker environments; concurrent products;
|
||||
runtime failure with prior retained-byte rollback; artifact-byte identity; and
|
||||
transaction, stage, workdir, and generated-file cleanup. Existing signal,
|
||||
timeout, interruption, concurrent-driver, and public-output transaction owners
|
||||
cover the unchanged mechanisms at those boundaries.
|
||||
|
||||
## 12. Candidate architectures and hard-gate decision
|
||||
|
||||
Five candidates were developed as coherent systems, not as feature bins.
|
||||
|
||||
Reference in New Issue
Block a user