summaryrefslogtreecommitdiffstats
path: root/libgo/go/testing
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/testing')
-rw-r--r--libgo/go/testing/benchmark.go20
-rw-r--r--libgo/go/testing/example.go78
-rw-r--r--libgo/go/testing/testing.go53
3 files changed, 111 insertions, 40 deletions
diff --git a/libgo/go/testing/benchmark.go b/libgo/go/testing/benchmark.go
index cb92fab50ad..25fb2d61918 100644
--- a/libgo/go/testing/benchmark.go
+++ b/libgo/go/testing/benchmark.go
@@ -34,11 +34,12 @@ type InternalBenchmark struct {
// timing and to specify the number of iterations to run.
type B struct {
common
- N int
- benchmark InternalBenchmark
- bytes int64
- timerOn bool
- result BenchmarkResult
+ N int
+ benchmark InternalBenchmark
+ bytes int64
+ timerOn bool
+ showAllocResult bool
+ result BenchmarkResult
// The initial states of memStats.Mallocs and memStats.TotalAlloc.
startAllocs uint64
startBytes uint64
@@ -91,6 +92,13 @@ func (b *B) ResetTimer() {
// If this is called, the benchmark will report ns/op and MB/s.
func (b *B) SetBytes(n int64) { b.bytes = n }
+// ReportAllocs enables malloc statistics for this benchmark.
+// It is equivalent to setting -test.benchmem, but it only affects the
+// benchmark function that calls ReportAllocs.
+func (b *B) ReportAllocs() {
+ b.showAllocResult = true
+}
+
func (b *B) nsPerOp() int64 {
if b.N <= 0 {
return 0
@@ -298,7 +306,7 @@ func RunBenchmarks(matchString func(pat, str string) (bool, error), benchmarks [
continue
}
results := r.String()
- if *benchmarkMemory {
+ if *benchmarkMemory || b.showAllocResult {
results += "\t" + r.MemString()
}
fmt.Println(results)
diff --git a/libgo/go/testing/example.go b/libgo/go/testing/example.go
index dc97255965e..828c2d3eda8 100644
--- a/libgo/go/testing/example.go
+++ b/libgo/go/testing/example.go
@@ -24,8 +24,6 @@ func RunExamples(matchString func(pat, str string) (bool, error), examples []Int
var eg InternalExample
- stdout := os.Stdout
-
for _, eg = range examples {
matched, err := matchString(*match, eg.Name)
if err != nil {
@@ -35,48 +33,68 @@ func RunExamples(matchString func(pat, str string) (bool, error), examples []Int
if !matched {
continue
}
- if *chatty {
- fmt.Printf("=== RUN: %s\n", eg.Name)
+ if !runExample(eg) {
+ ok = false
}
+ }
+
+ return
+}
+
+func runExample(eg InternalExample) (ok bool) {
+ if *chatty {
+ fmt.Printf("=== RUN: %s\n", eg.Name)
+ }
- // capture stdout
- r, w, err := os.Pipe()
+ // Capture stdout.
+ stdout := os.Stdout
+ r, w, err := os.Pipe()
+ if err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+ os.Stdout = w
+ outC := make(chan string)
+ go func() {
+ buf := new(bytes.Buffer)
+ _, err := io.Copy(buf, r)
+ r.Close()
if err != nil {
- fmt.Fprintln(os.Stderr, err)
+ fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
os.Exit(1)
}
- os.Stdout = w
- outC := make(chan string)
- go func() {
- buf := new(bytes.Buffer)
- _, err := io.Copy(buf, r)
- if err != nil {
- fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
- os.Exit(1)
- }
- outC <- buf.String()
- }()
+ outC <- buf.String()
+ }()
+
+ start := time.Now()
+ ok = true
- // run example
- t0 := time.Now()
- eg.F()
- dt := time.Now().Sub(t0)
+ // Clean up in a deferred call so we can recover if the example panics.
+ defer func() {
+ d := time.Now().Sub(start)
- // close pipe, restore stdout, get output
+ // Close pipe, restore stdout, get output.
w.Close()
os.Stdout = stdout
out := <-outC
- // report any errors
- tstr := fmt.Sprintf("(%.2f seconds)", dt.Seconds())
- if g, e := strings.TrimSpace(out), strings.TrimSpace(eg.Output); g != e {
- fmt.Printf("--- FAIL: %s %s\ngot:\n%s\nwant:\n%s\n",
- eg.Name, tstr, g, e)
+ var fail string
+ err := recover()
+ if g, e := strings.TrimSpace(out), strings.TrimSpace(eg.Output); g != e && err == nil {
+ fail = fmt.Sprintf("got:\n%s\nwant:\n%s\n", g, e)
+ }
+ if fail != "" || err != nil {
+ fmt.Printf("--- FAIL: %s (%v)\n%s", eg.Name, d, fail)
ok = false
} else if *chatty {
- fmt.Printf("--- PASS: %s %s\n", eg.Name, tstr)
+ fmt.Printf("--- PASS: %s (%v)\n", eg.Name, d)
}
- }
+ if err != nil {
+ panic(err)
+ }
+ }()
+ // Run example.
+ eg.F()
return
}
diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go
index 66b41a50fa7..c1917f8fe03 100644
--- a/libgo/go/testing/testing.go
+++ b/libgo/go/testing/testing.go
@@ -10,6 +10,14 @@
// [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:
+// func TestTimeConsuming(t *testing.T) {
+// if testing.Short() {
+// t.Skip("skipping test in short mode.")
+// }
+// ...
+// }
+//
// Functions of the form
// func BenchmarkXxx(*testing.B)
// are considered benchmarks, and are executed by the "go test" command when
@@ -42,8 +50,8 @@
//
// The package also runs and verifies example code. Example functions may
// include a concluding comment that begins with "Output:" and is compared with
-// the standard output of the function when the tests are run, as in these
-// examples of an example:
+// the standard output of the function when the tests are run. (The comparison
+// ignores leading and trailing space.) These are examples of an example:
//
// func ExampleHello() {
// fmt.Println("hello")
@@ -185,6 +193,7 @@ 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.
@@ -194,7 +203,7 @@ func (c *common) Fail() {
c.failed = true
}
-// Failed returns whether the function has failed.
+// Failed reports whether the function has failed.
func (c *common) Failed() bool {
c.mu.RLock()
defer c.mu.RUnlock()
@@ -328,10 +337,46 @@ func (t *T) report() {
if t.Failed() {
fmt.Printf(format, "FAIL", t.name, tstr, t.output)
} else if *chatty {
- fmt.Printf(format, "PASS", t.name, tstr, t.output)
+ if t.Skipped() {
+ fmt.Printf(format, "SKIP", t.name, tstr, t.output)
+ } else {
+ fmt.Printf(format, "PASS", t.name, tstr, t.output)
+ }
}
}
+// 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 {
OpenPOWER on IntegriCloud