Source file
src/runtime/debuglog_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package runtime_test
24
25 import (
26 "fmt"
27 "regexp"
28 "runtime"
29 "strings"
30 "sync"
31 "testing"
32 )
33
34 func skipDebugLog(t *testing.T) {
35 if runtime.DlogEnabled {
36 t.Skip("debug log tests disabled to avoid collisions with real debug logs")
37 }
38 }
39
40 func dlogCanonicalize(x string) string {
41 begin := regexp.MustCompile(`(?m)^>> begin log \d+ <<\n`)
42 x = begin.ReplaceAllString(x, "")
43 prefix := regexp.MustCompile(`(?m)^\[[^]]+\]`)
44 x = prefix.ReplaceAllString(x, "[]")
45 return x
46 }
47
48 func TestDebugLog(t *testing.T) {
49 skipDebugLog(t)
50 runtime.ResetDebugLog()
51 runtime.Dlog().S("testing").End()
52 got := dlogCanonicalize(runtime.DumpDebugLog())
53 if want := "[] testing\n"; got != want {
54 t.Fatalf("want %q, got %q", want, got)
55 }
56 }
57
58 func TestDebugLogTypes(t *testing.T) {
59 skipDebugLog(t)
60 runtime.ResetDebugLog()
61 var varString = strings.Repeat("a", 4)
62 runtime.Dlog().B(true).B(false).I(-42).I16(0x7fff).U64(^uint64(0)).Hex(0xfff).P(nil).S(varString).S("const string").End()
63 got := dlogCanonicalize(runtime.DumpDebugLog())
64 if want := "[] true false -42 32767 18446744073709551615 0xfff 0x0 aaaa const string\n"; got != want {
65 t.Fatalf("want %q, got %q", want, got)
66 }
67 }
68
69 func TestDebugLogSym(t *testing.T) {
70 skipDebugLog(t)
71 runtime.ResetDebugLog()
72 pc, _, _, _ := runtime.Caller(0)
73 runtime.Dlog().PC(pc).End()
74 got := dlogCanonicalize(runtime.DumpDebugLog())
75 want := regexp.MustCompile(`\[\] 0x[0-9a-f]+ \[runtime_test\.TestDebugLogSym\+0x[0-9a-f]+ .*/debuglog_test\.go:[0-9]+\]\n`)
76 if !want.MatchString(got) {
77 t.Fatalf("want matching %s, got %q", want, got)
78 }
79 }
80
81 func TestDebugLogInterleaving(t *testing.T) {
82 skipDebugLog(t)
83 runtime.ResetDebugLog()
84
85 n1 := runtime.CountDebugLog()
86 t.Logf("number of log shards at start: %d", n1)
87
88 const limit = 1000
89 const concurrency = 10
90
91
92 var wg sync.WaitGroup
93 i := 0
94 chans := make([]chan bool, concurrency)
95 for gid := range concurrency {
96 chans[gid] = make(chan bool)
97 wg.Add(1)
98 go func() {
99 defer wg.Done()
100 var log *runtime.Dlogger
101 for {
102 <-chans[gid]
103 if log != nil {
104 log.End()
105 }
106 next := chans[(gid+1)%len(chans)]
107 if i >= limit {
108 close(next)
109 break
110 }
111
112
113
114 log = runtime.Dlog().I(i)
115 i++
116
117 next <- true
118 }
119 }()
120 }
121
122 chans[0] <- true
123
124
125 wg.Wait()
126 gotFull := runtime.DumpDebugLog()
127 got := dlogCanonicalize(gotFull)
128
129 n2 := runtime.CountDebugLog()
130 t.Logf("number of log shards at end: %d", n2)
131 if n2 < concurrency {
132 t.Errorf("created %d log shards, expected >= %d", n2, concurrency)
133 }
134
135
136 var want strings.Builder
137 for i := 0; i < limit; i++ {
138 fmt.Fprintf(&want, "[] %d\n", i)
139 }
140
141 if got != want.String() {
142
143
144
145 t.Fatalf("want %q, got (uncanonicalized) %q", want.String(), gotFull)
146 }
147 }
148
149 func TestDebugLogWraparound(t *testing.T) {
150 skipDebugLog(t)
151
152
153 runtime.LockOSThread()
154 defer runtime.UnlockOSThread()
155
156 runtime.ResetDebugLog()
157 var longString = strings.Repeat("a", 128)
158 var want strings.Builder
159 for i, j := 0, 0; j < 2*runtime.DebugLogBytes; i, j = i+1, j+len(longString) {
160 runtime.Dlog().I(i).S(longString).End()
161 fmt.Fprintf(&want, "[] %d %s\n", i, longString)
162 }
163 log := runtime.DumpDebugLog()
164
165
166 lost := regexp.MustCompile(`^>> begin log \d+; lost first \d+KB <<\n`)
167 if !lost.MatchString(log) {
168 t.Fatalf("want matching %s, got %q", lost, log)
169 }
170 idx := lost.FindStringIndex(log)
171
172 log = dlogCanonicalize(log[idx[1]:])
173
174
175 if !strings.HasSuffix(want.String(), log) {
176 t.Fatalf("wrong suffix:\n%s", log)
177 }
178 }
179
180 func TestDebugLogLongString(t *testing.T) {
181 skipDebugLog(t)
182
183 runtime.ResetDebugLog()
184 var longString = strings.Repeat("a", runtime.DebugLogStringLimit+1)
185 runtime.Dlog().S(longString).End()
186 got := dlogCanonicalize(runtime.DumpDebugLog())
187 want := "[] " + strings.Repeat("a", runtime.DebugLogStringLimit) + " ..(1 more bytes)..\n"
188 if got != want {
189 t.Fatalf("want %q, got %q", want, got)
190 }
191 }
192
View as plain text