@@ -6,6 +6,19 @@ package main_test
6
6
7
7
import (
8
8
"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"
9
22
"debug/elf"
10
23
"debug/macho"
11
24
"debug/pe"
@@ -29,21 +42,6 @@ import (
29
42
"strings"
30
43
"testing"
31
44
"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"
47
45
)
48
46
49
47
func init () {
@@ -2801,3 +2799,71 @@ func TestExecInDeletedDir(t *testing.T) {
2801
2799
// `go version` should not fail
2802
2800
tg .run ("version" )
2803
2801
}
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