mirror of
https://github.com/golang/go.git
synced 2025-11-08 12:41:02 +00:00
testing: catch panicking example and report, just like tests
Fixes #4670. R=rsc CC=golang-dev https://golang.org/cl/7148043
This commit is contained in:
parent
07dfd8b131
commit
5bd5ed2b57
1 changed files with 57 additions and 42 deletions
|
|
@ -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)
|
||||
}
|
||||
|
||||
// capture 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.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
outC <- buf.String()
|
||||
}()
|
||||
|
||||
// run example
|
||||
t0 := time.Now()
|
||||
eg.F()
|
||||
dt := time.Now().Sub(t0)
|
||||
|
||||
// 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)
|
||||
if !runExample(eg) {
|
||||
ok = false
|
||||
} else if *chatty {
|
||||
fmt.Printf("--- PASS: %s %s\n", eg.Name, tstr)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func runExample(eg InternalExample) (ok bool) {
|
||||
if *chatty {
|
||||
fmt.Printf("=== RUN: %s\n", eg.Name)
|
||||
}
|
||||
|
||||
// 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.Fprintf(os.Stderr, "testing: copying pipe: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
outC <- buf.String()
|
||||
}()
|
||||
|
||||
start := time.Now()
|
||||
|
||||
// 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
|
||||
|
||||
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 (%v)\n", eg.Name, d)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Run example.
|
||||
eg.F()
|
||||
return
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue