Add optional passing more
diff --git a/tools/http2_interop/testsuite.go b/tools/http2_interop/testsuite.go
index fcfacf5..51d36e2 100644
--- a/tools/http2_interop/testsuite.go
+++ b/tools/http2_interop/testsuite.go
@@ -1,6 +1,7 @@
 package http2interop
 
 import (
+	"path"
 	"runtime"
 	"strings"
 	"sync"
@@ -9,29 +10,40 @@
 
 // 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) func() {
-	pc, _, _, ok := runtime.Caller(1)
-	if !ok {
-		t.Fatal("Can't get caller info")
-	}
-	return func() {
+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()
-		name := strings.Split(fullName, ".")[1]
-		allCaseInfos.lock.Lock()
-		defer allCaseInfos.lock.Unlock()
-		allCaseInfos.Cases = append(allCaseInfos.Cases, &caseInfo{
-			Name:    name,
-			Passed:  !t.Failed(),
-			Skipped: t.Skipped(),
-		})
+		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"`
+	Skipped bool   `json:"skipped,omitempty"`
+	Fatal   bool   `json:"fatal,omitempty"`
 }
 
 type caseInfos struct {