github.com/miolini/go@v0.0.0-20160405192216-fca68c8cb408/src/compress/flate/writer_test.go (about)

     1  // Copyright 2012 The 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  package flate
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io"
    11  	"io/ioutil"
    12  	"math/rand"
    13  	"runtime"
    14  	"testing"
    15  )
    16  
    17  func benchmarkEncoder(b *testing.B, testfile, level, n int) {
    18  	b.StopTimer()
    19  	b.SetBytes(int64(n))
    20  	buf0, err := ioutil.ReadFile(testfiles[testfile])
    21  	if err != nil {
    22  		b.Fatal(err)
    23  	}
    24  	if len(buf0) == 0 {
    25  		b.Fatalf("test file %q has no data", testfiles[testfile])
    26  	}
    27  	buf1 := make([]byte, n)
    28  	for i := 0; i < n; i += len(buf0) {
    29  		if len(buf0) > n-i {
    30  			buf0 = buf0[:n-i]
    31  		}
    32  		copy(buf1[i:], buf0)
    33  	}
    34  	buf0 = nil
    35  	w, err := NewWriter(ioutil.Discard, level)
    36  	if err != nil {
    37  		b.Fatal(err)
    38  	}
    39  	runtime.GC()
    40  	b.StartTimer()
    41  	for i := 0; i < b.N; i++ {
    42  		w.Reset(ioutil.Discard)
    43  		w.Write(buf1)
    44  		w.Close()
    45  	}
    46  }
    47  
    48  func BenchmarkEncodeDigitsHuffman1e4(b *testing.B)  { benchmarkEncoder(b, digits, huffman, 1e4) }
    49  func BenchmarkEncodeDigitsHuffman1e5(b *testing.B)  { benchmarkEncoder(b, digits, huffman, 1e5) }
    50  func BenchmarkEncodeDigitsHuffman1e6(b *testing.B)  { benchmarkEncoder(b, digits, huffman, 1e6) }
    51  func BenchmarkEncodeDigitsSpeed1e4(b *testing.B)    { benchmarkEncoder(b, digits, speed, 1e4) }
    52  func BenchmarkEncodeDigitsSpeed1e5(b *testing.B)    { benchmarkEncoder(b, digits, speed, 1e5) }
    53  func BenchmarkEncodeDigitsSpeed1e6(b *testing.B)    { benchmarkEncoder(b, digits, speed, 1e6) }
    54  func BenchmarkEncodeDigitsDefault1e4(b *testing.B)  { benchmarkEncoder(b, digits, default_, 1e4) }
    55  func BenchmarkEncodeDigitsDefault1e5(b *testing.B)  { benchmarkEncoder(b, digits, default_, 1e5) }
    56  func BenchmarkEncodeDigitsDefault1e6(b *testing.B)  { benchmarkEncoder(b, digits, default_, 1e6) }
    57  func BenchmarkEncodeDigitsCompress1e4(b *testing.B) { benchmarkEncoder(b, digits, compress, 1e4) }
    58  func BenchmarkEncodeDigitsCompress1e5(b *testing.B) { benchmarkEncoder(b, digits, compress, 1e5) }
    59  func BenchmarkEncodeDigitsCompress1e6(b *testing.B) { benchmarkEncoder(b, digits, compress, 1e6) }
    60  func BenchmarkEncodeTwainHuffman1e4(b *testing.B)   { benchmarkEncoder(b, twain, huffman, 1e4) }
    61  func BenchmarkEncodeTwainHuffman1e5(b *testing.B)   { benchmarkEncoder(b, twain, huffman, 1e5) }
    62  func BenchmarkEncodeTwainHuffman1e6(b *testing.B)   { benchmarkEncoder(b, twain, huffman, 1e6) }
    63  func BenchmarkEncodeTwainSpeed1e4(b *testing.B)     { benchmarkEncoder(b, twain, speed, 1e4) }
    64  func BenchmarkEncodeTwainSpeed1e5(b *testing.B)     { benchmarkEncoder(b, twain, speed, 1e5) }
    65  func BenchmarkEncodeTwainSpeed1e6(b *testing.B)     { benchmarkEncoder(b, twain, speed, 1e6) }
    66  func BenchmarkEncodeTwainDefault1e4(b *testing.B)   { benchmarkEncoder(b, twain, default_, 1e4) }
    67  func BenchmarkEncodeTwainDefault1e5(b *testing.B)   { benchmarkEncoder(b, twain, default_, 1e5) }
    68  func BenchmarkEncodeTwainDefault1e6(b *testing.B)   { benchmarkEncoder(b, twain, default_, 1e6) }
    69  func BenchmarkEncodeTwainCompress1e4(b *testing.B)  { benchmarkEncoder(b, twain, compress, 1e4) }
    70  func BenchmarkEncodeTwainCompress1e5(b *testing.B)  { benchmarkEncoder(b, twain, compress, 1e5) }
    71  func BenchmarkEncodeTwainCompress1e6(b *testing.B)  { benchmarkEncoder(b, twain, compress, 1e6) }
    72  
    73  // errorWriter is a writer that fails after N writes.
    74  type errorWriter struct {
    75  	N int
    76  }
    77  
    78  func (e *errorWriter) Write(b []byte) (int, error) {
    79  	if e.N <= 0 {
    80  		return 0, io.ErrClosedPipe
    81  	}
    82  	e.N--
    83  	return len(b), nil
    84  }
    85  
    86  // Test if errors from the underlying writer is passed upwards.
    87  func TestWriteError(t *testing.T) {
    88  	buf := new(bytes.Buffer)
    89  	for i := 0; i < 1024*1024; i++ {
    90  		buf.WriteString(fmt.Sprintf("asdasfasf%d%dfghfgujyut%dyutyu\n", i, i, i))
    91  	}
    92  	in := buf.Bytes()
    93  	// We create our own buffer to control number of writes.
    94  	copyBuffer := make([]byte, 1024)
    95  	for l := 0; l < 10; l++ {
    96  		for fail := 1; fail <= 512; fail *= 2 {
    97  			// Fail after 'fail' writes
    98  			ew := &errorWriter{N: fail}
    99  			w, err := NewWriter(ew, l)
   100  			if err != nil {
   101  				t.Fatalf("NewWriter: level %d: %v", l, err)
   102  			}
   103  			n, err := io.CopyBuffer(w, bytes.NewBuffer(in), copyBuffer)
   104  			if err == nil {
   105  				t.Fatalf("Level %d: Expected an error, writer was %#v", l, ew)
   106  			}
   107  			n2, err := w.Write([]byte{1, 2, 2, 3, 4, 5})
   108  			if n2 != 0 {
   109  				t.Fatal("Level", l, "Expected 0 length write, got", n)
   110  			}
   111  			if err == nil {
   112  				t.Fatal("Level", l, "Expected an error")
   113  			}
   114  			err = w.Flush()
   115  			if err == nil {
   116  				t.Fatal("Level", l, "Expected an error on flush")
   117  			}
   118  			err = w.Close()
   119  			if err == nil {
   120  				t.Fatal("Level", l, "Expected an error on close")
   121  			}
   122  
   123  			w.Reset(ioutil.Discard)
   124  			n2, err = w.Write([]byte{1, 2, 3, 4, 5, 6})
   125  			if err != nil {
   126  				t.Fatal("Level", l, "Got unexpected error after reset:", err)
   127  			}
   128  			if n2 == 0 {
   129  				t.Fatal("Level", l, "Got 0 length write, expected > 0")
   130  			}
   131  			if testing.Short() {
   132  				return
   133  			}
   134  		}
   135  	}
   136  }
   137  
   138  // Test if two runs produce identical results
   139  // even when writing different sizes to the Writer.
   140  func TestDeterministicL0(t *testing.T)  { testDeterministic(0, t) }
   141  func TestDeterministicL1(t *testing.T)  { testDeterministic(1, t) }
   142  func TestDeterministicL2(t *testing.T)  { testDeterministic(2, t) }
   143  func TestDeterministicL3(t *testing.T)  { testDeterministic(3, t) }
   144  func TestDeterministicL4(t *testing.T)  { testDeterministic(4, t) }
   145  func TestDeterministicL5(t *testing.T)  { testDeterministic(5, t) }
   146  func TestDeterministicL6(t *testing.T)  { testDeterministic(6, t) }
   147  func TestDeterministicL7(t *testing.T)  { testDeterministic(7, t) }
   148  func TestDeterministicL8(t *testing.T)  { testDeterministic(8, t) }
   149  func TestDeterministicL9(t *testing.T)  { testDeterministic(9, t) }
   150  func TestDeterministicLM2(t *testing.T) { testDeterministic(-2, t) }
   151  
   152  func testDeterministic(i int, t *testing.T) {
   153  	// Test so much we cross a good number of block boundaries.
   154  	var length = maxStoreBlockSize*30 + 500
   155  	if testing.Short() {
   156  		length /= 10
   157  	}
   158  
   159  	// Create a random, but compressible stream.
   160  	rng := rand.New(rand.NewSource(1))
   161  	t1 := make([]byte, length)
   162  	for i := range t1 {
   163  		t1[i] = byte(rng.Int63() & 7)
   164  	}
   165  
   166  	// Do our first encode.
   167  	var b1 bytes.Buffer
   168  	br := bytes.NewBuffer(t1)
   169  	w, err := NewWriter(&b1, i)
   170  	if err != nil {
   171  		t.Fatal(err)
   172  	}
   173  	// Use a very small prime sized buffer.
   174  	cbuf := make([]byte, 787)
   175  	_, err = io.CopyBuffer(w, br, cbuf)
   176  	if err != nil {
   177  		t.Fatal(err)
   178  	}
   179  	w.Close()
   180  
   181  	// We choose a different buffer size,
   182  	// bigger than a maximum block, and also a prime.
   183  	var b2 bytes.Buffer
   184  	cbuf = make([]byte, 81761)
   185  	br2 := bytes.NewBuffer(t1)
   186  	w2, err := NewWriter(&b2, i)
   187  	if err != nil {
   188  		t.Fatal(err)
   189  	}
   190  	_, err = io.CopyBuffer(w2, br2, cbuf)
   191  	if err != nil {
   192  		t.Fatal(err)
   193  	}
   194  	w2.Close()
   195  
   196  	b1b := b1.Bytes()
   197  	b2b := b2.Bytes()
   198  
   199  	if !bytes.Equal(b1b, b2b) {
   200  		t.Errorf("level %d did not produce deterministic result, result mismatch, len(a) = %d, len(b) = %d", i, len(b1b), len(b2b))
   201  	}
   202  }