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.
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
28 func (d dropper) Drop(err error) {
32 func short(s string) string {
36 return fmt.Sprintf("%s...(skipping %d bytes)...%s", s[:20], len(s)-40, s[len(s)-20:])
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]
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)
52 func testGenerator(t *testing.T, reset func(), gen func() (string, bool)) {
53 buf := new(bytes.Buffer)
66 if _, err := ww.Write([]byte(s)); err != nil {
70 if err := w.Close(); err != nil {
75 r := NewReader(buf, dropper{t}, true, true)
85 x, err := ioutil.ReadAll(rr)
90 t.Fatalf("got %q, want %q", short(string(x)), short(s))
93 if _, err := r.Next(); err != io.EOF {
94 t.Fatalf("got %v, want %v", err, io.EOF)
98 func testLiterals(t *testing.T, s []string) {
103 gen := func() (string, bool) {
110 testGenerator(t, reset, gen)
113 func TestMany(t *testing.T) {
119 gen := func() (string, bool) {
124 return fmt.Sprintf("%d.", i-1), true
126 testGenerator(t, reset, gen)
129 func TestRandom(t *testing.T) {
136 i, r = 0, rand.New(rand.NewSource(0))
138 gen := func() (string, bool) {
143 return strings.Repeat(string(uint8(i)), r.Intn(2*blockSize+16)), true
145 testGenerator(t, reset, gen)
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),
156 func TestBoundary(t *testing.T) {
157 for i := blockSize - 16; i < blockSize+16; 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})
168 func TestFlush(t *testing.T) {
169 buf := new(bytes.Buffer)
171 // Write a couple of records. Everything should still be held
172 // in the record.Writer buffer, so that buf.Len should be 0.
174 w0.Write([]byte("0"))
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)
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 {
185 if got, want := buf.Len(), 17; got != want {
186 t.Fatalf("buffer length #1: got %d want %d", got, want)
188 // Do another write, one that isn't large enough to complete the block.
189 // The write should not have flowed through to buf.
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)
195 // Flushing should get us up to 10024 bytes written.
196 // 10024 = 17 + 7 + 10000.
197 if err := w.Flush(); err != nil {
200 if got, want := buf.Len(), 10024; got != want {
201 t.Fatalf("buffer length #3: got %d want %d", got, want)
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.
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)
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 {
217 if got, want := buf.Len(), 50038; got != want {
218 t.Fatalf("buffer length #5: got %d want %d", got, want)
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 {
225 n, err := io.Copy(ioutil.Discard, rr)
227 t.Fatalf("read #%d: %v", i, err)
230 t.Fatalf("read #%d: got %d bytes want %d", i, n, want)
235 func TestNonExhaustiveRead(t *testing.T) {
237 buf := new(bytes.Buffer)
238 p := make([]byte, 10)
239 rnd := rand.New(rand.NewSource(1))
242 for i := 0; i < n; i++ {
243 length := len(p) + rnd.Intn(3*blockSize)
244 s := string(uint8(i)) + "123456789abcdefgh"
246 ww.Write([]byte(big(s, length)))
248 if err := w.Close(); err != nil {
252 r := NewReader(buf, dropper{t}, true, true)
253 for i := 0; i < n; i++ {
255 _, err := io.ReadFull(rr, p)
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)
266 func TestStaleReader(t *testing.T) {
267 buf := new(bytes.Buffer)
274 w0.Write([]byte("0"))
279 w1.Write([]byte("11"))
280 if err := w.Close(); err != nil {
284 r := NewReader(buf, dropper{t}, true, true)
294 if _, err := r0.Read(p); err == nil || !strings.Contains(err.Error(), "stale") {
295 t.Fatalf("stale read #0: unexpected error: %v", err)
297 if _, err := r1.Read(p); err != nil {
298 t.Fatalf("fresh read #1: got %v want nil error", err)
301 t.Fatalf("fresh read #1: byte contents: got '%c' want '1'", p[0])
305 func TestStaleWriter(t *testing.T) {
306 buf := new(bytes.Buffer)
317 if _, err := w0.Write([]byte("0")); err == nil || !strings.Contains(err.Error(), "stale") {
318 t.Fatalf("stale write #0: unexpected error: %v", err)
320 if _, err := w1.Write([]byte("11")); err != nil {
321 t.Fatalf("fresh write #1: got %v want nil error", err)
323 if err := w.Flush(); err != nil {
324 t.Fatalf("flush: %v", err)
326 if _, err := w1.Write([]byte("0")); err == nil || !strings.Contains(err.Error(), "stale") {
327 t.Fatalf("stale write #1: unexpected error: %v", err)
331 func TestCorrupt_MissingLastBlock(t *testing.T) {
332 buf := new(bytes.Buffer)
341 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-1024)); err != nil {
342 t.Fatalf("write #0: unexpected error: %v", err)
350 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil {
351 t.Fatalf("write #1: unexpected error: %v", err)
354 if err := w.Close(); err != nil {
358 // Cut the last block.
359 b := buf.Bytes()[:blockSize]
360 r := NewReader(bytes.NewReader(b), dropper{t}, false, true)
367 n, err := io.Copy(ioutil.Discard, rr)
369 t.Fatalf("read #0: %v", err)
371 if n != blockSize-1024 {
372 t.Fatalf("read #0: got %d bytes want %d", n, blockSize-1024)
380 n, err = io.Copy(ioutil.Discard, rr)
381 if err != io.ErrUnexpectedEOF {
382 t.Fatalf("read #1: unexpected error: %v", err)
385 if _, err := r.Next(); err != io.EOF {
386 t.Fatalf("last next: unexpected error: %v", err)
390 func TestCorrupt_CorruptedFirstBlock(t *testing.T) {
391 buf := new(bytes.Buffer)
400 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize/2)); err != nil {
401 t.Fatalf("write #0: unexpected error: %v", err)
409 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil {
410 t.Fatalf("write #1: unexpected error: %v", err)
418 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+1)); err != nil {
419 t.Fatalf("write #2: unexpected error: %v", err)
427 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+2)); err != nil {
428 t.Fatalf("write #3: unexpected error: %v", err)
431 if err := w.Close(); err != nil {
436 // Corrupting block #0.
437 for i := 0; i < 1024; i++ {
441 r := NewReader(bytes.NewReader(b), dropper{t}, false, true)
443 // First read (third record).
448 n, err := io.Copy(ioutil.Discard, rr)
450 t.Fatalf("read #0: %v", err)
452 if want := int64(blockSize-headerSize) + 1; n != want {
453 t.Fatalf("read #0: got %d bytes want %d", n, want)
456 // Second read (fourth record).
461 n, err = io.Copy(ioutil.Discard, rr)
463 t.Fatalf("read #1: %v", err)
465 if want := int64(blockSize-headerSize) + 2; n != want {
466 t.Fatalf("read #1: got %d bytes want %d", n, want)
469 if _, err := r.Next(); err != io.EOF {
470 t.Fatalf("last next: unexpected error: %v", err)
474 func TestCorrupt_CorruptedMiddleBlock(t *testing.T) {
475 buf := new(bytes.Buffer)
484 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize/2)); err != nil {
485 t.Fatalf("write #0: unexpected error: %v", err)
493 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil {
494 t.Fatalf("write #1: unexpected error: %v", err)
502 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+1)); err != nil {
503 t.Fatalf("write #2: unexpected error: %v", err)
511 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+2)); err != nil {
512 t.Fatalf("write #3: unexpected error: %v", err)
515 if err := w.Close(); err != nil {
520 // Corrupting block #1.
521 for i := 0; i < 1024; i++ {
525 r := NewReader(bytes.NewReader(b), dropper{t}, false, true)
527 // First read (first record).
532 n, err := io.Copy(ioutil.Discard, rr)
534 t.Fatalf("read #0: %v", err)
536 if want := int64(blockSize / 2); n != want {
537 t.Fatalf("read #0: got %d bytes want %d", n, want)
540 // Second read (second record).
545 n, err = io.Copy(ioutil.Discard, rr)
546 if err != io.ErrUnexpectedEOF {
547 t.Fatalf("read #1: unexpected error: %v", err)
550 // Third read (fourth record).
555 n, err = io.Copy(ioutil.Discard, rr)
557 t.Fatalf("read #2: %v", err)
559 if want := int64(blockSize-headerSize) + 2; n != want {
560 t.Fatalf("read #2: got %d bytes want %d", n, want)
563 if _, err := r.Next(); err != io.EOF {
564 t.Fatalf("last next: unexpected error: %v", err)
568 func TestCorrupt_CorruptedLastBlock(t *testing.T) {
569 buf := new(bytes.Buffer)
578 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize/2)); err != nil {
579 t.Fatalf("write #0: unexpected error: %v", err)
587 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil {
588 t.Fatalf("write #1: unexpected error: %v", err)
596 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+1)); err != nil {
597 t.Fatalf("write #2: unexpected error: %v", err)
605 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+2)); err != nil {
606 t.Fatalf("write #3: unexpected error: %v", err)
609 if err := w.Close(); err != nil {
614 // Corrupting block #3.
615 for i := len(b) - 1; i > len(b)-1024; i-- {
619 r := NewReader(bytes.NewReader(b), dropper{t}, false, true)
621 // First read (first record).
626 n, err := io.Copy(ioutil.Discard, rr)
628 t.Fatalf("read #0: %v", err)
630 if want := int64(blockSize / 2); n != want {
631 t.Fatalf("read #0: got %d bytes want %d", n, want)
634 // Second read (second record).
639 n, err = io.Copy(ioutil.Discard, rr)
641 t.Fatalf("read #1: %v", err)
643 if want := int64(blockSize - headerSize); n != want {
644 t.Fatalf("read #1: got %d bytes want %d", n, want)
647 // Third read (third record).
652 n, err = io.Copy(ioutil.Discard, rr)
654 t.Fatalf("read #2: %v", err)
656 if want := int64(blockSize-headerSize) + 1; n != want {
657 t.Fatalf("read #2: got %d bytes want %d", n, want)
660 // Fourth read (fourth record).
665 n, err = io.Copy(ioutil.Discard, rr)
666 if err != io.ErrUnexpectedEOF {
667 t.Fatalf("read #3: unexpected error: %v", err)
670 if _, err := r.Next(); err != io.EOF {
671 t.Fatalf("last next: unexpected error: %v", err)
675 func TestCorrupt_FirstChuckLengthOverflow(t *testing.T) {
676 buf := new(bytes.Buffer)
685 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize/2)); err != nil {
686 t.Fatalf("write #0: unexpected error: %v", err)
694 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil {
695 t.Fatalf("write #1: unexpected error: %v", err)
703 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+1)); err != nil {
704 t.Fatalf("write #2: unexpected error: %v", err)
707 if err := w.Close(); err != nil {
712 // Corrupting record #1.
714 binary.LittleEndian.PutUint16(b[x+4:], 0xffff)
716 r := NewReader(bytes.NewReader(b), dropper{t}, false, true)
718 // First read (first record).
723 n, err := io.Copy(ioutil.Discard, rr)
725 t.Fatalf("read #0: %v", err)
727 if want := int64(blockSize / 2); n != want {
728 t.Fatalf("read #0: got %d bytes want %d", n, want)
731 // Second read (second record).
736 n, err = io.Copy(ioutil.Discard, rr)
737 if err != io.ErrUnexpectedEOF {
738 t.Fatalf("read #1: unexpected error: %v", err)
741 if _, err := r.Next(); err != io.EOF {
742 t.Fatalf("last next: unexpected error: %v", err)
746 func TestCorrupt_MiddleChuckLengthOverflow(t *testing.T) {
747 buf := new(bytes.Buffer)
756 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize/2)); err != nil {
757 t.Fatalf("write #0: unexpected error: %v", err)
765 if _, err := ww.Write(bytes.Repeat([]byte("0"), blockSize-headerSize)); err != nil {
766 t.Fatalf("write #1: unexpected error: %v", err)
774 if _, err := ww.Write(bytes.Repeat([]byte("0"), (blockSize-headerSize)+1)); err != nil {
775 t.Fatalf("write #2: unexpected error: %v", err)
778 if err := w.Close(); err != nil {
783 // Corrupting record #1.
784 x := blockSize/2 + headerSize
785 binary.LittleEndian.PutUint16(b[x+4:], 0xffff)
787 r := NewReader(bytes.NewReader(b), dropper{t}, false, true)
789 // First read (first record).
794 n, err := io.Copy(ioutil.Discard, rr)
796 t.Fatalf("read #0: %v", err)
798 if want := int64(blockSize / 2); n != want {
799 t.Fatalf("read #0: got %d bytes want %d", n, want)
802 // Second read (third record).
807 n, err = io.Copy(ioutil.Discard, rr)
809 t.Fatalf("read #1: %v", err)
811 if want := int64(blockSize-headerSize) + 1; n != want {
812 t.Fatalf("read #1: got %d bytes want %d", n, want)
815 if _, err := r.Next(); err != io.EOF {
816 t.Fatalf("last next: unexpected error: %v", err)