Home | History | Annotate | Download | only in bytes
      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.
      4 
      5 package bytes_test
      6 
      7 import (
      8 	. "bytes"
      9 	"io"
     10 	"math/rand"
     11 	"runtime"
     12 	"testing"
     13 	"unicode/utf8"
     14 )
     15 
     16 const N = 10000      // make this bigger for a larger (and slower) test
     17 var data string      // test data for write tests
     18 var testBytes []byte // test data; same as data but as a slice.
     19 
     20 func init() {
     21 	testBytes = make([]byte, N)
     22 	for i := 0; i < N; i++ {
     23 		testBytes[i] = 'a' + byte(i%26)
     24 	}
     25 	data = string(testBytes)
     26 }
     27 
     28 // Verify that contents of buf match the string s.
     29 func check(t *testing.T, testname string, buf *Buffer, s string) {
     30 	bytes := buf.Bytes()
     31 	str := buf.String()
     32 	if buf.Len() != len(bytes) {
     33 		t.Errorf("%s: buf.Len() == %d, len(buf.Bytes()) == %d", testname, buf.Len(), len(bytes))
     34 	}
     35 
     36 	if buf.Len() != len(str) {
     37 		t.Errorf("%s: buf.Len() == %d, len(buf.String()) == %d", testname, buf.Len(), len(str))
     38 	}
     39 
     40 	if buf.Len() != len(s) {
     41 		t.Errorf("%s: buf.Len() == %d, len(s) == %d", testname, buf.Len(), len(s))
     42 	}
     43 
     44 	if string(bytes) != s {
     45 		t.Errorf("%s: string(buf.Bytes()) == %q, s == %q", testname, string(bytes), s)
     46 	}
     47 }
     48 
     49 // Fill buf through n writes of string fus.
     50 // The initial contents of buf corresponds to the string s;
     51 // the result is the final contents of buf returned as a string.
     52 func fillString(t *testing.T, testname string, buf *Buffer, s string, n int, fus string) string {
     53 	check(t, testname+" (fill 1)", buf, s)
     54 	for ; n > 0; n-- {
     55 		m, err := buf.WriteString(fus)
     56 		if m != len(fus) {
     57 			t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fus))
     58 		}
     59 		if err != nil {
     60 			t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
     61 		}
     62 		s += fus
     63 		check(t, testname+" (fill 4)", buf, s)
     64 	}
     65 	return s
     66 }
     67 
     68 // Fill buf through n writes of byte slice fub.
     69 // The initial contents of buf corresponds to the string s;
     70 // the result is the final contents of buf returned as a string.
     71 func fillBytes(t *testing.T, testname string, buf *Buffer, s string, n int, fub []byte) string {
     72 	check(t, testname+" (fill 1)", buf, s)
     73 	for ; n > 0; n-- {
     74 		m, err := buf.Write(fub)
     75 		if m != len(fub) {
     76 			t.Errorf(testname+" (fill 2): m == %d, expected %d", m, len(fub))
     77 		}
     78 		if err != nil {
     79 			t.Errorf(testname+" (fill 3): err should always be nil, found err == %s", err)
     80 		}
     81 		s += string(fub)
     82 		check(t, testname+" (fill 4)", buf, s)
     83 	}
     84 	return s
     85 }
     86 
     87 func TestNewBuffer(t *testing.T) {
     88 	buf := NewBuffer(testBytes)
     89 	check(t, "NewBuffer", buf, data)
     90 }
     91 
     92 func TestNewBufferString(t *testing.T) {
     93 	buf := NewBufferString(data)
     94 	check(t, "NewBufferString", buf, data)
     95 }
     96 
     97 // Empty buf through repeated reads into fub.
     98 // The initial contents of buf corresponds to the string s.
     99 func empty(t *testing.T, testname string, buf *Buffer, s string, fub []byte) {
    100 	check(t, testname+" (empty 1)", buf, s)
    101 
    102 	for {
    103 		n, err := buf.Read(fub)
    104 		if n == 0 {
    105 			break
    106 		}
    107 		if err != nil {
    108 			t.Errorf(testname+" (empty 2): err should always be nil, found err == %s", err)
    109 		}
    110 		s = s[n:]
    111 		check(t, testname+" (empty 3)", buf, s)
    112 	}
    113 
    114 	check(t, testname+" (empty 4)", buf, "")
    115 }
    116 
    117 func TestBasicOperations(t *testing.T) {
    118 	var buf Buffer
    119 
    120 	for i := 0; i < 5; i++ {
    121 		check(t, "TestBasicOperations (1)", &buf, "")
    122 
    123 		buf.Reset()
    124 		check(t, "TestBasicOperations (2)", &buf, "")
    125 
    126 		buf.Truncate(0)
    127 		check(t, "TestBasicOperations (3)", &buf, "")
    128 
    129 		n, err := buf.Write([]byte(data[0:1]))
    130 		if n != 1 {
    131 			t.Errorf("wrote 1 byte, but n == %d", n)
    132 		}
    133 		if err != nil {
    134 			t.Errorf("err should always be nil, but err == %s", err)
    135 		}
    136 		check(t, "TestBasicOperations (4)", &buf, "a")
    137 
    138 		buf.WriteByte(data[1])
    139 		check(t, "TestBasicOperations (5)", &buf, "ab")
    140 
    141 		n, err = buf.Write([]byte(data[2:26]))
    142 		if n != 24 {
    143 			t.Errorf("wrote 25 bytes, but n == %d", n)
    144 		}
    145 		check(t, "TestBasicOperations (6)", &buf, string(data[0:26]))
    146 
    147 		buf.Truncate(26)
    148 		check(t, "TestBasicOperations (7)", &buf, string(data[0:26]))
    149 
    150 		buf.Truncate(20)
    151 		check(t, "TestBasicOperations (8)", &buf, string(data[0:20]))
    152 
    153 		empty(t, "TestBasicOperations (9)", &buf, string(data[0:20]), make([]byte, 5))
    154 		empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100))
    155 
    156 		buf.WriteByte(data[1])
    157 		c, err := buf.ReadByte()
    158 		if err != nil {
    159 			t.Error("ReadByte unexpected eof")
    160 		}
    161 		if c != data[1] {
    162 			t.Errorf("ReadByte wrong value c=%v", c)
    163 		}
    164 		c, err = buf.ReadByte()
    165 		if err == nil {
    166 			t.Error("ReadByte unexpected not eof")
    167 		}
    168 	}
    169 }
    170 
    171 func TestLargeStringWrites(t *testing.T) {
    172 	var buf Buffer
    173 	limit := 30
    174 	if testing.Short() {
    175 		limit = 9
    176 	}
    177 	for i := 3; i < limit; i += 3 {
    178 		s := fillString(t, "TestLargeWrites (1)", &buf, "", 5, data)
    179 		empty(t, "TestLargeStringWrites (2)", &buf, s, make([]byte, len(data)/i))
    180 	}
    181 	check(t, "TestLargeStringWrites (3)", &buf, "")
    182 }
    183 
    184 func TestLargeByteWrites(t *testing.T) {
    185 	var buf Buffer
    186 	limit := 30
    187 	if testing.Short() {
    188 		limit = 9
    189 	}
    190 	for i := 3; i < limit; i += 3 {
    191 		s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, testBytes)
    192 		empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(data)/i))
    193 	}
    194 	check(t, "TestLargeByteWrites (3)", &buf, "")
    195 }
    196 
    197 func TestLargeStringReads(t *testing.T) {
    198 	var buf Buffer
    199 	for i := 3; i < 30; i += 3 {
    200 		s := fillString(t, "TestLargeReads (1)", &buf, "", 5, data[0:len(data)/i])
    201 		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)))
    202 	}
    203 	check(t, "TestLargeStringReads (3)", &buf, "")
    204 }
    205 
    206 func TestLargeByteReads(t *testing.T) {
    207 	var buf Buffer
    208 	for i := 3; i < 30; i += 3 {
    209 		s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
    210 		empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(data)))
    211 	}
    212 	check(t, "TestLargeByteReads (3)", &buf, "")
    213 }
    214 
    215 func TestMixedReadsAndWrites(t *testing.T) {
    216 	var buf Buffer
    217 	s := ""
    218 	for i := 0; i < 50; i++ {
    219 		wlen := rand.Intn(len(data))
    220 		if i%2 == 0 {
    221 			s = fillString(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, data[0:wlen])
    222 		} else {
    223 			s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testBytes[0:wlen])
    224 		}
    225 
    226 		rlen := rand.Intn(len(data))
    227 		fub := make([]byte, rlen)
    228 		n, _ := buf.Read(fub)
    229 		s = s[n:]
    230 	}
    231 	empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()))
    232 }
    233 
    234 func TestCapWithPreallocatedSlice(t *testing.T) {
    235 	buf := NewBuffer(make([]byte, 10))
    236 	n := buf.Cap()
    237 	if n != 10 {
    238 		t.Errorf("expected 10, got %d", n)
    239 	}
    240 }
    241 
    242 func TestCapWithSliceAndWrittenData(t *testing.T) {
    243 	buf := NewBuffer(make([]byte, 0, 10))
    244 	buf.Write([]byte("test"))
    245 	n := buf.Cap()
    246 	if n != 10 {
    247 		t.Errorf("expected 10, got %d", n)
    248 	}
    249 }
    250 
    251 func TestNil(t *testing.T) {
    252 	var b *Buffer
    253 	if b.String() != "<nil>" {
    254 		t.Errorf("expected <nil>; got %q", b.String())
    255 	}
    256 }
    257 
    258 func TestReadFrom(t *testing.T) {
    259 	var buf Buffer
    260 	for i := 3; i < 30; i += 3 {
    261 		s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
    262 		var b Buffer
    263 		b.ReadFrom(&buf)
    264 		empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(data)))
    265 	}
    266 }
    267 
    268 func TestWriteTo(t *testing.T) {
    269 	var buf Buffer
    270 	for i := 3; i < 30; i += 3 {
    271 		s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i])
    272 		var b Buffer
    273 		buf.WriteTo(&b)
    274 		empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(data)))
    275 	}
    276 }
    277 
    278 func TestRuneIO(t *testing.T) {
    279 	const NRune = 1000
    280 	// Built a test slice while we write the data
    281 	b := make([]byte, utf8.UTFMax*NRune)
    282 	var buf Buffer
    283 	n := 0
    284 	for r := rune(0); r < NRune; r++ {
    285 		size := utf8.EncodeRune(b[n:], r)
    286 		nbytes, err := buf.WriteRune(r)
    287 		if err != nil {
    288 			t.Fatalf("WriteRune(%U) error: %s", r, err)
    289 		}
    290 		if nbytes != size {
    291 			t.Fatalf("WriteRune(%U) expected %d, got %d", r, size, nbytes)
    292 		}
    293 		n += size
    294 	}
    295 	b = b[0:n]
    296 
    297 	// Check the resulting bytes
    298 	if !Equal(buf.Bytes(), b) {
    299 		t.Fatalf("incorrect result from WriteRune: %q not %q", buf.Bytes(), b)
    300 	}
    301 
    302 	p := make([]byte, utf8.UTFMax)
    303 	// Read it back with ReadRune
    304 	for r := rune(0); r < NRune; r++ {
    305 		size := utf8.EncodeRune(p, r)
    306 		nr, nbytes, err := buf.ReadRune()
    307 		if nr != r || nbytes != size || err != nil {
    308 			t.Fatalf("ReadRune(%U) got %U,%d not %U,%d (err=%s)", r, nr, nbytes, r, size, err)
    309 		}
    310 	}
    311 
    312 	// Check that UnreadRune works
    313 	buf.Reset()
    314 	buf.Write(b)
    315 	for r := rune(0); r < NRune; r++ {
    316 		r1, size, _ := buf.ReadRune()
    317 		if err := buf.UnreadRune(); err != nil {
    318 			t.Fatalf("UnreadRune(%U) got error %q", r, err)
    319 		}
    320 		r2, nbytes, err := buf.ReadRune()
    321 		if r1 != r2 || r1 != r || nbytes != size || err != nil {
    322 			t.Fatalf("ReadRune(%U) after UnreadRune got %U,%d not %U,%d (err=%s)", r, r2, nbytes, r, size, err)
    323 		}
    324 	}
    325 }
    326 
    327 func TestNext(t *testing.T) {
    328 	b := []byte{0, 1, 2, 3, 4}
    329 	tmp := make([]byte, 5)
    330 	for i := 0; i <= 5; i++ {
    331 		for j := i; j <= 5; j++ {
    332 			for k := 0; k <= 6; k++ {
    333 				// 0 <= i <= j <= 5; 0 <= k <= 6
    334 				// Check that if we start with a buffer
    335 				// of length j at offset i and ask for
    336 				// Next(k), we get the right bytes.
    337 				buf := NewBuffer(b[0:j])
    338 				n, _ := buf.Read(tmp[0:i])
    339 				if n != i {
    340 					t.Fatalf("Read %d returned %d", i, n)
    341 				}
    342 				bb := buf.Next(k)
    343 				want := k
    344 				if want > j-i {
    345 					want = j - i
    346 				}
    347 				if len(bb) != want {
    348 					t.Fatalf("in %d,%d: len(Next(%d)) == %d", i, j, k, len(bb))
    349 				}
    350 				for l, v := range bb {
    351 					if v != byte(l+i) {
    352 						t.Fatalf("in %d,%d: Next(%d)[%d] = %d, want %d", i, j, k, l, v, l+i)
    353 					}
    354 				}
    355 			}
    356 		}
    357 	}
    358 }
    359 
    360 var readBytesTests = []struct {
    361 	buffer   string
    362 	delim    byte
    363 	expected []string
    364 	err      error
    365 }{
    366 	{"", 0, []string{""}, io.EOF},
    367 	{"a\x00", 0, []string{"a\x00"}, nil},
    368 	{"abbbaaaba", 'b', []string{"ab", "b", "b", "aaab"}, nil},
    369 	{"hello\x01world", 1, []string{"hello\x01"}, nil},
    370 	{"foo\nbar", 0, []string{"foo\nbar"}, io.EOF},
    371 	{"alpha\nbeta\ngamma\n", '\n', []string{"alpha\n", "beta\n", "gamma\n"}, nil},
    372 	{"alpha\nbeta\ngamma", '\n', []string{"alpha\n", "beta\n", "gamma"}, io.EOF},
    373 }
    374 
    375 func TestReadBytes(t *testing.T) {
    376 	for _, test := range readBytesTests {
    377 		buf := NewBufferString(test.buffer)
    378 		var err error
    379 		for _, expected := range test.expected {
    380 			var bytes []byte
    381 			bytes, err = buf.ReadBytes(test.delim)
    382 			if string(bytes) != expected {
    383 				t.Errorf("expected %q, got %q", expected, bytes)
    384 			}
    385 			if err != nil {
    386 				break
    387 			}
    388 		}
    389 		if err != test.err {
    390 			t.Errorf("expected error %v, got %v", test.err, err)
    391 		}
    392 	}
    393 }
    394 
    395 func TestReadString(t *testing.T) {
    396 	for _, test := range readBytesTests {
    397 		buf := NewBufferString(test.buffer)
    398 		var err error
    399 		for _, expected := range test.expected {
    400 			var s string
    401 			s, err = buf.ReadString(test.delim)
    402 			if s != expected {
    403 				t.Errorf("expected %q, got %q", expected, s)
    404 			}
    405 			if err != nil {
    406 				break
    407 			}
    408 		}
    409 		if err != test.err {
    410 			t.Errorf("expected error %v, got %v", test.err, err)
    411 		}
    412 	}
    413 }
    414 
    415 func BenchmarkReadString(b *testing.B) {
    416 	const n = 32 << 10
    417 
    418 	data := make([]byte, n)
    419 	data[n-1] = 'x'
    420 	b.SetBytes(int64(n))
    421 	for i := 0; i < b.N; i++ {
    422 		buf := NewBuffer(data)
    423 		_, err := buf.ReadString('x')
    424 		if err != nil {
    425 			b.Fatal(err)
    426 		}
    427 	}
    428 }
    429 
    430 func TestGrow(t *testing.T) {
    431 	x := []byte{'x'}
    432 	y := []byte{'y'}
    433 	tmp := make([]byte, 72)
    434 	for _, startLen := range []int{0, 100, 1000, 10000, 100000} {
    435 		xBytes := Repeat(x, startLen)
    436 		for _, growLen := range []int{0, 100, 1000, 10000, 100000} {
    437 			buf := NewBuffer(xBytes)
    438 			// If we read, this affects buf.off, which is good to test.
    439 			readBytes, _ := buf.Read(tmp)
    440 			buf.Grow(growLen)
    441 			yBytes := Repeat(y, growLen)
    442 			// Check no allocation occurs in write, as long as we're single-threaded.
    443 			var m1, m2 runtime.MemStats
    444 			runtime.ReadMemStats(&m1)
    445 			buf.Write(yBytes)
    446 			runtime.ReadMemStats(&m2)
    447 			if runtime.GOMAXPROCS(-1) == 1 && m1.Mallocs != m2.Mallocs {
    448 				t.Errorf("allocation occurred during write")
    449 			}
    450 			// Check that buffer has correct data.
    451 			if !Equal(buf.Bytes()[0:startLen-readBytes], xBytes[readBytes:]) {
    452 				t.Errorf("bad initial data at %d %d", startLen, growLen)
    453 			}
    454 			if !Equal(buf.Bytes()[startLen-readBytes:startLen-readBytes+growLen], yBytes) {
    455 				t.Errorf("bad written data at %d %d", startLen, growLen)
    456 			}
    457 		}
    458 	}
    459 }
    460 
    461 // Was a bug: used to give EOF reading empty slice at EOF.
    462 func TestReadEmptyAtEOF(t *testing.T) {
    463 	b := new(Buffer)
    464 	slice := make([]byte, 0)
    465 	n, err := b.Read(slice)
    466 	if err != nil {
    467 		t.Errorf("read error: %v", err)
    468 	}
    469 	if n != 0 {
    470 		t.Errorf("wrong count; got %d want 0", n)
    471 	}
    472 }
    473 
    474 func TestUnreadByte(t *testing.T) {
    475 	b := new(Buffer)
    476 	b.WriteString("abcdefghijklmnopqrstuvwxyz")
    477 
    478 	_, err := b.ReadBytes('m')
    479 	if err != nil {
    480 		t.Fatalf("ReadBytes: %v", err)
    481 	}
    482 
    483 	err = b.UnreadByte()
    484 	if err != nil {
    485 		t.Fatalf("UnreadByte: %v", err)
    486 	}
    487 	c, err := b.ReadByte()
    488 	if err != nil {
    489 		t.Fatalf("ReadByte: %v", err)
    490 	}
    491 	if c != 'm' {
    492 		t.Errorf("ReadByte = %q; want %q", c, 'm')
    493 	}
    494 }
    495 
    496 // Tests that we occasionally compact. Issue 5154.
    497 func TestBufferGrowth(t *testing.T) {
    498 	var b Buffer
    499 	buf := make([]byte, 1024)
    500 	b.Write(buf[0:1])
    501 	var cap0 int
    502 	for i := 0; i < 5<<10; i++ {
    503 		b.Write(buf)
    504 		b.Read(buf)
    505 		if i == 0 {
    506 			cap0 = b.Cap()
    507 		}
    508 	}
    509 	cap1 := b.Cap()
    510 	// (*Buffer).grow allows for 2x capacity slop before sliding,
    511 	// so set our error threshold at 3x.
    512 	if cap1 > cap0*3 {
    513 		t.Errorf("buffer cap = %d; too big (grew from %d)", cap1, cap0)
    514 	}
    515 }
    516 
    517 func BenchmarkWriteRune(b *testing.B) {
    518 	const n = 4 << 10
    519 	const r = ''
    520 	b.SetBytes(int64(n * utf8.RuneLen(r)))
    521 	buf := NewBuffer(make([]byte, n*utf8.UTFMax))
    522 	for i := 0; i < b.N; i++ {
    523 		buf.Reset()
    524 		for i := 0; i < n; i++ {
    525 			buf.WriteRune(r)
    526 		}
    527 	}
    528 }
    529 
    530 // From Issue 5154.
    531 func BenchmarkBufferNotEmptyWriteRead(b *testing.B) {
    532 	buf := make([]byte, 1024)
    533 	for i := 0; i < b.N; i++ {
    534 		var b Buffer
    535 		b.Write(buf[0:1])
    536 		for i := 0; i < 5<<10; i++ {
    537 			b.Write(buf)
    538 			b.Read(buf)
    539 		}
    540 	}
    541 }
    542 
    543 // Check that we don't compact too often. From Issue 5154.
    544 func BenchmarkBufferFullSmallReads(b *testing.B) {
    545 	buf := make([]byte, 1024)
    546 	for i := 0; i < b.N; i++ {
    547 		var b Buffer
    548 		b.Write(buf)
    549 		for b.Len()+20 < b.Cap() {
    550 			b.Write(buf[:10])
    551 		}
    552 		for i := 0; i < 5<<10; i++ {
    553 			b.Read(buf[:1])
    554 			b.Write(buf[:1])
    555 		}
    556 	}
    557 }
    558