Source file
src/runtime/runtime_test.go
Documentation: runtime
1
2
3
4
5 package runtime_test
6
7 import (
8 "flag"
9 "io"
10 . "runtime"
11 "runtime/debug"
12 "strings"
13 "testing"
14 "unsafe"
15 )
16
17 var flagQuick = flag.Bool("quick", false, "skip slow tests, for second run in all.bash")
18
19 func init() {
20
21
22
23 SetTracebackEnv("system")
24 }
25
26 var errf error
27
28 func errfn() error {
29 return errf
30 }
31
32 func errfn1() error {
33 return io.EOF
34 }
35
36 func BenchmarkIfaceCmp100(b *testing.B) {
37 for i := 0; i < b.N; i++ {
38 for j := 0; j < 100; j++ {
39 if errfn() == io.EOF {
40 b.Fatal("bad comparison")
41 }
42 }
43 }
44 }
45
46 func BenchmarkIfaceCmpNil100(b *testing.B) {
47 for i := 0; i < b.N; i++ {
48 for j := 0; j < 100; j++ {
49 if errfn1() == nil {
50 b.Fatal("bad comparison")
51 }
52 }
53 }
54 }
55
56 var efaceCmp1 interface{}
57 var efaceCmp2 interface{}
58
59 func BenchmarkEfaceCmpDiff(b *testing.B) {
60 x := 5
61 efaceCmp1 = &x
62 y := 6
63 efaceCmp2 = &y
64 for i := 0; i < b.N; i++ {
65 for j := 0; j < 100; j++ {
66 if efaceCmp1 == efaceCmp2 {
67 b.Fatal("bad comparison")
68 }
69 }
70 }
71 }
72
73 func BenchmarkEfaceCmpDiffIndirect(b *testing.B) {
74 efaceCmp1 = [2]int{1, 2}
75 efaceCmp2 = [2]int{1, 2}
76 for i := 0; i < b.N; i++ {
77 for j := 0; j < 100; j++ {
78 if efaceCmp1 != efaceCmp2 {
79 b.Fatal("bad comparison")
80 }
81 }
82 }
83 }
84
85 func BenchmarkDefer(b *testing.B) {
86 for i := 0; i < b.N; i++ {
87 defer1()
88 }
89 }
90
91 func defer1() {
92 defer func(x, y, z int) {
93 if recover() != nil || x != 1 || y != 2 || z != 3 {
94 panic("bad recover")
95 }
96 }(1, 2, 3)
97 }
98
99 func BenchmarkDefer10(b *testing.B) {
100 for i := 0; i < b.N/10; i++ {
101 defer2()
102 }
103 }
104
105 func defer2() {
106 for i := 0; i < 10; i++ {
107 defer func(x, y, z int) {
108 if recover() != nil || x != 1 || y != 2 || z != 3 {
109 panic("bad recover")
110 }
111 }(1, 2, 3)
112 }
113 }
114
115 func BenchmarkDeferMany(b *testing.B) {
116 for i := 0; i < b.N; i++ {
117 defer func(x, y, z int) {
118 if recover() != nil || x != 1 || y != 2 || z != 3 {
119 panic("bad recover")
120 }
121 }(1, 2, 3)
122 }
123 }
124
125 func BenchmarkPanicRecover(b *testing.B) {
126 for i := 0; i < b.N; i++ {
127 defer3()
128 }
129 }
130
131 func defer3() {
132 defer func(x, y, z int) {
133 if recover() == nil {
134 panic("failed recover")
135 }
136 }(1, 2, 3)
137 panic("hi")
138 }
139
140
141 func TestStopCPUProfilingWithProfilerOff(t *testing.T) {
142 SetCPUProfileRate(0)
143 }
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158 var faultAddrs = []uint64{
159
160 0,
161 1,
162 0xfff,
163
164
165 0xffffffffffffffff,
166 0xfffffffffffff001,
167 0xffffffffffff0001,
168 0xfffffffffff00001,
169 0xffffffffff000001,
170 0xfffffffff0000001,
171 0xffffffff00000001,
172 0xfffffff000000001,
173 0xffffff0000000001,
174 0xfffff00000000001,
175 0xffff000000000001,
176 0xfff0000000000001,
177 0xff00000000000001,
178 0xf000000000000001,
179 0x8000000000000001,
180 }
181
182 func TestSetPanicOnFault(t *testing.T) {
183 old := debug.SetPanicOnFault(true)
184 defer debug.SetPanicOnFault(old)
185
186 nfault := 0
187 for _, addr := range faultAddrs {
188 testSetPanicOnFault(t, uintptr(addr), &nfault)
189 }
190 if nfault == 0 {
191 t.Fatalf("none of the addresses faulted")
192 }
193 }
194
195
196
197
198
199 func testSetPanicOnFault(t *testing.T, addr uintptr, nfault *int) {
200 if GOOS == "js" {
201 t.Skip("js does not support catching faults")
202 }
203
204 defer func() {
205 if err := recover(); err != nil {
206 *nfault++
207 }
208 }()
209
210
211
212
213
214 v := *(*byte)(unsafe.Pointer(addr))
215 t.Logf("addr %#x: %#x\n", addr, v)
216 }
217
218 func eqstring_generic(s1, s2 string) bool {
219 if len(s1) != len(s2) {
220 return false
221 }
222
223
224 for i := 0; i < len(s1); i++ {
225 if s1[i] != s2[i] {
226 return false
227 }
228 }
229 return true
230 }
231
232 func TestEqString(t *testing.T) {
233
234
235
236 s := []string{
237 "",
238 "a",
239 "c",
240 "aaa",
241 "ccc",
242 "cccc"[:3],
243 "1234567890",
244 }
245 for _, s1 := range s {
246 for _, s2 := range s {
247 x := s1 == s2
248 y := eqstring_generic(s1, s2)
249 if x != y {
250 t.Errorf(`("%s" == "%s") = %t, want %t`, s1, s2, x, y)
251 }
252 }
253 }
254 }
255
256 func TestTrailingZero(t *testing.T) {
257
258 type T1 struct {
259 n int32
260 z [0]byte
261 }
262 if unsafe.Sizeof(T1{}) != 8 {
263 t.Errorf("sizeof(%#v)==%d, want 8", T1{}, unsafe.Sizeof(T1{}))
264 }
265 type T2 struct {
266 n int64
267 z struct{}
268 }
269 if unsafe.Sizeof(T2{}) != 8+unsafe.Sizeof(uintptr(0)) {
270 t.Errorf("sizeof(%#v)==%d, want %d", T2{}, unsafe.Sizeof(T2{}), 8+unsafe.Sizeof(uintptr(0)))
271 }
272 type T3 struct {
273 n byte
274 z [4]struct{}
275 }
276 if unsafe.Sizeof(T3{}) != 2 {
277 t.Errorf("sizeof(%#v)==%d, want 2", T3{}, unsafe.Sizeof(T3{}))
278 }
279
280 type T4 struct {
281 a int32
282 b int16
283 c int8
284 z struct{}
285 }
286 if unsafe.Sizeof(T4{}) != 8 {
287 t.Errorf("sizeof(%#v)==%d, want 8", T4{}, unsafe.Sizeof(T4{}))
288 }
289
290 type T5 struct {
291 }
292 if unsafe.Sizeof(T5{}) != 0 {
293 t.Errorf("sizeof(%#v)==%d, want 0", T5{}, unsafe.Sizeof(T5{}))
294 }
295 }
296
297 func TestAppendGrowth(t *testing.T) {
298 var x []int64
299 check := func(want int) {
300 if cap(x) != want {
301 t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want)
302 }
303 }
304
305 check(0)
306 want := 1
307 for i := 1; i <= 100; i++ {
308 x = append(x, 1)
309 check(want)
310 if i&(i-1) == 0 {
311 want = 2 * i
312 }
313 }
314 }
315
316 var One = []int64{1}
317
318 func TestAppendSliceGrowth(t *testing.T) {
319 var x []int64
320 check := func(want int) {
321 if cap(x) != want {
322 t.Errorf("len=%d, cap=%d, want cap=%d", len(x), cap(x), want)
323 }
324 }
325
326 check(0)
327 want := 1
328 for i := 1; i <= 100; i++ {
329 x = append(x, One...)
330 check(want)
331 if i&(i-1) == 0 {
332 want = 2 * i
333 }
334 }
335 }
336
337 func TestGoroutineProfileTrivial(t *testing.T) {
338
339
340
341
342 for i := 0; ; i++ {
343 n1, ok := GoroutineProfile(nil)
344 if n1 < 1 || ok {
345 t.Fatalf("GoroutineProfile(nil) = %d, %v, want >0, false", n1, ok)
346 }
347 n2, ok := GoroutineProfile(make([]StackRecord, n1))
348 if n2 == n1 && ok {
349 break
350 }
351 t.Logf("GoroutineProfile(%d) = %d, %v, want %d, true", n1, n2, ok, n1)
352 if i >= 10 {
353 t.Fatalf("GoroutineProfile not converging")
354 }
355 }
356 }
357
358 func TestVersion(t *testing.T) {
359
360 vers := Version()
361 if strings.Contains(vers, "\r") || strings.Contains(vers, "\n") {
362 t.Fatalf("cr/nl in version: %q", vers)
363 }
364 }
365
View as plain text