github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/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 BenchmarkEncode(b *testing.B) { 18 doBench(b, func(b *testing.B, buf0 []byte, level, n int) { 19 b.StopTimer() 20 b.SetBytes(int64(n)) 21 22 buf1 := make([]byte, n) 23 for i := 0; i < n; i += len(buf0) { 24 if len(buf0) > n-i { 25 buf0 = buf0[:n-i] 26 } 27 copy(buf1[i:], buf0) 28 } 29 buf0 = nil 30 w, err := NewWriter(ioutil.Discard, level) 31 if err != nil { 32 b.Fatal(err) 33 } 34 runtime.GC() 35 b.StartTimer() 36 for i := 0; i < b.N; i++ { 37 w.Reset(ioutil.Discard) 38 w.Write(buf1) 39 w.Close() 40 } 41 }) 42 } 43 44 // errorWriter is a writer that fails after N writes. 45 type errorWriter struct { 46 N int 47 } 48 49 func (e *errorWriter) Write(b []byte) (int, error) { 50 if e.N <= 0 { 51 return 0, io.ErrClosedPipe 52 } 53 e.N-- 54 return len(b), nil 55 } 56 57 // Test if errors from the underlying writer is passed upwards. 58 func TestWriteError(t *testing.T) { 59 buf := new(bytes.Buffer) 60 n := 65536 61 if !testing.Short() { 62 n *= 4 63 } 64 for i := 0; i < n; i++ { 65 fmt.Fprintf(buf, "asdasfasf%d%dfghfgujyut%dyutyu\n", i, i, i) 66 } 67 in := buf.Bytes() 68 // We create our own buffer to control number of writes. 69 copyBuffer := make([]byte, 128) 70 for l := 0; l < 10; l++ { 71 for fail := 1; fail <= 256; fail *= 2 { 72 // Fail after 'fail' writes 73 ew := &errorWriter{N: fail} 74 w, err := NewWriter(ew, l) 75 if err != nil { 76 t.Fatalf("NewWriter: level %d: %v", l, err) 77 } 78 n, err := io.CopyBuffer(w, bytes.NewBuffer(in), copyBuffer) 79 if err == nil { 80 t.Fatalf("Level %d: Expected an error, writer was %#v", l, ew) 81 } 82 n2, err := w.Write([]byte{1, 2, 2, 3, 4, 5}) 83 if n2 != 0 { 84 t.Fatal("Level", l, "Expected 0 length write, got", n) 85 } 86 if err == nil { 87 t.Fatal("Level", l, "Expected an error") 88 } 89 err = w.Flush() 90 if err == nil { 91 t.Fatal("Level", l, "Expected an error on flush") 92 } 93 err = w.Close() 94 if err == nil { 95 t.Fatal("Level", l, "Expected an error on close") 96 } 97 98 w.Reset(ioutil.Discard) 99 n2, err = w.Write([]byte{1, 2, 3, 4, 5, 6}) 100 if err != nil { 101 t.Fatal("Level", l, "Got unexpected error after reset:", err) 102 } 103 if n2 == 0 { 104 t.Fatal("Level", l, "Got 0 length write, expected > 0") 105 } 106 if testing.Short() { 107 return 108 } 109 } 110 } 111 } 112 113 // Test if two runs produce identical results 114 // even when writing different sizes to the Writer. 115 func TestDeterministic(t *testing.T) { 116 for i := 0; i <= 9; i++ { 117 t.Run(fmt.Sprint("L", i), func(t *testing.T) { testDeterministic(i, t) }) 118 } 119 t.Run("LM2", func(t *testing.T) { testDeterministic(-2, t) }) 120 } 121 122 func testDeterministic(i int, t *testing.T) { 123 // Test so much we cross a good number of block boundaries. 124 var length = maxStoreBlockSize*30 + 500 125 if testing.Short() { 126 length /= 10 127 } 128 129 // Create a random, but compressible stream. 130 rng := rand.New(rand.NewSource(1)) 131 t1 := make([]byte, length) 132 for i := range t1 { 133 t1[i] = byte(rng.Int63() & 7) 134 } 135 136 // Do our first encode. 137 var b1 bytes.Buffer 138 br := bytes.NewBuffer(t1) 139 w, err := NewWriter(&b1, i) 140 if err != nil { 141 t.Fatal(err) 142 } 143 // Use a very small prime sized buffer. 144 cbuf := make([]byte, 787) 145 _, err = io.CopyBuffer(w, br, cbuf) 146 if err != nil { 147 t.Fatal(err) 148 } 149 w.Close() 150 151 // We choose a different buffer size, 152 // bigger than a maximum block, and also a prime. 153 var b2 bytes.Buffer 154 cbuf = make([]byte, 81761) 155 br2 := bytes.NewBuffer(t1) 156 w2, err := NewWriter(&b2, i) 157 if err != nil { 158 t.Fatal(err) 159 } 160 _, err = io.CopyBuffer(w2, br2, cbuf) 161 if err != nil { 162 t.Fatal(err) 163 } 164 w2.Close() 165 166 b1b := b1.Bytes() 167 b2b := b2.Bytes() 168 169 if !bytes.Equal(b1b, b2b) { 170 t.Errorf("level %d did not produce deterministic result, result mismatch, len(a) = %d, len(b) = %d", i, len(b1b), len(b2b)) 171 } 172 }