1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
17 const N = 10000 // make this bigger for a larger (and slower) test
18 var testString string // test data for write tests
19 var testBytes []byte // test data; same as testString but as a slice.
21 type negativeReader struct{}
23 func (r *negativeReader) Read([]byte) (int, error) { return -1, nil }
26 testBytes = make([]byte, N)
27 for i := 0; i < N; i++ {
28 testBytes[i] = 'a' + byte(i%26)
30 testString = string(testBytes)
33 // Verify that contents of buf match the string s.
34 func check(t *testing.T, testname string, buf *Buffer, s string) {
37 if buf.Len() != len(bytes) {
38 t.Errorf("%s: buf.Len() == %d, len(buf.Bytes()) == %d", testname, buf.Len(), len(bytes))
41 if buf.Len() != len(str) {
42 t.Errorf("%s: buf.Len() == %d, len(buf.String()) == %d", testname, buf.Len(), len(str))
45 if buf.Len() != len(s) {
46 t.Errorf("%s: buf.Len() == %d, len(s) == %d", testname, buf.Len(), len(s))
49 if string(bytes) != s {
50 t.Errorf("%s: string(buf.Bytes()) == %q, s == %q", testname, string(bytes), s)
54 // Fill buf through n writes of string fus.
55 // The initial contents of buf corresponds to the string s;
56 // the result is the final contents of buf returned as a string.
57 func fillString(t *testing.T, testname string, buf *Buffer, s string, n int, fus string) string {
58 check(t, testname+" (fill 1)", buf, s)
60 m, err := buf.WriteString(fus)
62 t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fus))
65 t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
68 check(t, testname+" (fill 4)", buf, s)
73 // Fill buf through n writes of byte slice fub.
74 // The initial contents of buf corresponds to the string s;
75 // the result is the final contents of buf returned as a string.
76 func fillBytes(t *testing.T, testname string, buf *Buffer, s string, n int, fub []byte) string {
77 check(t, testname+" (fill 1)", buf, s)
79 m, err := buf.Write(fub)
81 t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fub))
84 t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
87 check(t, testname+" (fill 4)", buf, s)
92 func TestNewBuffer(t *testing.T) {
93 buf := NewBuffer(testBytes)
94 check(t, "NewBuffer", buf, testString)
97 func TestNewBufferString(t *testing.T) {
98 buf := NewBufferString(testString)
99 check(t, "NewBufferString", buf, testString)
102 // Empty buf through repeated reads into fub.
103 // The initial contents of buf corresponds to the string s.
104 func empty(t *testing.T, testname string, buf *Buffer, s string, fub []byte) {
105 check(t, testname+" (empty 1)", buf, s)
108 n, err := buf.Read(fub)
113 t.Errorf(testname+" (empty 2): err should always be nil, found err == %s", err)
116 check(t, testname+" (empty 3)", buf, s)
119 check(t, testname+" (empty 4)", buf, "")
122 func TestBasicOperations(t *testing.T) {
125 for i := 0; i < 5; i++ {
126 check(t, "TestBasicOperations (1)", &buf, "")
129 check(t, "TestBasicOperations (2)", &buf, "")
132 check(t, "TestBasicOperations (3)", &buf, "")
134 n, err := buf.Write(testBytes[0:1])
135 if want := 1; err != nil || n != want {
136 t.Errorf("Write: got (%d, %v), want (%d, %v)", n, err, want, nil)
138 check(t, "TestBasicOperations (4)", &buf, "a")
140 buf.WriteByte(testString[1])
141 check(t, "TestBasicOperations (5)", &buf, "ab")
143 n, err = buf.Write(testBytes[2:26])
144 if want := 24; err != nil || n != want {
145 t.Errorf("Write: got (%d, %v), want (%d, %v)", n, err, want, nil)
147 check(t, "TestBasicOperations (6)", &buf, testString[0:26])
150 check(t, "TestBasicOperations (7)", &buf, testString[0:26])
153 check(t, "TestBasicOperations (8)", &buf, testString[0:20])
155 empty(t, "TestBasicOperations (9)", &buf, testString[0:20], make([]byte, 5))
156 empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100))
158 buf.WriteByte(testString[1])
159 c, err := buf.ReadByte()
160 if want := testString[1]; err != nil || c != want {
161 t.Errorf("ReadByte: got (%q, %v), want (%q, %v)", c, err, want, nil)
163 c, err = buf.ReadByte()
165 t.Errorf("ReadByte: got (%q, %v), want (%q, %v)", c, err, byte(0), io.EOF)
170 func TestLargeStringWrites(t *testing.T) {
176 for i := 3; i < limit; i += 3 {
177 s := fillString(t, "TestLargeWrites (1)", &buf, "", 5, testString)
178 empty(t, "TestLargeStringWrites (2)", &buf, s, make([]byte, len(testString)/i))
180 check(t, "TestLargeStringWrites (3)", &buf, "")
183 func TestLargeByteWrites(t *testing.T) {
189 for i := 3; i < limit; i += 3 {
190 s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, testBytes)
191 empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(testString)/i))
193 check(t, "TestLargeByteWrites (3)", &buf, "")
196 func TestLargeStringReads(t *testing.T) {
198 for i := 3; i < 30; i += 3 {
199 s := fillString(t, "TestLargeReads (1)", &buf, "", 5, testString[0:len(testString)/i])
200 empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(testString)))
202 check(t, "TestLargeStringReads (3)", &buf, "")
205 func TestLargeByteReads(t *testing.T) {
207 for i := 3; i < 30; i += 3 {
208 s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
209 empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(testString)))
211 check(t, "TestLargeByteReads (3)", &buf, "")
214 func TestMixedReadsAndWrites(t *testing.T) {
217 for i := 0; i < 50; i++ {
218 wlen := rand.Intn(len(testString))
220 s = fillString(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testString[0:wlen])
222 s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testBytes[0:wlen])
225 rlen := rand.Intn(len(testString))
226 fub := make([]byte, rlen)
227 n, _ := buf.Read(fub)
230 empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()))
233 func TestCapWithPreallocatedSlice(t *testing.T) {
234 buf := NewBuffer(make([]byte, 10))
237 t.Errorf("expected 10, got %d", n)
241 func TestCapWithSliceAndWrittenData(t *testing.T) {
242 buf := NewBuffer(make([]byte, 0, 10))
243 buf.Write([]byte("test"))
246 t.Errorf("expected 10, got %d", n)
250 func TestNil(t *testing.T) {
252 if b.String() != "<nil>" {
253 t.Errorf("expected <nil>; got %q", b.String())
257 func TestReadFrom(t *testing.T) {
259 for i := 3; i < 30; i += 3 {
260 s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
263 empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(testString)))
267 type panicReader struct{ panic bool }
269 func (r panicReader) Read(p []byte) (int, error) {
276 // Make sure that an empty Buffer remains empty when
277 // it is "grown" before a Read that panics
278 func TestReadFromPanicReader(t *testing.T) {
280 // First verify non-panic behaviour
282 i, err := buf.ReadFrom(panicReader{})
287 t.Fatalf("unexpected return from bytes.ReadFrom (1): got: %d, want %d", i, 0)
289 check(t, "TestReadFromPanicReader (1)", &buf, "")
291 // Confirm that when Reader panics, the empty buffer remains empty
295 check(t, "TestReadFromPanicReader (2)", &buf2, "")
297 buf2.ReadFrom(panicReader{panic: true})
300 func TestReadFromNegativeReader(t *testing.T) {
303 switch err := recover().(type) {
305 t.Fatal("bytes.Buffer.ReadFrom didn't panic")
307 // this is the error string of errNegativeRead
308 wantError := "bytes.Buffer: reader returned negative count from Read"
309 if err.Error() != wantError {
310 t.Fatalf("recovered panic: got %v, want %v", err.Error(), wantError)
313 t.Fatalf("unexpected panic value: %#v", err)
317 b.ReadFrom(new(negativeReader))
320 func TestWriteTo(t *testing.T) {
322 for i := 3; i < 30; i += 3 {
323 s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
326 empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(testString)))
330 func TestWriteAppend(t *testing.T) {
333 for i := 0; i < 1000; i++ {
334 b := got.AvailableBuffer()
335 b = strconv.AppendInt(b, int64(i), 10)
336 want = strconv.AppendInt(want, int64(i), 10)
339 if !Equal(got.Bytes(), want) {
340 t.Fatalf("Bytes() = %q, want %q", got, want)
343 // With a sufficiently sized buffer, there should be no allocations.
344 n := testing.AllocsPerRun(100, func() {
346 for i := 0; i < 1000; i++ {
347 b := got.AvailableBuffer()
348 b = strconv.AppendInt(b, int64(i), 10)
353 t.Errorf("allocations occurred while appending")
357 func TestRuneIO(t *testing.T) {
359 // Built a test slice while we write the data
360 b := make([]byte, utf8.UTFMax*NRune)
363 for r := rune(0); r < NRune; r++ {
364 size := utf8.EncodeRune(b[n:], r)
365 nbytes, err := buf.WriteRune(r)
367 t.Fatalf("WriteRune(%U) error: %s", r, err)
370 t.Fatalf("WriteRune(%U) expected %d, got %d", r, size, nbytes)
376 // Check the resulting bytes
377 if !Equal(buf.Bytes(), b) {
378 t.Fatalf("incorrect result from WriteRune: %q not %q", buf.Bytes(), b)
381 p := make([]byte, utf8.UTFMax)
382 // Read it back with ReadRune
383 for r := rune(0); r < NRune; r++ {
384 size := utf8.EncodeRune(p, r)
385 nr, nbytes, err := buf.ReadRune()
386 if nr != r || nbytes != size || err != nil {
387 t.Fatalf("ReadRune(%U) got %U,%d not %U,%d (err=%s)", r, nr, nbytes, r, size, err)
391 // Check that UnreadRune works
395 if err := buf.UnreadRune(); err == nil {
396 t.Fatal("UnreadRune at EOF: got no error")
398 if _, _, err := buf.ReadRune(); err == nil {
399 t.Fatal("ReadRune at EOF: got no error")
401 if err := buf.UnreadRune(); err == nil {
402 t.Fatal("UnreadRune after ReadRune at EOF: got no error")
407 for r := rune(0); r < NRune; r++ {
408 r1, size, _ := buf.ReadRune()
409 if err := buf.UnreadRune(); err != nil {
410 t.Fatalf("UnreadRune(%U) got error %q", r, err)
412 r2, nbytes, err := buf.ReadRune()
413 if r1 != r2 || r1 != r || nbytes != size || err != nil {
414 t.Fatalf("ReadRune(%U) after UnreadRune got %U,%d not %U,%d (err=%s)", r, r2, nbytes, r, size, err)
419 func TestWriteInvalidRune(t *testing.T) {
420 // Invalid runes, including negative ones, should be written as
422 for _, r := range []rune{-1, utf8.MaxRune + 1} {
425 check(t, fmt.Sprintf("TestWriteInvalidRune (%d)", r), &buf, "\uFFFD")
429 func TestNext(t *testing.T) {
430 b := []byte{0, 1, 2, 3, 4}
431 tmp := make([]byte, 5)
432 for i := 0; i <= 5; i++ {
433 for j := i; j <= 5; j++ {
434 for k := 0; k <= 6; k++ {
435 // 0 <= i <= j <= 5; 0 <= k <= 6
436 // Check that if we start with a buffer
437 // of length j at offset i and ask for
438 // Next(k), we get the right bytes.
439 buf := NewBuffer(b[0:j])
440 n, _ := buf.Read(tmp[0:i])
442 t.Fatalf("Read %d returned %d", i, n)
450 t.Fatalf("in %d,%d: len(Next(%d)) == %d", i, j, k, len(bb))
452 for l, v := range bb {
454 t.Fatalf("in %d,%d: Next(%d)[%d] = %d, want %d", i, j, k, l, v, l+i)
462 var readBytesTests = []struct {
468 {"", 0, []string{""}, io.EOF},
469 {"a\x00", 0, []string{"a\x00"}, nil},
470 {"abbbaaaba", 'b', []string{"ab", "b", "b", "aaab"}, nil},
471 {"hello\x01world", 1, []string{"hello\x01"}, nil},
472 {"foo\nbar", 0, []string{"foo\nbar"}, io.EOF},
473 {"alpha\nbeta\ngamma\n", '\n', []string{"alpha\n", "beta\n", "gamma\n"}, nil},
474 {"alpha\nbeta\ngamma", '\n', []string{"alpha\n", "beta\n", "gamma"}, io.EOF},
477 func TestReadBytes(t *testing.T) {
478 for _, test := range readBytesTests {
479 buf := NewBufferString(test.buffer)
481 for _, expected := range test.expected {
483 bytes, err = buf.ReadBytes(test.delim)
484 if string(bytes) != expected {
485 t.Errorf("expected %q, got %q", expected, bytes)
492 t.Errorf("expected error %v, got %v", test.err, err)
497 func TestReadString(t *testing.T) {
498 for _, test := range readBytesTests {
499 buf := NewBufferString(test.buffer)
501 for _, expected := range test.expected {
503 s, err = buf.ReadString(test.delim)
505 t.Errorf("expected %q, got %q", expected, s)
512 t.Errorf("expected error %v, got %v", test.err, err)
517 func BenchmarkReadString(b *testing.B) {
520 data := make([]byte, n)
523 for i := 0; i < b.N; i++ {
524 buf := NewBuffer(data)
525 _, err := buf.ReadString('x')
532 func TestGrow(t *testing.T) {
535 tmp := make([]byte, 72)
536 for _, growLen := range []int{0, 100, 1000, 10000, 100000} {
537 for _, startLen := range []int{0, 100, 1000, 10000, 100000} {
538 xBytes := Repeat(x, startLen)
540 buf := NewBuffer(xBytes)
541 // If we read, this affects buf.off, which is good to test.
542 readBytes, _ := buf.Read(tmp)
543 yBytes := Repeat(y, growLen)
544 allocs := testing.AllocsPerRun(100, func() {
548 // Check no allocation occurs in write, as long as we're single-threaded.
550 t.Errorf("allocation occurred during write")
552 // Check that buffer has correct data.
553 if !Equal(buf.Bytes()[0:startLen-readBytes], xBytes[readBytes:]) {
554 t.Errorf("bad initial data at %d %d", startLen, growLen)
556 if !Equal(buf.Bytes()[startLen-readBytes:startLen-readBytes+growLen], yBytes) {
557 t.Errorf("bad written data at %d %d", startLen, growLen)
563 func TestGrowOverflow(t *testing.T) {
565 if err := recover(); err != ErrTooLarge {
566 t.Errorf("after too-large Grow, recover() = %v; want %v", err, ErrTooLarge)
570 buf := NewBuffer(make([]byte, 1))
571 const maxInt = int(^uint(0) >> 1)
575 // Was a bug: used to give EOF reading empty slice at EOF.
576 func TestReadEmptyAtEOF(t *testing.T) {
578 slice := make([]byte, 0)
579 n, err := b.Read(slice)
581 t.Errorf("read error: %v", err)
584 t.Errorf("wrong count; got %d want 0", n)
588 func TestUnreadByte(t *testing.T) {
592 if err := b.UnreadByte(); err == nil {
593 t.Fatal("UnreadByte at EOF: got no error")
595 if _, err := b.ReadByte(); err == nil {
596 t.Fatal("ReadByte at EOF: got no error")
598 if err := b.UnreadByte(); err == nil {
599 t.Fatal("UnreadByte after ReadByte at EOF: got no error")
603 b.WriteString("abcdefghijklmnopqrstuvwxyz")
605 // after unsuccessful read
606 if n, err := b.Read(nil); n != 0 || err != nil {
607 t.Fatalf("Read(nil) = %d,%v; want 0,nil", n, err)
609 if err := b.UnreadByte(); err == nil {
610 t.Fatal("UnreadByte after Read(nil): got no error")
613 // after successful read
614 if _, err := b.ReadBytes('m'); err != nil {
615 t.Fatalf("ReadBytes: %v", err)
617 if err := b.UnreadByte(); err != nil {
618 t.Fatalf("UnreadByte: %v", err)
620 c, err := b.ReadByte()
622 t.Fatalf("ReadByte: %v", err)
625 t.Errorf("ReadByte = %q; want %q", c, 'm')
629 // Tests that we occasionally compact. Issue 5154.
630 func TestBufferGrowth(t *testing.T) {
632 buf := make([]byte, 1024)
635 for i := 0; i < 5<<10; i++ {
643 // (*Buffer).grow allows for 2x capacity slop before sliding,
644 // so set our error threshold at 3x.
646 t.Errorf("buffer cap = %d; too big (grew from %d)", cap1, cap0)
650 func BenchmarkWriteByte(b *testing.B) {
653 buf := NewBuffer(make([]byte, n))
654 for i := 0; i < b.N; i++ {
656 for i := 0; i < n; i++ {
662 func BenchmarkWriteRune(b *testing.B) {
665 b.SetBytes(int64(n * utf8.RuneLen(r)))
666 buf := NewBuffer(make([]byte, n*utf8.UTFMax))
667 for i := 0; i < b.N; i++ {
669 for i := 0; i < n; i++ {
676 func BenchmarkBufferNotEmptyWriteRead(b *testing.B) {
677 buf := make([]byte, 1024)
678 for i := 0; i < b.N; i++ {
681 for i := 0; i < 5<<10; i++ {
688 // Check that we don't compact too often. From Issue 5154.
689 func BenchmarkBufferFullSmallReads(b *testing.B) {
690 buf := make([]byte, 1024)
691 for i := 0; i < b.N; i++ {
694 for b.Len()+20 < b.Cap() {
697 for i := 0; i < 5<<10; i++ {
704 func BenchmarkBufferWriteBlock(b *testing.B) {
705 block := make([]byte, 1024)
706 for _, n := range []int{1 << 12, 1 << 16, 1 << 20} {
707 b.Run(fmt.Sprintf("N%d", n), func(b *testing.B) {
709 for i := 0; i < b.N; i++ {
719 func BenchmarkBufferAppendNoCopy(b *testing.B) {
722 b.SetBytes(int64(bb.Available()))
724 for i := 0; i < b.N; i++ {
726 b := bb.AvailableBuffer()
727 b = b[:cap(b)] // use max capacity to simulate a large append operation
728 bb.Write(b) // should be nearly infinitely fast