]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/testing/internal/testdeps/deps.go
testing: add available godoc link
[gostls13.git] / src / testing / internal / testdeps / deps.go
index 3608d332946e2ebee0558a35c35c7930a65e923a..868307550eab60005dbbf915d231aadb46271d4b 100644 (file)
@@ -12,16 +12,22 @@ package testdeps
 
 import (
        "bufio"
+       "context"
+       "internal/fuzz"
        "internal/testlog"
        "io"
+       "os"
+       "os/signal"
+       "reflect"
        "regexp"
        "runtime/pprof"
        "strings"
        "sync"
+       "time"
 )
 
 // TestDeps is an implementation of the testing.testDeps interface,
-// suitable for passing to testing.MainStart.
+// suitable for passing to [testing.MainStart].
 type TestDeps struct{}
 
 var matchPat string
@@ -126,3 +132,68 @@ func (TestDeps) StopTestLog() error {
 func (TestDeps) SetPanicOnExit0(v bool) {
        testlog.SetPanicOnExit0(v)
 }
+
+func (TestDeps) CoordinateFuzzing(
+       timeout time.Duration,
+       limit int64,
+       minimizeTimeout time.Duration,
+       minimizeLimit int64,
+       parallel int,
+       seed []fuzz.CorpusEntry,
+       types []reflect.Type,
+       corpusDir,
+       cacheDir string) (err error) {
+       // Fuzzing may be interrupted with a timeout or if the user presses ^C.
+       // In either case, we'll stop worker processes gracefully and save
+       // crashers and interesting values.
+       ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
+       defer cancel()
+       err = fuzz.CoordinateFuzzing(ctx, fuzz.CoordinateFuzzingOpts{
+               Log:             os.Stderr,
+               Timeout:         timeout,
+               Limit:           limit,
+               MinimizeTimeout: minimizeTimeout,
+               MinimizeLimit:   minimizeLimit,
+               Parallel:        parallel,
+               Seed:            seed,
+               Types:           types,
+               CorpusDir:       corpusDir,
+               CacheDir:        cacheDir,
+       })
+       if err == ctx.Err() {
+               return nil
+       }
+       return err
+}
+
+func (TestDeps) RunFuzzWorker(fn func(fuzz.CorpusEntry) error) error {
+       // Worker processes may or may not receive a signal when the user presses ^C
+       // On POSIX operating systems, a signal sent to a process group is delivered
+       // to all processes in that group. This is not the case on Windows.
+       // If the worker is interrupted, return quickly and without error.
+       // If only the coordinator process is interrupted, it tells each worker
+       // process to stop by closing its "fuzz_in" pipe.
+       ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
+       defer cancel()
+       err := fuzz.RunFuzzWorker(ctx, fn)
+       if err == ctx.Err() {
+               return nil
+       }
+       return err
+}
+
+func (TestDeps) ReadCorpus(dir string, types []reflect.Type) ([]fuzz.CorpusEntry, error) {
+       return fuzz.ReadCorpus(dir, types)
+}
+
+func (TestDeps) CheckCorpus(vals []any, types []reflect.Type) error {
+       return fuzz.CheckCorpus(vals, types)
+}
+
+func (TestDeps) ResetCoverage() {
+       fuzz.ResetCoverage()
+}
+
+func (TestDeps) SnapshotCoverage() {
+       fuzz.SnapshotCoverage()
+}