github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/runtime/coverage/ts_test.go (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 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 //go:linkname testing_testGoCoverDir testing.testGoCoverDir 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 // TestTestSupport does a basic verification of the functionality in 32 // runtime/coverage.processCoverTestDir (doing this here as opposed to 33 // relying on other test paths will provide a better signal when 34 // running "go test -cover" for this package). 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 // Check for existence of text file. 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 // Check for percent output with expected tokens. 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 //go:noinline 73 func thisFunctionOnlyCalledFromSnapshotTest(n int) int { 74 if funcInvoked { 75 panic("bad") 76 } 77 funcInvoked = true 78 79 // Contents here not especially important, just so long as we 80 // have some statements. 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 // Tests runtime/coverage.snapshot() directly. Note that if 91 // coverage is not enabled, the hook is designed to just return 92 // zero. 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 // Returns a pair F,T where F is a meta-data file generated from 119 // "hello.go" above, and T is a token to look for that should be 120 // present in the coverage report from F. 121 func genAuxMeta(t *testing.T, dstdir string) (string, string) { 122 // Do a GOCOVERDIR=<tmp> go run hello.go 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 // Pick out the generated meta-data file. 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 // Manufacture a new, separate meta-data file not related to this 163 // test. Contents are not important, just so long as the 164 // packages/paths are different. 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 // Write a metafiles file. 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 // Kick off guts of test. 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 // Look for the expected things in the coverage profile. 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 }