...

Source file src/pkg/testing/internal/testdeps/deps.go

     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	

View as plain text