1
2
3
4
5 package zlib
6
7 import (
8 "bytes"
9 "fmt"
10 "internal/testenv"
11 "io"
12 "os"
13 "testing"
14 )
15
16 var filenames = []string{
17 "../testdata/gettysburg.txt",
18 "../testdata/e.txt",
19 "../testdata/pi.txt",
20 }
21
22 var data = []string{
23 "test a reasonable sized string that can be compressed",
24 }
25
26
27
28 func testFileLevelDict(t *testing.T, fn string, level int, d string) {
29
30 golden, err := os.Open(fn)
31 if err != nil {
32 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
33 return
34 }
35 defer golden.Close()
36 b0, err0 := io.ReadAll(golden)
37 if err0 != nil {
38 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err0)
39 return
40 }
41 testLevelDict(t, fn, b0, level, d)
42 }
43
44 func testLevelDict(t *testing.T, fn string, b0 []byte, level int, d string) {
45
46 var dict []byte
47 if d != "" {
48 dict = []byte(d)
49 }
50
51
52 piper, pipew := io.Pipe()
53 defer piper.Close()
54 go func() {
55 defer pipew.Close()
56 zlibw, err := NewWriterLevelDict(pipew, level, dict)
57 if err != nil {
58 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
59 return
60 }
61 defer zlibw.Close()
62 _, err = zlibw.Write(b0)
63 if err != nil {
64 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
65 return
66 }
67 }()
68 zlibr, err := NewReaderDict(piper, dict)
69 if err != nil {
70 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err)
71 return
72 }
73 defer zlibr.Close()
74
75
76 b1, err1 := io.ReadAll(zlibr)
77 if err1 != nil {
78 t.Errorf("%s (level=%d, dict=%q): %v", fn, level, d, err1)
79 return
80 }
81 if len(b0) != len(b1) {
82 t.Errorf("%s (level=%d, dict=%q): length mismatch %d versus %d", fn, level, d, len(b0), len(b1))
83 return
84 }
85 for i := 0; i < len(b0); i++ {
86 if b0[i] != b1[i] {
87 t.Errorf("%s (level=%d, dict=%q): mismatch at %d, 0x%02x versus 0x%02x\n", fn, level, d, i, b0[i], b1[i])
88 return
89 }
90 }
91 }
92
93 func testFileLevelDictReset(t *testing.T, fn string, level int, dict []byte) {
94 var b0 []byte
95 var err error
96 if fn != "" {
97 b0, err = os.ReadFile(fn)
98 if err != nil {
99 t.Errorf("%s (level=%d): %v", fn, level, err)
100 return
101 }
102 }
103
104
105 buf := new(bytes.Buffer)
106 var zlibw *Writer
107 if dict == nil {
108 zlibw, err = NewWriterLevel(buf, level)
109 } else {
110 zlibw, err = NewWriterLevelDict(buf, level, dict)
111 }
112 if err == nil {
113 _, err = zlibw.Write(b0)
114 }
115 if err == nil {
116 err = zlibw.Close()
117 }
118 if err != nil {
119 t.Errorf("%s (level=%d): %v", fn, level, err)
120 return
121 }
122 out := buf.String()
123
124
125 buf2 := new(bytes.Buffer)
126 zlibw.Reset(buf2)
127 _, err = zlibw.Write(b0)
128 if err == nil {
129 err = zlibw.Close()
130 }
131 if err != nil {
132 t.Errorf("%s (level=%d): %v", fn, level, err)
133 return
134 }
135 out2 := buf2.String()
136
137 if out2 != out {
138 t.Errorf("%s (level=%d): different output after reset (got %d bytes, expected %d",
139 fn, level, len(out2), len(out))
140 }
141 }
142
143 func TestWriter(t *testing.T) {
144 for i, s := range data {
145 b := []byte(s)
146 tag := fmt.Sprintf("#%d", i)
147 testLevelDict(t, tag, b, DefaultCompression, "")
148 testLevelDict(t, tag, b, NoCompression, "")
149 testLevelDict(t, tag, b, HuffmanOnly, "")
150 for level := BestSpeed; level <= BestCompression; level++ {
151 testLevelDict(t, tag, b, level, "")
152 }
153 }
154 }
155
156 func TestWriterBig(t *testing.T) {
157 for i, fn := range filenames {
158 testFileLevelDict(t, fn, DefaultCompression, "")
159 testFileLevelDict(t, fn, NoCompression, "")
160 testFileLevelDict(t, fn, HuffmanOnly, "")
161 for level := BestSpeed; level <= BestCompression; level++ {
162 testFileLevelDict(t, fn, level, "")
163 if level >= 1 && testing.Short() && testenv.Builder() == "" {
164 break
165 }
166 }
167 if i == 0 && testing.Short() && testenv.Builder() == "" {
168 break
169 }
170 }
171 }
172
173 func TestWriterDict(t *testing.T) {
174 const dictionary = "0123456789."
175 for i, fn := range filenames {
176 testFileLevelDict(t, fn, DefaultCompression, dictionary)
177 testFileLevelDict(t, fn, NoCompression, dictionary)
178 testFileLevelDict(t, fn, HuffmanOnly, dictionary)
179 for level := BestSpeed; level <= BestCompression; level++ {
180 testFileLevelDict(t, fn, level, dictionary)
181 if level >= 1 && testing.Short() && testenv.Builder() == "" {
182 break
183 }
184 }
185 if i == 0 && testing.Short() && testenv.Builder() == "" {
186 break
187 }
188 }
189 }
190
191 func TestWriterReset(t *testing.T) {
192 const dictionary = "0123456789."
193 for _, fn := range filenames {
194 testFileLevelDictReset(t, fn, NoCompression, nil)
195 testFileLevelDictReset(t, fn, DefaultCompression, nil)
196 testFileLevelDictReset(t, fn, HuffmanOnly, nil)
197 testFileLevelDictReset(t, fn, NoCompression, []byte(dictionary))
198 testFileLevelDictReset(t, fn, DefaultCompression, []byte(dictionary))
199 testFileLevelDictReset(t, fn, HuffmanOnly, []byte(dictionary))
200 if testing.Short() {
201 break
202 }
203 for level := BestSpeed; level <= BestCompression; level++ {
204 testFileLevelDictReset(t, fn, level, nil)
205 }
206 }
207 }
208
209 func TestWriterDictIsUsed(t *testing.T) {
210 var input = []byte("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.")
211 var buf bytes.Buffer
212 compressor, err := NewWriterLevelDict(&buf, BestCompression, input)
213 if err != nil {
214 t.Errorf("error in NewWriterLevelDict: %s", err)
215 return
216 }
217 compressor.Write(input)
218 compressor.Close()
219 const expectedMaxSize = 25
220 output := buf.Bytes()
221 if len(output) > expectedMaxSize {
222 t.Errorf("result too large (got %d, want <= %d bytes). Is the dictionary being used?", len(output), expectedMaxSize)
223 }
224 }
225
View as plain text