ww test: report no tests to run
This commit is contained in:
@@ -7635,8 +7635,9 @@ name per selected descriptor and emits no harness list bytes when its filters
|
||||
select zero tests. The test product still starts, package initialization still
|
||||
runs, the harness returns success without accounting, and the coordinator still
|
||||
emits the normal package `ok` result. Ordinary non-list execution with zero
|
||||
selected tests remains distinct: it keeps `[no matches]` and its
|
||||
discovered/selected/started/completed accounting.
|
||||
selected tests remains distinct: it keeps its
|
||||
discovered/selected/started/completed accounting and, as implemented later in
|
||||
section 11.39, uses the pinned no-tests warning and package-result suffix.
|
||||
|
||||
#### Pinned Go evidence and fact classification
|
||||
|
||||
@@ -7695,7 +7696,9 @@ runtime difference:
|
||||
([`go/build/build.go`, lines 538–549](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L538-L549)
|
||||
and [939–967](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L939-L967)),
|
||||
asserted by `TestMultiplePackageImport` and official `testdata/multi`
|
||||
([`go/build/build_test.go`, lines 105–133](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build_test.go#L105-L133)).
|
||||
([`go/build/build_test.go`, lines 105–133](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build_test.go#L105-L133),
|
||||
[`testdata/multi/file.go`, lines 1–5](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/testdata/multi/file.go#L1-L5),
|
||||
and [`file_appengine.go`, lines 1–5](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/testdata/multi/file_appengine.go#L1-L5)).
|
||||
Both WW stages rejected an `alpha`/`beta` directory with zero stdout and the
|
||||
same 159 stderr bytes (SHA-256
|
||||
`eaaa0c91f41b5d3deac4caf4299d5c7c650a1330be9b43edd090b8bfea906076`).
|
||||
@@ -7742,7 +7745,8 @@ initialization order, symbols, and publication names keep their existing roles.
|
||||
The product process and package initialization still run in list mode; no
|
||||
per-test child starts. Positive matching, option diagnostics and precedence,
|
||||
ordinary non-list no-match output, no-test-file results, and raw-file rejection
|
||||
are unchanged.
|
||||
were unchanged by this list-only slice; section 11.39 subsequently changes only
|
||||
the ordinary no-match warning and successful result annotation.
|
||||
|
||||
The shared support implementation change legitimately changes its object,
|
||||
archive, and linked test-product bytes. Its exported signature and `.wwi` byte
|
||||
@@ -7766,7 +7770,8 @@ initialization, cold and warm persistent work, absence of list/accounting
|
||||
sentinels, positive deterministic selection, running `-o` retention, later
|
||||
direct execution, stage stdout/stderr equality, retained executable byte
|
||||
identity, and `.new` cleanup. The existing routing observer separately keeps
|
||||
ordinary non-list `[no matches]` plus accounting pinned.
|
||||
the section-11.37 baseline for ordinary non-list reporting; section 11.39
|
||||
supersedes that private marker while retaining the accounting.
|
||||
|
||||
No persisted-byte contract changed: build workdir format remains `18`, test
|
||||
workdir format remains `19`, and semantic storage format remains `3`.
|
||||
@@ -7946,6 +7951,174 @@ check introduces no independently interruptible or shared state.
|
||||
No valid persisted-byte contract changed. Build workdir format remains `18`,
|
||||
test workdir format remains `19`, and semantic storage format remains `3`.
|
||||
|
||||
### 11.39 Implemented ordinary zero-match test results
|
||||
|
||||
An ordinary successful directory `ww test` whose valid `-run`/`-filter`
|
||||
selection starts no registered test now uses Go's externally visible no-tests
|
||||
protocol. The shared test runtime writes exactly
|
||||
`testing: warning: no tests to run\n` through standard error, retains WW's
|
||||
discovered/selected/started/completed accounting, and returns success. The
|
||||
directory coordinator recognizes that exact line at capture byte zero or after
|
||||
a newline and appends ` [no tests to run]` to the corresponding successful
|
||||
package `ok` result. WW's former `[no matches]` sentinel is no longer emitted.
|
||||
|
||||
This is deliberately distinct from the completed list-mode rule: list mode
|
||||
returns before the warning/accounting branch and retains an unsuffixed package
|
||||
result. A source-bearing directory without test files also retains its separate
|
||||
`? <package> [no test files]` result and starts no runtime product.
|
||||
|
||||
#### Pinned Go evidence and fact classification
|
||||
|
||||
The sole semantic authority is official Go 1.26.5 at commit
|
||||
`c19862e5f8415b4f24b189d065ed739517c548ba`:
|
||||
|
||||
- `testing.(*M).Run` returns directly from list mode at lines 2407–2411. In
|
||||
ordinary execution it gathers whether tests, examples, or fuzz targets ran,
|
||||
writes exactly `testing: warning: no tests to run` to stderr when none did,
|
||||
and keeps the outcome successful when no independent failure occurred
|
||||
([`testing/testing.go`, lines 2432–2485](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/testing/testing.go#L2432-L2485)).
|
||||
- `cmd/go` defines the line-delimited `noTestsToRun` marker
|
||||
([`cmd/go/internal/test/test.go`, line 1385](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/test/test.go#L1385))
|
||||
and, after a successful test process, recognizes it at capture byte zero or
|
||||
after a newline and appends ` [no tests to run]` to the package result
|
||||
([method `(*runTestActor).Act`, lines 1706–1732](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/internal/test/test.go#L1706-L1732)).
|
||||
- Official script/testdata `test_match_no_tests.txt` runs one registered test
|
||||
through a nonmatching filter and asserts the suffixed successful package
|
||||
result
|
||||
([lines 1–11](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/test_match_no_tests.txt#L1-L11)).
|
||||
- Official precedence script/testdata `test_match_no_tests_build_failure.txt`
|
||||
asserts that a build failure under a nonmatching filter produces `FAIL` and
|
||||
does not acquire a successful no-tests result
|
||||
([lines 1–18](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/go/testdata/script/test_match_no_tests_build_failure.txt#L1-L18)).
|
||||
|
||||
Those branches, exact bytes, success conditions, delimiter checks, result
|
||||
suffix, and script assertions are **behavior directly implemented or asserted
|
||||
by pinned Go**. That the runtime owns whether a test ran, the coordinator owns
|
||||
the package-result annotation, a build failure precedes both, and an arbitrary
|
||||
mid-line substring is not the marker are **behavior derived from the pinned
|
||||
implementation**.
|
||||
|
||||
WW retains its fnmatch-based local `-run`/`-filter` language rather than
|
||||
adopting Go regular expressions. WW also has an established always-visible
|
||||
harness report rather than Go's quiet/`-v` presentation switch, so this slice
|
||||
does not suppress every successful product capture or replace WW accounting
|
||||
with Go's `PASS` line. Within that honest local presentation boundary, the
|
||||
zero-execution warning, stream owner, success classification, marker delimiter,
|
||||
and package annotation apply directly.
|
||||
|
||||
#### Fresh four-axis audit and direct pre-fix measurements
|
||||
|
||||
The bounded audit examined all four permanent axes before selecting this test
|
||||
runtime/coordinator difference. Commands used Cstage `out/bin/ww` and WWstage
|
||||
`out/bin/ww_ww` against identical sources:
|
||||
|
||||
- **Go-like build:** pinned linker method
|
||||
`(*ErrorReporter).errorUnresolved` gives missing `main.main` a dedicated
|
||||
failure ([`cmd/link/internal/ld/errors.go`, lines 29–67](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/link/internal/ld/errors.go#L29-L67)),
|
||||
asserted by `TestUndefinedRelocErrors` and official `issue10978`
|
||||
([`cmd/link/internal/ld/ld_test.go`, lines 19–45](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/link/internal/ld/ld_test.go#L19-L45),
|
||||
[`testdata/issue10978/main.go`, lines 5–27](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/cmd/link/internal/ld/testdata/issue10978/main.go#L5-L27)).
|
||||
Both WW stages rejected a declared-main package with no entry, emitted empty
|
||||
stdout and the same 50 stderr bytes (SHA-256
|
||||
`9ed4d7684412c6d2e615041902072c81e9e09acb3970246d89a2c8bdddd2fcfa`),
|
||||
and published nothing. This applicable build property was aligned.
|
||||
- **Go-like test:** with one registered test, both stages exited 0 for
|
||||
`test -run no-such-*`, emitted empty stderr, and emitted the same 120 stdout
|
||||
bytes (SHA-256
|
||||
`ca12f88ebf1f94d3a2ca63ed1bc1e9b5a4811a660df3af4e70c7b9624ef97c40`):
|
||||
`[no matches]`, zero-selection accounting, and an unsuffixed package `ok`.
|
||||
This private marker and missing result annotation were the selected gap.
|
||||
Empty list selection and positive ordinary selection were already aligned
|
||||
controls and stayed outside the changed branch.
|
||||
- **Go-like package:** pinned `MultiplePackageError` and directory scanning
|
||||
reject conflicting declarations
|
||||
([`go/build/build.go`, lines 538–549](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L538-L549)
|
||||
and [939–967](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build.go#L939-L967)),
|
||||
asserted by `TestMultiplePackageImport` and official `testdata/multi`
|
||||
([`go/build/build_test.go`, lines 105–133](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/go/build/build_test.go#L105-L133)).
|
||||
Both WW stages rejected one `first`/`second` directory with empty stdout and
|
||||
byte-identical 161-byte stderr (SHA-256
|
||||
`a2d95681b8a97d55c26367084cd294632fa015882d1aa53b0df63f24bcf24ced`).
|
||||
This applicable package property was aligned.
|
||||
- **Go-like import:** pinned `unusedImports` and `errorUnusedPkg` reject every
|
||||
nonblank unused import
|
||||
([`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)),
|
||||
asserted by official `importdecl0a.go`
|
||||
([lines 9–26](https://github.com/golang/go/blob/c19862e5f8415b4f24b189d065ed739517c548ba/src/internal/types/testdata/check/importdecl0/importdecl0a.go#L9-L26)).
|
||||
Both stages rejected an unused dotted `fmt` import with empty stdout and the
|
||||
same semantic diagnostic;
|
||||
raw stderr differed only in the deliberately stage-named private output path.
|
||||
This applicable import property was aligned.
|
||||
|
||||
The WW statuses, streams, lengths, hashes, and diagnostics are **directly
|
||||
measured WW behavior**. The linked official implementation and testdata are
|
||||
**behavior directly implemented or asserted by pinned Go**. Applying the
|
||||
runtime/coordinator split without changing WW's filter syntax or harness report
|
||||
is **behavior derived from the pinned implementation**.
|
||||
|
||||
#### Ownership, final behavior, and preserved boundaries
|
||||
|
||||
`lib/test/run.ww` is the runtime owner. Its existing `selected == 0` branch now
|
||||
writes the pinned warning through the same EINTR-safe fd writer used elsewhere,
|
||||
targeting stderr, then writes the unchanged accounting to stdout and returns 0.
|
||||
Its earlier list return is untouched. A directly invoked retained binary
|
||||
therefore exposes the warning on stderr and accounting on stdout.
|
||||
|
||||
`internal/wwpackage/package.ww` is the directory result owner. It already gives
|
||||
each product one combined stdout/stderr capture and emits that capture in
|
||||
canonical group order. Its new predicate accepts only the exact warning at byte
|
||||
zero or following `\n`; after `pkgrunok` succeeds, `pkgemitgroup` appends the
|
||||
suffix to the result it already owns. Text embedded mid-line in a running test
|
||||
does not match. A failed, signalled, timed-out, interrupted, or unstartable test
|
||||
does not reach the successful result. A producer failure never starts the
|
||||
runtime and cannot synthesize the warning or suffix.
|
||||
|
||||
Both selected driver stages compile the same `lib/test` code into test products
|
||||
and delegate directory execution to the same WW-native coordinator, so no
|
||||
C-only or self-host-only semantic fork was introduced. Direct post-fix probes
|
||||
through both stages exited 0, emitted empty coordinator stderr, and emitted the
|
||||
same 159 stdout bytes (SHA-256
|
||||
`a67242ab79b9bd9bca1a32073c1fccbb9aa4fa9d8ad52ced667b25c54dc1be08`):
|
||||
the warning, unchanged accounting, and suffixed package result.
|
||||
|
||||
Loading and Go-platform source selection are unchanged. Production,
|
||||
internal-test, external-test, recompiled-for-test, support, and generated-main
|
||||
graph nodes and actions are unchanged. Compilers, assemblers, archivers, and
|
||||
linkers retain their diagnostics and scheduling. The support implementation
|
||||
change legitimately changes its object/archive and linked test-product bytes,
|
||||
but its exported signature and `.wwi` contract do not change; valid Cstage and
|
||||
WWstage retained products remain byte-identical.
|
||||
|
||||
Declared package names and canonical dotted import identities remain separate.
|
||||
The coordinator annotates an already-owned result; it derives no identity from
|
||||
the warning, alias, declared name, path leaf, filename, physical directory,
|
||||
output path, artifact name, or linker order. Physical directories remain test
|
||||
cwd and result-label metadata only, never package/import/graph/action/artifact/
|
||||
symbol/`.wwi`/publication/persistence identity.
|
||||
|
||||
Cold and warm persistent work produce identical result bytes and still run the
|
||||
test product because there is no test-result cache. A successful retained run
|
||||
publishes the privately tested executable through the existing guarded install.
|
||||
A later producer failure preserves prior public bytes, and restored valid reuse
|
||||
reproduces the same warning/suffix without rewriting an identical executable.
|
||||
Publication rejection, rollback, existing-output preservation, concurrency,
|
||||
interruption, process-group cancellation, capture separation, final `FAIL`, and
|
||||
cleanup remain with their existing owners. No active `.new`, `.install`,
|
||||
`.wwtxn.*`, adjacent `.sepwork`, process, or capture residue is introduced.
|
||||
|
||||
The WW-native `ordinary_no_match_uses_go_warning_and_result_suffix` observer
|
||||
proves both stages; cold/warm reuse; concurrent reverse-requested packages and
|
||||
ordered per-product markers; exact mid-line rejection; positive, list, and
|
||||
no-test-files controls; retained publication and direct stderr ownership;
|
||||
producer-failure precedence; cold/repeated failure; prior-output preservation;
|
||||
restored reuse; normalized diagnostic parity; retained executable byte identity;
|
||||
and transaction/output-scratch cleanup. Existing signal, timeout, interruption,
|
||||
and process-group observers continue to prove those unchanged mechanisms.
|
||||
|
||||
This is runtime/coordinator presentation, not a persisted-byte contract. Build
|
||||
workdir format remains `18`, test workdir format remains `19`, and semantic
|
||||
storage format remains `3`.
|
||||
|
||||
## 12. Candidate architectures and hard-gate decision
|
||||
|
||||
Five candidates were developed as coherent systems, not as feature bins.
|
||||
|
||||
18
docs/spec.md
18
docs/spec.md
@@ -828,12 +828,18 @@ List mode starts the same directory-owned product and therefore performs its
|
||||
ordinary package initialization, but it does not start any selected test child.
|
||||
The harness emits exactly one newline-terminated qualified name for each test
|
||||
selected by the command's filters, in descriptor order. If the selected set is
|
||||
empty, the harness emits no list payload, no `[no matches]` sentinel, and no
|
||||
accounting, and returns success; the coordinator still emits the ordinary
|
||||
successful package result. This does not alter non-list execution: a valid
|
||||
filter selecting no tests continues to emit `[no matches]` and the
|
||||
discovered/selected/started/completed accounting. A retained binary invoked
|
||||
directly has no coordinator package result.
|
||||
empty, the harness emits no list payload, warning, or accounting and returns
|
||||
success; the coordinator still emits the ordinary successful package result
|
||||
without a no-tests suffix. Ordinary non-list execution is distinct: a valid
|
||||
filter selecting no tests writes exactly
|
||||
`testing: warning: no tests to run\n` through the harness's standard error,
|
||||
preserves the discovered/selected/started/completed accounting and successful
|
||||
exit, and causes a successful directory package result to end in
|
||||
` [no tests to run]`. The coordinator recognizes that exact warning only at
|
||||
capture byte zero or after a newline. Directory execution combines the warning
|
||||
and accounting in its product-local capture; a retained binary invoked directly
|
||||
keeps the warning on standard error, its accounting on standard output, and has
|
||||
no coordinator package result.
|
||||
|
||||
After those ordered results, an ordinary explicit `ww test` request that records
|
||||
an attributable setup, build, or execution failure emits exactly one standalone
|
||||
|
||||
@@ -222,12 +222,18 @@ run loop exactly. Measured on the 31-package `lib/...` walk:
|
||||
List mode uses that same product process and initialization boundary but starts
|
||||
no per-test child. The shared language harness emits only selected qualified
|
||||
test names, one per line in descriptor order. A valid filter selecting no tests
|
||||
therefore produces no harness list bytes, no `[no matches]` marker, and no
|
||||
accounting while the process returns success; the coordinator continues with
|
||||
the package's normal `ok` result. Ordinary non-list zero-selection execution
|
||||
retains its `[no matches]` marker and accounting. Concurrent products keep
|
||||
independent empty or nonempty captures, and persistent work never caches a test
|
||||
result.
|
||||
therefore produces no harness list bytes, warning, or accounting while the
|
||||
process returns success; the coordinator continues with the package's normal
|
||||
unsuffixed `ok` result. Ordinary non-list zero-selection execution instead
|
||||
writes the exact line `testing: warning: no tests to run` through harness
|
||||
stderr, retains its accounting and successful status, and gives the successful
|
||||
package `ok` result the suffix ` [no tests to run]`. Marker recognition is
|
||||
line-delimited, at capture byte zero or after a newline; an arbitrary substring
|
||||
in user output does not annotate the result. Concurrent products keep
|
||||
independent empty or nonempty captures, markers, and suffixes, and persistent
|
||||
work never caches a test result. A directly invoked retained binary exposes the
|
||||
warning on stderr and accounting on stdout because no coordinator combines its
|
||||
descriptors or emits a package result.
|
||||
|
||||
Directory test binaries are always linked under the coordinator's temporary
|
||||
product root. `-c` independently requests a caller-visible executable copy and
|
||||
|
||||
Reference in New Issue
Block a user