1
2
3
4
5
6
7
8
9
10
11 package testdeps
12
13 import (
14 "bufio"
15 "context"
16 "internal/fuzz"
17 "internal/testlog"
18 "io"
19 "os"
20 "os/signal"
21 "reflect"
22 "regexp"
23 "runtime/pprof"
24 "strings"
25 "sync"
26 "time"
27 )
28
29
30 var Cover bool
31
32
33
34 type TestDeps struct{}
35
36 var matchPat string
37 var matchRe *regexp.Regexp
38
39 func (TestDeps) MatchString(pat, str string) (result bool, err error) {
40 if matchRe == nil || matchPat != pat {
41 matchPat = pat
42 matchRe, err = regexp.Compile(matchPat)
43 if err != nil {
44 return
45 }
46 }
47 return matchRe.MatchString(str), nil
48 }
49
50 func (TestDeps) StartCPUProfile(w io.Writer) error {
51 return pprof.StartCPUProfile(w)
52 }
53
54 func (TestDeps) StopCPUProfile() {
55 pprof.StopCPUProfile()
56 }
57
58 func (TestDeps) WriteProfileTo(name string, w io.Writer, debug int) error {
59 return pprof.Lookup(name).WriteTo(w, debug)
60 }
61
62
63 var ImportPath string
64
65 func (TestDeps) ImportPath() string {
66 return ImportPath
67 }
68
69 var ModulePath string
70
71 func (TestDeps) ModulePath() string {
72 return ModulePath
73 }
74
75
76 type testLog struct {
77 mu sync.Mutex
78 w *bufio.Writer
79 set bool
80 }
81
82 func (l *testLog) Getenv(key string) {
83 l.add("getenv", key)
84 }
85
86 func (l *testLog) Open(name string) {
87 l.add("open", name)
88 }
89
90 func (l *testLog) Stat(name string) {
91 l.add("stat", name)
92 }
93
94 func (l *testLog) Chdir(name string) {
95 l.add("chdir", name)
96 }
97
98
99 func (l *testLog) add(op, name string) {
100 if strings.Contains(name, "\n") || name == "" {
101 return
102 }
103
104 l.mu.Lock()
105 defer l.mu.Unlock()
106 if l.w == nil {
107 return
108 }
109 l.w.WriteString(op)
110 l.w.WriteByte(' ')
111 l.w.WriteString(name)
112 l.w.WriteByte('\n')
113 }
114
115 var log testLog
116
117 func (TestDeps) StartTestLog(w io.Writer) {
118 log.mu.Lock()
119 log.w = bufio.NewWriter(w)
120 if !log.set {
121
122
123
124
125 log.set = true
126 testlog.SetLogger(&log)
127 log.w.WriteString("# test log\n")
128 }
129 log.mu.Unlock()
130 }
131
132 func (TestDeps) StopTestLog() error {
133 log.mu.Lock()
134 defer log.mu.Unlock()
135 err := log.w.Flush()
136 log.w = nil
137 return err
138 }
139
140
141 func (TestDeps) SetPanicOnExit0(v bool) {
142 testlog.SetPanicOnExit0(v)
143 }
144
145 func (TestDeps) CoordinateFuzzing(
146 timeout time.Duration,
147 limit int64,
148 minimizeTimeout time.Duration,
149 minimizeLimit int64,
150 parallel int,
151 seed []fuzz.CorpusEntry,
152 types []reflect.Type,
153 corpusDir,
154 cacheDir string) (err error) {
155
156
157
158 ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
159 defer cancel()
160 err = fuzz.CoordinateFuzzing(ctx, fuzz.CoordinateFuzzingOpts{
161 Log: os.Stderr,
162 Timeout: timeout,
163 Limit: limit,
164 MinimizeTimeout: minimizeTimeout,
165 MinimizeLimit: minimizeLimit,
166 Parallel: parallel,
167 Seed: seed,
168 Types: types,
169 CorpusDir: corpusDir,
170 CacheDir: cacheDir,
171 })
172 if err == ctx.Err() {
173 return nil
174 }
175 return err
176 }
177
178 func (TestDeps) RunFuzzWorker(fn func(fuzz.CorpusEntry) error) error {
179
180
181
182
183
184
185 ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
186 defer cancel()
187 err := fuzz.RunFuzzWorker(ctx, fn)
188 if err == ctx.Err() {
189 return nil
190 }
191 return err
192 }
193
194 func (TestDeps) ReadCorpus(dir string, types []reflect.Type) ([]fuzz.CorpusEntry, error) {
195 return fuzz.ReadCorpus(dir, types)
196 }
197
198 func (TestDeps) CheckCorpus(vals []any, types []reflect.Type) error {
199 return fuzz.CheckCorpus(vals, types)
200 }
201
202 func (TestDeps) ResetCoverage() {
203 fuzz.ResetCoverage()
204 }
205
206 func (TestDeps) SnapshotCoverage() {
207 fuzz.SnapshotCoverage()
208 }
209
210 var CoverMode string
211 var Covered string
212 var CoverSelectedPackages []string
213
214
215
216
217
218 var (
219 CoverSnapshotFunc func() float64
220 CoverProcessTestDirFunc func(dir string, cfile string, cm string, cpkg string, w io.Writer, selpkgs []string) error
221 CoverMarkProfileEmittedFunc func(val bool)
222 )
223
224 func (TestDeps) InitRuntimeCoverage() (mode string, tearDown func(string, string) (string, error), snapcov func() float64) {
225 if CoverMode == "" {
226 return
227 }
228 return CoverMode, coverTearDown, CoverSnapshotFunc
229 }
230
231 func coverTearDown(coverprofile string, gocoverdir string) (string, error) {
232 var err error
233 if gocoverdir == "" {
234 gocoverdir, err = os.MkdirTemp("", "gocoverdir")
235 if err != nil {
236 return "error setting GOCOVERDIR: bad os.MkdirTemp return", err
237 }
238 defer os.RemoveAll(gocoverdir)
239 }
240 CoverMarkProfileEmittedFunc(true)
241 cmode := CoverMode
242 if err := CoverProcessTestDirFunc(gocoverdir, coverprofile, cmode, Covered, os.Stdout, CoverSelectedPackages); err != nil {
243 return "error generating coverage report", err
244 }
245 return "", nil
246 }
247
View as plain text