github.com/stingnevermore/go@v0.0.0-20180120041312-3810f5bfed72/src/bytes/buffer_test.go (about) 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 testString string // test data for write tests 18 var testBytes []byte // test data; same as testString but as a slice. 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 // Verify that contents of buf match the string s. 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 // Fill buf through n writes of string fus. 54 // The initial contents of buf corresponds to the string s; 55 // the result is the final contents of buf returned as a string. 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 // Fill buf through n writes of byte slice fub. 73 // The initial contents of buf corresponds to the string s; 74 // the result is the final contents of buf returned as a string. 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 // Empty buf through repeated reads into fub. 102 // The initial contents of buf corresponds to the string s. 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 n != 1 { 135 t.Errorf("wrote 1 byte, but n == %d", n) 136 } 137 if err != nil { 138 t.Errorf("err should always be nil, but err == %s", err) 139 } 140 check(t, "TestBasicOperations (4)", &buf, "a") 141 142 buf.WriteByte(testString[1]) 143 check(t, "TestBasicOperations (5)", &buf, "ab") 144 145 n, err = buf.Write(testBytes[2:26]) 146 if n != 24 { 147 t.Errorf("wrote 24 bytes, but n == %d", n) 148 } 149 check(t, "TestBasicOperations (6)", &buf, testString[0:26]) 150 151 buf.Truncate(26) 152 check(t, "TestBasicOperations (7)", &buf, testString[0:26]) 153 154 buf.Truncate(20) 155 check(t, "TestBasicOperations (8)", &buf, testString[0:20]) 156 157 empty(t, "TestBasicOperations (9)", &buf, testString[0:20], make([]byte, 5)) 158 empty(t, "TestBasicOperations (10)", &buf, "", make([]byte, 100)) 159 160 buf.WriteByte(testString[1]) 161 c, err := buf.ReadByte() 162 if err != nil { 163 t.Error("ReadByte unexpected eof") 164 } 165 if c != testString[1] { 166 t.Errorf("ReadByte wrong value c=%v", c) 167 } 168 c, err = buf.ReadByte() 169 if err == nil { 170 t.Error("ReadByte unexpected not eof") 171 } 172 } 173 } 174 175 func TestLargeStringWrites(t *testing.T) { 176 var buf Buffer 177 limit := 30 178 if testing.Short() { 179 limit = 9 180 } 181 for i := 3; i < limit; i += 3 { 182 s := fillString(t, "TestLargeWrites (1)", &buf, "", 5, testString) 183 empty(t, "TestLargeStringWrites (2)", &buf, s, make([]byte, len(testString)/i)) 184 } 185 check(t, "TestLargeStringWrites (3)", &buf, "") 186 } 187 188 func TestLargeByteWrites(t *testing.T) { 189 var buf Buffer 190 limit := 30 191 if testing.Short() { 192 limit = 9 193 } 194 for i := 3; i < limit; i += 3 { 195 s := fillBytes(t, "TestLargeWrites (1)", &buf, "", 5, testBytes) 196 empty(t, "TestLargeByteWrites (2)", &buf, s, make([]byte, len(testString)/i)) 197 } 198 check(t, "TestLargeByteWrites (3)", &buf, "") 199 } 200 201 func TestLargeStringReads(t *testing.T) { 202 var buf Buffer 203 for i := 3; i < 30; i += 3 { 204 s := fillString(t, "TestLargeReads (1)", &buf, "", 5, testString[0:len(testString)/i]) 205 empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(testString))) 206 } 207 check(t, "TestLargeStringReads (3)", &buf, "") 208 } 209 210 func TestLargeByteReads(t *testing.T) { 211 var buf Buffer 212 for i := 3; i < 30; i += 3 { 213 s := fillBytes(t, "TestLargeReads (1)", &buf, "", 5, testBytes[0:len(testBytes)/i]) 214 empty(t, "TestLargeReads (2)", &buf, s, make([]byte, len(testString))) 215 } 216 check(t, "TestLargeByteReads (3)", &buf, "") 217 } 218 219 func TestMixedReadsAndWrites(t *testing.T) { 220 var buf Buffer 221 s := "" 222 for i := 0; i < 50; i++ { 223 wlen := rand.Intn(len(testString)) 224 if i%2 == 0 { 225 s = fillString(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testString[0:wlen]) 226 } else { 227 s = fillBytes(t, "TestMixedReadsAndWrites (1)", &buf, s, 1, testBytes[0:wlen]) 228 } 229 230 rlen := rand.Intn(len(testString)) 231 fub := make([]byte, rlen) 232 n, _ := buf.Read(fub) 233 s = s[n:] 234 } 235 empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len())) 236 } 237 238 func TestCapWithPreallocatedSlice(t *testing.T) { 239 buf := NewBuffer(make([]byte, 10)) 240 n := buf.Cap() 241 if n != 10 { 242 t.Errorf("expected 10, got %d", n) 243 } 244 } 245 246 func TestCapWithSliceAndWrittenData(t *testing.T) { 247 buf := NewBuffer(make([]byte, 0, 10)) 248 buf.Write([]byte("test")) 249 n := buf.Cap() 250 if n != 10 { 251 t.Errorf("expected 10, got %d", n) 252 } 253 } 254 255 func TestNil(t *testing.T) { 256 var b *Buffer 257 if b.String() != "<nil>" { 258 t.Errorf("expected <nil>; got %q", b.String()) 259 } 260 } 261 262 func TestReadFrom(t *testing.T) { 263 var buf Buffer 264 for i := 3; i < 30; i += 3 { 265 s := fillBytes(t, "TestReadFrom (1)", &buf, "", 5, testBytes[0:len(testBytes)/i]) 266 var b Buffer 267 b.ReadFrom(&buf) 268 empty(t, "TestReadFrom (2)", &b, s, make([]byte, len(testString))) 269 } 270 } 271 272 func TestReadFromNegativeReader(t *testing.T) { 273 var b Buffer 274 defer func() { 275 switch err := recover().(type) { 276 case nil: 277 t.Fatal("bytes.Buffer.ReadFrom didn't panic") 278 case error: 279 // this is the error string of errNegativeRead 280 wantError := "bytes.Buffer: reader returned negative count from Read" 281 if err.Error() != wantError { 282 t.Fatalf("recovered panic: got %v, want %v", err.Error(), wantError) 283 } 284 default: 285 t.Fatalf("unexpected panic value: %#v", err) 286 } 287 }() 288 289 b.ReadFrom(new(negativeReader)) 290 } 291 292 func TestWriteTo(t *testing.T) { 293 var buf Buffer 294 for i := 3; i < 30; i += 3 { 295 s := fillBytes(t, "TestWriteTo (1)", &buf, "", 5, testBytes[0:len(testBytes)/i]) 296 var b Buffer 297 buf.WriteTo(&b) 298 empty(t, "TestWriteTo (2)", &b, s, make([]byte, len(testString))) 299 } 300 } 301 302 func TestRuneIO(t *testing.T) { 303 const NRune = 1000 304 // Built a test slice while we write the data 305 b := make([]byte, utf8.UTFMax*NRune) 306 var buf Buffer 307 n := 0 308 for r := rune(0); r < NRune; r++ { 309 size := utf8.EncodeRune(b[n:], r) 310 nbytes, err := buf.WriteRune(r) 311 if err != nil { 312 t.Fatalf("WriteRune(%U) error: %s", r, err) 313 } 314 if nbytes != size { 315 t.Fatalf("WriteRune(%U) expected %d, got %d", r, size, nbytes) 316 } 317 n += size 318 } 319 b = b[0:n] 320 321 // Check the resulting bytes 322 if !Equal(buf.Bytes(), b) { 323 t.Fatalf("incorrect result from WriteRune: %q not %q", buf.Bytes(), b) 324 } 325 326 p := make([]byte, utf8.UTFMax) 327 // Read it back with ReadRune 328 for r := rune(0); r < NRune; r++ { 329 size := utf8.EncodeRune(p, r) 330 nr, nbytes, err := buf.ReadRune() 331 if nr != r || nbytes != size || err != nil { 332 t.Fatalf("ReadRune(%U) got %U,%d not %U,%d (err=%s)", r, nr, nbytes, r, size, err) 333 } 334 } 335 336 // Check that UnreadRune works 337 buf.Reset() 338 339 // check at EOF 340 if err := buf.UnreadRune(); err == nil { 341 t.Fatal("UnreadRune at EOF: got no error") 342 } 343 if _, _, err := buf.ReadRune(); err == nil { 344 t.Fatal("ReadRune at EOF: got no error") 345 } 346 if err := buf.UnreadRune(); err == nil { 347 t.Fatal("UnreadRune after ReadRune at EOF: got no error") 348 } 349 350 // check not at EOF 351 buf.Write(b) 352 for r := rune(0); r < NRune; r++ { 353 r1, size, _ := buf.ReadRune() 354 if err := buf.UnreadRune(); err != nil { 355 t.Fatalf("UnreadRune(%U) got error %q", r, err) 356 } 357 r2, nbytes, err := buf.ReadRune() 358 if r1 != r2 || r1 != r || nbytes != size || err != nil { 359 t.Fatalf("ReadRune(%U) after UnreadRune got %U,%d not %U,%d (err=%s)", r, r2, nbytes, r, size, err) 360 } 361 } 362 } 363 364 func TestNext(t *testing.T) { 365 b := []byte{0, 1, 2, 3, 4} 366 tmp := make([]byte, 5) 367 for i := 0; i <= 5; i++ { 368 for j := i; j <= 5; j++ { 369 for k := 0; k <= 6; k++ { 370 // 0 <= i <= j <= 5; 0 <= k <= 6 371 // Check that if we start with a buffer 372 // of length j at offset i and ask for 373 // Next(k), we get the right bytes. 374 buf := NewBuffer(b[0:j]) 375 n, _ := buf.Read(tmp[0:i]) 376 if n != i { 377 t.Fatalf("Read %d returned %d", i, n) 378 } 379 bb := buf.Next(k) 380 want := k 381 if want > j-i { 382 want = j - i 383 } 384 if len(bb) != want { 385 t.Fatalf("in %d,%d: len(Next(%d)) == %d", i, j, k, len(bb)) 386 } 387 for l, v := range bb { 388 if v != byte(l+i) { 389 t.Fatalf("in %d,%d: Next(%d)[%d] = %d, want %d", i, j, k, l, v, l+i) 390 } 391 } 392 } 393 } 394 } 395 } 396 397 var readBytesTests = []struct { 398 buffer string 399 delim byte 400 expected []string 401 err error 402 }{ 403 {"", 0, []string{""}, io.EOF}, 404 {"a\x00", 0, []string{"a\x00"}, nil}, 405 {"abbbaaaba", 'b', []string{"ab", "b", "b", "aaab"}, nil}, 406 {"hello\x01world", 1, []string{"hello\x01"}, nil}, 407 {"foo\nbar", 0, []string{"foo\nbar"}, io.EOF}, 408 {"alpha\nbeta\ngamma\n", '\n', []string{"alpha\n", "beta\n", "gamma\n"}, nil}, 409 {"alpha\nbeta\ngamma", '\n', []string{"alpha\n", "beta\n", "gamma"}, io.EOF}, 410 } 411 412 func TestReadBytes(t *testing.T) { 413 for _, test := range readBytesTests { 414 buf := NewBufferString(test.buffer) 415 var err error 416 for _, expected := range test.expected { 417 var bytes []byte 418 bytes, err = buf.ReadBytes(test.delim) 419 if string(bytes) != expected { 420 t.Errorf("expected %q, got %q", expected, bytes) 421 } 422 if err != nil { 423 break 424 } 425 } 426 if err != test.err { 427 t.Errorf("expected error %v, got %v", test.err, err) 428 } 429 } 430 } 431 432 func TestReadString(t *testing.T) { 433 for _, test := range readBytesTests { 434 buf := NewBufferString(test.buffer) 435 var err error 436 for _, expected := range test.expected { 437 var s string 438 s, err = buf.ReadString(test.delim) 439 if s != expected { 440 t.Errorf("expected %q, got %q", expected, s) 441 } 442 if err != nil { 443 break 444 } 445 } 446 if err != test.err { 447 t.Errorf("expected error %v, got %v", test.err, err) 448 } 449 } 450 } 451 452 func BenchmarkReadString(b *testing.B) { 453 const n = 32 << 10 454 455 data := make([]byte, n) 456 data[n-1] = 'x' 457 b.SetBytes(int64(n)) 458 for i := 0; i < b.N; i++ { 459 buf := NewBuffer(data) 460 _, err := buf.ReadString('x') 461 if err != nil { 462 b.Fatal(err) 463 } 464 } 465 } 466 467 func TestGrow(t *testing.T) { 468 x := []byte{'x'} 469 y := []byte{'y'} 470 tmp := make([]byte, 72) 471 for _, startLen := range []int{0, 100, 1000, 10000, 100000} { 472 xBytes := Repeat(x, startLen) 473 for _, growLen := range []int{0, 100, 1000, 10000, 100000} { 474 buf := NewBuffer(xBytes) 475 // If we read, this affects buf.off, which is good to test. 476 readBytes, _ := buf.Read(tmp) 477 buf.Grow(growLen) 478 yBytes := Repeat(y, growLen) 479 // Check no allocation occurs in write, as long as we're single-threaded. 480 var m1, m2 runtime.MemStats 481 runtime.ReadMemStats(&m1) 482 buf.Write(yBytes) 483 runtime.ReadMemStats(&m2) 484 if runtime.GOMAXPROCS(-1) == 1 && m1.Mallocs != m2.Mallocs { 485 t.Errorf("allocation occurred during write") 486 } 487 // Check that buffer has correct data. 488 if !Equal(buf.Bytes()[0:startLen-readBytes], xBytes[readBytes:]) { 489 t.Errorf("bad initial data at %d %d", startLen, growLen) 490 } 491 if !Equal(buf.Bytes()[startLen-readBytes:startLen-readBytes+growLen], yBytes) { 492 t.Errorf("bad written data at %d %d", startLen, growLen) 493 } 494 } 495 } 496 } 497 498 func TestGrowOverflow(t *testing.T) { 499 defer func() { 500 if err := recover(); err != ErrTooLarge { 501 t.Errorf("after too-large Grow, recover() = %v; want %v", err, ErrTooLarge) 502 } 503 }() 504 505 buf := NewBuffer(make([]byte, 1)) 506 const maxInt = int(^uint(0) >> 1) 507 buf.Grow(maxInt) 508 } 509 510 // Was a bug: used to give EOF reading empty slice at EOF. 511 func TestReadEmptyAtEOF(t *testing.T) { 512 b := new(Buffer) 513 slice := make([]byte, 0) 514 n, err := b.Read(slice) 515 if err != nil { 516 t.Errorf("read error: %v", err) 517 } 518 if n != 0 { 519 t.Errorf("wrong count; got %d want 0", n) 520 } 521 } 522 523 func TestUnreadByte(t *testing.T) { 524 b := new(Buffer) 525 526 // check at EOF 527 if err := b.UnreadByte(); err == nil { 528 t.Fatal("UnreadByte at EOF: got no error") 529 } 530 if _, err := b.ReadByte(); err == nil { 531 t.Fatal("ReadByte at EOF: got no error") 532 } 533 if err := b.UnreadByte(); err == nil { 534 t.Fatal("UnreadByte after ReadByte at EOF: got no error") 535 } 536 537 // check not at EOF 538 b.WriteString("abcdefghijklmnopqrstuvwxyz") 539 540 // after unsuccessful read 541 if n, err := b.Read(nil); n != 0 || err != nil { 542 t.Fatalf("Read(nil) = %d,%v; want 0,nil", n, err) 543 } 544 if err := b.UnreadByte(); err == nil { 545 t.Fatal("UnreadByte after Read(nil): got no error") 546 } 547 548 // after successful read 549 if _, err := b.ReadBytes('m'); err != nil { 550 t.Fatalf("ReadBytes: %v", err) 551 } 552 if err := b.UnreadByte(); err != nil { 553 t.Fatalf("UnreadByte: %v", err) 554 } 555 c, err := b.ReadByte() 556 if err != nil { 557 t.Fatalf("ReadByte: %v", err) 558 } 559 if c != 'm' { 560 t.Errorf("ReadByte = %q; want %q", c, 'm') 561 } 562 } 563 564 // Tests that we occasionally compact. Issue 5154. 565 func TestBufferGrowth(t *testing.T) { 566 var b Buffer 567 buf := make([]byte, 1024) 568 b.Write(buf[0:1]) 569 var cap0 int 570 for i := 0; i < 5<<10; i++ { 571 b.Write(buf) 572 b.Read(buf) 573 if i == 0 { 574 cap0 = b.Cap() 575 } 576 } 577 cap1 := b.Cap() 578 // (*Buffer).grow allows for 2x capacity slop before sliding, 579 // so set our error threshold at 3x. 580 if cap1 > cap0*3 { 581 t.Errorf("buffer cap = %d; too big (grew from %d)", cap1, cap0) 582 } 583 } 584 585 func BenchmarkWriteByte(b *testing.B) { 586 const n = 4 << 10 587 b.SetBytes(n) 588 buf := NewBuffer(make([]byte, n)) 589 for i := 0; i < b.N; i++ { 590 buf.Reset() 591 for i := 0; i < n; i++ { 592 buf.WriteByte('x') 593 } 594 } 595 } 596 597 func BenchmarkWriteRune(b *testing.B) { 598 const n = 4 << 10 599 const r = '☺' 600 b.SetBytes(int64(n * utf8.RuneLen(r))) 601 buf := NewBuffer(make([]byte, n*utf8.UTFMax)) 602 for i := 0; i < b.N; i++ { 603 buf.Reset() 604 for i := 0; i < n; i++ { 605 buf.WriteRune(r) 606 } 607 } 608 } 609 610 // From Issue 5154. 611 func BenchmarkBufferNotEmptyWriteRead(b *testing.B) { 612 buf := make([]byte, 1024) 613 for i := 0; i < b.N; i++ { 614 var b Buffer 615 b.Write(buf[0:1]) 616 for i := 0; i < 5<<10; i++ { 617 b.Write(buf) 618 b.Read(buf) 619 } 620 } 621 } 622 623 // Check that we don't compact too often. From Issue 5154. 624 func BenchmarkBufferFullSmallReads(b *testing.B) { 625 buf := make([]byte, 1024) 626 for i := 0; i < b.N; i++ { 627 var b Buffer 628 b.Write(buf) 629 for b.Len()+20 < b.Cap() { 630 b.Write(buf[:10]) 631 } 632 for i := 0; i < 5<<10; i++ { 633 b.Read(buf[:1]) 634 b.Write(buf[:1]) 635 } 636 } 637 }