github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/syndtr/goleveldb/leveldb/journal/journal_test.go (about) 1 // Copyright 2011 The LevelDB-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 // Taken from: https://code.google.com/p/leveldb-go/source/browse/leveldb/record/record_test.go?r=df1fa28f7f3be6c3935548169002309c12967135 6 // License, authors and contributors informations can be found at bellow URLs respectively: 7 // https://code.google.com/p/leveldb-go/source/browse/LICENSE 8 // https://code.google.com/p/leveldb-go/source/browse/AUTHORS 9 // https://code.google.com/p/leveldb-go/source/browse/CONTRIBUTORS 10 11 package journal 12 13 import ( 14 "bytes" 15 "encoding/binary" 16 "fmt" 17 "io" 18 "io/ioutil" 19 "math/rand" 20 "strings" 21 "testing" 22 ) 23 24 type dropper struct { 25 t *testing.T 26 } 27 28 func (d dropper) Drop(err error) { 29 d.t.Log(err) 30 } 31 32 func short(s string) string { 33 if len(s) < 64 { 34 return s 35 } 36 return fmt.Sprintf("%s...(skipping %d bytes)...%s", s[:20], len(s)-40, s[len(s)-20:]) 37 } 38 39 // big returns a string of length n, composed of repetitions of partial. 40 func big(partial string, n int) string { 41 return strings.Repeat(partial, n/len(partial)+1)[:n] 42 } 43 44 func TestEmpty(t *testing.T) { 45 buf := new(bytes.Buffer) 46 r := NewReader(buf, dropper{t}, true, true) 47 if _, err := r.Next(); err != io.EOF { 48 t.Fatalf("got %v, want %v", err, io.EOF) 49 } 50 } 51 52 func testGenerator(t *testing.T, reset func(), gen func() (string, bool)) { 53 buf := new(bytes.Buffer) 54 55 reset() 56 w := NewWriter(buf) 57 for { 58 s, ok := gen() 59 if !ok { 60 break 61 } 62 ww, err := w.Next() 63 if err != nil { 64 t.Fatal(err) 65 } 66 if _, err := ww.Write([]byte(s)); err != nil { 67 t.Fatal(err) 68 } 69 } 70 if err := w.Close(); err != nil { 71 t.Fatal(err) 72 } 73 74 reset() 75 r := NewReader(buf, dropper{t}, true, true) 76 for { 77 s, ok := gen() 78 if !ok { 79 break 80 } 81 rr, err := r.Next() 82 if err != nil { 83 t.Fatal(err) 84 } 85 x, err := ioutil.ReadAll(rr) 86 if err != nil { 87 t.Fatal(err) 88 } 89 if string(x) != s { 90 t.Fatalf("got %q, want %q", short(string(x)), short(s)) 91 } 92 } 93 if _, err := r.Next(); err != io.EOF { 94 t.Fatalf("got %v, want %v", err, io.EOF) 95 } 96 } 97 98 func testLiterals(t *testing.T, s []string) { 99 var i int 100 reset := func() { 101 i = 0 102 } 103 gen := func() (string, bool) { 104 if i == len(s) { 105 return "", false 106 } 107 i++ 108 return s[i-1], true 109 } 110 testGenerator(t, reset, gen) 111 } 112 113 func TestMany(t *testing.T) { 114 const n = 1e5 115 var i int 116 reset := func() { 117 i = 0 118 } 119 gen := func() (string, bool) { 120 if i == n { 121 return "", false 122 } 123 i++ 124 return fmt.Sprintf("%d.", i-1), true 125 } 126 testGenerator(t, reset, gen) 127 } 128 129 func TestRandom(t *testing.T) { 130 const n = 1e2 131 var ( 132 i int 133 r *rand.Rand 134 ) 135 reset := func() { 136 i, r = 0, rand.New(rand.NewSource(0)) 137 } 138 gen := func() (string, bool) { 139 if i == n { 140 return "", false 141 } 142 i++ 143 return strings.Repeat(string(uint8(i)), r.Intn(2*blockSize+16)), true 144 } 145 testGenerator(t, reset, gen) 146 } 147 148 func TestBasic(t *testing.T) { 149 testLiterals(t, []string{ 150 strings.Repeat("a", 1000), 151 strings.Repeat("b", 97270), 152 strings.Repeat("c", 8000), 153 }) 154 } 155 156 func TestBoundary(t *testing.T) { 157 for i := blockSize - 16; i < blockSize+16; i++ { 158 s0 := big("abcd", i) 159 for j := blockSize - 16; j < blockSize+16; j++ { 160 s1 := big("ABCDE", j) 161 testLiterals(t, []string{s0, s1}) 162 testLiterals(t, []string{s0, "", s1}) 163 testLiterals(t, []string{s0, "x", s1}) 164 } 165 } 166 } 167 168 func TestFlush(t *testing.T) { 169 buf := new(bytes.Buffer) 170 w := NewWriter(buf) 171 // Write a couple of records. Everything should still be held 172 // in the record.Writer buffer, so that buf.Len should be 0. 173 w0, _ := w.Next() 174 w0.Write([]byte("0")) 175 w1, _ := w.Next() 176 w1.Write([]byte("11")) 177 if got, want := buf.Len(), 0; got != want { 178 t.Fatalf("buffer length #0: got %d want %d", got, want) 179 } 180 // Flush the record.Writer buffer, which should yield 17 bytes. 181 // 17 = 2*7 + 1 + 2, which is two headers and 1 + 2 payload bytes. 182 if err := w.Flush(); err != nil { 183 t.Fatal(err) 184 } 185 if got, want := buf.Len(), 17; got != want { 186 t.Fatalf("buffer length #1: got %d want %d", got, want) 187 } 188 // Do another write, one that isn't large enough to complete the block. 189 // The write should not have flowed through to buf. 190 w2, _ := w.Next() 191 w2.Write(bytes.Repeat([]byte("2"), 10000)) 192 if got, want := buf.Len(), 17; got != want { 193 t.Fatalf("buffer length #2: got %d want %d", got, want) 194 } 195 // Flushing should get us up to 10024 bytes written. 196 // 10024 = 17 + 7 + 10000. 197 if err := w.Flush(); err != nil { 198 t.Fatal(err) 199 } 200 if got, want := buf.Len(), 10024; got != want { 201 t.Fatalf("buffer length #3: got %d want %d", got, want) 202 } 203 // Do a bigger write, one that completes the current block. 204 // We should now have 32768 bytes (a complete block), without 205 // an explicit flush. 206 w3, _ := w.Next() 207 w3.Write(bytes.Repeat([]byte("3"), 40000)) 208 if got, want := buf.Len(), 32768; got != want { 209 t.Fatalf("buffer length #4: got %d want %d", got, want) 210 } 211 // Flushing should get us up to 50038 bytes written. 212 // 50038 = 10024 + 2*7 + 40000. There are two headers because 213 // the one record was split into two chunks. 214 if err := w.Flush(); err != nil { 215 t.Fatal(err) 216 } 217 if got, want := buf.Len(), 50038; got != want { 218 t.Fatalf("buffer length #5: got %d want %d", got, want) 219 } 220 // Check that reading those records give the right lengths. 221 r := NewReader(buf, dropper{t}, true, true) 222 wants := []int64{1, 2, 10000, 40000} 223 for i, want := range wants { 224 rr, _ := r.Next() 225 n, err := io.Copy(ioutil.Discard, rr) 226 if err != nil { 227 t.Fatalf("read #%d: %v", i, err) 228 } 229 if n != want { 230 t.Fatalf("read #%d: got %d bytes want %d", i, n, want) 231 } 232 } 233 } 234 235 func TestNonExhaustiveRead(t *testing.T) { 236 const n = 100 237 buf := new(bytes.Buffer) 238 p := make([]byte, 10) 239 rnd := rand.New(rand.NewSource(1)) 240 241 w := NewWriter(buf) 242 for i := 0; i < n; i++ { 243 length := len(p) + rnd.Intn(3*blockSize) 244 s := string(uint8(i)) + "123456789abcdefgh" 245 ww, _ := w.Next() 246 ww.Write([]byte(big(s, length))) 247 } 248 if err := w.Close(); err != nil { 249 t.Fatal(err) 250 } 251 252 r := NewReader(buf, dropper{t}, true, true) 253 for i := 0; i < n; i++ { 254 rr, _ := r.Next() 255 _, err := io.ReadFull(rr, p) 256 if err != nil { 257 t.Fatal(err) 258 } 259 want := string(uint8(i)) + "123456789" 260 if got := string(p); got != want { 261 t.Fatalf("read #%d: got %q want %q", i, got, want) 262 } 263 } 264 } 265 266 func TestStaleReader(t *testing.T) { 267 buf := new(bytes.Buffer) 268 269 w := NewWriter(buf) 270 w0, err := w.Next() 271 if err != nil { 272 t.Fatal(err) 273 } 274 w0.Write([]byte("0")) 275 w1, err := w.Next() 276 if err != nil { 277 t.Fatal(err) 278 } 279 w1.Write([]byte("11")) 280 if err := w.Close(); err != nil { 281 t.Fatal(err) 282 } 283 284 r := NewReader(buf, dropper{t}, true, true) 285 r0, err := r.Next() 286 if err != nil { 287 t.Fatal(err) 288 } 289 r1, err := r.Next() 290 if err != nil { 291 t.Fatal(err) 292 } 293 p := make([]byte, 1) 294 if _, err := r0.Read(p); err == nil || !strings.Contains(err.Error(), "stale") { 295 t.Fatalf("stale read #0: unexpected error: %v", err) 296 } 297 if _, err := r1.Read(p); err != nil { 298 t.Fatalf("fresh read #1: got %v want nil error", err) 299 } 300 if p[0] != '1' { 301 t.Fatalf("fresh read #1: byte contents: got '%c' want '1'", p[0]) 302 } 303 } 304 305 func TestStaleWriter(t *testing.T) { 306 buf := new(bytes.Buffer) 307 308 w := NewWriter(buf) 309 w0, err := w.Next() 310 if err != nil { 311 t.Fatal(err) 312 } 313 w1, err := w.Next() 314 if err != nil { 315 t.Fatal(err) 316 } 317 if _, err := w0.Write([]byte("0")); err == nil || !strings.Contains(err.Error(), "stale") { 318 t.Fatalf("stale write #0: unexpected error: %v", err) 319 } 320 if _, err := w1.Write([]byte("11")); err != nil { 321 t.Fatalf("fresh write #1: got %v want nil error", err) 322 } 323 if err := w.Flush(); err != nil { 324 t.Fatalf("flush: %v", err) 325 } 326 if _, err := w1.Write([]byte("0")); err == nil || !strings.Contains(err.Error(), "stale") { 327 t.Fatalf("stale write #1: unexpected error: %v", err) 328 } 329 } 330 331 func TestCorrupt_MissingLastBlock(t *testing.T) { 332 buf := new(bytes.Buffer) 333 334 w := NewWriter(buf) 335 336 // First record. 337 ww, err := w.Next() 338 if err != nil { 339 t.Fatal(err) 340 } 341 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-1024)); err != nil { 342 t.Fatalf("write #0: unexpected error: %v", err) 343 } 344 345 // Second record. 346 ww, err = w.Next() 347 if err != nil { 348 t.Fatal(err) 349 } 350 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil { 351 t.Fatalf("write #1: unexpected error: %v", err) 352 } 353 354 if err := w.Close(); err != nil { 355 t.Fatal(err) 356 } 357 358 // Cut the last block. 359 b := buf.Bytes()[:blockSize] 360 r := NewReader(bytes.NewReader(b), dropper{t}, false, true) 361 362 // First read. 363 rr, err := r.Next() 364 if err != nil { 365 t.Fatal(err) 366 } 367 n, err := io.Copy(ioutil.Discard, rr) 368 if err != nil { 369 t.Fatalf("read #0: %v", err) 370 } 371 if n != blockSize-1024 { 372 t.Fatalf("read #0: got %d bytes want %d", n, blockSize-1024) 373 } 374 375 // Second read. 376 rr, err = r.Next() 377 if err != nil { 378 t.Fatal(err) 379 } 380 n, err = io.Copy(ioutil.Discard, rr) 381 if err != io.ErrUnexpectedEOF { 382 t.Fatalf("read #1: unexpected error: %v", err) 383 } 384 385 if _, err := r.Next(); err != io.EOF { 386 t.Fatalf("last next: unexpected error: %v", err) 387 } 388 } 389 390 func TestCorrupt_CorruptedFirstBlock(t *testing.T) { 391 buf := new(bytes.Buffer) 392 393 w := NewWriter(buf) 394 395 // First record. 396 ww, err := w.Next() 397 if err != nil { 398 t.Fatal(err) 399 } 400 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize/2)); err != nil { 401 t.Fatalf("write #0: unexpected error: %v", err) 402 } 403 404 // Second record. 405 ww, err = w.Next() 406 if err != nil { 407 t.Fatal(err) 408 } 409 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil { 410 t.Fatalf("write #1: unexpected error: %v", err) 411 } 412 413 // Third record. 414 ww, err = w.Next() 415 if err != nil { 416 t.Fatal(err) 417 } 418 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+1)); err != nil { 419 t.Fatalf("write #2: unexpected error: %v", err) 420 } 421 422 // Fourth record. 423 ww, err = w.Next() 424 if err != nil { 425 t.Fatal(err) 426 } 427 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+2)); err != nil { 428 t.Fatalf("write #3: unexpected error: %v", err) 429 } 430 431 if err := w.Close(); err != nil { 432 t.Fatal(err) 433 } 434 435 b := buf.Bytes() 436 // Corrupting block #0. 437 for i := 0; i < 1024; i++ { 438 b[i] = '1' 439 } 440 441 r := NewReader(bytes.NewReader(b), dropper{t}, false, true) 442 443 // First read (third record). 444 rr, err := r.Next() 445 if err != nil { 446 t.Fatal(err) 447 } 448 n, err := io.Copy(ioutil.Discard, rr) 449 if err != nil { 450 t.Fatalf("read #0: %v", err) 451 } 452 if want := int64(blockSize-headerSize) + 1; n != want { 453 t.Fatalf("read #0: got %d bytes want %d", n, want) 454 } 455 456 // Second read (fourth record). 457 rr, err = r.Next() 458 if err != nil { 459 t.Fatal(err) 460 } 461 n, err = io.Copy(ioutil.Discard, rr) 462 if err != nil { 463 t.Fatalf("read #1: %v", err) 464 } 465 if want := int64(blockSize-headerSize) + 2; n != want { 466 t.Fatalf("read #1: got %d bytes want %d", n, want) 467 } 468 469 if _, err := r.Next(); err != io.EOF { 470 t.Fatalf("last next: unexpected error: %v", err) 471 } 472 } 473 474 func TestCorrupt_CorruptedMiddleBlock(t *testing.T) { 475 buf := new(bytes.Buffer) 476 477 w := NewWriter(buf) 478 479 // First record. 480 ww, err := w.Next() 481 if err != nil { 482 t.Fatal(err) 483 } 484 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize/2)); err != nil { 485 t.Fatalf("write #0: unexpected error: %v", err) 486 } 487 488 // Second record. 489 ww, err = w.Next() 490 if err != nil { 491 t.Fatal(err) 492 } 493 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil { 494 t.Fatalf("write #1: unexpected error: %v", err) 495 } 496 497 // Third record. 498 ww, err = w.Next() 499 if err != nil { 500 t.Fatal(err) 501 } 502 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+1)); err != nil { 503 t.Fatalf("write #2: unexpected error: %v", err) 504 } 505 506 // Fourth record. 507 ww, err = w.Next() 508 if err != nil { 509 t.Fatal(err) 510 } 511 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+2)); err != nil { 512 t.Fatalf("write #3: unexpected error: %v", err) 513 } 514 515 if err := w.Close(); err != nil { 516 t.Fatal(err) 517 } 518 519 b := buf.Bytes() 520 // Corrupting block #1. 521 for i := 0; i < 1024; i++ { 522 b[blockSize+i] = '1' 523 } 524 525 r := NewReader(bytes.NewReader(b), dropper{t}, false, true) 526 527 // First read (first record). 528 rr, err := r.Next() 529 if err != nil { 530 t.Fatal(err) 531 } 532 n, err := io.Copy(ioutil.Discard, rr) 533 if err != nil { 534 t.Fatalf("read #0: %v", err) 535 } 536 if want := int64(blockSize / 2); n != want { 537 t.Fatalf("read #0: got %d bytes want %d", n, want) 538 } 539 540 // Second read (second record). 541 rr, err = r.Next() 542 if err != nil { 543 t.Fatal(err) 544 } 545 n, err = io.Copy(ioutil.Discard, rr) 546 if err != io.ErrUnexpectedEOF { 547 t.Fatalf("read #1: unexpected error: %v", err) 548 } 549 550 // Third read (fourth record). 551 rr, err = r.Next() 552 if err != nil { 553 t.Fatal(err) 554 } 555 n, err = io.Copy(ioutil.Discard, rr) 556 if err != nil { 557 t.Fatalf("read #2: %v", err) 558 } 559 if want := int64(blockSize-headerSize) + 2; n != want { 560 t.Fatalf("read #2: got %d bytes want %d", n, want) 561 } 562 563 if _, err := r.Next(); err != io.EOF { 564 t.Fatalf("last next: unexpected error: %v", err) 565 } 566 } 567 568 func TestCorrupt_CorruptedLastBlock(t *testing.T) { 569 buf := new(bytes.Buffer) 570 571 w := NewWriter(buf) 572 573 // First record. 574 ww, err := w.Next() 575 if err != nil { 576 t.Fatal(err) 577 } 578 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize/2)); err != nil { 579 t.Fatalf("write #0: unexpected error: %v", err) 580 } 581 582 // Second record. 583 ww, err = w.Next() 584 if err != nil { 585 t.Fatal(err) 586 } 587 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil { 588 t.Fatalf("write #1: unexpected error: %v", err) 589 } 590 591 // Third record. 592 ww, err = w.Next() 593 if err != nil { 594 t.Fatal(err) 595 } 596 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+1)); err != nil { 597 t.Fatalf("write #2: unexpected error: %v", err) 598 } 599 600 // Fourth record. 601 ww, err = w.Next() 602 if err != nil { 603 t.Fatal(err) 604 } 605 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+2)); err != nil { 606 t.Fatalf("write #3: unexpected error: %v", err) 607 } 608 609 if err := w.Close(); err != nil { 610 t.Fatal(err) 611 } 612 613 b := buf.Bytes() 614 // Corrupting block #3. 615 for i := len(b) - 1; i > len(b)-1024; i-- { 616 b[i] = '1' 617 } 618 619 r := NewReader(bytes.NewReader(b), dropper{t}, false, true) 620 621 // First read (first record). 622 rr, err := r.Next() 623 if err != nil { 624 t.Fatal(err) 625 } 626 n, err := io.Copy(ioutil.Discard, rr) 627 if err != nil { 628 t.Fatalf("read #0: %v", err) 629 } 630 if want := int64(blockSize / 2); n != want { 631 t.Fatalf("read #0: got %d bytes want %d", n, want) 632 } 633 634 // Second read (second record). 635 rr, err = r.Next() 636 if err != nil { 637 t.Fatal(err) 638 } 639 n, err = io.Copy(ioutil.Discard, rr) 640 if err != nil { 641 t.Fatalf("read #1: %v", err) 642 } 643 if want := int64(blockSize - headerSize); n != want { 644 t.Fatalf("read #1: got %d bytes want %d", n, want) 645 } 646 647 // Third read (third record). 648 rr, err = r.Next() 649 if err != nil { 650 t.Fatal(err) 651 } 652 n, err = io.Copy(ioutil.Discard, rr) 653 if err != nil { 654 t.Fatalf("read #2: %v", err) 655 } 656 if want := int64(blockSize-headerSize) + 1; n != want { 657 t.Fatalf("read #2: got %d bytes want %d", n, want) 658 } 659 660 // Fourth read (fourth record). 661 rr, err = r.Next() 662 if err != nil { 663 t.Fatal(err) 664 } 665 n, err = io.Copy(ioutil.Discard, rr) 666 if err != io.ErrUnexpectedEOF { 667 t.Fatalf("read #3: unexpected error: %v", err) 668 } 669 670 if _, err := r.Next(); err != io.EOF { 671 t.Fatalf("last next: unexpected error: %v", err) 672 } 673 } 674 675 func TestCorrupt_FirstChuckLengthOverflow(t *testing.T) { 676 buf := new(bytes.Buffer) 677 678 w := NewWriter(buf) 679 680 // First record. 681 ww, err := w.Next() 682 if err != nil { 683 t.Fatal(err) 684 } 685 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize/2)); err != nil { 686 t.Fatalf("write #0: unexpected error: %v", err) 687 } 688 689 // Second record. 690 ww, err = w.Next() 691 if err != nil { 692 t.Fatal(err) 693 } 694 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil { 695 t.Fatalf("write #1: unexpected error: %v", err) 696 } 697 698 // Third record. 699 ww, err = w.Next() 700 if err != nil { 701 t.Fatal(err) 702 } 703 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+1)); err != nil { 704 t.Fatalf("write #2: unexpected error: %v", err) 705 } 706 707 if err := w.Close(); err != nil { 708 t.Fatal(err) 709 } 710 711 b := buf.Bytes() 712 // Corrupting record #1. 713 x := blockSize 714 binary.LittleEndian.PutUint16(b[x+4:], 0xffff) 715 716 r := NewReader(bytes.NewReader(b), dropper{t}, false, true) 717 718 // First read (first record). 719 rr, err := r.Next() 720 if err != nil { 721 t.Fatal(err) 722 } 723 n, err := io.Copy(ioutil.Discard, rr) 724 if err != nil { 725 t.Fatalf("read #0: %v", err) 726 } 727 if want := int64(blockSize / 2); n != want { 728 t.Fatalf("read #0: got %d bytes want %d", n, want) 729 } 730 731 // Second read (second record). 732 rr, err = r.Next() 733 if err != nil { 734 t.Fatal(err) 735 } 736 n, err = io.Copy(ioutil.Discard, rr) 737 if err != io.ErrUnexpectedEOF { 738 t.Fatalf("read #1: unexpected error: %v", err) 739 } 740 741 if _, err := r.Next(); err != io.EOF { 742 t.Fatalf("last next: unexpected error: %v", err) 743 } 744 } 745 746 func TestCorrupt_MiddleChuckLengthOverflow(t *testing.T) { 747 buf := new(bytes.Buffer) 748 749 w := NewWriter(buf) 750 751 // First record. 752 ww, err := w.Next() 753 if err != nil { 754 t.Fatal(err) 755 } 756 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize/2)); err != nil { 757 t.Fatalf("write #0: unexpected error: %v", err) 758 } 759 760 // Second record. 761 ww, err = w.Next() 762 if err != nil { 763 t.Fatal(err) 764 } 765 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil { 766 t.Fatalf("write #1: unexpected error: %v", err) 767 } 768 769 // Third record. 770 ww, err = w.Next() 771 if err != nil { 772 t.Fatal(err) 773 } 774 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+1)); err != nil { 775 t.Fatalf("write #2: unexpected error: %v", err) 776 } 777 778 if err := w.Close(); err != nil { 779 t.Fatal(err) 780 } 781 782 b := buf.Bytes() 783 // Corrupting record #1. 784 x := blockSize/2 + headerSize 785 binary.LittleEndian.PutUint16(b[x+4:], 0xffff) 786 787 r := NewReader(bytes.NewReader(b), dropper{t}, false, true) 788 789 // First read (first record). 790 rr, err := r.Next() 791 if err != nil { 792 t.Fatal(err) 793 } 794 n, err := io.Copy(ioutil.Discard, rr) 795 if err != nil { 796 t.Fatalf("read #0: %v", err) 797 } 798 if want := int64(blockSize / 2); n != want { 799 t.Fatalf("read #0: got %d bytes want %d", n, want) 800 } 801 802 // Second read (third record). 803 rr, err = r.Next() 804 if err != nil { 805 t.Fatal(err) 806 } 807 n, err = io.Copy(ioutil.Discard, rr) 808 if err != nil { 809 t.Fatalf("read #1: %v", err) 810 } 811 if want := int64(blockSize-headerSize) + 1; n != want { 812 t.Fatalf("read #1: got %d bytes want %d", n, want) 813 } 814 815 if _, err := r.Next(); err != io.EOF { 816 t.Fatalf("last next: unexpected error: %v", err) 817 } 818 }