github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/compress/flate/deflate_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 flate 6 7 import ( 8 "bytes" 9 "fmt" 10 "io" 11 "io/ioutil" 12 "sync" 13 "testing" 14 ) 15 16 type deflateTest struct { 17 in []byte 18 level int 19 out []byte 20 } 21 22 type deflateInflateTest struct { 23 in []byte 24 } 25 26 type reverseBitsTest struct { 27 in uint16 28 bitCount uint8 29 out uint16 30 } 31 32 var deflateTests = []*deflateTest{ 33 {[]byte{}, 0, []byte{1, 0, 0, 255, 255}}, 34 {[]byte{0x11}, -1, []byte{18, 4, 4, 0, 0, 255, 255}}, 35 {[]byte{0x11}, DefaultCompression, []byte{18, 4, 4, 0, 0, 255, 255}}, 36 {[]byte{0x11}, 4, []byte{18, 4, 4, 0, 0, 255, 255}}, 37 38 {[]byte{0x11}, 0, []byte{0, 1, 0, 254, 255, 17, 1, 0, 0, 255, 255}}, 39 {[]byte{0x11, 0x12}, 0, []byte{0, 2, 0, 253, 255, 17, 18, 1, 0, 0, 255, 255}}, 40 {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 0, 41 []byte{0, 8, 0, 247, 255, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0, 0, 255, 255}, 42 }, 43 {[]byte{}, 1, []byte{1, 0, 0, 255, 255}}, 44 {[]byte{0x11}, 1, []byte{18, 4, 4, 0, 0, 255, 255}}, 45 {[]byte{0x11, 0x12}, 1, []byte{18, 20, 2, 4, 0, 0, 255, 255}}, 46 {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 1, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}}, 47 {[]byte{}, 9, []byte{1, 0, 0, 255, 255}}, 48 {[]byte{0x11}, 9, []byte{18, 4, 4, 0, 0, 255, 255}}, 49 {[]byte{0x11, 0x12}, 9, []byte{18, 20, 2, 4, 0, 0, 255, 255}}, 50 {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 9, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}}, 51 } 52 53 var deflateInflateTests = []*deflateInflateTest{ 54 {[]byte{}}, 55 {[]byte{0x11}}, 56 {[]byte{0x11, 0x12}}, 57 {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}}, 58 {[]byte{0x11, 0x10, 0x13, 0x41, 0x21, 0x21, 0x41, 0x13, 0x87, 0x78, 0x13}}, 59 {largeDataChunk()}, 60 } 61 62 var reverseBitsTests = []*reverseBitsTest{ 63 {1, 1, 1}, 64 {1, 2, 2}, 65 {1, 3, 4}, 66 {1, 4, 8}, 67 {1, 5, 16}, 68 {17, 5, 17}, 69 {257, 9, 257}, 70 {29, 5, 23}, 71 } 72 73 func largeDataChunk() []byte { 74 result := make([]byte, 100000) 75 for i := range result { 76 result[i] = byte(i * i & 0xFF) 77 } 78 return result 79 } 80 81 func TestDeflate(t *testing.T) { 82 for _, h := range deflateTests { 83 var buf bytes.Buffer 84 w, err := NewWriter(&buf, h.level) 85 if err != nil { 86 t.Errorf("NewWriter: %v", err) 87 continue 88 } 89 w.Write(h.in) 90 w.Close() 91 if !bytes.Equal(buf.Bytes(), h.out) { 92 t.Errorf("Deflate(%d, %x) = %x, want %x", h.level, h.in, buf.Bytes(), h.out) 93 } 94 } 95 } 96 97 // A sparseReader returns a stream consisting of 0s followed by 1<<16 1s. 98 // This tests missing hash references in a very large input. 99 type sparseReader struct { 100 l int64 101 cur int64 102 } 103 104 func (r *sparseReader) Read(b []byte) (n int, err error) { 105 if r.cur >= r.l { 106 return 0, io.EOF 107 } 108 n = len(b) 109 cur := r.cur + int64(n) 110 if cur > r.l { 111 n -= int(cur - r.l) 112 cur = r.l 113 } 114 for i := range b[0:n] { 115 if r.cur+int64(i) >= r.l-1<<16 { 116 b[i] = 1 117 } else { 118 b[i] = 0 119 } 120 } 121 r.cur = cur 122 return 123 } 124 125 func TestVeryLongSparseChunk(t *testing.T) { 126 if testing.Short() { 127 t.Skip("skipping sparse chunk during short test") 128 } 129 w, err := NewWriter(ioutil.Discard, 1) 130 if err != nil { 131 t.Errorf("NewWriter: %v", err) 132 return 133 } 134 if _, err = io.Copy(w, &sparseReader{l: 23E8}); err != nil { 135 t.Errorf("Compress failed: %v", err) 136 return 137 } 138 } 139 140 type syncBuffer struct { 141 buf bytes.Buffer 142 mu sync.RWMutex 143 closed bool 144 ready chan bool 145 } 146 147 func newSyncBuffer() *syncBuffer { 148 return &syncBuffer{ready: make(chan bool, 1)} 149 } 150 151 func (b *syncBuffer) Read(p []byte) (n int, err error) { 152 for { 153 b.mu.RLock() 154 n, err = b.buf.Read(p) 155 b.mu.RUnlock() 156 if n > 0 || b.closed { 157 return 158 } 159 <-b.ready 160 } 161 } 162 163 func (b *syncBuffer) signal() { 164 select { 165 case b.ready <- true: 166 default: 167 } 168 } 169 170 func (b *syncBuffer) Write(p []byte) (n int, err error) { 171 n, err = b.buf.Write(p) 172 b.signal() 173 return 174 } 175 176 func (b *syncBuffer) WriteMode() { 177 b.mu.Lock() 178 } 179 180 func (b *syncBuffer) ReadMode() { 181 b.mu.Unlock() 182 b.signal() 183 } 184 185 func (b *syncBuffer) Close() error { 186 b.closed = true 187 b.signal() 188 return nil 189 } 190 191 func testSync(t *testing.T, level int, input []byte, name string) { 192 if len(input) == 0 { 193 return 194 } 195 196 t.Logf("--testSync %d, %d, %s", level, len(input), name) 197 buf := newSyncBuffer() 198 buf1 := new(bytes.Buffer) 199 buf.WriteMode() 200 w, err := NewWriter(io.MultiWriter(buf, buf1), level) 201 if err != nil { 202 t.Errorf("NewWriter: %v", err) 203 return 204 } 205 r := NewReader(buf) 206 207 // Write half the input and read back. 208 for i := 0; i < 2; i++ { 209 var lo, hi int 210 if i == 0 { 211 lo, hi = 0, (len(input)+1)/2 212 } else { 213 lo, hi = (len(input)+1)/2, len(input) 214 } 215 t.Logf("#%d: write %d-%d", i, lo, hi) 216 if _, err := w.Write(input[lo:hi]); err != nil { 217 t.Errorf("testSync: write: %v", err) 218 return 219 } 220 if i == 0 { 221 if err := w.Flush(); err != nil { 222 t.Errorf("testSync: flush: %v", err) 223 return 224 } 225 } else { 226 if err := w.Close(); err != nil { 227 t.Errorf("testSync: close: %v", err) 228 } 229 } 230 buf.ReadMode() 231 out := make([]byte, hi-lo+1) 232 m, err := io.ReadAtLeast(r, out, hi-lo) 233 t.Logf("#%d: read %d", i, m) 234 if m != hi-lo || err != nil { 235 t.Errorf("testSync/%d (%d, %d, %s): read %d: %d, %v (%d left)", i, level, len(input), name, hi-lo, m, err, buf.buf.Len()) 236 return 237 } 238 if !bytes.Equal(input[lo:hi], out[:hi-lo]) { 239 t.Errorf("testSync/%d: read wrong bytes: %x vs %x", i, input[lo:hi], out[:hi-lo]) 240 return 241 } 242 // This test originally checked that after reading 243 // the first half of the input, there was nothing left 244 // in the read buffer (buf.buf.Len() != 0) but that is 245 // not necessarily the case: the write Flush may emit 246 // some extra framing bits that are not necessary 247 // to process to obtain the first half of the uncompressed 248 // data. The test ran correctly most of the time, because 249 // the background goroutine had usually read even 250 // those extra bits by now, but it's not a useful thing to 251 // check. 252 buf.WriteMode() 253 } 254 buf.ReadMode() 255 out := make([]byte, 10) 256 if n, err := r.Read(out); n > 0 || err != io.EOF { 257 t.Errorf("testSync (%d, %d, %s): final Read: %d, %v (hex: %x)", level, len(input), name, n, err, out[0:n]) 258 } 259 if buf.buf.Len() != 0 { 260 t.Errorf("testSync (%d, %d, %s): extra data at end", level, len(input), name) 261 } 262 r.Close() 263 264 // stream should work for ordinary reader too 265 r = NewReader(buf1) 266 out, err = ioutil.ReadAll(r) 267 if err != nil { 268 t.Errorf("testSync: read: %s", err) 269 return 270 } 271 r.Close() 272 if !bytes.Equal(input, out) { 273 t.Errorf("testSync: decompress(compress(data)) != data: level=%d input=%s", level, name) 274 } 275 } 276 277 func testToFromWithLevelAndLimit(t *testing.T, level int, input []byte, name string, limit int) { 278 var buffer bytes.Buffer 279 w, err := NewWriter(&buffer, level) 280 if err != nil { 281 t.Errorf("NewWriter: %v", err) 282 return 283 } 284 w.Write(input) 285 w.Close() 286 if limit > 0 && buffer.Len() > limit { 287 t.Errorf("level: %d, len(compress(data)) = %d > limit = %d", level, buffer.Len(), limit) 288 return 289 } 290 r := NewReader(&buffer) 291 out, err := ioutil.ReadAll(r) 292 if err != nil { 293 t.Errorf("read: %s", err) 294 return 295 } 296 r.Close() 297 if !bytes.Equal(input, out) { 298 t.Errorf("decompress(compress(data)) != data: level=%d input=%s", level, name) 299 return 300 } 301 testSync(t, level, input, name) 302 } 303 304 func testToFromWithLimit(t *testing.T, input []byte, name string, limit [10]int) { 305 for i := 0; i < 10; i++ { 306 testToFromWithLevelAndLimit(t, i, input, name, limit[i]) 307 } 308 } 309 310 func TestDeflateInflate(t *testing.T) { 311 for i, h := range deflateInflateTests { 312 testToFromWithLimit(t, h.in, fmt.Sprintf("#%d", i), [10]int{}) 313 } 314 } 315 316 func TestReverseBits(t *testing.T) { 317 for _, h := range reverseBitsTests { 318 if v := reverseBits(h.in, h.bitCount); v != h.out { 319 t.Errorf("reverseBits(%v,%v) = %v, want %v", 320 h.in, h.bitCount, v, h.out) 321 } 322 } 323 } 324 325 type deflateInflateStringTest struct { 326 filename string 327 label string 328 limit [10]int 329 } 330 331 var deflateInflateStringTests = []deflateInflateStringTest{ 332 { 333 "../testdata/e.txt", 334 "2.718281828...", 335 [...]int{100018, 50650, 50960, 51150, 50930, 50790, 50790, 50790, 50790, 50790}, 336 }, 337 { 338 "../testdata/Mark.Twain-Tom.Sawyer.txt", 339 "Mark.Twain-Tom.Sawyer", 340 [...]int{407330, 187598, 180361, 172974, 169160, 163476, 160936, 160506, 160295, 160295}, 341 }, 342 } 343 344 func TestDeflateInflateString(t *testing.T) { 345 for _, test := range deflateInflateStringTests { 346 gold, err := ioutil.ReadFile(test.filename) 347 if err != nil { 348 t.Error(err) 349 } 350 testToFromWithLimit(t, gold, test.label, test.limit) 351 if testing.Short() { 352 break 353 } 354 } 355 } 356 357 func TestReaderDict(t *testing.T) { 358 const ( 359 dict = "hello world" 360 text = "hello again world" 361 ) 362 var b bytes.Buffer 363 w, err := NewWriter(&b, 5) 364 if err != nil { 365 t.Fatalf("NewWriter: %v", err) 366 } 367 w.Write([]byte(dict)) 368 w.Flush() 369 b.Reset() 370 w.Write([]byte(text)) 371 w.Close() 372 373 r := NewReaderDict(&b, []byte(dict)) 374 data, err := ioutil.ReadAll(r) 375 if err != nil { 376 t.Fatal(err) 377 } 378 if string(data) != "hello again world" { 379 t.Fatalf("read returned %q want %q", string(data), text) 380 } 381 } 382 383 func TestWriterDict(t *testing.T) { 384 const ( 385 dict = "hello world" 386 text = "hello again world" 387 ) 388 var b bytes.Buffer 389 w, err := NewWriter(&b, 5) 390 if err != nil { 391 t.Fatalf("NewWriter: %v", err) 392 } 393 w.Write([]byte(dict)) 394 w.Flush() 395 b.Reset() 396 w.Write([]byte(text)) 397 w.Close() 398 399 var b1 bytes.Buffer 400 w, _ = NewWriterDict(&b1, 5, []byte(dict)) 401 w.Write([]byte(text)) 402 w.Close() 403 404 if !bytes.Equal(b1.Bytes(), b.Bytes()) { 405 t.Fatalf("writer wrote %q want %q", b1.Bytes(), b.Bytes()) 406 } 407 } 408 409 // See http://code.google.com/p/go/issues/detail?id=2508 410 func TestRegression2508(t *testing.T) { 411 if testing.Short() { 412 t.Logf("test disabled with -short") 413 return 414 } 415 w, err := NewWriter(ioutil.Discard, 1) 416 if err != nil { 417 t.Fatalf("NewWriter: %v", err) 418 } 419 buf := make([]byte, 1024) 420 for i := 0; i < 131072; i++ { 421 if _, err := w.Write(buf); err != nil { 422 t.Fatalf("writer failed: %v", err) 423 } 424 } 425 w.Close() 426 }