testsuite.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright 2019 The gRPC Authors
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package http2interop
  15. import (
  16. "path"
  17. "runtime"
  18. "strings"
  19. "sync"
  20. "testing"
  21. )
  22. // When a test is skipped or fails, runtime.Goexit() is called which destroys the callstack.
  23. // This means the name of the test case is lost, so we need to grab a copy of pc before.
  24. func Report(t testing.TB) {
  25. // If the goroutine panics, Fatal()s, or Skip()s, the function name is at the 3rd callstack
  26. // layer. On success, its at 1st. Since it's hard to check which happened, just try both.
  27. pcs := make([]uintptr, 10)
  28. total := runtime.Callers(1, pcs)
  29. var name string
  30. for _, pc := range pcs[:total] {
  31. fn := runtime.FuncForPC(pc)
  32. fullName := fn.Name()
  33. if strings.HasPrefix(path.Ext(fullName), ".Test") {
  34. // Skip the leading .
  35. name = string([]byte(path.Ext(fullName))[1:])
  36. break
  37. }
  38. }
  39. if name == "" {
  40. return
  41. }
  42. allCaseInfos.lock.Lock()
  43. defer allCaseInfos.lock.Unlock()
  44. allCaseInfos.Cases = append(allCaseInfos.Cases, &caseInfo{
  45. Name: name,
  46. Passed: !t.Failed() && !t.Skipped(),
  47. Skipped: t.Skipped(),
  48. Fatal: t.Failed() && !strings.HasPrefix(name, "TestSoon"),
  49. })
  50. }
  51. type caseInfo struct {
  52. Name string `json:"name"`
  53. Passed bool `json:"passed"`
  54. Skipped bool `json:"skipped,omitempty"`
  55. Fatal bool `json:"fatal,omitempty"`
  56. }
  57. type caseInfos struct {
  58. lock sync.Mutex
  59. Cases []*caseInfo `json:"cases"`
  60. }
  61. var (
  62. allCaseInfos = caseInfos{}
  63. )