TestPanicweb implements the parsing of panicweb output. panicweb is a separate binary from the rest of panic because importing the "net" package causes a background thread to be started, which breaks "panic asleep".
(t *testing.T)
| 2043 | // "net" package causes a background thread to be started, which breaks "panic |
| 2044 | // asleep". |
| 2045 | func TestPanicweb(t *testing.T) { |
| 2046 | t.Parallel() |
| 2047 | if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" { |
| 2048 | t.Skip("https://github.com/maruel/panicparse/issues/66") |
| 2049 | } |
| 2050 | prefix := bytes.Buffer{} |
| 2051 | s, suffix, err := ScanSnapshot(bytes.NewReader(internaltest.PanicwebOutput()), &prefix, defaultOpts()) |
| 2052 | if err != io.EOF { |
| 2053 | t.Fatal(err) |
| 2054 | } |
| 2055 | if s == nil { |
| 2056 | t.Fatal("snapshot is nil") |
| 2057 | } |
| 2058 | compareString(t, "panic: Here's a snapshot of a normal web server.\n\n", prefix.String()) |
| 2059 | compareString(t, "", string(suffix)) |
| 2060 | if s.RemoteGOROOT != "" { |
| 2061 | t.Fatalf("unexpected RemoteGOROOT: %q", s.RemoteGOROOT) |
| 2062 | } |
| 2063 | if !s.guessPaths() { |
| 2064 | t.Error("expected success") |
| 2065 | } |
| 2066 | if s.RemoteGOROOT != strings.Replace(runtime.GOROOT(), "\\", "/", -1) { |
| 2067 | t.Fatalf("RemoteGOROOT mismatch; want:%q got:%q", runtime.GOROOT(), s.RemoteGOROOT) |
| 2068 | } |
| 2069 | if got := len(s.Goroutines); got < 30 { |
| 2070 | t.Fatalf("unexpected Goroutines; want at least 30, got %d", got) |
| 2071 | } |
| 2072 | // The goal here is not to find the exact match since it'll change across |
| 2073 | // OSes and Go versions, but to find some of the expected signatures. |
| 2074 | pwebDir := pathJoin(getPanicParseDir(t), "cmd", "panicweb") |
| 2075 | // Reduce the goroutines and categorize the signatures. |
| 2076 | var types []panicwebSignatureType |
| 2077 | for _, b := range s.Aggregate(AnyPointer).Buckets { |
| 2078 | types = append(types, identifyPanicwebSignature(t, b, pwebDir)) |
| 2079 | } |
| 2080 | // Count the expected types. |
| 2081 | if v := pstCount(types, pstUnknown); v != 0 { |
| 2082 | t.Fatalf("found %d unknown signatures", v) |
| 2083 | } |
| 2084 | if v := pstCount(types, pstMain); v != 1 { |
| 2085 | t.Fatalf("found %d pstMain signatures", v) |
| 2086 | } |
| 2087 | if v := pstCount(types, pstURL1handler); v != 1 && v != 2 { |
| 2088 | t.Fatalf("found %d URL1Handler signatures", v) |
| 2089 | } |
| 2090 | if v := pstCount(types, pstURL2handler); v != 1 && v != 2 { |
| 2091 | t.Fatalf("found %d URL2Handler signatures", v) |
| 2092 | } |
| 2093 | if v := pstCount(types, pstClient); v == 0 { |
| 2094 | t.Fatalf("found %d client signatures", v) |
| 2095 | } |
| 2096 | if v := pstCount(types, pstServe); v != 1 { |
| 2097 | t.Fatalf("found %d serve signatures", v) |
| 2098 | } |
| 2099 | if v := pstCount(types, pstColorable); v != 1 { |
| 2100 | t.Fatalf("found %d colorable signatures", v) |
| 2101 | } |
| 2102 | if v := pstCount(types, pstStdlib); v < 3 { |
nothing calls this directly
no test coverage detected
searching dependent graphs…