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  }