| Index: third_party/grpc/tools/http2_interop/testsuite.go
|
| diff --git a/third_party/grpc/tools/http2_interop/testsuite.go b/third_party/grpc/tools/http2_interop/testsuite.go
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..51d36e217ed7c8632436595a82523ce98bc07113
|
| --- /dev/null
|
| +++ b/third_party/grpc/tools/http2_interop/testsuite.go
|
| @@ -0,0 +1,56 @@
|
| +package http2interop
|
| +
|
| +import (
|
| + "path"
|
| + "runtime"
|
| + "strings"
|
| + "sync"
|
| + "testing"
|
| +)
|
| +
|
| +// When a test is skipped or fails, runtime.Goexit() is called which destroys the callstack.
|
| +// This means the name of the test case is lost, so we need to grab a copy of pc before.
|
| +func Report(t testing.TB) {
|
| + // If the goroutine panics, Fatal()s, or Skip()s, the function name is at the 3rd callstack
|
| + // layer. On success, its at 1st. Since it's hard to check which happened, just try both.
|
| + pcs := make([]uintptr, 10)
|
| + total := runtime.Callers(1, pcs)
|
| + var name string
|
| + for _, pc := range pcs[:total] {
|
| + fn := runtime.FuncForPC(pc)
|
| + fullName := fn.Name()
|
| + if strings.HasPrefix(path.Ext(fullName), ".Test") {
|
| + // Skip the leading .
|
| + name = string([]byte(path.Ext(fullName))[1:])
|
| + break
|
| + }
|
| + }
|
| + if name == "" {
|
| + return
|
| + }
|
| +
|
| + allCaseInfos.lock.Lock()
|
| + defer allCaseInfos.lock.Unlock()
|
| + allCaseInfos.Cases = append(allCaseInfos.Cases, &caseInfo{
|
| + Name: name,
|
| + Passed: !t.Failed() && !t.Skipped(),
|
| + Skipped: t.Skipped(),
|
| + Fatal: t.Failed() && !strings.HasPrefix(name, "TestSoon"),
|
| + })
|
| +}
|
| +
|
| +type caseInfo struct {
|
| + Name string `json:"name"`
|
| + Passed bool `json:"passed"`
|
| + Skipped bool `json:"skipped,omitempty"`
|
| + Fatal bool `json:"fatal,omitempty"`
|
| +}
|
| +
|
| +type caseInfos struct {
|
| + lock sync.Mutex
|
| + Cases []*caseInfo `json:"cases"`
|
| +}
|
| +
|
| +var (
|
| + allCaseInfos = caseInfos{}
|
| +)
|
|
|