1
2
3
4
5 package coverage
6
7 import (
8 "encoding/json"
9 "internal/coverage"
10 "internal/goexperiment"
11 "internal/testenv"
12 "os"
13 "os/exec"
14 "path/filepath"
15 "strings"
16 "testing"
17 _ "unsafe"
18 )
19
20
21 func testing_testGoCoverDir() string
22
23 func testGoCoverDir(t *testing.T) string {
24 tgcd := testing_testGoCoverDir()
25 if tgcd != "" {
26 return tgcd
27 }
28 return t.TempDir()
29 }
30
31
32
33
34
35 func TestTestSupport(t *testing.T) {
36 if !goexperiment.CoverageRedesign {
37 return
38 }
39 if testing.CoverMode() == "" {
40 return
41 }
42 tgcd := testGoCoverDir(t)
43 t.Logf("testing.testGoCoverDir() returns %s mode=%s\n",
44 tgcd, testing.CoverMode())
45
46 textfile := filepath.Join(t.TempDir(), "file.txt")
47 var sb strings.Builder
48 err := processCoverTestDirInternal(tgcd, textfile,
49 testing.CoverMode(), "", &sb)
50 if err != nil {
51 t.Fatalf("bad: %v", err)
52 }
53
54
55 if inf, err := os.Open(textfile); err != nil {
56 t.Fatalf("problems opening text file %s: %v", textfile, err)
57 } else {
58 inf.Close()
59 }
60
61
62 strout := sb.String()
63 want := "of statements"
64 if !strings.Contains(strout, want) {
65 t.Logf("output from run: %s\n", strout)
66 t.Fatalf("percent output missing token: %q", want)
67 }
68 }
69
70 var funcInvoked bool
71
72
73 func thisFunctionOnlyCalledFromSnapshotTest(n int) int {
74 if funcInvoked {
75 panic("bad")
76 }
77 funcInvoked = true
78
79
80
81 t := 0
82 for i := 0; i < n; i++ {
83 for j := 0; j < i; j++ {
84 t += i ^ j
85 }
86 }
87 return t
88 }
89
90
91
92
93 func TestCoverageSnapshot(t *testing.T) {
94 C1 := snapshot()
95 thisFunctionOnlyCalledFromSnapshotTest(15)
96 C2 := snapshot()
97 cond := "C1 > C2"
98 val := C1 > C2
99 if testing.CoverMode() != "" {
100 cond = "C1 >= C2"
101 val = C1 >= C2
102 }
103 t.Logf("%f %f\n", C1, C2)
104 if val {
105 t.Errorf("erroneous snapshots, %s = true C1=%f C2=%f",
106 cond, C1, C2)
107 }
108 }
109
110 const hellogo = `
111 package main
112
113 func main() {
114 println("hello")
115 }
116 `
117
118
119
120
121 func genAuxMeta(t *testing.T, dstdir string) (string, string) {
122
123 src := filepath.Join(dstdir, "hello.go")
124 if err := os.WriteFile(src, []byte(hellogo), 0777); err != nil {
125 t.Fatalf("write failed: %v", err)
126 }
127 args := []string{"run", "-covermode=" + testing.CoverMode(), src}
128 cmd := exec.Command(testenv.GoToolPath(t), args...)
129 cmd.Env = updateGoCoverDir(os.Environ(), dstdir, true)
130 if b, err := cmd.CombinedOutput(); err != nil {
131 t.Fatalf("go run failed (%v): %s", err, b)
132 }
133
134
135 files, err := os.ReadDir(dstdir)
136 if err != nil {
137 t.Fatalf("reading %s: %v", dstdir, err)
138 }
139 for _, f := range files {
140 if strings.HasPrefix(f.Name(), "covmeta") {
141 return filepath.Join(dstdir, f.Name()), "hello.go:"
142 }
143 }
144 t.Fatalf("could not locate generated meta-data file")
145 return "", ""
146 }
147
148 func TestAuxMetaDataFiles(t *testing.T) {
149 if !goexperiment.CoverageRedesign {
150 return
151 }
152 if testing.CoverMode() == "" {
153 return
154 }
155 testenv.MustHaveGoRun(t)
156 tgcd := testGoCoverDir(t)
157 t.Logf("testing.testGoCoverDir() returns %s mode=%s\n",
158 tgcd, testing.CoverMode())
159
160 td := t.TempDir()
161
162
163
164
165 othermetadir := filepath.Join(td, "othermeta")
166 if err := os.Mkdir(othermetadir, 0777); err != nil {
167 t.Fatalf("mkdir failed: %v", err)
168 }
169 mfile, token := genAuxMeta(t, othermetadir)
170
171
172 metafiles := filepath.Join(tgcd, coverage.MetaFilesFileName)
173 mfc := coverage.MetaFileCollection{
174 ImportPaths: []string{"command-line-arguments"},
175 MetaFileFragments: []string{mfile},
176 }
177 jdata, err := json.Marshal(mfc)
178 if err != nil {
179 t.Fatalf("marshal MetaFileCollection: %v", err)
180 }
181 if err := os.WriteFile(metafiles, jdata, 0666); err != nil {
182 t.Fatalf("write failed: %v", err)
183 }
184
185
186 var sb strings.Builder
187 textfile := filepath.Join(td, "file2.txt")
188 err = processCoverTestDirInternal(tgcd, textfile,
189 testing.CoverMode(), "", &sb)
190 if err != nil {
191 t.Fatalf("bad: %v", err)
192 }
193 if err = os.Remove(metafiles); err != nil {
194 t.Fatalf("removing metafiles file: %v", err)
195 }
196
197
198 contents, err := os.ReadFile(textfile)
199 strc := string(contents)
200 if err != nil {
201 t.Fatalf("problems reading text file %s: %v", textfile, err)
202 }
203 if !strings.Contains(strc, token) {
204 t.Logf("content: %s\n", string(contents))
205 t.Fatalf("cov profile does not contain aux meta content %q", token)
206 }
207 }
208
View as plain text