blob: 51d36e217ed7c8632436595a82523ce98bc07113 [file] [log] [blame]
Carl Mastrangelo3c786242015-12-02 14:46:50 -08001package http2interop
2
3import (
Carl Mastrangelo3e21ba42015-12-04 16:49:33 -08004 "path"
Carl Mastrangelo3c786242015-12-02 14:46:50 -08005 "runtime"
6 "strings"
7 "sync"
8 "testing"
9)
10
11// When a test is skipped or fails, runtime.Goexit() is called which destroys the callstack.
12// This means the name of the test case is lost, so we need to grab a copy of pc before.
Carl Mastrangelo3e21ba42015-12-04 16:49:33 -080013func Report(t testing.TB) {
14 // If the goroutine panics, Fatal()s, or Skip()s, the function name is at the 3rd callstack
15 // layer. On success, its at 1st. Since it's hard to check which happened, just try both.
16 pcs := make([]uintptr, 10)
17 total := runtime.Callers(1, pcs)
18 var name string
19 for _, pc := range pcs[:total] {
Carl Mastrangelo3c786242015-12-02 14:46:50 -080020 fn := runtime.FuncForPC(pc)
21 fullName := fn.Name()
Carl Mastrangelo3e21ba42015-12-04 16:49:33 -080022 if strings.HasPrefix(path.Ext(fullName), ".Test") {
23 // Skip the leading .
24 name = string([]byte(path.Ext(fullName))[1:])
25 break
26 }
Carl Mastrangelo3c786242015-12-02 14:46:50 -080027 }
Carl Mastrangelo3e21ba42015-12-04 16:49:33 -080028 if name == "" {
29 return
30 }
31
32 allCaseInfos.lock.Lock()
33 defer allCaseInfos.lock.Unlock()
34 allCaseInfos.Cases = append(allCaseInfos.Cases, &caseInfo{
35 Name: name,
36 Passed: !t.Failed() && !t.Skipped(),
37 Skipped: t.Skipped(),
38 Fatal: t.Failed() && !strings.HasPrefix(name, "TestSoon"),
39 })
Carl Mastrangelo3c786242015-12-02 14:46:50 -080040}
41
42type caseInfo struct {
43 Name string `json:"name"`
44 Passed bool `json:"passed"`
Carl Mastrangelo3e21ba42015-12-04 16:49:33 -080045 Skipped bool `json:"skipped,omitempty"`
46 Fatal bool `json:"fatal,omitempty"`
Carl Mastrangelo3c786242015-12-02 14:46:50 -080047}
48
49type caseInfos struct {
50 lock sync.Mutex
51 Cases []*caseInfo `json:"cases"`
52}
53
54var (
55 allCaseInfos = caseInfos{}
56)