diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-01-17 14:20:29 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-01-17 14:20:29 +0000 |
commit | c6d6367f848cfd8381aba41e035c5e7e873667c5 (patch) | |
tree | a218e98243463fc27f5053b4444e2544c63cd57a /libgo/go/testing | |
parent | 9bff0086915f544fa648ea81131f035cb9ce79a4 (diff) | |
download | gcc-c6d6367f848cfd8381aba41e035c5e7e873667c5.zip gcc-c6d6367f848cfd8381aba41e035c5e7e873667c5.tar.gz gcc-c6d6367f848cfd8381aba41e035c5e7e873667c5.tar.bz2 |
libgo: update to Go1.10beta2 release
Reviewed-on: https://go-review.googlesource.com/87897
From-SVN: r256794
Diffstat (limited to 'libgo/go/testing')
-rw-r--r-- | libgo/go/testing/internal/testdeps/deps.go | 70 | ||||
-rw-r--r-- | libgo/go/testing/testing.go | 61 |
2 files changed, 123 insertions, 8 deletions
diff --git a/libgo/go/testing/internal/testdeps/deps.go b/libgo/go/testing/internal/testdeps/deps.go index 042f696..4986898 100644 --- a/libgo/go/testing/internal/testdeps/deps.go +++ b/libgo/go/testing/internal/testdeps/deps.go @@ -11,9 +11,13 @@ package testdeps import ( + "bufio" + "internal/testlog" "io" "regexp" "runtime/pprof" + "strings" + "sync" ) // TestDeps is an implementation of the testing.testDeps interface, @@ -56,3 +60,69 @@ var ImportPath string func (TestDeps) ImportPath() string { return ImportPath } + +// testLog implements testlog.Interface, logging actions by package os. +type testLog struct { + mu sync.Mutex + w *bufio.Writer + set bool +} + +func (l *testLog) Getenv(key string) { + l.add("getenv", key) +} + +func (l *testLog) Open(name string) { + l.add("open", name) +} + +func (l *testLog) Stat(name string) { + l.add("stat", name) +} + +func (l *testLog) Chdir(name string) { + l.add("chdir", name) +} + +// add adds the (op, name) pair to the test log. +func (l *testLog) add(op, name string) { + if strings.Contains(name, "\n") || name == "" { + return + } + + l.mu.Lock() + defer l.mu.Unlock() + if l.w == nil { + return + } + l.w.WriteString(op) + l.w.WriteByte(' ') + l.w.WriteString(name) + l.w.WriteByte('\n') +} + +var log testLog +var didSetLogger bool + +func (TestDeps) StartTestLog(w io.Writer) { + log.mu.Lock() + log.w = bufio.NewWriter(w) + if !log.set { + // Tests that define TestMain and then run m.Run multiple times + // will call StartTestLog/StopTestLog multiple times. + // Checking log.set avoids calling testlog.SetLogger multiple times + // (which will panic) and also avoids writing the header multiple times. + log.set = true + testlog.SetLogger(&log) + log.w.WriteString("# test log\n") // known to cmd/go/internal/test/test.go + } + log.mu.Unlock() +} + +func (TestDeps) StopTestLog() error { + log.mu.Lock() + defer log.mu.Unlock() + err := log.w.Flush() + log.w = nil + return err +} diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go index d049b6c..f39d5ef 100644 --- a/libgo/go/testing/testing.go +++ b/libgo/go/testing/testing.go @@ -6,8 +6,8 @@ // It is intended to be used in concert with the ``go test'' command, which automates // execution of any function of the form // func TestXxx(*testing.T) -// where Xxx can be any alphanumeric string (but the first letter must not be in -// [a-z]) and serves to identify the test routine. +// where Xxx does not start with a lowercase letter. The function name +// serves to identify the test routine. // // Within these functions, use the Error, Fail or related methods to signal failure. // @@ -268,10 +268,12 @@ var ( timeout = flag.Duration("test.timeout", 0, "panic test binary after duration `d` (default 0, timeout disabled)") cpuListStr = flag.String("test.cpu", "", "comma-separated `list` of cpu counts to run each test with") parallel = flag.Int("test.parallel", runtime.GOMAXPROCS(0), "run at most `n` tests in parallel") + testlog = flag.String("test.testlogfile", "", "write test action log to `file` (for use only by cmd/go)") haveExamples bool // are there examples? - cpuList []int + cpuList []int + testlogFile *os.File numFailed uint32 // number of test failures ) @@ -518,7 +520,8 @@ func (c *common) Failed() bool { } // FailNow marks the function as having failed and stops its execution -// by calling runtime.Goexit. +// by calling runtime.Goexit (which then runs all deferred calls in the +// current goroutine). // Execution will continue at the next test or benchmark. // FailNow must be called from the goroutine running the // test or benchmark function, not from other goroutines @@ -779,9 +782,9 @@ func tRunner(t *T, fn func(t *T)) { t.finished = true } -// Run runs f as a subtest of t called name. It reports whether f succeeded. Run -// runs f in a separate goroutine and will block until all its parallel subtests -// have completed. +// Run runs f as a subtest of t called name. It runs f in a separate goroutine +// and blocks until f returns or calls t.Parallel to become a parallel test. +// Run reports whether f succeeded (or at least did not fail before calling t.Parallel). // // Run may be called simultaneously from multiple goroutines, but all such calls // must return before the outer test function for t returns. @@ -889,6 +892,8 @@ func (f matchStringOnly) StopCPUProfile() {} func (f matchStringOnly) WriteHeapProfile(w io.Writer) error { return errMain } func (f matchStringOnly) WriteProfileTo(string, io.Writer, int) error { return errMain } func (f matchStringOnly) ImportPath() string { return "" } +func (f matchStringOnly) StartTestLog(io.Writer) {} +func (f matchStringOnly) StopTestLog() error { return errMain } // Main is an internal function, part of the implementation of the "go test" command. // It was exported because it is cross-package and predates "internal" packages. @@ -909,6 +914,8 @@ type M struct { timer *time.Timer afterOnce sync.Once + + numRun int } // testDeps is an internal interface of functionality that is @@ -916,12 +923,14 @@ type M struct { // The canonical implementation of this interface is // testing/internal/testdeps's TestDeps. type testDeps interface { + ImportPath() string MatchString(pat, str string) (bool, error) StartCPUProfile(io.Writer) error StopCPUProfile() + StartTestLog(io.Writer) + StopTestLog() error WriteHeapProfile(io.Writer) error WriteProfileTo(string, io.Writer, int) error - ImportPath() string } // MainStart is meant for use by tests generated by 'go test'. @@ -938,6 +947,12 @@ func MainStart(deps testDeps, tests []InternalTest, benchmarks []InternalBenchma // Run runs the tests. It returns an exit code to pass to os.Exit. func (m *M) Run() int { + // Count the number of calls to m.Run. + // We only ever expected 1, but we didn't enforce that, + // and now there are tests in the wild that call m.Run multiple times. + // Sigh. golang.org/issue/23129. + m.numRun++ + // TestMain may have already called flag.Parse. if !flag.Parsed() { flag.Parse() @@ -1100,6 +1115,26 @@ func (m *M) before() { fmt.Fprintf(os.Stderr, "testing: cannot use -test.coverprofile because test binary was not built with coverage enabled\n") os.Exit(2) } + if *testlog != "" { + // Note: Not using toOutputDir. + // This file is for use by cmd/go, not users. + var f *os.File + var err error + if m.numRun == 1 { + f, err = os.Create(*testlog) + } else { + f, err = os.OpenFile(*testlog, os.O_WRONLY, 0) + if err == nil { + f.Seek(0, io.SeekEnd) + } + } + if err != nil { + fmt.Fprintf(os.Stderr, "testing: %s\n", err) + os.Exit(2) + } + m.deps.StartTestLog(f) + testlogFile = f + } } // after runs after all testing. @@ -1110,6 +1145,16 @@ func (m *M) after() { } func (m *M) writeProfiles() { + if *testlog != "" { + if err := m.deps.StopTestLog(); err != nil { + fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *testlog, err) + os.Exit(2) + } + if err := testlogFile.Close(); err != nil { + fmt.Fprintf(os.Stderr, "testing: can't write %s: %s\n", *testlog, err) + os.Exit(2) + } + } if *cpuProfile != "" { m.deps.StopCPUProfile() // flushes profile to disk } |