github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/klauspost/compress/flate/deflate_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Copyright (c) 2015 Klaus Post 3 // Use of this source code is governed by a BSD-style 4 // license that can be found in the LICENSE file. 5 6 package flate 7 8 import ( 9 "bytes" 10 "fmt" 11 "io" 12 "io/ioutil" 13 "reflect" 14 "strings" 15 "sync" 16 "testing" 17 ) 18 19 type deflateTest struct { 20 in []byte 21 level int 22 out []byte 23 } 24 25 type deflateInflateTest struct { 26 in []byte 27 } 28 29 type reverseBitsTest struct { 30 in uint16 31 bitCount uint8 32 out uint16 33 } 34 35 var deflateTests = []*deflateTest{ 36 {[]byte{}, 0, []byte{1, 0, 0, 255, 255}}, 37 {[]byte{0x11}, BestCompression, []byte{18, 4, 4, 0, 0, 255, 255}}, 38 {[]byte{0x11}, BestCompression, []byte{18, 4, 4, 0, 0, 255, 255}}, 39 {[]byte{0x11}, BestCompression, []byte{18, 4, 4, 0, 0, 255, 255}}, 40 41 {[]byte{0x11}, 0, []byte{0, 1, 0, 254, 255, 17, 1, 0, 0, 255, 255}}, 42 {[]byte{0x11, 0x12}, 0, []byte{0, 2, 0, 253, 255, 17, 18, 1, 0, 0, 255, 255}}, 43 {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 0, 44 []byte{0, 8, 0, 247, 255, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0, 0, 255, 255}, 45 }, 46 {[]byte{}, 1, []byte{1, 0, 0, 255, 255}}, 47 {[]byte{0x11}, BestCompression, []byte{18, 4, 4, 0, 0, 255, 255}}, 48 {[]byte{0x11, 0x12}, BestCompression, []byte{18, 20, 2, 4, 0, 0, 255, 255}}, 49 {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, BestCompression, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}}, 50 {[]byte{}, 9, []byte{1, 0, 0, 255, 255}}, 51 {[]byte{0x11}, 9, []byte{18, 4, 4, 0, 0, 255, 255}}, 52 {[]byte{0x11, 0x12}, 9, []byte{18, 20, 2, 4, 0, 0, 255, 255}}, 53 {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 9, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}}, 54 } 55 56 var deflateInflateTests = []*deflateInflateTest{ 57 {[]byte{}}, 58 {[]byte{0x11}}, 59 {[]byte{0x11, 0x12}}, 60 {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}}, 61 {[]byte{0x11, 0x10, 0x13, 0x41, 0x21, 0x21, 0x41, 0x13, 0x87, 0x78, 0x13}}, 62 {largeDataChunk()}, 63 } 64 65 var reverseBitsTests = []*reverseBitsTest{ 66 {1, 1, 1}, 67 {1, 2, 2}, 68 {1, 3, 4}, 69 {1, 4, 8}, 70 {1, 5, 16}, 71 {17, 5, 17}, 72 {257, 9, 257}, 73 {29, 5, 23}, 74 } 75 76 func largeDataChunk() []byte { 77 result := make([]byte, 100000) 78 for i := range result { 79 result[i] = byte(i * i & 0xFF) 80 } 81 return result 82 } 83 84 func TestCRCBulkOld(t *testing.T) { 85 for _, x := range deflateTests { 86 y := x.out 87 if len(y) >= minMatchLength { 88 y = append(y, y...) 89 for j := 4; j < len(y); j++ { 90 y := y[:j] 91 dst := make([]hash, len(y)-minMatchLength+1) 92 for i := range dst { 93 dst[i] = hash(i + 100) 94 } 95 oldBulkHash(y, dst) 96 for i, val := range dst { 97 got := val & hashMask 98 expect := oldHash(y[i:]) & hashMask 99 if got != expect && got == hash(i)+100 { 100 t.Errorf("Len:%d Index:%d, expected 0x%08x but not modified", len(y), i, expect) 101 } else if got != expect { 102 t.Errorf("Len:%d Index:%d, got 0x%08x expected:0x%08x", len(y), i, got, expect) 103 } else { 104 //t.Logf("Len:%d Index:%d OK (0x%08x)", len(y), i, got) 105 } 106 } 107 } 108 } 109 } 110 } 111 112 func TestDeflate(t *testing.T) { 113 for _, h := range deflateTests { 114 var buf bytes.Buffer 115 w, err := NewWriter(&buf, h.level) 116 if err != nil { 117 t.Errorf("NewWriter: %v", err) 118 continue 119 } 120 w.Write(h.in) 121 w.Close() 122 if !bytes.Equal(buf.Bytes(), h.out) { 123 t.Errorf("Deflate(%d, %x) = \n%#v, want \n%#v", h.level, h.in, buf.Bytes(), h.out) 124 } 125 } 126 } 127 128 // A sparseReader returns a stream consisting of 0s followed by 1<<16 1s. 129 // This tests missing hash references in a very large input. 130 type sparseReader struct { 131 l int64 132 cur int64 133 } 134 135 func (r *sparseReader) Read(b []byte) (n int, err error) { 136 if r.cur >= r.l { 137 return 0, io.EOF 138 } 139 n = len(b) 140 cur := r.cur + int64(n) 141 if cur > r.l { 142 n -= int(cur - r.l) 143 cur = r.l 144 } 145 for i := range b[0:n] { 146 if r.cur+int64(i) >= r.l-1<<16 { 147 b[i] = 1 148 } else { 149 b[i] = 0 150 } 151 } 152 r.cur = cur 153 return 154 } 155 156 func TestVeryLongSparseChunk(t *testing.T) { 157 if testing.Short() { 158 t.Skip("skipping sparse chunk during short test") 159 } 160 w, err := NewWriter(ioutil.Discard, 1) 161 if err != nil { 162 t.Errorf("NewWriter: %v", err) 163 return 164 } 165 if _, err = io.Copy(w, &sparseReader{l: 23E8}); err != nil { 166 t.Errorf("Compress failed: %v", err) 167 return 168 } 169 } 170 171 type syncBuffer struct { 172 buf bytes.Buffer 173 mu sync.RWMutex 174 closed bool 175 ready chan bool 176 } 177 178 func newSyncBuffer() *syncBuffer { 179 return &syncBuffer{ready: make(chan bool, 1)} 180 } 181 182 func (b *syncBuffer) Read(p []byte) (n int, err error) { 183 for { 184 b.mu.RLock() 185 n, err = b.buf.Read(p) 186 b.mu.RUnlock() 187 if n > 0 || b.closed { 188 return 189 } 190 <-b.ready 191 } 192 } 193 194 func (b *syncBuffer) signal() { 195 select { 196 case b.ready <- true: 197 default: 198 } 199 } 200 201 func (b *syncBuffer) Write(p []byte) (n int, err error) { 202 n, err = b.buf.Write(p) 203 b.signal() 204 return 205 } 206 207 func (b *syncBuffer) WriteMode() { 208 b.mu.Lock() 209 } 210 211 func (b *syncBuffer) ReadMode() { 212 b.mu.Unlock() 213 b.signal() 214 } 215 216 func (b *syncBuffer) Close() error { 217 b.closed = true 218 b.signal() 219 return nil 220 } 221 222 func testSync(t *testing.T, level int, input []byte, name string) { 223 if len(input) == 0 { 224 return 225 } 226 227 t.Logf("--testSync %d, %d, %s", level, len(input), name) 228 buf := newSyncBuffer() 229 buf1 := new(bytes.Buffer) 230 buf.WriteMode() 231 w, err := NewWriter(io.MultiWriter(buf, buf1), level) 232 if err != nil { 233 t.Errorf("NewWriter: %v", err) 234 return 235 } 236 r := NewReader(buf) 237 238 // Write half the input and read back. 239 for i := 0; i < 2; i++ { 240 var lo, hi int 241 if i == 0 { 242 lo, hi = 0, (len(input)+1)/2 243 } else { 244 lo, hi = (len(input)+1)/2, len(input) 245 } 246 t.Logf("#%d: write %d-%d", i, lo, hi) 247 if _, err := w.Write(input[lo:hi]); err != nil { 248 t.Errorf("testSync: write: %v", err) 249 return 250 } 251 if i == 0 { 252 if err := w.Flush(); err != nil { 253 t.Errorf("testSync: flush: %v", err) 254 return 255 } 256 } else { 257 if err := w.Close(); err != nil { 258 t.Errorf("testSync: close: %v", err) 259 } 260 } 261 buf.ReadMode() 262 out := make([]byte, hi-lo+1) 263 m, err := io.ReadAtLeast(r, out, hi-lo) 264 t.Logf("#%d: read %d", i, m) 265 if m != hi-lo || err != nil { 266 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()) 267 return 268 } 269 if !bytes.Equal(input[lo:hi], out[:hi-lo]) { 270 t.Errorf("testSync/%d: read wrong bytes: %x vs %x", i, input[lo:hi], out[:hi-lo]) 271 return 272 } 273 // This test originally checked that after reading 274 // the first half of the input, there was nothing left 275 // in the read buffer (buf.buf.Len() != 0) but that is 276 // not necessarily the case: the write Flush may emit 277 // some extra framing bits that are not necessary 278 // to process to obtain the first half of the uncompressed 279 // data. The test ran correctly most of the time, because 280 // the background goroutine had usually read even 281 // those extra bits by now, but it's not a useful thing to 282 // check. 283 buf.WriteMode() 284 } 285 buf.ReadMode() 286 out := make([]byte, 10) 287 if n, err := r.Read(out); n > 0 || err != io.EOF { 288 t.Errorf("testSync (%d, %d, %s): final Read: %d, %v (hex: %x)", level, len(input), name, n, err, out[0:n]) 289 } 290 if buf.buf.Len() != 0 { 291 t.Errorf("testSync (%d, %d, %s): extra data at end", level, len(input), name) 292 } 293 r.Close() 294 295 // stream should work for ordinary reader too 296 r = NewReader(buf1) 297 out, err = ioutil.ReadAll(r) 298 if err != nil { 299 t.Errorf("testSync: read: %s", err) 300 return 301 } 302 r.Close() 303 if !bytes.Equal(input, out) { 304 t.Errorf("testSync: decompress(compress(data)) != data: level=%d input=%s", level, name) 305 } 306 } 307 308 func testToFromWithLevelAndLimit(t *testing.T, level int, input []byte, name string, limit int) { 309 var buffer bytes.Buffer 310 w, err := NewWriter(&buffer, level) 311 if err != nil { 312 t.Errorf("NewWriter: %v", err) 313 return 314 } 315 w.Write(input) 316 w.Close() 317 if limit > 0 && buffer.Len() > limit { 318 t.Errorf("level: %d, len(compress(data)) = %d > limit = %d", level, buffer.Len(), limit) 319 return 320 } 321 if limit > 0 { 322 t.Logf("level: %d - Size:%.2f%%, %d b\n", level, float64(buffer.Len()*100)/float64(limit), buffer.Len()) 323 } 324 r := NewReader(&buffer) 325 out, err := ioutil.ReadAll(r) 326 if err != nil { 327 t.Errorf("read: %s", err) 328 return 329 } 330 r.Close() 331 if !bytes.Equal(input, out) { 332 t.Errorf("decompress(compress(data)) != data: level=%d input=%s", level, name) 333 return 334 } 335 testSync(t, level, input, name) 336 } 337 338 func testToFromWithLimit(t *testing.T, input []byte, name string, limit [11]int) { 339 for i := 0; i < 10; i++ { 340 testToFromWithLevelAndLimit(t, i, input, name, limit[i]) 341 } 342 testToFromWithLevelAndLimit(t, -2, input, name, limit[10]) 343 } 344 345 func TestDeflateInflate(t *testing.T) { 346 for i, h := range deflateInflateTests { 347 testToFromWithLimit(t, h.in, fmt.Sprintf("#%d", i), [11]int{}) 348 } 349 } 350 351 func TestReverseBits(t *testing.T) { 352 for _, h := range reverseBitsTests { 353 if v := reverseBits(h.in, h.bitCount); v != h.out { 354 t.Errorf("reverseBits(%v,%v) = %v, want %v", 355 h.in, h.bitCount, v, h.out) 356 } 357 } 358 } 359 360 type deflateInflateStringTest struct { 361 filename string 362 label string 363 limit [11]int // Number 11 is ConstantCompression 364 } 365 366 var deflateInflateStringTests = []deflateInflateStringTest{ 367 { 368 "../testdata/e.txt", 369 "2.718281828...", 370 [...]int{100018, 67900, 50960, 51150, 50930, 50790, 50790, 50790, 50790, 50790, 43683 + 100}, 371 }, 372 { 373 "../testdata/Mark.Twain-Tom.Sawyer.txt", 374 "Mark.Twain-Tom.Sawyer", 375 [...]int{407330, 195000, 185361, 180974, 169160, 164476, 162936, 160506, 160295, 160295, 233460 + 100}, 376 }, 377 } 378 379 func TestDeflateInflateString(t *testing.T) { 380 for _, test := range deflateInflateStringTests { 381 gold, err := ioutil.ReadFile(test.filename) 382 if err != nil { 383 t.Error(err) 384 } 385 // Remove returns that may be present on Windows 386 neutral := strings.Map(func(r rune) rune { 387 if r != '\r' { 388 return r 389 } 390 return -1 391 }, string(gold)) 392 393 testToFromWithLimit(t, []byte(neutral), test.label, test.limit) 394 395 if testing.Short() { 396 break 397 } 398 } 399 } 400 401 func TestReaderDict(t *testing.T) { 402 const ( 403 dict = "hello world" 404 text = "hello again world" 405 ) 406 var b bytes.Buffer 407 w, err := NewWriter(&b, 5) 408 if err != nil { 409 t.Fatalf("NewWriter: %v", err) 410 } 411 w.Write([]byte(dict)) 412 w.Flush() 413 b.Reset() 414 w.Write([]byte(text)) 415 w.Close() 416 417 r := NewReaderDict(&b, []byte(dict)) 418 data, err := ioutil.ReadAll(r) 419 if err != nil { 420 t.Fatal(err) 421 } 422 if string(data) != "hello again world" { 423 t.Fatalf("read returned %q want %q", string(data), text) 424 } 425 } 426 427 func TestWriterDict(t *testing.T) { 428 const ( 429 dict = "hello world Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." 430 text = "hello world Lorem ipsum dolor sit amet" 431 ) 432 // This test is sensitive to algorithm changes that skip 433 // data in favour of speed. Higher levels are less prone to this 434 // so we test level 4-9. 435 for l := 4; l < 9; l++ { 436 var b bytes.Buffer 437 w, err := NewWriter(&b, l) 438 if err != nil { 439 t.Fatalf("level %d, NewWriter: %v", l, err) 440 } 441 w.Write([]byte(dict)) 442 w.Flush() 443 b.Reset() 444 w.Write([]byte(text)) 445 w.Close() 446 447 var b1 bytes.Buffer 448 w, _ = NewWriterDict(&b1, l, []byte(dict)) 449 w.Write([]byte(text)) 450 w.Close() 451 452 if !bytes.Equal(b1.Bytes(), b.Bytes()) { 453 t.Errorf("level %d, writer wrote\n%v\n want\n%v", l, b1.Bytes(), b.Bytes()) 454 } 455 } 456 } 457 458 // See http://code.google.com/p/go/issues/detail?id=2508 459 func TestRegression2508(t *testing.T) { 460 if testing.Short() { 461 t.Logf("test disabled with -short") 462 return 463 } 464 w, err := NewWriter(ioutil.Discard, 1) 465 if err != nil { 466 t.Fatalf("NewWriter: %v", err) 467 } 468 buf := make([]byte, 1024) 469 for i := 0; i < 131072; i++ { 470 if _, err := w.Write(buf); err != nil { 471 t.Fatalf("writer failed: %v", err) 472 } 473 } 474 w.Close() 475 } 476 477 func TestWriterReset(t *testing.T) { 478 for level := -2; level <= 9; level++ { 479 if level == -1 { 480 level++ 481 } 482 if testing.Short() && level > 1 { 483 break 484 } 485 w, err := NewWriter(ioutil.Discard, level) 486 if err != nil { 487 t.Fatalf("NewWriter: %v", err) 488 } 489 buf := []byte("hello world") 490 for i := 0; i < 1024; i++ { 491 w.Write(buf) 492 } 493 w.Reset(ioutil.Discard) 494 495 wref, err := NewWriter(ioutil.Discard, level) 496 if err != nil { 497 t.Fatalf("NewWriter: %v", err) 498 } 499 500 // DeepEqual doesn't compare functions. 501 w.d.fill, wref.d.fill = nil, nil 502 w.d.step, wref.d.step = nil, nil 503 w.d.bulkHasher, wref.d.bulkHasher = nil, nil 504 w.d.snap, wref.d.snap = nil, nil 505 506 // hashMatch is always overwritten when used. 507 copy(w.d.hashMatch[:], wref.d.hashMatch[:]) 508 if w.d.tokens.n != 0 { 509 t.Errorf("level %d Writer not reset after Reset. %d tokens were present", level, w.d.tokens.n) 510 } 511 // As long as the length is 0, we don't care about the content. 512 w.d.tokens = wref.d.tokens 513 514 // We don't care if there are values in the window, as long as it is at d.index is 0 515 w.d.window = wref.d.window 516 if !reflect.DeepEqual(w, wref) { 517 t.Errorf("level %d Writer not reset after Reset", level) 518 } 519 } 520 testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, NoCompression) }) 521 testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, DefaultCompression) }) 522 testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, BestCompression) }) 523 testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriter(w, ConstantCompression) }) 524 dict := []byte("we are the world") 525 testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, NoCompression, dict) }) 526 testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, DefaultCompression, dict) }) 527 testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, BestCompression, dict) }) 528 testResetOutput(t, func(w io.Writer) (*Writer, error) { return NewWriterDict(w, ConstantCompression, dict) }) 529 } 530 531 func testResetOutput(t *testing.T, newWriter func(w io.Writer) (*Writer, error)) { 532 buf := new(bytes.Buffer) 533 w, err := newWriter(buf) 534 if err != nil { 535 t.Fatalf("NewWriter: %v", err) 536 } 537 b := []byte("hello world") 538 for i := 0; i < 1024; i++ { 539 w.Write(b) 540 } 541 w.Close() 542 out1 := buf.Bytes() 543 544 buf2 := new(bytes.Buffer) 545 w.Reset(buf2) 546 for i := 0; i < 1024; i++ { 547 w.Write(b) 548 } 549 w.Close() 550 out2 := buf2.Bytes() 551 552 if len(out1) != len(out2) { 553 t.Errorf("got %d, expected %d bytes", len(out2), len(out1)) 554 } 555 if bytes.Compare(out1, out2) != 0 { 556 mm := 0 557 for i, b := range out1[:len(out2)] { 558 if b != out2[i] { 559 t.Errorf("mismatch index %d: %02x, expected %02x", i, out2[i], b) 560 } 561 mm++ 562 if mm == 10 { 563 t.Fatal("Stopping") 564 } 565 } 566 } 567 t.Logf("got %d bytes", len(out1)) 568 } 569 570 // A writer that fails after N writes. 571 type errorWriter struct { 572 N int 573 } 574 575 func (e *errorWriter) Write(b []byte) (int, error) { 576 if e.N <= 0 { 577 return 0, io.ErrClosedPipe 578 } 579 e.N-- 580 return len(b), nil 581 } 582 583 // Test if errors from the underlying writer is passed upwards. 584 func TestWriteError(t *testing.T) { 585 buf := new(bytes.Buffer) 586 for i := 0; i < 1024*1024; i++ { 587 buf.WriteString(fmt.Sprintf("asdasfasf%d%dfghfgujyut%dyutyu\n", i, i, i)) 588 } 589 in := buf.Bytes() 590 for l := -2; l < 10; l++ { 591 for fail := 1; fail <= 512; fail *= 2 { 592 // Fail after 2 writes 593 ew := &errorWriter{N: fail} 594 w, err := NewWriter(ew, l) 595 if err != nil { 596 t.Errorf("NewWriter: level %d: %v", l, err) 597 } 598 n, err := io.Copy(w, bytes.NewBuffer(in)) 599 if err == nil { 600 t.Errorf("Level %d: Expected an error, writer was %#v", l, ew) 601 } 602 n2, err := w.Write([]byte{1, 2, 2, 3, 4, 5}) 603 if n2 != 0 { 604 t.Error("Level", l, "Expected 0 length write, got", n) 605 } 606 if err == nil { 607 t.Error("Level", l, "Expected an error") 608 } 609 err = w.Flush() 610 if err == nil { 611 t.Error("Level", l, "Expected an error on close") 612 } 613 err = w.Close() 614 if err == nil { 615 t.Error("Level", l, "Expected an error on close") 616 } 617 618 w.Reset(ioutil.Discard) 619 n2, err = w.Write([]byte{1, 2, 3, 4, 5, 6}) 620 if err != nil { 621 t.Error("Level", l, "Got unexpected error after reset:", err) 622 } 623 if n2 == 0 { 624 t.Error("Level", l, "Got 0 length write, expected > 0") 625 } 626 if testing.Short() { 627 return 628 } 629 } 630 } 631 632 }