github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/cmd/cover/cover_test.go (about) 1 // Copyright 2013 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 main_test 6 7 import ( 8 "bytes" 9 "fmt" 10 "internal/testenv" 11 "io/ioutil" 12 "os" 13 "os/exec" 14 "path/filepath" 15 "regexp" 16 "testing" 17 ) 18 19 const ( 20 // Data directory, also the package directory for the test. 21 testdata = "testdata" 22 23 // Binaries we compile. 24 testcover = "./testcover.exe" 25 ) 26 27 var ( 28 // Files we use. 29 testMain = filepath.Join(testdata, "main.go") 30 testTest = filepath.Join(testdata, "test.go") 31 coverInput = filepath.Join(testdata, "test_line.go") 32 coverOutput = filepath.Join(testdata, "test_cover.go") 33 coverProfile = filepath.Join(testdata, "profile.cov") 34 ) 35 36 var debug = false // Keeps the rewritten files around if set. 37 38 // Run this shell script, but do it in Go so it can be run by "go test". 39 // 40 // replace the word LINE with the line number < testdata/test.go > testdata/test_line.go 41 // go build -o ./testcover 42 // ./testcover -mode=count -var=CoverTest -o ./testdata/test_cover.go testdata/test_line.go 43 // go run ./testdata/main.go ./testdata/test.go 44 // 45 func TestCover(t *testing.T) { 46 testenv.MustHaveGoBuild(t) 47 48 // Read in the test file (testTest) and write it, with LINEs specified, to coverInput. 49 file, err := ioutil.ReadFile(testTest) 50 if err != nil { 51 t.Fatal(err) 52 } 53 lines := bytes.Split(file, []byte("\n")) 54 for i, line := range lines { 55 lines[i] = bytes.Replace(line, []byte("LINE"), []byte(fmt.Sprint(i+1)), -1) 56 } 57 if err := ioutil.WriteFile(coverInput, bytes.Join(lines, []byte("\n")), 0666); err != nil { 58 t.Fatal(err) 59 } 60 61 // defer removal of test_line.go 62 if !debug { 63 defer os.Remove(coverInput) 64 } 65 66 // go build -o testcover 67 cmd := exec.Command(testenv.GoToolPath(t), "build", "-o", testcover) 68 run(cmd, t) 69 70 // defer removal of testcover 71 defer os.Remove(testcover) 72 73 // ./testcover -mode=count -var=thisNameMustBeVeryLongToCauseOverflowOfCounterIncrementStatementOntoNextLineForTest -o ./testdata/test_cover.go testdata/test_line.go 74 cmd = exec.Command(testcover, "-mode=count", "-var=thisNameMustBeVeryLongToCauseOverflowOfCounterIncrementStatementOntoNextLineForTest", "-o", coverOutput, coverInput) 75 run(cmd, t) 76 77 // defer removal of ./testdata/test_cover.go 78 if !debug { 79 defer os.Remove(coverOutput) 80 } 81 82 // go run ./testdata/main.go ./testdata/test.go 83 cmd = exec.Command(testenv.GoToolPath(t), "run", testMain, coverOutput) 84 run(cmd, t) 85 86 file, err = ioutil.ReadFile(coverOutput) 87 if err != nil { 88 t.Fatal(err) 89 } 90 // compiler directive must appear right next to function declaration. 91 if got, err := regexp.MatchString(".*\n//go:nosplit\nfunc someFunction().*", string(file)); err != nil || !got { 92 t.Errorf("misplaced compiler directive: got=(%v, %v); want=(true; nil)", got, err) 93 } 94 // "go:linkname" compiler directive should be present. 95 if got, err := regexp.MatchString(`.*go\:linkname some\_name some\_name.*`, string(file)); err != nil || !got { 96 t.Errorf("'go:linkname' compiler directive not found: got=(%v, %v); want=(true; nil)", got, err) 97 } 98 99 // No other comments should be present in generated code. 100 c := ".*// This comment shouldn't appear in generated go code.*" 101 if got, err := regexp.MatchString(c, string(file)); err != nil || got { 102 t.Errorf("non compiler directive comment %q found. got=(%v, %v); want=(false; nil)", c, got, err) 103 } 104 } 105 106 // Makes sure that `cover -func=profile.cov` reports accurate coverage. 107 // Issue #20515. 108 func TestCoverFunc(t *testing.T) { 109 // go tool cover -func ./testdata/profile.cov 110 cmd := exec.Command(testenv.GoToolPath(t), "tool", "cover", "-func", coverProfile) 111 out, err := cmd.Output() 112 if err != nil { 113 if ee, ok := err.(*exec.ExitError); ok { 114 t.Logf("%s", ee.Stderr) 115 } 116 t.Fatal(err) 117 } 118 119 if got, err := regexp.Match(".*total:.*100.0.*", out); err != nil || !got { 120 t.Logf("%s", out) 121 t.Errorf("invalid coverage counts. got=(%v, %v); want=(true; nil)", got, err) 122 } 123 } 124 125 func run(c *exec.Cmd, t *testing.T) { 126 c.Stdout = os.Stdout 127 c.Stderr = os.Stderr 128 err := c.Run() 129 if err != nil { 130 t.Fatal(err) 131 } 132 }