You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

818 lines
18 KiB

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