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