-
Notifications
You must be signed in to change notification settings - Fork 18.9k
Description
What version of Go are you using (go version)?
$ go version go version go1.20.4 darwin/arm64
Does this issue reproduce with the latest release?
Yes, with devel go1.21-91b8cc0d.
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="" GOARCH="arm64" GOBIN="" GOCACHE="/Users/filippo/Library/Caches/go-build" GOENV="/Users/filippo/Library/Application Support/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="arm64" GOHOSTOS="darwin" GOINSECURE="" GOMODCACHE="/Users/filippo/pkg/mod" GONOPROXY="github.com/FiloSottile/*,filippo.io/*" GONOSUMDB="" GOOS="darwin" GOPATH="/Users/filippo" GOPRIVATE="" GOPROXY="https://proxy.golang.org" GOROOT="/opt/homebrew/Cellar/go/1.20.4/libexec" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/opt/homebrew/Cellar/go/1.20.4/libexec/pkg/tool/darwin_arm64" GOVCS="" GOVERSION="go1.20.4" GCCGO="gccgo" AR="ar" CC="cc" CXX="c++" CGO_ENABLED="1" GOMOD="/Users/filippo/src/filippo.io/litetlog/go.mod" GOWORK="" CGO_CFLAGS="-O2 -g" CGO_CPPFLAGS="" CGO_CXXFLAGS="-O2 -g" CGO_FFLAGS="-O2 -g" CGO_LDFLAGS="-O2 -g" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/_j/hq4ytn1n4b94fhrpvvb9tktr0000gn/T/go-build1323402631=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
Within a Go test, built a binary from a different package in the same module with -cover and executed it.
Ran the test with -coverpkg=./....
What did you expect to see?
Coverage of the command invocation included in the test summary.
What did you see instead?
coverage: 0.0% of statements in ./...
I expected this to work because there is explicit support for it in the testing package, which propagates the temporary GOCOVERDIR to the environment.
go/src/cmd/go/internal/test/test.go
Lines 1326 to 1330 in 91b8cc0
| // Even though we are passing the -test.gocoverdir option to | |
| // the test binary, also set GOCOVERDIR as well. This is | |
| // intended to help with tests that run "go build" to build | |
| // fresh copies of tools to test as part of the testing. | |
| addToEnv = "GOCOVERDIR=" + gcd |
Indeed, rogpeppe/go-internal#201 takes advantage of this to run the test binary as a subprocess and collect coverage from that invocation with the coverage of the main test run.
However, there is then code to exclude coverage from other binaries, introduced for #57924.
go/src/runtime/coverage/testsupport.go
Lines 84 to 96 in 91b8cc0
| // Generate the expected hash string based on the final meta-data | |
| // hash for this test, then look only for pods that refer to that | |
| // hash (just in case there are multiple instrumented executables | |
| // in play). See issue #57924 for more on this. | |
| hashstring := fmt.Sprintf("%x", finalHash) | |
| for _, p := range podlist { | |
| if !strings.Contains(p.MetaFile, hashstring) { | |
| continue | |
| } | |
| if err := ts.processPod(p); err != nil { | |
| return err | |
| } | |
| } |
I think running integration tests within a Go test is a more idiomatic way to do it than rigging a script with go tool covdata invocations, and it's nice that GOCOVERDIR gets already set up and propagated automatically, but the pattern then breaks when the coverage data is not collected.
As an aside, it should be documented somewhere how test coverage is propagated and collected.