github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/testing/internal/testdeps/deps.go (about) 1 // Copyright 2016 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 testdeps provides access to dependencies needed by test execution. 6 // 7 // This package is imported by the generated main package, which passes 8 // TestDeps into testing.Main. This allows tests to use packages at run time 9 // without making those packages direct dependencies of package testing. 10 // Direct dependencies of package testing are harder to write tests for. 11 package testdeps 12 13 import ( 14 "bufio" 15 "internal/testlog" 16 "io" 17 "regexp" 18 "runtime/pprof" 19 "strings" 20 "sync" 21 ) 22 23 // TestDeps is an implementation of the testing.testDeps interface, 24 // suitable for passing to testing.MainStart. 25 type TestDeps struct{} 26 27 var matchPat string 28 var matchRe *regexp.Regexp 29 30 func (TestDeps) MatchString(pat, str string) (result bool, err error) { 31 if matchRe == nil || matchPat != pat { 32 matchPat = pat 33 matchRe, err = regexp.Compile(matchPat) 34 if err != nil { 35 return 36 } 37 } 38 return matchRe.MatchString(str), nil 39 } 40 41 func (TestDeps) StartCPUProfile(w io.Writer) error { 42 return pprof.StartCPUProfile(w) 43 } 44 45 func (TestDeps) StopCPUProfile() { 46 pprof.StopCPUProfile() 47 } 48 49 func (TestDeps) WriteProfileTo(name string, w io.Writer, debug int) error { 50 return pprof.Lookup(name).WriteTo(w, debug) 51 } 52 53 // ImportPath is the import path of the testing binary, set by the generated main function. 54 var ImportPath string 55 56 func (TestDeps) ImportPath() string { 57 return ImportPath 58 } 59 60 // testLog implements testlog.Interface, logging actions by package os. 61 type testLog struct { 62 mu sync.Mutex 63 w *bufio.Writer 64 set bool 65 } 66 67 func (l *testLog) Getenv(key string) { 68 l.add("getenv", key) 69 } 70 71 func (l *testLog) Open(name string) { 72 l.add("open", name) 73 } 74 75 func (l *testLog) Stat(name string) { 76 l.add("stat", name) 77 } 78 79 func (l *testLog) Chdir(name string) { 80 l.add("chdir", name) 81 } 82 83 // add adds the (op, name) pair to the test log. 84 func (l *testLog) add(op, name string) { 85 if strings.Contains(name, "\n") || name == "" { 86 return 87 } 88 89 l.mu.Lock() 90 defer l.mu.Unlock() 91 if l.w == nil { 92 return 93 } 94 l.w.WriteString(op) 95 l.w.WriteByte(' ') 96 l.w.WriteString(name) 97 l.w.WriteByte('\n') 98 } 99 100 var log testLog 101 102 func (TestDeps) StartTestLog(w io.Writer) { 103 log.mu.Lock() 104 log.w = bufio.NewWriter(w) 105 if !log.set { 106 // Tests that define TestMain and then run m.Run multiple times 107 // will call StartTestLog/StopTestLog multiple times. 108 // Checking log.set avoids calling testlog.SetLogger multiple times 109 // (which will panic) and also avoids writing the header multiple times. 110 log.set = true 111 testlog.SetLogger(&log) 112 log.w.WriteString("# test log\n") // known to cmd/go/internal/test/test.go 113 } 114 log.mu.Unlock() 115 } 116 117 func (TestDeps) StopTestLog() error { 118 log.mu.Lock() 119 defer log.mu.Unlock() 120 err := log.w.Flush() 121 log.w = nil 122 return err 123 } 124 125 // SetPanicOnExit0 tells the os package whether to panic on os.Exit(0). 126 func (TestDeps) SetPanicOnExit0(v bool) { 127 testlog.SetPanicOnExit0(v) 128 }