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 }