diff options
Diffstat (limited to 'libgo/go/testing')
-rw-r--r-- | libgo/go/testing/allocs.go | 41 | ||||
-rw-r--r-- | libgo/go/testing/iotest/reader.go | 8 | ||||
-rw-r--r-- | libgo/go/testing/quick/quick.go | 2 | ||||
-rw-r--r-- | libgo/go/testing/testing.go | 119 |
4 files changed, 111 insertions, 59 deletions
diff --git a/libgo/go/testing/allocs.go b/libgo/go/testing/allocs.go new file mode 100644 index 00000000000..d142a330b08 --- /dev/null +++ b/libgo/go/testing/allocs.go @@ -0,0 +1,41 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testing + +import ( + "runtime" +) + +// AllocsPerRun returns the average number of allocations during calls to f. +// +// To compute the number of allocations, the function will first be run once as +// a warm-up. The average number of allocations over the specified number of +// runs will then be measured and returned. +// +// AllocsPerRun sets GOMAXPROCS to 1 during its measurement and will restore +// it before returning. +func AllocsPerRun(runs int, f func()) (avg float64) { + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1)) + + // Warm up the function + f() + + // Measure the starting statistics + var memstats runtime.MemStats + runtime.ReadMemStats(&memstats) + mallocs := 0 - memstats.Mallocs + + // Run the function the specified number of times + for i := 0; i < runs; i++ { + f() + } + + // Read the final statistics + runtime.ReadMemStats(&memstats) + mallocs += memstats.Mallocs + + // Average the mallocs over the runs (not counting the warm-up) + return float64(mallocs) / float64(runs) +} diff --git a/libgo/go/testing/iotest/reader.go b/libgo/go/testing/iotest/reader.go index 441b9102d94..a5bccca9063 100644 --- a/libgo/go/testing/iotest/reader.go +++ b/libgo/go/testing/iotest/reader.go @@ -37,9 +37,11 @@ func (r *halfReader) Read(p []byte) (int, error) { return r.r.Read(p[0 : (len(p)+1)/2]) } -// DataErrReader returns a Reader that returns the final -// error with the last data read, instead of by itself with -// zero bytes of data. +// DataErrReader changes the way errors are handled by a Reader. Normally, a +// Reader returns an error (typically EOF) from the first Read call after the +// last piece of data is read. DataErrReader wraps a Reader and changes its +// behavior so the final error is returned along with the final data, instead +// of in the first call after the final data. func DataErrReader(r io.Reader) io.Reader { return &dataErrReader{r, nil, make([]byte, 1024)} } type dataErrReader struct { diff --git a/libgo/go/testing/quick/quick.go b/libgo/go/testing/quick/quick.go index 24270982281..761a6471b57 100644 --- a/libgo/go/testing/quick/quick.go +++ b/libgo/go/testing/quick/quick.go @@ -140,8 +140,6 @@ func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) { default: return reflect.Value{}, false } - - return } // A Config structure contains options for running a test. diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go index c1917f8fe03..312d2873296 100644 --- a/libgo/go/testing/testing.go +++ b/libgo/go/testing/testing.go @@ -10,7 +10,7 @@ // [a-z]) and serves to identify the test routine. // These TestXxx routines should be declared within the package they are testing. // -// Tests may be skipped if not applicable like this: +// Tests and benchmarks may be skipped if not applicable like this: // func TestTimeConsuming(t *testing.T) { // if testing.Short() { // t.Skip("skipping test in short mode.") @@ -18,6 +18,8 @@ // ... // } // +// Benchmarks +// // Functions of the form // func BenchmarkXxx(*testing.B) // are considered benchmarks, and are executed by the "go test" command when @@ -33,6 +35,7 @@ // } // } // +// The benchmark function must run the target code b.N times. // The benchmark package will vary b.N until the benchmark function lasts // long enough to be timed reliably. The output // BenchmarkHello 10000000 282 ns/op @@ -48,8 +51,10 @@ // } // } // +// Examples +// // The package also runs and verifies example code. Example functions may -// include a concluding comment that begins with "Output:" and is compared with +// include a concluding line comment that begins with "Output:" and is compared with // the standard output of the function when the tests are run. (The comparison // ignores leading and trailing space.) These are examples of an example: // @@ -129,9 +134,10 @@ var ( // common holds the elements common between T and B and // captures common methods such as Errorf. type common struct { - mu sync.RWMutex // guards output and failed - output []byte // Output generated by test or benchmark. - failed bool // Test or benchmark has failed. + mu sync.RWMutex // guards output and failed + output []byte // Output generated by test or benchmark. + failed bool // Test or benchmark has failed. + skipped bool // Test of benchmark has been skipped. start time.Time // Time test or benchmark started duration time.Duration @@ -165,21 +171,17 @@ func decorate(s string) string { line = 1 } buf := new(bytes.Buffer) + // Every line is indented at least one tab. + buf.WriteByte('\t') fmt.Fprintf(buf, "%s:%d: ", file, line) - lines := strings.Split(s, "\n") if l := len(lines); l > 1 && lines[l-1] == "" { lines = lines[:l-1] } for i, line := range lines { if i > 0 { - buf.WriteByte('\n') - } - // Every line is indented at least one tab. - buf.WriteByte('\t') - if i > 0 { // Second and subsequent lines are indented an extra tab. - buf.WriteByte('\t') + buf.WriteString("\n\t\t") } buf.WriteString(line) } @@ -193,7 +195,6 @@ type T struct { common name string // Name of test. startParallel chan bool // Parallel tests will wait on this. - skipped bool // Test has been skipped. } // Fail marks the function as having failed but continues execution. @@ -212,6 +213,10 @@ func (c *common) Failed() bool { // FailNow marks the function as having failed and stops its execution. // 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 +// created during the test. Calling FailNow does not stop +// those other goroutines. func (c *common) FailNow() { c.Fail() @@ -244,40 +249,77 @@ func (c *common) log(s string) { c.output = append(c.output, decorate(s)...) } -// Log formats its arguments using default formatting, analogous to Println(), -// and records the text in the error log. +// Log formats its arguments using default formatting, analogous to Println, +// and records the text in the error log. The text will be printed only if +// the test fails or the -test.v flag is set. func (c *common) Log(args ...interface{}) { c.log(fmt.Sprintln(args...)) } -// Logf formats its arguments according to the format, analogous to Printf(), -// and records the text in the error log. +// Logf formats its arguments according to the format, analogous to Printf, +// and records the text in the error log. The text will be printed only if +// the test fails or the -test.v flag is set. func (c *common) Logf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) } -// Error is equivalent to Log() followed by Fail(). +// Error is equivalent to Log followed by Fail. func (c *common) Error(args ...interface{}) { c.log(fmt.Sprintln(args...)) c.Fail() } -// Errorf is equivalent to Logf() followed by Fail(). +// Errorf is equivalent to Logf followed by Fail. func (c *common) Errorf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) c.Fail() } -// Fatal is equivalent to Log() followed by FailNow(). +// Fatal is equivalent to Log followed by FailNow. func (c *common) Fatal(args ...interface{}) { c.log(fmt.Sprintln(args...)) c.FailNow() } -// Fatalf is equivalent to Logf() followed by FailNow(). +// Fatalf is equivalent to Logf followed by FailNow. func (c *common) Fatalf(format string, args ...interface{}) { c.log(fmt.Sprintf(format, args...)) c.FailNow() } +// Skip is equivalent to Log followed by SkipNow. +func (c *common) Skip(args ...interface{}) { + c.log(fmt.Sprintln(args...)) + c.SkipNow() +} + +// Skipf is equivalent to Logf followed by SkipNow. +func (c *common) Skipf(format string, args ...interface{}) { + c.log(fmt.Sprintf(format, args...)) + c.SkipNow() +} + +// SkipNow marks the test as having been skipped and stops its execution. +// Execution will continue at the next test or benchmark. See also FailNow. +// SkipNow must be called from the goroutine running the test, not from +// other goroutines created during the test. Calling SkipNow does not stop +// those other goroutines. +func (c *common) SkipNow() { + c.skip() + runtime.Goexit() +} + +func (c *common) skip() { + c.mu.Lock() + defer c.mu.Unlock() + c.skipped = true +} + +// Skipped reports whether the test was skipped. +func (c *common) Skipped() bool { + c.mu.RLock() + defer c.mu.RUnlock() + return c.skipped +} + // Parallel signals that this test is to be run in parallel with (and only with) -// other parallel tests in this CPU group. +// other parallel tests. func (t *T) Parallel() { t.signal <- (*T)(nil) // Release main testing loop <-t.startParallel // Wait for serial tests to finish @@ -301,6 +343,7 @@ func tRunner(t *T, test *InternalTest) { t.duration = time.Now().Sub(t.start) // If the test panicked, print any test output before dying. if err := recover(); err != nil { + t.Fail() t.report() panic(err) } @@ -345,38 +388,6 @@ func (t *T) report() { } } -// Skip is equivalent to Log() followed by SkipNow(). -func (t *T) Skip(args ...interface{}) { - t.log(fmt.Sprintln(args...)) - t.SkipNow() -} - -// Skipf is equivalent to Logf() followed by SkipNow(). -func (t *T) Skipf(format string, args ...interface{}) { - t.log(fmt.Sprintf(format, args...)) - t.SkipNow() -} - -// SkipNow marks the function as having been skipped and stops its execution. -// Execution will continue at the next test or benchmark. See also, t.FailNow. -func (t *T) SkipNow() { - t.skip() - runtime.Goexit() -} - -func (t *T) skip() { - t.mu.Lock() - defer t.mu.Unlock() - t.skipped = true -} - -// Skipped reports whether the function was skipped. -func (t *T) Skipped() bool { - t.mu.RLock() - defer t.mu.RUnlock() - return t.skipped -} - func RunTests(matchString func(pat, str string) (bool, error), tests []InternalTest) (ok bool) { ok = true if len(tests) == 0 && !haveExamples { |