test: separate behavior and command compatibility checks - #2450
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
LLGo baseline benchmarks
Program measurements
Core language and compiler benchmarks
Compared with |
There was a problem hiding this comment.
Code Review: Test suite reorganization
This is a well-structured refactor of the test suite: consolidating test/go acceptance tests into command-integration tests under test/cmd/llgo/, splitting the compiler driver by build tag (//go:build !llgo vs //go:build llgo), adding testdata fixtures, and re-enabling go vet on ./test/go. The design is coherent and the sync.Once build-once pattern for the llgo binary is implemented correctly (build error stored, t.Fatalf called outside the Do closure).
Below are the noteworthy findings. Most are minor; the CI vet change is worth a closer look.
Non-inline / design notes
-
Duplicated helper body.
runGoCompilerintest/cmd/llgo/command_helpers_test.goandrunCompilerintest/cmd/llgo/command_go_test.go(//go:build !llgo) have byte-for-byte identical bodies. The intent is sound (runCompilerbecomesllgounder thellgotag), but under!llgothe duplication means a future fix to stream/error handling must land in two places. Consider having the!llgorunCompilerdelegate torunGoCompiler. -
runCompilermerges stderr into stdout only on error. On a successful run stderr is discarded; on failure it is appended. For the textual-diff tests (print-builtin, float conversion) this means a warning-only successful run yields different captured text than a failure. Fine for pass/fail, but worth a one-line comment on the convention since three definitions share it. -
Redundant full-stdlib export.
writeToolCompileStdlibImportCfgintest/cmd/llgo/tool_compile_compat_test.goshells out togo list -export ... stdper subtest (and per build variant). The Go build cache absorbs this on warm caches, but on cold CI caches it pays the full stdlib export multiple times; memoizing via a package-levelsync.Oncewould remove the repeat. -
Timeout comment references a stale run. In
.github/workflows/go.yml, the "known-good #172 Windows coverage run took about 56 minutes" figure predates this reorg; refresh it if the new workload changes wall-clock time materially. (Info only.)
Everything else — the deliberately-unsafe cgo fault injection (properly gated behind //go:build llgo, volatile used to defeat clang UB folding, MallocFree null-checks), the CHECK-comment fixtures, and the pull_request (not pull_request_target) workflow trigger keeping CODECOV_TOKEN away from fork PRs — checked out cleanly.
Findings without inline locations
.github/workflows/go.yml:138: Dropping-vet=offhere re-enablesgo veton./test/go. Note thattest/go/newexpr_go126_test.go(gated//go:build go1.26) uses llgo'snew(expr)extension (new(0),new(123),new(i > 0)), which is not valid standard Go. When this step runs on a Go 1.26+ toolchain with the stockgocompiler, that file would fail to build/vet. Please confirm this was validated on the CI Go version — the removed comment previously documented exactly why-vet=offwas needed here. Consider adding a short note explaining vet is now safe because the vet-incompatible fixtures moved totest/cmd/llgo(as embedded source strings).
|
Addressed the remaining non-inline review points in
Local validation after the changes:
|
This extracts the test-layout refactor from the Windows R10 work so it can be reviewed and merged independently. It does not change compiler or runtime production code.
Test ownership
The change keeps each kind of test at the layer that owns it:
_test.gocases undertest/go;test/cmd/llgo, withllgoand!llgowrappers selecting the compiler;cl/_test*;internal/build;test/cgoandtest/llgoext.Benefits
runtime.NumGoroutinecases re-execute the already-built test binary in an isolated child process, adding neither another package nor another LLGo build.The isolated
test/gotiming is not used as the overall speedup because some work moved to better-owned packages. Instead, the comparison below measures the directly affected CI steps, which includetest/goand every destination package:Test with coverage, aggregate across macOS, Linux, MinGW, and MSVCRun versioned LLGo tests, aggregate across five platform/shard jobsThese values sum the duration of the affected step on each runner; they are not workflow wall time. Both PR runs improve the aggregate, while individual runners remain noisy (for example, the LLGo MSVC lane is about three minutes slower in the fixed run). The repository gains one test package (
test/cmd/llgo), while the changed_test.gofiles have 26 added and 27 removed test functions overall, so the result reflects retained-but-consolidated coverage rather than hiding the work outsidetest/go.Validation
go test ./test/go ./test/cmd/llgotest/gowith LLGo and Go 1.26.7runtime.NumGoroutineregression cases repeated 100 times with Go 1.26.7 and 20 times with Go 1.27llgo test ./test/cmd/llgo, using the same Go 1.27 modfile path as CIinternal/buildtests for ABI modes, DWARF panic modes, and SSA DebugRef orderingclfixtures for deferred panic IR and cgo defer orderingtest/cgoandtest/llgoextcases under LLGoThe complete
internal/buildpackage also passed in the original development worktree. The completeclpackage exceeded its existing 10-minute aggregate timeout in an unrelated Python/DWARF fixture; all changedclfixtures pass independently.