golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.9k stars 17.65k forks source link

cmd/go: duplicate lines in coverage file after update to 1.22 #65636

Open alainstoffels opened 8 months ago

alainstoffels commented 8 months ago

Go version

go version go1.22.0 windows/amd64

Output of go env in your module/workspace:

GO111MODULE=on
GOARCH=amd64
GOBIN=
GOCACHE=C:\Users\astoffels\AppData\Local\go-build
GOENV=C:\Users\astoffels\AppData\Roaming\go\env
GOEXE=.exe
GOEXPERIMENT=
GOFLAGS=
GOHOSTARCH=amd64
GOHOSTOS=windows
GOINSECURE=
GOMODCACHE=C:\Source\golang\pkg\mod
GONOPROXY=
GONOSUMDB=
GOOS=windows
GOPATH=C:\Source\golang
GOPRIVATE=
GOPROXY=https://proxy.golang.org,direct
GOROOT=C:/Program Files/Go
GOSUMDB=sum.golang.org
GOTMPDIR=
GOTOOLCHAIN=auto
GOTOOLDIR=C:\Program Files\Go\pkg\tool\windows_amd64
GOVCS=
GOVERSION=go1.22.0
GCCGO=gccgo
GOAMD64=v1
AR=ar
CC=gcc
CXX=g++
CGO_ENABLED=0
GOMOD=C:\Source\golang\src\coverageRepro\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=-m64 -fno-caret-diagnostics -Qunused-arguments -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=C:\Users\ASTOFF~1\AppData\Local\Temp\go-build2371241097=/tmp/go-build -gno-record-gcc-switches

What did you do?

Clone https://github.com/alainstoffels/coverageRepro Run inside the root of the repo: go test -cover -coverpkg=./... -coverprofile=coverage.out ./...

What did you see happen?

coverage.out now contains 2 lines for coverageRepro/bar/bar.go. One where it indicates that it's not covered, and another where it indicates that it is covered:

mode: set
coverageRepro/bar/bar.go:3.12,5.2 1 0
coverageRepro/bar/bar.go:3.12,5.2 1 1
coverageRepro/foo/foo.go:5.12,7.2 1 1

foo.Foo() calls bar.Bar(), so foo.TestFoo() should cover bar.Bar().

What did you expect to see?

I would expect it to output a single line for coverageRepro/bar/bar.go, indicating it as covered, like it did before the 1.22 update:

mode: set
coverageRepro/bar/bar.go:3.12,5.2 1 1
coverageRepro/foo/foo.go:5.12,7.2 1 1
alainstoffels commented 8 months ago

In our codebase, this has caused our coverage file to increase from 260 MB to 1.53 GB.

Also, it's likely that this is related to https://github.com/golang/go/issues/65570

aaron42net commented 8 months ago

Does GOEXPERIMENT=nocoverageredesign go test -cover -coverpkg=./... -coverprofile=coverage.out ./... work around the problem? If so, it is also related to the coverage redesign (which seems likely).

alainstoffels commented 8 months ago

Does GOEXPERIMENT=nocoverageredesign go test -cover -coverpkg=./... -coverprofile=coverage.out ./... work around the problem? If so, it is also related to the coverage redesign (which seems likely).

That does indeed solve the problem.

thanm commented 8 months ago

From what I can see, this behavior is present well prior to the coverage redesign work (I see it in Go 1.19).

Here is an example:

$ go version
go version go1.19.13 linux/amd64
$ go test -short -coverprofile=/tmp/c.p -coverpkg=bytes,archive/tar bytes archive/tar
ok      bytes   0.097s  coverage: 40.4% of statements in bytes, archive/tar
ok      archive/tar 0.122s  coverage: 57.2% of statements in bytes, archive/tar
$ fgrep buffer.go:77 /tmp/c.p
bytes/buffer.go:77.28,77.49 1 1
bytes/buffer.go:77.28,77.49 1 0
$ 

Similar behavior on tip with GOEXPERIMENT=nocoverageredesign:

$ go version
go version devel go1.23-39ec246e73 Tue Feb 6 22:21:42 2024 +0000 linux/amd64
$ rm -f /tmp/c.p 
$ GOEXPERIMENT=nocoverageredesign go test -short -coverprofile=/tmp/c.p -coverpkg=bytes,archive/tar bytes archive/tar
ok      bytes   0.108s  coverage: 40.3% of statements in bytes, archive/tar
ok      archive/tar 0.095s  coverage: 56.7% of statements in bytes, archive/tar
$ fgrep buffer.go:66 /tmp/c.p
bytes/buffer.go:66.34,67.14 1 0
bytes/buffer.go:66.34,67.14 1 1
$