]> Cypherpunks repositories - gostls13.git/commitdiff
testing: catch panicking example and report, just like tests
authorAndrew Gerrand <adg@golang.org>
Thu, 17 Jan 2013 23:28:18 +0000 (10:28 +1100)
committerAndrew Gerrand <adg@golang.org>
Thu, 17 Jan 2013 23:28:18 +0000 (10:28 +1100)
Fixes #4670.

R=rsc
CC=golang-dev
https://golang.org/cl/7148043

src/pkg/testing/example.go

index 34d4b2bda99bfe5372926a8882495925b07444a0..4aec4830e1fb621f8b6f61d9f7830a03ec7367e9 100644 (file)
@@ -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,49 +33,66 @@ 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)
-                       r.Close()
-                       if err != nil {
-                               fmt.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
-                               os.Exit(1)
-                       }
-                       outC <- buf.String()
-               }()
+               outC <- buf.String()
+       }()
 
-               // run example
-               t0 := time.Now()
-               eg.F()
-               dt := time.Now().Sub(t0)
+       start := time.Now()
 
-               // close pipe, restore stdout, get output
+       // 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.
                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)
-                       ok = false
+               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)
                } 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
 }