@@ -6,6 +6,19 @@ package main_test
66
77import (
88 "bytes"
9+ cmdgo "cmd/go"
10+ "cmd/go/internal/base"
11+ "cmd/go/internal/cache"
12+ "cmd/go/internal/cfg"
13+ "cmd/go/internal/gover"
14+ "cmd/go/internal/robustio"
15+ "cmd/go/internal/search"
16+ "cmd/go/internal/toolchain"
17+ "cmd/go/internal/vcs"
18+ "cmd/go/internal/vcweb/vcstest"
19+ "cmd/go/internal/web"
20+ "cmd/go/internal/work"
21+ "cmd/internal/sys"
922 "debug/elf"
1023 "debug/macho"
1124 "debug/pe"
@@ -29,21 +42,6 @@ import (
2942 "strings"
3043 "testing"
3144 "time"
32-
33- "cmd/go/internal/base"
34- "cmd/go/internal/cache"
35- "cmd/go/internal/cfg"
36- "cmd/go/internal/gover"
37- "cmd/go/internal/robustio"
38- "cmd/go/internal/search"
39- "cmd/go/internal/toolchain"
40- "cmd/go/internal/vcs"
41- "cmd/go/internal/vcweb/vcstest"
42- "cmd/go/internal/web"
43- "cmd/go/internal/work"
44- "cmd/internal/sys"
45-
46- cmdgo "cmd/go"
4745)
4846
4947func init () {
@@ -2801,3 +2799,71 @@ func TestExecInDeletedDir(t *testing.T) {
28012799 // `go version` should not fail
28022800 tg .run ("version" )
28032801}
2802+
2803+ func TestCacheCoverageProfile (t * testing.T ) {
2804+ tooSlow (t , "links and runs a test binary multiple times with coverage enabled" )
2805+
2806+ if gocacheverify .Value () == "1" {
2807+ t .Skip ("GODEBUG gocacheverify" )
2808+ }
2809+
2810+ tg := testgo (t )
2811+ defer tg .cleanup ()
2812+
2813+ tg .parallel ()
2814+ tg .setenv ("GOPATH" , filepath .Join (tg .pwd (), "testdata" ))
2815+ tg .makeTempdir ()
2816+ tg .setenv ("GOCACHE" , tg .path ("c1" ))
2817+
2818+ // checkProfile asserts that the given profile contains the given mode
2819+ // and coverage lines for all given files.
2820+ checkProfile := func (t * testing.T , profile , mode string , files ... string ) {
2821+ t .Helper ()
2822+ if out , err := os .ReadFile (profile ); err != nil {
2823+ t .Fatalf ("failed to open coverprofile: %v" , err )
2824+ } else {
2825+ if n := bytes .Count (out , []byte ("mode: " + mode )); n != 1 {
2826+ if n == 0 {
2827+ t .Fatalf ("missing mode: %s" , mode )
2828+ } else {
2829+ t .Fatalf ("too many mode: %s" , mode )
2830+ }
2831+ }
2832+ for _ , fname := range files {
2833+ if ! bytes .Contains (out , []byte (fname )) {
2834+ t .Fatalf ("missing file in coverprofile: %s" , fname )
2835+ }
2836+ }
2837+ }
2838+ }
2839+
2840+ tg .run ("test" , "-coverprofile=" + tg .path ("cover.out" ), "-x" , "-v" , "-short" , "strings" )
2841+ tg .grepStdout (`ok \t` , "expected strings test to succeed" )
2842+ checkProfile (t , tg .path ("cover.out" ), "set" , "strings/strings.go" )
2843+
2844+ // Repeat commands should use the cache.
2845+ tg .run ("test" , "-coverprofile=" + tg .path ("cover.out" ), "-x" , "-v" , "-short" , "strings" )
2846+ tg .grepStdout (`ok \tstrings\t\(cached\)` , "expected strings test results to be cached" )
2847+ checkProfile (t , tg .path ("cover.out" ), "set" , "strings/strings.go" )
2848+
2849+ // Cover profiles should be cached independently. Since strings is already cached,
2850+ // only math should need to run.
2851+ tg .run ("test" , "-coverprofile=" + tg .path ("cover.out" ), "-x" , "-v" , "-short" , "strings" , "math" )
2852+ tg .grepStdout (`ok \tstrings\t\(cached\)` , "expected strings test results to be cached" )
2853+ checkProfile (t , tg .path ("cover.out" ), "set" , "strings/strings.go" , "math/mod.go" )
2854+
2855+ // A new -coverprofile file should use the cached coverage profile contents.
2856+ tg .run ("test" , "-coverprofile=" + tg .path ("cover1.out" ), "-x" , "-v" , "-short" , "strings" )
2857+ tg .grepStdout (`ok \tstrings\t\(cached\)` , "expected cached strings test results to be used regardless of -coverprofile" )
2858+ checkProfile (t , tg .path ("cover1.out" ), "set" , "strings/strings.go" )
2859+
2860+ // A new -covermode should not use the cached coverage profile, since the covermode changes
2861+ // the profile output.
2862+ tg .run ("test" , "-covermode=count" , "-coverprofile=" + tg .path ("cover.out" ), "-x" , "-v" , "-short" , "strings" )
2863+ tg .grepStdoutNot (`ok \tstrings\t\(cached\)` , "cached strings test results should not be used with different -covermode" )
2864+
2865+ // A new -coverpkg should not use the cached coverage profile, since the coverpkg changes
2866+ // the profile output.
2867+ tg .run ("test" , "-coverpkg=math" , "-coverprofile=" + tg .path ("cover.out" ), "-x" , "-v" , "-short" , "strings" )
2868+ tg .grepStdoutNot (`ok \tstrings\t\(cached\)` , "cached strings test results should not be used with different -coverpkg" )
2869+ }
0 commit comments