github.com/euank/go@v0.0.0-20160829210321-495514729181/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 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 for level := BestSpeed; level <= BestCompression; level++ { 161 testFileLevelDict(t, fn, level, "") 162 if level >= 1 && testing.Short() && testenv.Builder() == "" { 163 break 164 } 165 } 166 if i == 0 && testing.Short() && testenv.Builder() == "" { 167 break 168 } 169 } 170 } 171 172 func TestWriterDict(t *testing.T) { 173 const dictionary = "0123456789." 174 for i, fn := range filenames { 175 testFileLevelDict(t, fn, DefaultCompression, dictionary) 176 testFileLevelDict(t, fn, NoCompression, dictionary) 177 for level := BestSpeed; level <= BestCompression; level++ { 178 testFileLevelDict(t, fn, level, dictionary) 179 if level >= 1 && testing.Short() && testenv.Builder() == "" { 180 break 181 } 182 } 183 if i == 0 && testing.Short() && testenv.Builder() == "" { 184 break 185 } 186 } 187 } 188 189 func TestWriterReset(t *testing.T) { 190 const dictionary = "0123456789." 191 for _, fn := range filenames { 192 testFileLevelDictReset(t, fn, NoCompression, nil) 193 testFileLevelDictReset(t, fn, DefaultCompression, nil) 194 testFileLevelDictReset(t, fn, NoCompression, []byte(dictionary)) 195 testFileLevelDictReset(t, fn, DefaultCompression, []byte(dictionary)) 196 if testing.Short() { 197 break 198 } 199 for level := BestSpeed; level <= BestCompression; level++ { 200 testFileLevelDictReset(t, fn, level, nil) 201 } 202 } 203 } 204 205 func TestWriterDictIsUsed(t *testing.T) { 206 var input = []byte("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.") 207 var buf bytes.Buffer 208 compressor, err := NewWriterLevelDict(&buf, BestCompression, input) 209 if err != nil { 210 t.Errorf("error in NewWriterLevelDict: %s", err) 211 return 212 } 213 compressor.Write(input) 214 compressor.Close() 215 const expectedMaxSize = 25 216 output := buf.Bytes() 217 if len(output) > expectedMaxSize { 218 t.Errorf("result too large (got %d, want <= %d bytes). Is the dictionary being used?", len(output), expectedMaxSize) 219 } 220 }