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