Source file
src/runtime/panic_test.go
1
2
3
4
5 package runtime_test
6
7 import (
8 "slices"
9 "strings"
10 "testing"
11 "time"
12 )
13
14
15
16
17 func TestPanicWithDirectlyPrintableCustomTypes(t *testing.T) {
18 tests := []struct {
19 name string
20 wantPanicPrefix string
21 }{
22 {"panicCustomBool", `panic: main.MyBool(true)`},
23 {"panicCustomComplex128", `panic: main.MyComplex128(32.1+10i)`},
24 {"panicCustomComplex64", `panic: main.MyComplex64(0.11+3i)`},
25 {"panicCustomFloat32", `panic: main.MyFloat32(-93.7)`},
26 {"panicCustomFloat64", `panic: main.MyFloat64(-93.7)`},
27 {"panicCustomInt", `panic: main.MyInt(93)`},
28 {"panicCustomInt8", `panic: main.MyInt8(93)`},
29 {"panicCustomInt16", `panic: main.MyInt16(93)`},
30 {"panicCustomInt32", `panic: main.MyInt32(93)`},
31 {"panicCustomInt64", `panic: main.MyInt64(93)`},
32 {"panicCustomString", `panic: main.MyString("Panic` + "\n\t" + `line two")`},
33 {"panicCustomUint", `panic: main.MyUint(93)`},
34 {"panicCustomUint8", `panic: main.MyUint8(93)`},
35 {"panicCustomUint16", `panic: main.MyUint16(93)`},
36 {"panicCustomUint32", `panic: main.MyUint32(93)`},
37 {"panicCustomUint64", `panic: main.MyUint64(93)`},
38 {"panicCustomUintptr", `panic: main.MyUintptr(93)`},
39 {"panicDeferFatal", "panic: runtime.errorString(\"invalid memory address or nil pointer dereference\")\n\tfatal error: sync: unlock of unlocked mutex"},
40 {"panicDoublieDeferFatal", "panic: runtime.errorString(\"invalid memory address or nil pointer dereference\") [recovered, repanicked]\n\tfatal error: sync: unlock of unlocked mutex"},
41 }
42
43 for _, tt := range tests {
44 t := t
45 t.Run(tt.name, func(t *testing.T) {
46 output := runTestProg(t, "testprog", tt.name)
47 if !strings.HasPrefix(output, tt.wantPanicPrefix) {
48 t.Fatalf("%q\nis not present in\n%s", tt.wantPanicPrefix, output)
49 }
50 })
51 }
52 }
53
54 func TestPanicRecoverSpeed(t *testing.T) {
55
56 t.Skip("This test is too flaky at the moment. But it does normally pass. Suggestions for making it less flaky are welcome.")
57
58
59 var f func(int)
60 f = func(n int) {
61 if n == 0 {
62 panic("done")
63 }
64 defer func() {
65 err := recover()
66 panic(err)
67 }()
68 f(n - 1)
69 }
70
71 time := func(f func()) time.Duration {
72 var times []time.Duration
73 for range 10 {
74 start := time.Now()
75 f()
76 times = append(times, time.Since(start))
77 }
78 slices.Sort(times)
79 times = times[1 : len(times)-1]
80 var avg time.Duration
81 for _, v := range times {
82 avg += v / time.Duration(len(times))
83 }
84 return avg
85 }
86
87 a := time(func() {
88 defer func() { recover() }()
89 f(1024)
90 })
91 b := time(func() {
92 defer func() { recover() }()
93 f(2048)
94 })
95 m := b.Seconds() / a.Seconds()
96 t.Logf("a: %v, b: %v, m: %v", a, b, m)
97 if m > 3.5 {
98 t.Errorf("more than 2x time increase: %v", m)
99 }
100 }
101
View as plain text