-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Open
Labels
GoCommandcmd/gocmd/goNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Description
Go version
go1.26-devel_bb124921e9 Sun Jul 27 12:36:07 2025 -0400 darwin/amd64
Output of go env
in your module/workspace:
╰─ go env
AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/Users/ryancurrah/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/ryancurrah/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/fk/8lgm5_252mb0ln68l_z9wlz80000gn/T/go-build3317734112=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/Users/ryancurrah/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/ryancurrah/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/Users/ryancurrah/git/github.com/ryancurrah/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/ryancurrah/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/Users/ryancurrah/git/github.com/ryancurrah/go/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.26-devel_bb124921e9 Sun Jul 27 12:36:07 2025 -0400'
GOWORK=''
PKG_CONFIG='pkg-config'
What did you do?
Hello guys,
Thanks a lot for resolving #23565.
I started testing this feature and encountered a problem that occurs when I use the go test command with the -coverpkg
flag.
When coverage is collected with the -coverpkg
flag and test result caching is enabled, the generated report may include lines that no longer exist.
This happens because:
- Each test package attempts to collect coverage for all packages matching the
-coverpkg
pattern. - If the test result is loaded from the cache, the coverage data may be outdated—especially if the test package does not directly or indirectly depend on the modified code, leaving the cache uninvalidated.
For example we have project with layout:
Project layout
proj/
some_func.go
some_func_test.go
sub/
sub.go
sub_test.go
sum/
sum.go
Files Content
some_func.go
package proj
import "proj/sum"
func SomeFunc(a, b int) int {
if a == 0 && b == 0 {
return 0
}
return sum.Sum(a, b)
}
sub.go
package sub
func Sub(a, b int) int {
if a == 0 && b == 0 {
return 0
}
return a - b
}
sum.go
package sum
func Sum(a, b int) int {
if a == 0 {
return b
}
return a + b
}
some_func_test.go
package proj
import (
"github.com/stretchr/testify/require"
"testing"
)
func Test_SomeFunc(t *testing.T) {
t.Run("test1", func(t *testing.T) {
require.Equal(t, 2, SomeFunc(1, 1))
})
}
sub_test.go
package sub
import (
"github.com/stretchr/testify/require"
"testing"
)
func Test_Sub(t *testing.T) {
t.Run("test_sub1", func(t *testing.T) {
require.Equal(t, 0, Sub(1, 1))
})
}
Coverage result of this tests
go test -coverpkg=proj/... -coverprofile=cover.out ./proj/...
ok proj (cached) coverage: 44.4% of statements in proj/...
ok proj/sub (cached) coverage: 22.2% of statements in proj/...
proj/sum coverage: 0.0% of statements
mode: set
proj/some_func.go:5.29,6.22 1 1
proj/some_func.go:6.22,8.3 1 0
proj/some_func.go:9.2,9.22 1 1
proj/sub/sub.go:3.24,4.22 1 0
proj/sub/sub.go:4.22,6.3 1 0
proj/sub/sub.go:7.2,7.14 1 0
proj/sum/sum.go:3.24,4.12 1 1
proj/sum/sum.go:4.12,6.3 1 0
proj/sum/sum.go:7.2,7.14 1 1
proj/some_func.go:5.29,6.22 1 0
proj/some_func.go:6.22,8.3 1 0
proj/some_func.go:9.2,9.22 1 0
proj/sub/sub.go:3.24,4.22 1 1
proj/sub/sub.go:4.22,6.3 1 0
proj/sub/sub.go:7.2,7.14 1 1
proj/sum/sum.go:3.24,4.12 1 0
proj/sum/sum.go:4.12,6.3 1 0
proj/sum/sum.go:7.2,7.14 1 0
proj/sum/sum.go:3.24,4.12 1 0
proj/sum/sum.go:4.12,6.3 1 0
proj/sum/sum.go:7.2,7.14 1 0
Change sub.go a bit
sub.go
package sub
func Sub(a, b int) int {
if a == 0 && b == 0 || a == -100 {
return 0
}
return a - b
}
Coverage result after change
go test -coverpkg=proj/... -coverprofile=cover.out ./proj/...
ok proj (cached) coverage: 44.4% of statements in proj/...
ok proj/sub 0.005s coverage: 22.2% of statements in proj/...
proj/sum coverage: 0.0% of statements
mode: set
proj/some_func.go:5.29,6.22 1 1
proj/some_func.go:6.22,8.3 1 0
proj/some_func.go:9.2,9.22 1 1
proj/sub/sub.go:3.24,4.22 1 0 <- Old (Should have been invalidated and removed)
proj/sub/sub.go:4.22,6.3 1 0
proj/sub/sub.go:7.2,7.14 1 0
proj/sum/sum.go:3.24,4.12 1 1
proj/sum/sum.go:4.12,6.3 1 0
proj/sum/sum.go:7.2,7.14 1 1
proj/some_func.go:5.29,6.22 1 0
proj/some_func.go:6.22,8.3 1 0
proj/some_func.go:9.2,9.22 1 0
proj/sub/sub.go:3.24,4.35 1 1 <- New
proj/sub/sub.go:4.35,6.3 1 0
proj/sub/sub.go:7.2,7.14 1 1
proj/sum/sum.go:3.24,4.12 1 0
proj/sum/sum.go:4.12,6.3 1 0
proj/sum/sum.go:7.2,7.14 1 0
proj/sum/sum.go:3.24,4.12 1 0
proj/sum/sum.go:4.12,6.3 1 0
proj/sum/sum.go:7.2,7.14 1 0
What did you see happen?
The report merges cached and fresh coverage, so you end up with two sub.go:3.24
entries, one that is stale and one that is correct. That duplication trips up tools that emit Cobertura XML.
What did you expect to see?
I expected the report to keep only the latest coverage and invalidate the cached coverage reports.
jbub
Metadata
Metadata
Assignees
Labels
GoCommandcmd/gocmd/goNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.