Source file
src/runtime/profbuf_test.go
1
2
3
4
5 package runtime_test
6
7 import (
8 "reflect"
9 . "runtime"
10 "testing"
11 "time"
12 "unsafe"
13 )
14
15 func TestProfBuf(t *testing.T) {
16 const hdrSize = 2
17
18 write := func(t *testing.T, b *ProfBuf, tag unsafe.Pointer, now int64, hdr []uint64, stk []uintptr) {
19 b.Write(&tag, now, hdr, stk)
20 }
21 read := func(t *testing.T, b *ProfBuf, data []uint64, tags []unsafe.Pointer) {
22 rdata, rtags, eof := b.Read(ProfBufNonBlocking)
23 if !reflect.DeepEqual(rdata, data) || !reflect.DeepEqual(rtags, tags) {
24 t.Fatalf("unexpected profile read:\nhave data %#x\nwant data %#x\nhave tags %#x\nwant tags %#x", rdata, data, rtags, tags)
25 }
26 if eof {
27 t.Fatalf("unexpected eof")
28 }
29 }
30 readBlock := func(t *testing.T, b *ProfBuf, data []uint64, tags []unsafe.Pointer) func() {
31 c := make(chan int)
32 go func() {
33 eof := data == nil
34 rdata, rtags, reof := b.Read(ProfBufBlocking)
35 if !reflect.DeepEqual(rdata, data) || !reflect.DeepEqual(rtags, tags) || reof != eof {
36
37 t.Errorf("unexpected profile read:\nhave data %#x\nwant data %#x\nhave tags %#x\nwant tags %#x\nhave eof=%v, want %v", rdata, data, rtags, tags, reof, eof)
38 }
39 c <- 1
40 }()
41 time.Sleep(10 * time.Millisecond)
42 return func() {
43 select {
44 case <-c:
45 case <-time.After(1 * time.Second):
46 t.Fatalf("timeout waiting for blocked read")
47 }
48 }
49 }
50 readEOF := func(t *testing.T, b *ProfBuf) {
51 rdata, rtags, eof := b.Read(ProfBufBlocking)
52 if rdata != nil || rtags != nil || !eof {
53 t.Errorf("unexpected profile read: %#x, %#x, eof=%v; want nil, nil, eof=true", rdata, rtags, eof)
54 }
55 rdata, rtags, eof = b.Read(ProfBufNonBlocking)
56 if rdata != nil || rtags != nil || !eof {
57 t.Errorf("unexpected profile read (non-blocking): %#x, %#x, eof=%v; want nil, nil, eof=true", rdata, rtags, eof)
58 }
59 }
60
61 myTags := make([]byte, 100)
62 t.Logf("myTags is %p", &myTags[0])
63
64 t.Run("BasicWriteRead", func(t *testing.T) {
65 b := NewProfBuf(2, 11, 1)
66 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
67 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
68 read(t, b, nil, nil)
69 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
70 read(t, b, []uint64{8, 99, 101, 102, 201, 202, 203, 204}, []unsafe.Pointer{unsafe.Pointer(&myTags[2])})
71 })
72
73 t.Run("ReadMany", func(t *testing.T) {
74 b := NewProfBuf(2, 50, 50)
75 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
76 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
77 write(t, b, unsafe.Pointer(&myTags[1]), 500, []uint64{502, 504}, []uintptr{506})
78 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 99, 101, 102, 201, 202, 203, 204, 5, 500, 502, 504, 506}, []unsafe.Pointer{unsafe.Pointer(&myTags[0]), unsafe.Pointer(&myTags[2]), unsafe.Pointer(&myTags[1])})
79 })
80
81 t.Run("ReadManyShortData", func(t *testing.T) {
82 b := NewProfBuf(2, 50, 50)
83 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
84 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
85 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 99, 101, 102, 201, 202, 203, 204}, []unsafe.Pointer{unsafe.Pointer(&myTags[0]), unsafe.Pointer(&myTags[2])})
86 })
87
88 t.Run("ReadManyShortTags", func(t *testing.T) {
89 b := NewProfBuf(2, 50, 50)
90 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
91 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
92 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 99, 101, 102, 201, 202, 203, 204}, []unsafe.Pointer{unsafe.Pointer(&myTags[0]), unsafe.Pointer(&myTags[2])})
93 })
94
95 t.Run("ReadAfterOverflow1", func(t *testing.T) {
96
97 b := NewProfBuf(2, 16, 5)
98 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
99 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
100 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5})
101 read(t, b, []uint64{6, 1, 2, 3, 4, 5}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
102
103 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204, 205, 206, 207, 208, 209})
104 for i := 0; i < 299; i++ {
105 write(t, b, unsafe.Pointer(&myTags[3]), int64(100+i), []uint64{101, 102}, []uintptr{201, 202, 203, 204})
106 }
107 write(t, b, unsafe.Pointer(&myTags[1]), 500, []uint64{502, 504}, []uintptr{506})
108 read(t, b, []uint64{5, 99, 0, 0, 300, 5, 500, 502, 504, 506}, []unsafe.Pointer{nil, unsafe.Pointer(&myTags[1])})
109 })
110
111 t.Run("ReadAfterOverflow2", func(t *testing.T) {
112
113 b := NewProfBuf(2, 16, 5)
114 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
115 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213})
116 for i := 0; i < 299; i++ {
117 write(t, b, unsafe.Pointer(&myTags[3]), 100, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
118 }
119 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
120 write(t, b, unsafe.Pointer(&myTags[1]), 500, []uint64{502, 504}, []uintptr{})
121 read(t, b, []uint64{5, 99, 0, 0, 301}, []unsafe.Pointer{nil})
122 write(t, b, unsafe.Pointer(&myTags[1]), 500, []uint64{502, 505}, []uintptr{506})
123 read(t, b, []uint64{5, 500, 502, 505, 506}, []unsafe.Pointer{unsafe.Pointer(&myTags[1])})
124 })
125
126 t.Run("ReadAtEndAfterOverflow", func(t *testing.T) {
127 b := NewProfBuf(2, 12, 5)
128 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
129 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
130 for i := 0; i < 299; i++ {
131 write(t, b, unsafe.Pointer(&myTags[3]), 100, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
132 }
133 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
134 read(t, b, []uint64{5, 99, 0, 0, 300}, []unsafe.Pointer{nil})
135 write(t, b, unsafe.Pointer(&myTags[1]), 500, []uint64{502, 504}, []uintptr{506})
136 read(t, b, []uint64{5, 500, 502, 504, 506}, []unsafe.Pointer{unsafe.Pointer(&myTags[1])})
137 })
138
139 t.Run("BlockingWriteRead", func(t *testing.T) {
140 b := NewProfBuf(2, 11, 1)
141 wait := readBlock(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
142 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
143 wait()
144 wait = readBlock(t, b, []uint64{8, 99, 101, 102, 201, 202, 203, 204}, []unsafe.Pointer{unsafe.Pointer(&myTags[2])})
145 time.Sleep(10 * time.Millisecond)
146 write(t, b, unsafe.Pointer(&myTags[2]), 99, []uint64{101, 102}, []uintptr{201, 202, 203, 204})
147 wait()
148 wait = readBlock(t, b, nil, nil)
149 b.Close()
150 wait()
151 wait = readBlock(t, b, nil, nil)
152 wait()
153 readEOF(t, b)
154 })
155
156 t.Run("DataWraparound", func(t *testing.T) {
157 b := NewProfBuf(2, 16, 1024)
158 for i := 0; i < 10; i++ {
159 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
160 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
161 read(t, b, nil, nil)
162 }
163 })
164
165 t.Run("TagWraparound", func(t *testing.T) {
166 b := NewProfBuf(2, 1024, 2)
167 for i := 0; i < 10; i++ {
168 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
169 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
170 read(t, b, nil, nil)
171 }
172 })
173
174 t.Run("BothWraparound", func(t *testing.T) {
175 b := NewProfBuf(2, 16, 2)
176 for i := 0; i < 10; i++ {
177 write(t, b, unsafe.Pointer(&myTags[0]), 1, []uint64{2, 3}, []uintptr{4, 5, 6, 7, 8, 9})
178 read(t, b, []uint64{10, 1, 2, 3, 4, 5, 6, 7, 8, 9}, []unsafe.Pointer{unsafe.Pointer(&myTags[0])})
179 read(t, b, nil, nil)
180 }
181 })
182 }
183
View as plain text