...

Source file src/github.com/syndtr/goleveldb/leveldb/journal/journal_test.go

Documentation: github.com/syndtr/goleveldb/leveldb/journal

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

View as plain text