aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/testing
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-01-17 14:20:29 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-17 14:20:29 +0000
commitc6d6367f848cfd8381aba41e035c5e7e873667c5 (patch)
treea218e98243463fc27f5053b4444e2544c63cd57a /libgo/go/testing
parent9bff0086915f544fa648ea81131f035cb9ce79a4 (diff)
downloadgcc-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.go70
-rw-r--r--libgo/go/testing/testing.go61
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
}