Home | History | Annotate | Download | only in http2_interop
      1 package http2interop
      2 
      3 import (
      4 	"path"
      5 	"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.
     13 func 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] {
     20 		fn := runtime.FuncForPC(pc)
     21 		fullName := fn.Name()
     22 		if strings.HasPrefix(path.Ext(fullName), ".Test") {
     23 			// Skip the leading .
     24 			name = string([]byte(path.Ext(fullName))[1:])
     25 			break
     26 		}
     27 	}
     28 	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 	})
     40 }
     41 
     42 type caseInfo struct {
     43 	Name    string `json:"name"`
     44 	Passed  bool   `json:"passed"`
     45 	Skipped bool   `json:"skipped,omitempty"`
     46 	Fatal   bool   `json:"fatal,omitempty"`
     47 }
     48 
     49 type caseInfos struct {
     50 	lock  sync.Mutex
     51 	Cases []*caseInfo `json:"cases"`
     52 }
     53 
     54 var (
     55 	allCaseInfos = caseInfos{}
     56 )
     57