1
2
3
4
5 package flate
6
7 import (
8 "bytes"
9 "fmt"
10 "io"
11 "math/rand"
12 "runtime"
13 "testing"
14 )
15
16 func BenchmarkEncode(b *testing.B) {
17 doBench(b, func(b *testing.B, buf0 []byte, level, n int) {
18 b.StopTimer()
19 b.SetBytes(int64(n))
20
21 buf1 := make([]byte, n)
22 for i := 0; i < n; i += len(buf0) {
23 if len(buf0) > n-i {
24 buf0 = buf0[:n-i]
25 }
26 copy(buf1[i:], buf0)
27 }
28 buf0 = nil
29 w, err := NewWriter(io.Discard, level)
30 if err != nil {
31 b.Fatal(err)
32 }
33 runtime.GC()
34 b.StartTimer()
35 for i := 0; i < b.N; i++ {
36 w.Reset(io.Discard)
37 w.Write(buf1)
38 w.Close()
39 }
40 })
41 }
42
43
44 type errorWriter struct {
45 N int
46 }
47
48 func (e *errorWriter) Write(b []byte) (int, error) {
49 if e.N <= 0 {
50 return 0, io.ErrClosedPipe
51 }
52 e.N--
53 return len(b), nil
54 }
55
56
57 func TestWriteError(t *testing.T) {
58 t.Parallel()
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
69 copyBuffer := make([]byte, 128)
70 for l := 0; l < 10; l++ {
71 for fail := 1; fail <= 256; fail *= 2 {
72
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, struct{ io.Reader }{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(io.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
114
115 func TestDeterministic(t *testing.T) {
116 t.Parallel()
117 for i := 0; i <= 9; i++ {
118 t.Run(fmt.Sprint("L", i), func(t *testing.T) { testDeterministic(i, t) })
119 }
120 t.Run("LM2", func(t *testing.T) { testDeterministic(-2, t) })
121 }
122
123 func testDeterministic(i int, t *testing.T) {
124 t.Parallel()
125
126 var length = maxStoreBlockSize*30 + 500
127 if testing.Short() {
128 length /= 10
129 }
130
131
132 rng := rand.New(rand.NewSource(1))
133 t1 := make([]byte, length)
134 for i := range t1 {
135 t1[i] = byte(rng.Int63() & 7)
136 }
137
138
139 var b1 bytes.Buffer
140 br := bytes.NewBuffer(t1)
141 w, err := NewWriter(&b1, i)
142 if err != nil {
143 t.Fatal(err)
144 }
145
146 cbuf := make([]byte, 787)
147 _, err = io.CopyBuffer(w, struct{ io.Reader }{br}, cbuf)
148 if err != nil {
149 t.Fatal(err)
150 }
151 w.Close()
152
153
154
155 var b2 bytes.Buffer
156 cbuf = make([]byte, 81761)
157 br2 := bytes.NewBuffer(t1)
158 w2, err := NewWriter(&b2, i)
159 if err != nil {
160 t.Fatal(err)
161 }
162 _, err = io.CopyBuffer(w2, struct{ io.Reader }{br2}, cbuf)
163 if err != nil {
164 t.Fatal(err)
165 }
166 w2.Close()
167
168 b1b := b1.Bytes()
169 b2b := b2.Bytes()
170
171 if !bytes.Equal(b1b, b2b) {
172 t.Errorf("level %d did not produce deterministic result, result mismatch, len(a) = %d, len(b) = %d", i, len(b1b), len(b2b))
173 }
174 }
175
176
177
178
179 func TestDeflateFast_Reset(t *testing.T) {
180 buf := new(bytes.Buffer)
181 n := 65536
182
183 for i := 0; i < n; i++ {
184 fmt.Fprintf(buf, "asdfasdfasdfasdf%d%dfghfgujyut%dyutyu\n", i, i, i)
185 }
186
187 const level = 1
188 in := buf.Bytes()
189 offset := 1
190 if testing.Short() {
191 offset = 256
192 }
193
194
195 var want bytes.Buffer
196 w, err := NewWriter(&want, level)
197 if err != nil {
198 t.Fatalf("NewWriter: level %d: %v", level, err)
199 }
200
201
202 w.Write(in)
203 w.Write(in)
204 w.Write(in)
205 w.Close()
206
207 for ; offset <= 256; offset *= 2 {
208 w, err := NewWriter(io.Discard, level)
209 if err != nil {
210 t.Fatalf("NewWriter: level %d: %v", level, err)
211 }
212
213
214
215 for i := 0; i < (bufferReset-len(in)-offset-maxMatchOffset)/maxMatchOffset; i++ {
216
217 w.d.reset(nil)
218 }
219 var got bytes.Buffer
220 w.Reset(&got)
221
222
223 for i := 0; i < 3; i++ {
224 _, err = w.Write(in)
225 if err != nil {
226 t.Fatal(err)
227 }
228 }
229 err = w.Close()
230 if err != nil {
231 t.Fatal(err)
232 }
233 if !bytes.Equal(got.Bytes(), want.Bytes()) {
234 t.Fatalf("output did not match at wraparound, len(want) = %d, len(got) = %d", want.Len(), got.Len())
235 }
236 }
237 }
238
View as plain text