deflate_test.go 11 KB

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