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