Source file
src/bytes/buffer_test.go
1
2
3
4
5 package bytes_test
6
7 import (
8 . "bytes"
9 "fmt"
10 "io"
11 "math/rand"
12 "testing"
13 "unicode/utf8"
14 )
15
16 const N = 10000
17 var testString string
18 var testBytes []byte
19
20 type negativeReader struct{}
21
22 func (r *negativeReader) Read([]byte) (int, error) { return -1, nil }
23
24 func init() {
25 testBytes = make([]byte, N)
26 for i := 0; i < N; i++ {
27 testBytes[i] = 'a' + byte(i%26)
28 }
29 testString = string(testBytes)
30 }
31
32
33 func check(t *testing.T, testname string, buf *Buffer, s string) {
34 bytes := buf.Bytes()
35 str := buf.String()
36 if buf.Len() != len(bytes) {
37 t.Errorf("%s: buf.Len() == %d, len(buf.Bytes()) == %d", testname, buf.Len(), len(bytes))
38 }
39
40 if buf.Len() != len(str) {
41 t.Errorf("%s: buf.Len() == %d, len(buf.String()) == %d", testname, buf.Len(), len(str))
42 }
43
44 if buf.Len() != len(s) {
45 t.Errorf("%s: buf.Len() == %d, len(s) == %d", testname, buf.Len(), len(s))
46 }
47
48 if string(bytes) != s {
49 t.Errorf("%s: string(buf.Bytes()) == %q, s == %q", testname, string(bytes), s)
50 }
51 }
52
53
54
55
56 func fillString(t *testing.T, testname string, buf *Buffer, s string, n int, fus string) string {
57 check(t, testname+" (fill 1)", buf, s)
58 for ; n > 0; n-- {
59 m, err := buf.WriteString(fus)
60 if m != len(fus) {
61 t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fus))
62 }
63 if err != nil {
64 t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
65 }
66 s += fus
67 check(t, testname+" (fill 4)", buf, s)
68 }
69 return s
70 }
71
72
73
74
75 func fillBytes(t *testing.T, testname string, buf *Buffer, s string, n int, fub []byte) string {
76 check(t, testname+" (fill 1)", buf, s)
77 for ; n > 0; n-- {
78 m, err := buf.Write(fub)
79 if m != len(fub) {
80 t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fub))
81 }
82 if err != nil {
83 t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
84 }
85 s += string(fub)
86 check(t, testname+" (fill 4)", buf, s)
87 }
88 return s
89 }
90
91 func TestNewBuffer(t *testing.T) {
92 buf := NewBuffer(testBytes)
93 check(t, "NewBuffer", buf, testString)
94 }
95
96 func TestNewBufferString(t *testing.T) {
97 buf := NewBufferString(testString)
98 check(t, "NewBufferString", buf, testString)
99 }
100
101
102
103 func empty(t *testing.T, testname string, buf *Buffer, s string, fub []byte) {
104 check(t, testname+" (empty 1)", buf, s)
105
106 for {
107 n, err := buf.Read(fub)
108 if n == 0 {
109 break
110 }
111 if err != nil {
112 t.Errorf(testname+" (empty 2): err should always be nil, found err == %s", err)
113 }
114 s = s[n:]
115 check(t, testname+" (empty 3)", buf, s)
116 }
117
118 check(t, testname+" (empty 4)", buf, "")
119 }
120
121 func TestBasicOperations(t *testing.T) {
122 var buf Buffer
123
124 for i := 0; i < 5; i++ {
125 check(t, "TestBasicOperations (1)", &buf, "")
126
127 buf.Reset()
128 check(t, "TestBasicOperations (2)", &buf, "")
129
130 buf.Truncate(0)
131 check(t, "TestBasicOperations (3)", &buf, "")
132
133 n, err := buf.Write(testBytes[0:1])
134 if want := 1; err != nil || n != want {
135 t.Errorf("Write: got (%d, %v), want (%d, %v)", n, err, want, nil)
136 }
137 check(t, "TestBasicOperations (4)", &buf, "a")
138
139 buf.WriteByte(testString[1])
140 check(t, "TestBasicOperations (5)", &buf, "ab")
141
142 n, err = buf.Write(testBytes[2:26])
143 if want := 24; err != nil || n != want {
144 t.Errorf("Write: got (%d, %v), want (%d, %v)", n, err, want, nil)
145 }
146 check(t, "TestBasicOperations (6)", &buf, testString[0:26])
147
148 buf.Truncate(26)
149 check(t, "TestBasicOperations (7)", &buf, testString[0:26])
150
151 buf.Truncate(20)
152 check(t, "TestBasicOperations (8)", &buf, testString[0:20])
153
154 empty(t, "TestBasicOperations (9)", &buf, testString[0:20], make([]byte, 5))
155 empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100))
156
157 buf.WriteByte(testString[1])
158 c, err := buf.ReadByte()
159 if want := testString[1]; err != nil || c != want {
160 t.Errorf("ReadByte: got (%q, %v), want (%q, %v)", c, err, want, nil)
161 }
162 c, err = buf.ReadByte()
163 if err != io.EOF {
164 t.Errorf("ReadByte: got (%q, %v), want (%q, %v)", c, err, byte(0), io.EOF)
165 }
166 }
167 }
168
169 func TestLargeStringWrites(t *testing.T) {
170 var buf Buffer
171 limit := 30
172 if testing.Short() {
173 limit = 9
174 }
175 for i := 3; i < limit; i += 3 {
176 s := fillString(t, "TestLargeWrites (1)", &buf, "", 5, testString)
177 empty(t, "TestLargeStringWrites (2)", &buf, s, make([]byte, len(testString)/i))
178 }
179 check(t, "TestLargeStringWrites (3)", &buf, "")
180 }
181
182 func TestLargeByteWrites(t *testing.T) {
183 var buf Buffer
184 limit := 30
185 if testing.Short() {
186 limit = 9
187 }
188 for i := 3; i < limit; i += 3 {
189 s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, testBytes)
190 empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(testString)/i))
191 }
192 check(t, "TestLargeByteWrites (3)", &buf, "")
193 }
194
195 func TestLargeStringReads(t *testing.T) {
196 var buf Buffer
197 for i := 3; i < 30; i += 3 {
198 s := fillString(t, "TestLargeReads (1)", &buf, "", 5, testString[0:len(testString)/i])
199 empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(testString)))
200 }
201 check(t, "TestLargeStringReads (3)", &buf, "")
202 }
203
204 func TestLargeByteReads(t *testing.T) {
205 var buf Buffer
206 for i := 3; i < 30; i += 3 {
207 s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
208 empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(testString)))
209 }
210 check(t, "TestLargeByteReads (3)", &buf, "")
211 }
212
213 func TestMixedReadsAndWrites(t *testing.T) {
214 var buf Buffer
215 s := ""
216 for i := 0; i < 50; i++ {
217 wlen := rand.Intn(len(testString))
218 if i%2 == 0 {
219 s = fillString(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testString[0:wlen])
220 } else {
221 s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testBytes[0:wlen])
222 }
223
224 rlen := rand.Intn(len(testString))
225 fub := make([]byte, rlen)
226 n, _ := buf.Read(fub)
227 s = s[n:]
228 }
229 empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()))
230 }
231
232 func TestCapWithPreallocatedSlice(t *testing.T) {
233 buf := NewBuffer(make([]byte, 10))
234 n := buf.Cap()
235 if n != 10 {
236 t.Errorf("expected 10, got %d", n)
237 }
238 }
239
240 func TestCapWithSliceAndWrittenData(t *testing.T) {
241 buf := NewBuffer(make([]byte, 0, 10))
242 buf.Write([]byte("test"))
243 n := buf.Cap()
244 if n != 10 {
245 t.Errorf("expected 10, got %d", n)
246 }
247 }
248
249 func TestNil(t *testing.T) {
250 var b *Buffer
251 if b.String() != "<nil>" {
252 t.Errorf("expected <nil>; got %q", b.String())
253 }
254 }
255
256 func TestReadFrom(t *testing.T) {
257 var buf Buffer
258 for i := 3; i < 30; i += 3 {
259 s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
260 var b Buffer
261 b.ReadFrom(&buf)
262 empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(testString)))
263 }
264 }
265
266 type panicReader struct{ panic bool }
267
268 func (r panicReader) Read(p []byte) (int, error) {
269 if r.panic {
270 panic(nil)
271 }
272 return 0, io.EOF
273 }
274
275
276
277 func TestReadFromPanicReader(t *testing.T) {
278
279
280 var buf Buffer
281 i, err := buf.ReadFrom(panicReader{})
282 if err != nil {
283 t.Fatal(err)
284 }
285 if i != 0 {
286 t.Fatalf("unexpected return from bytes.ReadFrom (1): got: %d, want %d", i, 0)
287 }
288 check(t, "TestReadFromPanicReader (1)", &buf, "")
289
290
291 var buf2 Buffer
292 defer func() {
293 recover()
294 check(t, "TestReadFromPanicReader (2)", &buf2, "")
295 }()
296 buf2.ReadFrom(panicReader{panic: true})
297 }
298
299 func TestReadFromNegativeReader(t *testing.T) {
300 var b Buffer
301 defer func() {
302 switch err := recover().(type) {
303 case nil:
304 t.Fatal("bytes.Buffer.ReadFrom didn't panic")
305 case error:
306
307 wantError := "bytes.Buffer: reader returned negative count from Read"
308 if err.Error() != wantError {
309 t.Fatalf("recovered panic: got %v, want %v", err.Error(), wantError)
310 }
311 default:
312 t.Fatalf("unexpected panic value: %#v", err)
313 }
314 }()
315
316 b.ReadFrom(new(negativeReader))
317 }
318
319 func TestWriteTo(t *testing.T) {
320 var buf Buffer
321 for i := 3; i < 30; i += 3 {
322 s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
323 var b Buffer
324 buf.WriteTo(&b)
325 empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(testString)))
326 }
327 }
328
329 func TestRuneIO(t *testing.T) {
330 const NRune = 1000
331
332 b := make([]byte, utf8.UTFMax*NRune)
333 var buf Buffer
334 n := 0
335 for r := rune(0); r < NRune; r++ {
336 size := utf8.EncodeRune(b[n:], r)
337 nbytes, err := buf.WriteRune(r)
338 if err != nil {
339 t.Fatalf("WriteRune(%U) error: %s", r, err)
340 }
341 if nbytes != size {
342 t.Fatalf("WriteRune(%U) expected %d, got %d", r, size, nbytes)
343 }
344 n += size
345 }
346 b = b[0:n]
347
348
349 if !Equal(buf.Bytes(), b) {
350 t.Fatalf("incorrect result from WriteRune: %q not %q", buf.Bytes(), b)
351 }
352
353 p := make([]byte, utf8.UTFMax)
354
355 for r := rune(0); r < NRune; r++ {
356 size := utf8.EncodeRune(p, r)
357 nr, nbytes, err := buf.ReadRune()
358 if nr != r || nbytes != size || err != nil {
359 t.Fatalf("ReadRune(%U) got %U,%d not %U,%d (err=%s)", r, nr, nbytes, r, size, err)
360 }
361 }
362
363
364 buf.Reset()
365
366
367 if err := buf.UnreadRune(); err == nil {
368 t.Fatal("UnreadRune at EOF: got no error")
369 }
370 if _, _, err := buf.ReadRune(); err == nil {
371 t.Fatal("ReadRune at EOF: got no error")
372 }
373 if err := buf.UnreadRune(); err == nil {
374 t.Fatal("UnreadRune after ReadRune at EOF: got no error")
375 }
376
377
378 buf.Write(b)
379 for r := rune(0); r < NRune; r++ {
380 r1, size, _ := buf.ReadRune()
381 if err := buf.UnreadRune(); err != nil {
382 t.Fatalf("UnreadRune(%U) got error %q", r, err)
383 }
384 r2, nbytes, err := buf.ReadRune()
385 if r1 != r2 || r1 != r || nbytes != size || err != nil {
386 t.Fatalf("ReadRune(%U) after UnreadRune got %U,%d not %U,%d (err=%s)", r, r2, nbytes, r, size, err)
387 }
388 }
389 }
390
391 func TestWriteInvalidRune(t *testing.T) {
392
393
394 for _, r := range []rune{-1, utf8.MaxRune + 1} {
395 var buf Buffer
396 buf.WriteRune(r)
397 check(t, fmt.Sprintf("TestWriteInvalidRune (%d)", r), &buf, "\uFFFD")
398 }
399 }
400
401 func TestNext(t *testing.T) {
402 b := []byte{0, 1, 2, 3, 4}
403 tmp := make([]byte, 5)
404 for i := 0; i <= 5; i++ {
405 for j := i; j <= 5; j++ {
406 for k := 0; k <= 6; k++ {
407
408
409
410
411 buf := NewBuffer(b[0:j])
412 n, _ := buf.Read(tmp[0:i])
413 if n != i {
414 t.Fatalf("Read %d returned %d", i, n)
415 }
416 bb := buf.Next(k)
417 want := k
418 if want > j-i {
419 want = j - i
420 }
421 if len(bb) != want {
422 t.Fatalf("in %d,%d: len(Next(%d)) == %d", i, j, k, len(bb))
423 }
424 for l, v := range bb {
425 if v != byte(l+i) {
426 t.Fatalf("in %d,%d: Next(%d)[%d] = %d, want %d", i, j, k, l, v, l+i)
427 }
428 }
429 }
430 }
431 }
432 }
433
434 var readBytesTests = []struct {
435 buffer string
436 delim byte
437 expected []string
438 err error
439 }{
440 {"", 0, []string{""}, io.EOF},
441 {"a\x00", 0, []string{"a\x00"}, nil},
442 {"abbbaaaba", 'b', []string{"ab", "b", "b", "aaab"}, nil},
443 {"hello\x01world", 1, []string{"hello\x01"}, nil},
444 {"foo\nbar", 0, []string{"foo\nbar"}, io.EOF},
445 {"alpha\nbeta\ngamma\n", '\n', []string{"alpha\n", "beta\n", "gamma\n"}, nil},
446 {"alpha\nbeta\ngamma", '\n', []string{"alpha\n", "beta\n", "gamma"}, io.EOF},
447 }
448
449 func TestReadBytes(t *testing.T) {
450 for _, test := range readBytesTests {
451 buf := NewBufferString(test.buffer)
452 var err error
453 for _, expected := range test.expected {
454 var bytes []byte
455 bytes, err = buf.ReadBytes(test.delim)
456 if string(bytes) != expected {
457 t.Errorf("expected %q, got %q", expected, bytes)
458 }
459 if err != nil {
460 break
461 }
462 }
463 if err != test.err {
464 t.Errorf("expected error %v, got %v", test.err, err)
465 }
466 }
467 }
468
469 func TestReadString(t *testing.T) {
470 for _, test := range readBytesTests {
471 buf := NewBufferString(test.buffer)
472 var err error
473 for _, expected := range test.expected {
474 var s string
475 s, err = buf.ReadString(test.delim)
476 if s != expected {
477 t.Errorf("expected %q, got %q", expected, s)
478 }
479 if err != nil {
480 break
481 }
482 }
483 if err != test.err {
484 t.Errorf("expected error %v, got %v", test.err, err)
485 }
486 }
487 }
488
489 func BenchmarkReadString(b *testing.B) {
490 const n = 32 << 10
491
492 data := make([]byte, n)
493 data[n-1] = 'x'
494 b.SetBytes(int64(n))
495 for i := 0; i < b.N; i++ {
496 buf := NewBuffer(data)
497 _, err := buf.ReadString('x')
498 if err != nil {
499 b.Fatal(err)
500 }
501 }
502 }
503
504 func TestGrow(t *testing.T) {
505 x := []byte{'x'}
506 y := []byte{'y'}
507 tmp := make([]byte, 72)
508 for _, growLen := range []int{0, 100, 1000, 10000, 100000} {
509 for _, startLen := range []int{0, 100, 1000, 10000, 100000} {
510 xBytes := Repeat(x, startLen)
511
512 buf := NewBuffer(xBytes)
513
514 readBytes, _ := buf.Read(tmp)
515 yBytes := Repeat(y, growLen)
516 allocs := testing.AllocsPerRun(100, func() {
517 buf.Grow(growLen)
518 buf.Write(yBytes)
519 })
520
521 if allocs != 0 {
522 t.Errorf("allocation occurred during write")
523 }
524
525 if !Equal(buf.Bytes()[0:startLen-readBytes], xBytes[readBytes:]) {
526 t.Errorf("bad initial data at %d %d", startLen, growLen)
527 }
528 if !Equal(buf.Bytes()[startLen-readBytes:startLen-readBytes+growLen], yBytes) {
529 t.Errorf("bad written data at %d %d", startLen, growLen)
530 }
531 }
532 }
533 }
534
535 func TestGrowOverflow(t *testing.T) {
536 defer func() {
537 if err := recover(); err != ErrTooLarge {
538 t.Errorf("after too-large Grow, recover() = %v; want %v", err, ErrTooLarge)
539 }
540 }()
541
542 buf := NewBuffer(make([]byte, 1))
543 const maxInt = int(^uint(0) >> 1)
544 buf.Grow(maxInt)
545 }
546
547
548 func TestReadEmptyAtEOF(t *testing.T) {
549 b := new(Buffer)
550 slice := make([]byte, 0)
551 n, err := b.Read(slice)
552 if err != nil {
553 t.Errorf("read error: %v", err)
554 }
555 if n != 0 {
556 t.Errorf("wrong count; got %d want 0", n)
557 }
558 }
559
560 func TestUnreadByte(t *testing.T) {
561 b := new(Buffer)
562
563
564 if err := b.UnreadByte(); err == nil {
565 t.Fatal("UnreadByte at EOF: got no error")
566 }
567 if _, err := b.ReadByte(); err == nil {
568 t.Fatal("ReadByte at EOF: got no error")
569 }
570 if err := b.UnreadByte(); err == nil {
571 t.Fatal("UnreadByte after ReadByte at EOF: got no error")
572 }
573
574
575 b.WriteString("abcdefghijklmnopqrstuvwxyz")
576
577
578 if n, err := b.Read(nil); n != 0 || err != nil {
579 t.Fatalf("Read(nil) = %d,%v; want 0,nil", n, err)
580 }
581 if err := b.UnreadByte(); err == nil {
582 t.Fatal("UnreadByte after Read(nil): got no error")
583 }
584
585
586 if _, err := b.ReadBytes('m'); err != nil {
587 t.Fatalf("ReadBytes: %v", err)
588 }
589 if err := b.UnreadByte(); err != nil {
590 t.Fatalf("UnreadByte: %v", err)
591 }
592 c, err := b.ReadByte()
593 if err != nil {
594 t.Fatalf("ReadByte: %v", err)
595 }
596 if c != 'm' {
597 t.Errorf("ReadByte = %q; want %q", c, 'm')
598 }
599 }
600
601
602 func TestBufferGrowth(t *testing.T) {
603 var b Buffer
604 buf := make([]byte, 1024)
605 b.Write(buf[0:1])
606 var cap0 int
607 for i := 0; i < 5<<10; i++ {
608 b.Write(buf)
609 b.Read(buf)
610 if i == 0 {
611 cap0 = b.Cap()
612 }
613 }
614 cap1 := b.Cap()
615
616
617 if cap1 > cap0*3 {
618 t.Errorf("buffer cap = %d; too big (grew from %d)", cap1, cap0)
619 }
620 }
621
622 func BenchmarkWriteByte(b *testing.B) {
623 const n = 4 << 10
624 b.SetBytes(n)
625 buf := NewBuffer(make([]byte, n))
626 for i := 0; i < b.N; i++ {
627 buf.Reset()
628 for i := 0; i < n; i++ {
629 buf.WriteByte('x')
630 }
631 }
632 }
633
634 func BenchmarkWriteRune(b *testing.B) {
635 const n = 4 << 10
636 const r = '☺'
637 b.SetBytes(int64(n * utf8.RuneLen(r)))
638 buf := NewBuffer(make([]byte, n*utf8.UTFMax))
639 for i := 0; i < b.N; i++ {
640 buf.Reset()
641 for i := 0; i < n; i++ {
642 buf.WriteRune(r)
643 }
644 }
645 }
646
647
648 func BenchmarkBufferNotEmptyWriteRead(b *testing.B) {
649 buf := make([]byte, 1024)
650 for i := 0; i < b.N; i++ {
651 var b Buffer
652 b.Write(buf[0:1])
653 for i := 0; i < 5<<10; i++ {
654 b.Write(buf)
655 b.Read(buf)
656 }
657 }
658 }
659
660
661 func BenchmarkBufferFullSmallReads(b *testing.B) {
662 buf := make([]byte, 1024)
663 for i := 0; i < b.N; i++ {
664 var b Buffer
665 b.Write(buf)
666 for b.Len()+20 < b.Cap() {
667 b.Write(buf[:10])
668 }
669 for i := 0; i < 5<<10; i++ {
670 b.Read(buf[:1])
671 b.Write(buf[:1])
672 }
673 }
674 }
675
View as plain text