1
2
3
4
5 package util
6
7 import (
8 "bytes"
9 "io"
10 "math/rand"
11 "runtime"
12 "testing"
13 )
14
15 const N = 10000
16 var data string
17 var testBytes []byte
18
19 func init() {
20 testBytes = make([]byte, N)
21 for i := 0; i < N; i++ {
22 testBytes[i] = 'a' + byte(i%26)
23 }
24 data = string(testBytes)
25 }
26
27
28 func check(t *testing.T, testname string, buf *Buffer, s string) {
29 bytes := buf.Bytes()
30 str := buf.String()
31 if buf.Len() != len(bytes) {
32 t.Errorf("%s: buf.Len() == %d, len(buf.Bytes()) == %d", testname, buf.Len(), len(bytes))
33 }
34
35 if buf.Len() != len(str) {
36 t.Errorf("%s: buf.Len() == %d, len(buf.String()) == %d", testname, buf.Len(), len(str))
37 }
38
39 if buf.Len() != len(s) {
40 t.Errorf("%s: buf.Len() == %d, len(s) == %d", testname, buf.Len(), len(s))
41 }
42
43 if string(bytes) != s {
44 t.Errorf("%s: string(buf.Bytes()) == %q, s == %q", testname, string(bytes), s)
45 }
46 }
47
48
49
50
51 func fillBytes(t *testing.T, testname string, buf *Buffer, s string, n int, fub []byte) string {
52 check(t, testname+" (fill 1)", buf, s)
53 for ; n > 0; n-- {
54 m, err := buf.Write(fub)
55 if m != len(fub) {
56 t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fub))
57 }
58 if err != nil {
59 t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
60 }
61 s += string(fub)
62 check(t, testname+" (fill 4)", buf, s)
63 }
64 return s
65 }
66
67 func TestNewBuffer(t *testing.T) {
68 buf := NewBuffer(testBytes)
69 check(t, "NewBuffer", buf, data)
70 }
71
72
73
74 func empty(t *testing.T, testname string, buf *Buffer, s string, fub []byte) {
75 check(t, testname+" (empty 1)", buf, s)
76
77 for {
78 n, err := buf.Read(fub)
79 if n == 0 {
80 break
81 }
82 if err != nil {
83 t.Errorf(testname+" (empty 2): err should always be nil, found err == %s", err)
84 }
85 s = s[n:]
86 check(t, testname+" (empty 3)", buf, s)
87 }
88
89 check(t, testname+" (empty 4)", buf, "")
90 }
91
92 func TestBasicOperations(t *testing.T) {
93 var buf Buffer
94
95 for i := 0; i < 5; i++ {
96 check(t, "TestBasicOperations (1)", &buf, "")
97
98 buf.Reset()
99 check(t, "TestBasicOperations (2)", &buf, "")
100
101 buf.Truncate(0)
102 check(t, "TestBasicOperations (3)", &buf, "")
103
104 n, err := buf.Write([]byte(data[0:1]))
105 if n != 1 {
106 t.Errorf("wrote 1 byte, but n == %d", n)
107 }
108 if err != nil {
109 t.Errorf("err should always be nil, but err == %s", err)
110 }
111 check(t, "TestBasicOperations (4)", &buf, "a")
112
113 if err := buf.WriteByte(data[1]); err != nil {
114 t.Fatal(err)
115 }
116 check(t, "TestBasicOperations (5)", &buf, "ab")
117
118 n, err = buf.Write([]byte(data[2:26]))
119 if err != nil {
120 t.Fatal(err)
121 }
122 if n != 24 {
123 t.Errorf("wrote 25 bytes, but n == %d", n)
124 }
125 check(t, "TestBasicOperations (6)", &buf, data[0:26])
126
127 buf.Truncate(26)
128 check(t, "TestBasicOperations (7)", &buf, data[0:26])
129
130 buf.Truncate(20)
131 check(t, "TestBasicOperations (8)", &buf, data[0:20])
132
133 empty(t, "TestBasicOperations (9)", &buf, data[0:20], make([]byte, 5))
134 empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100))
135
136 if err := buf.WriteByte(data[1]); err != nil {
137 t.Fatal(err)
138 }
139 c, err := buf.ReadByte()
140 if err != nil {
141 t.Error("ReadByte unexpected eof")
142 }
143 if c != data[1] {
144 t.Errorf("ReadByte wrong value c=%v", c)
145 }
146 _, err = buf.ReadByte()
147 if err == nil {
148 t.Error("ReadByte unexpected not eof")
149 }
150 }
151 }
152
153 func TestLargeByteWrites(t *testing.T) {
154 var buf Buffer
155 limit := 30
156 if testing.Short() {
157 limit = 9
158 }
159 for i := 3; i < limit; i += 3 {
160 s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, testBytes)
161 empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(data)/i))
162 }
163 check(t, "TestLargeByteWrites (3)", &buf, "")
164 }
165
166 func TestLargeByteReads(t *testing.T) {
167 var buf Buffer
168 for i := 3; i < 30; i += 3 {
169 s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
170 empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)))
171 }
172 check(t, "TestLargeByteReads (3)", &buf, "")
173 }
174
175 func TestMixedReadsAndWrites(t *testing.T) {
176 var buf Buffer
177 s := ""
178 for i := 0; i < 50; i++ {
179 wlen := rand.Intn(len(data))
180 s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testBytes[0:wlen])
181 rlen := rand.Intn(len(data))
182 fub := make([]byte, rlen)
183 n, _ := buf.Read(fub)
184 s = s[n:]
185 }
186 empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()))
187 }
188
189 func TestNil(t *testing.T) {
190 var b *Buffer
191 if b.String() != "<nil>" {
192 t.Errorf("expected <nil>; got %q", b.String())
193 }
194 }
195
196 func TestReadFrom(t *testing.T) {
197 var buf Buffer
198 for i := 3; i < 30; i += 3 {
199 s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
200 var b Buffer
201 if _, err := b.ReadFrom(&buf); err != nil {
202 t.Fatal(err)
203 }
204 empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(data)))
205 }
206 }
207
208 func TestWriteTo(t *testing.T) {
209 var buf Buffer
210 for i := 3; i < 30; i += 3 {
211 s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
212 var b Buffer
213 if _, err := buf.WriteTo(&b); err != nil {
214 t.Fatal(err)
215 }
216 empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(data)))
217 }
218 }
219
220 func TestNext(t *testing.T) {
221 b := []byte{0, 1, 2, 3, 4}
222 tmp := make([]byte, 5)
223 for i := 0; i <= 5; i++ {
224 for j := i; j <= 5; j++ {
225 for k := 0; k <= 6; k++ {
226
227
228
229
230 buf := NewBuffer(b[0:j])
231 n, _ := buf.Read(tmp[0:i])
232 if n != i {
233 t.Fatalf("Read %d returned %d", i, n)
234 }
235 bb := buf.Next(k)
236 want := k
237 if want > j-i {
238 want = j - i
239 }
240 if len(bb) != want {
241 t.Fatalf("in %d,%d: len(Next(%d)) == %d", i, j, k, len(bb))
242 }
243 for l, v := range bb {
244 if v != byte(l+i) {
245 t.Fatalf("in %d,%d: Next(%d)[%d] = %d, want %d", i, j, k, l, v, l+i)
246 }
247 }
248 }
249 }
250 }
251 }
252
253 var readBytesTests = []struct {
254 buffer string
255 delim byte
256 expected []string
257 err error
258 }{
259 {"", 0, []string{""}, io.EOF},
260 {"a\x00", 0, []string{"a\x00"}, nil},
261 {"abbbaaaba", 'b', []string{"ab", "b", "b", "aaab"}, nil},
262 {"hello\x01world", 1, []string{"hello\x01"}, nil},
263 {"foo\nbar", 0, []string{"foo\nbar"}, io.EOF},
264 {"alpha\nbeta\ngamma\n", '\n', []string{"alpha\n", "beta\n", "gamma\n"}, nil},
265 {"alpha\nbeta\ngamma", '\n', []string{"alpha\n", "beta\n", "gamma"}, io.EOF},
266 }
267
268 func TestReadBytes(t *testing.T) {
269 for _, test := range readBytesTests {
270 buf := NewBuffer([]byte(test.buffer))
271 var err error
272 for _, expected := range test.expected {
273 var bytes []byte
274 bytes, err = buf.ReadBytes(test.delim)
275 if string(bytes) != expected {
276 t.Errorf("expected %q, got %q", expected, bytes)
277 }
278 if err != nil {
279 break
280 }
281 }
282 if err != test.err {
283 t.Errorf("expected error %v, got %v", test.err, err)
284 }
285 }
286 }
287
288 func TestGrow(t *testing.T) {
289 x := []byte{'x'}
290 y := []byte{'y'}
291 tmp := make([]byte, 72)
292 for _, startLen := range []int{0, 100, 1000, 10000, 100000} {
293 xBytes := bytes.Repeat(x, startLen)
294 for _, growLen := range []int{0, 100, 1000, 10000, 100000} {
295 buf := NewBuffer(xBytes)
296
297 readBytes, _ := buf.Read(tmp)
298 buf.Grow(growLen)
299 yBytes := bytes.Repeat(y, growLen)
300
301 var m1, m2 runtime.MemStats
302 runtime.ReadMemStats(&m1)
303 if _, err := buf.Write(yBytes); err != nil {
304 t.Fatal(err)
305 }
306 runtime.ReadMemStats(&m2)
307 if runtime.GOMAXPROCS(-1) == 1 && m1.Mallocs != m2.Mallocs {
308 t.Errorf("allocation occurred during write")
309 }
310
311 if !bytes.Equal(buf.Bytes()[0:startLen-readBytes], xBytes[readBytes:]) {
312 t.Errorf("bad initial data at %d %d", startLen, growLen)
313 }
314 if !bytes.Equal(buf.Bytes()[startLen-readBytes:startLen-readBytes+growLen], yBytes) {
315 t.Errorf("bad written data at %d %d", startLen, growLen)
316 }
317 }
318 }
319 }
320
321
322 func TestReadEmptyAtEOF(t *testing.T) {
323 b := new(Buffer)
324 slice := make([]byte, 0)
325 n, err := b.Read(slice)
326 if err != nil {
327 t.Errorf("read error: %v", err)
328 }
329 if n != 0 {
330 t.Errorf("wrong count; got %d want 0", n)
331 }
332 }
333
334
335 func TestBufferGrowth(t *testing.T) {
336 var b Buffer
337 buf := make([]byte, 1024)
338 if _, err := b.Write(buf[0:1]); err != nil {
339 t.Fatal(err)
340 }
341 var cap0 int
342 for i := 0; i < 5<<10; i++ {
343 if _, err := b.Write(buf); err != nil {
344 t.Fatal(err)
345 }
346 if _, err := b.Read(buf); err != nil {
347 t.Fatal(err)
348 }
349 if i == 0 {
350 cap0 = cap(b.buf)
351 }
352 }
353 cap1 := cap(b.buf)
354
355
356 if cap1 > cap0*3 {
357 t.Errorf("buffer cap = %d; too big (grew from %d)", cap1, cap0)
358 }
359 }
360
361 func BenchmarkWriteByte(b *testing.B) {
362 const n = 4 << 10
363 b.SetBytes(n)
364 buf := NewBuffer(make([]byte, n))
365 for i := 0; i < b.N; i++ {
366 buf.Reset()
367 for i := 0; i < n; i++ {
368 if err := buf.WriteByte('x'); err != nil {
369 b.Fatal(err)
370 }
371 }
372 }
373 }
374
375 func BenchmarkAlloc(b *testing.B) {
376 const n = 4 << 10
377 b.SetBytes(n)
378 buf := NewBuffer(make([]byte, n))
379 for i := 0; i < b.N; i++ {
380 buf.Reset()
381 for i := 0; i < n; i++ {
382 buf.Alloc(1)
383 }
384 }
385 }
386
387
388 func BenchmarkBufferNotEmptyWriteRead(b *testing.B) {
389 buf := make([]byte, 1024)
390 for i := 0; i < b.N; i++ {
391 var buf2 Buffer
392 if _, err := buf2.Write(buf[0:1]); err != nil {
393 b.Fatal(err)
394 }
395 for i := 0; i < 5<<10; i++ {
396 if _, err := buf2.Write(buf); err != nil {
397 b.Fatal(err)
398 }
399 if _, err := buf2.Read(buf); err != nil {
400 b.Fatal(err)
401 }
402 }
403 }
404 }
405
406
407 func BenchmarkBufferFullSmallReads(b *testing.B) {
408 buf := make([]byte, 1024)
409 for i := 0; i < b.N; i++ {
410 var buf2 Buffer
411 if _, err := buf2.Write(buf); err != nil {
412 b.Fatal(err)
413 }
414 for buf2.Len()+20 < cap(buf2.buf) {
415 if _, err := buf2.Write(buf[:10]); err != nil {
416 b.Fatal(err)
417 }
418 }
419 for i := 0; i < 5<<10; i++ {
420 if _, err := buf2.Read(buf[:1]); err != nil {
421 b.Fatal(err)
422 }
423 if _, err := buf2.Write(buf[:1]); err != nil {
424 b.Fatal(err)
425 }
426 }
427 }
428 }
429
View as plain text