Skip to content

cmd/go: -coverprofile with relative path uses wrong file name #22430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ghost opened this issue Oct 24, 2017 · 8 comments
Closed

cmd/go: -coverprofile with relative path uses wrong file name #22430

ghost opened this issue Oct 24, 2017 · 8 comments
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@ghost
Copy link

ghost commented Oct 24, 2017

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.9.1 darwin/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

macOS Sierra 10.12.6

What did you do?

If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on play.golang.org is best.

I am trying to generate coverage reports for a simple application but am unable to due to the wrong path being generated in the -coverprofile output

I am having the issue outlined here: Masterminds/glide#43 . I've recreated the problem with a simple example modeled after the skeleton of my application. I am on macOS Sierra, go1.9 is installed via goenv.

Directory structure

$ tree src/
src/
├── cover.out
├── lib
│   └── foo
│       ├── Dummy.go
│       ├── SuperDummy.go
│       └── TestSuperDummy_test.go
├── main.go

Dummy.go

package foo

func HelloWorld() string {
	return  "hello world"
}

SuperDummy.go

package foo

import "fmt"

type SuperDummy struct {
	Forename string
}

func (dummy SuperDummy) SayHello() {
	fmt.Printf("Hello my name is %s!", dummy.Forename)
}

TestSuperDummy_test.go

package foo

import "testing"

func TestSuperDummy_SayHello(t *testing.T) {
	var d = SuperDummy{"Paul"}
	d.SayHello()
}

main.go

package main

import (
	"./lib/foo"
	"fmt"
)

func main() {
	var d foo.SuperDummy = foo.SuperDummy{"Patrick"}
	d.SayHello()
	fmt.Println(foo.HelloWorld())
}

From the src/ directory I ran go test ./lib/foo -coverprofile=cover.out which yielded:

src$ go test ./lib/foo -coverprofile=cover.out
ok      _/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo   0.007s  coverage: 50.0% of statements
src$ cat cover.out 
mode: set
_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo/Dummy.go:3.26,5.2 1 0
_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo/SuperDummy.go:9.36,11.2 1 1

Running go tool cover -html=cover.out yields the error :

src$ go tool cover -html=cover.out
cover: can't find "Dummy.go": cannot find package "_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo/" in any of:
        /Users/patrickburton/.goenv/versions/1.9.0/src/_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo (from $GOROOT)
        /Users/patrickburton/.go/src/_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo (from $GOPATH)
        /Users/patrickburton/IdeaProjects/src/_/Users/patrickburton/IdeaProjects/gotestcoverage/src/lib/foo
@ianlancetaylor ianlancetaylor changed the title Wrong path in go test -coverprofile? cmd/go: -coverprofile with relative path uses wrong file name Oct 25, 2017
@ianlancetaylor ianlancetaylor added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Oct 25, 2017
@ianlancetaylor ianlancetaylor added this to the Unplanned milestone Oct 25, 2017
@ianlancetaylor
Copy link
Member

My guess is that this is a bug related to using something other than an import path with -coverprofile.

@ghost
Copy link
Author

ghost commented Nov 28, 2017

@ianlancetaylor What do you mean? Do you know of any workarounds?

@ianlancetaylor
Copy link
Member

I think I meant that in the command line go test ./lib/foo -coverprofile=cover.out the argument to go test, ./lib/foo, is not an import path. The workaround would be to use an import path. It's worth trying, anyhow.

@ghost
Copy link
Author

ghost commented Nov 28, 2017

I tried this, however the cover tool seems to prefix the coverage data with things like the CWD or command-line-arguments. For example I run the following commands from the foo/ directory and get these results:

foo$ go test *.go -coverprofile=cover.out
ok      command-line-arguments  0.006s  coverage: 50.0% of statements
foo$ go tool cover -html=cover.out
cover: can't find "Dummy.go": cannot find package "command-line-arguments/" in any of:
        /Users/patrickburton/.goenv/versions/1.9.1/src/command-line-arguments (from $GOROOT)
        /Users/patrickburton/.go/src/command-line-arguments (from $GOPATH)
        /Users/patrickburton/IdeaProjects/gotest-issue/src/command-line-arguments

If you look at the last line /Users/patrickburton/IdeaProjects/gotest-issue/src/command-line-arguments, command-line-arguments isn't even in my GOPATH:

elimstats$ echo $GOPATH
/Users/patrickburton/.go:/Users/patrickburton/IdeaProjects:/Users/patrickburton/IdeaProjects/elimstats/src/lib/elimstats:/Users/patrickburton/IdeaProjects/elimstats/src/lib

@zpeters
Copy link

zpeters commented Apr 25, 2018

@TheD0ctor did you ever find a workaround for this? Still seeing this in 1.9.5

@centerorbit
Copy link

centerorbit commented Aug 21, 2018

I see this too, here's my workaround (running inside my repo directory):

go test -coverprofile=c.out
sed -i "s/_$(pwd|sed 's/\//\\\//g')/./g" c.out
go tool cover -html=c.out -o=c.html
  1. Outputs test coverage to c.out
  2. Uses two seds:
    • The inside sed escapes the slashes from the pwd command (/dirs/now/like/so)
    • With the escaped pwd, we use the outer sed to find/replace the absolute path, with just a relative path of ./
  3. go tool cover can now successfully process c.out into c.html

@morrowc
Copy link

morrowc commented Oct 27, 2019

FWIW this is still in this state as of go1.11

$ go test -v -coverprofile=coverage.out -covermode=count ./...
...
coverage: 70.0% of statements
$ more coverage.out
mode: count
/home/me/scripts/git/parsembox/parsembox.go:31.38,36.2 1 10
/home/me/scripts/git/parsembox/parsembox.go:38.34,42.2 3 15

For some projects I've had this in a githook:
go test -coverprofile=coverage.out sed -i "s/_$(pwd|sed 's/\//\\\//g')/./g" coverage.out
which kinda stinks, but works :(

note: the sed recipe acopy/paste problem... fixed, I hope :)

@seankhliao
Copy link
Member

I think this no longer reproduces.

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Dec 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

5 participants