decompress_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. package huff0
  2. import (
  3. "bytes"
  4. "testing"
  5. )
  6. func TestDecompress1X(t *testing.T) {
  7. for _, test := range testfiles {
  8. t.Run(test.name, func(t *testing.T) {
  9. var s = &Scratch{}
  10. buf0, err := test.fn()
  11. if err != nil {
  12. t.Fatal(err)
  13. }
  14. if len(buf0) > BlockSizeMax {
  15. buf0 = buf0[:BlockSizeMax]
  16. }
  17. b, re, err := Compress1X(buf0, s)
  18. if err != test.err1X {
  19. t.Errorf("want error %v (%T), got %v (%T)", test.err1X, test.err1X, err, err)
  20. }
  21. if err != nil {
  22. t.Log(test.name, err.Error())
  23. return
  24. }
  25. if b == nil {
  26. t.Error("got no output")
  27. return
  28. }
  29. if len(s.OutTable) == 0 {
  30. t.Error("got no table definition")
  31. }
  32. if re {
  33. t.Error("claimed to have re-used.")
  34. }
  35. if len(s.OutData) == 0 {
  36. t.Error("got no data output")
  37. }
  38. wantRemain := len(s.OutData)
  39. t.Logf("%s: %d -> %d bytes (%.2f:1) %t (table: %d bytes)", test.name, len(buf0), len(b), float64(len(buf0))/float64(len(b)), re, len(s.OutTable))
  40. s.Out = nil
  41. var remain []byte
  42. s, remain, err = ReadTable(b, s)
  43. if err != nil {
  44. t.Error(err)
  45. return
  46. }
  47. var buf bytes.Buffer
  48. if s.matches(s.prevTable, &buf); buf.Len() > 0 {
  49. t.Error(buf.String())
  50. }
  51. if len(remain) != wantRemain {
  52. t.Fatalf("remain mismatch, want %d, got %d bytes", wantRemain, len(remain))
  53. }
  54. t.Logf("remain: %d bytes, ok", len(remain))
  55. dc, err := s.Decompress1X(remain)
  56. if err != nil {
  57. t.Error(err)
  58. return
  59. }
  60. if len(buf0) != len(dc) {
  61. t.Errorf(test.name+"decompressed, want size: %d, got %d", len(buf0), len(dc))
  62. if len(buf0) > len(dc) {
  63. buf0 = buf0[:len(dc)]
  64. } else {
  65. dc = dc[:len(buf0)]
  66. }
  67. if !bytes.Equal(buf0, dc) {
  68. if len(dc) > 1024 {
  69. t.Log(string(dc[:1024]))
  70. t.Errorf(test.name+"decompressed, got delta: \n(in)\t%02x !=\n(out)\t%02x\n", buf0[:1024], dc[:1024])
  71. } else {
  72. t.Log(string(dc))
  73. t.Errorf(test.name+"decompressed, got delta: (in) %v != (out) %v\n", buf0, dc)
  74. }
  75. }
  76. return
  77. }
  78. if !bytes.Equal(buf0, dc) {
  79. if len(buf0) > 1024 {
  80. t.Log(string(dc[:1024]))
  81. } else {
  82. t.Log(string(dc))
  83. }
  84. //t.Errorf(test.name+": decompressed, got delta: \n%s")
  85. t.Errorf(test.name + ": decompressed, got delta")
  86. }
  87. if !t.Failed() {
  88. t.Log("... roundtrip ok!")
  89. }
  90. })
  91. }
  92. }
  93. func TestDecompress4X(t *testing.T) {
  94. for _, test := range testfiles {
  95. t.Run(test.name, func(t *testing.T) {
  96. var s = &Scratch{}
  97. buf0, err := test.fn()
  98. if err != nil {
  99. t.Fatal(err)
  100. }
  101. if len(buf0) > BlockSizeMax {
  102. buf0 = buf0[:BlockSizeMax]
  103. }
  104. b, re, err := Compress4X(buf0, s)
  105. if err != test.err4X {
  106. t.Errorf("want error %v (%T), got %v (%T)", test.err1X, test.err1X, err, err)
  107. }
  108. if err != nil {
  109. t.Log(test.name, err.Error())
  110. return
  111. }
  112. if b == nil {
  113. t.Error("got no output")
  114. return
  115. }
  116. if len(s.OutTable) == 0 {
  117. t.Error("got no table definition")
  118. }
  119. if re {
  120. t.Error("claimed to have re-used.")
  121. }
  122. if len(s.OutData) == 0 {
  123. t.Error("got no data output")
  124. }
  125. wantRemain := len(s.OutData)
  126. t.Logf("%s: %d -> %d bytes (%.2f:1) %t (table: %d bytes)", test.name, len(buf0), len(b), float64(len(buf0))/float64(len(b)), re, len(s.OutTable))
  127. s.Out = nil
  128. var remain []byte
  129. s, remain, err = ReadTable(b, s)
  130. if err != nil {
  131. t.Error(err)
  132. return
  133. }
  134. var buf bytes.Buffer
  135. if s.matches(s.prevTable, &buf); buf.Len() > 0 {
  136. t.Error(buf.String())
  137. }
  138. if len(remain) != wantRemain {
  139. t.Fatalf("remain mismatch, want %d, got %d bytes", wantRemain, len(remain))
  140. }
  141. t.Logf("remain: %d bytes, ok", len(remain))
  142. dc, err := s.Decompress4X(remain, len(buf0))
  143. if err != nil {
  144. t.Error(err)
  145. return
  146. }
  147. if len(buf0) != len(dc) {
  148. t.Errorf(test.name+"decompressed, want size: %d, got %d", len(buf0), len(dc))
  149. if len(buf0) > len(dc) {
  150. buf0 = buf0[:len(dc)]
  151. } else {
  152. dc = dc[:len(buf0)]
  153. }
  154. if !bytes.Equal(buf0, dc) {
  155. if len(dc) > 1024 {
  156. t.Log(string(dc[:1024]))
  157. t.Errorf(test.name+"decompressed, got delta: \n(in)\t%02x !=\n(out)\t%02x\n", buf0[:1024], dc[:1024])
  158. } else {
  159. t.Log(string(dc))
  160. t.Errorf(test.name+"decompressed, got delta: (in) %v != (out) %v\n", buf0, dc)
  161. }
  162. }
  163. return
  164. }
  165. if !bytes.Equal(buf0, dc) {
  166. if len(buf0) > 1024 {
  167. t.Log(string(dc[:1024]))
  168. } else {
  169. t.Log(string(dc))
  170. }
  171. //t.Errorf(test.name+": decompressed, got delta: \n%s")
  172. t.Errorf(test.name + ": decompressed, got delta")
  173. }
  174. if !t.Failed() {
  175. t.Log("... roundtrip ok!")
  176. }
  177. })
  178. }
  179. }
  180. func TestRoundtrip1XFuzz(t *testing.T) {
  181. for _, test := range testfilesExtended {
  182. t.Run(test.name, func(t *testing.T) {
  183. var s = &Scratch{}
  184. buf0, err := test.fn()
  185. if err != nil {
  186. t.Fatal(err)
  187. }
  188. if len(buf0) > BlockSizeMax {
  189. buf0 = buf0[:BlockSizeMax]
  190. }
  191. b, re, err := Compress1X(buf0, s)
  192. if err != nil {
  193. if err == ErrIncompressible || err == ErrUseRLE || err == ErrTooBig {
  194. t.Log(test.name, err.Error())
  195. return
  196. }
  197. t.Error(test.name, err.Error())
  198. return
  199. }
  200. if b == nil {
  201. t.Error("got no output")
  202. return
  203. }
  204. if len(s.OutTable) == 0 {
  205. t.Error("got no table definition")
  206. }
  207. if re {
  208. t.Error("claimed to have re-used.")
  209. }
  210. if len(s.OutData) == 0 {
  211. t.Error("got no data output")
  212. }
  213. wantRemain := len(s.OutData)
  214. t.Logf("%s: %d -> %d bytes (%.2f:1) %t (table: %d bytes)", test.name, len(buf0), len(b), float64(len(buf0))/float64(len(b)), re, len(s.OutTable))
  215. s.Out = nil
  216. var remain []byte
  217. s, remain, err = ReadTable(b, s)
  218. if err != nil {
  219. t.Error(err)
  220. return
  221. }
  222. var buf bytes.Buffer
  223. if s.matches(s.prevTable, &buf); buf.Len() > 0 {
  224. t.Error(buf.String())
  225. }
  226. if len(remain) != wantRemain {
  227. t.Fatalf("remain mismatch, want %d, got %d bytes", wantRemain, len(remain))
  228. }
  229. t.Logf("remain: %d bytes, ok", len(remain))
  230. dc, err := s.Decompress1X(remain)
  231. if err != nil {
  232. t.Error(err)
  233. return
  234. }
  235. if len(buf0) != len(dc) {
  236. t.Errorf(test.name+"decompressed, want size: %d, got %d", len(buf0), len(dc))
  237. if len(buf0) > len(dc) {
  238. buf0 = buf0[:len(dc)]
  239. } else {
  240. dc = dc[:len(buf0)]
  241. }
  242. if !bytes.Equal(buf0, dc) {
  243. if len(dc) > 1024 {
  244. t.Log(string(dc[:1024]))
  245. t.Errorf(test.name+"decompressed, got delta: \n(in)\t%02x !=\n(out)\t%02x\n", buf0[:1024], dc[:1024])
  246. } else {
  247. t.Log(string(dc))
  248. t.Errorf(test.name+"decompressed, got delta: (in) %v != (out) %v\n", buf0, dc)
  249. }
  250. }
  251. return
  252. }
  253. if !bytes.Equal(buf0, dc) {
  254. if len(buf0) > 1024 {
  255. t.Log(string(dc[:1024]))
  256. } else {
  257. t.Log(string(dc))
  258. }
  259. //t.Errorf(test.name+": decompressed, got delta: \n%s")
  260. t.Errorf(test.name + ": decompressed, got delta")
  261. }
  262. if !t.Failed() {
  263. t.Log("... roundtrip ok!")
  264. }
  265. })
  266. }
  267. }
  268. func TestRoundtrip4XFuzz(t *testing.T) {
  269. for _, test := range testfilesExtended {
  270. t.Run(test.name, func(t *testing.T) {
  271. var s = &Scratch{}
  272. buf0, err := test.fn()
  273. if err != nil {
  274. t.Fatal(err)
  275. }
  276. if len(buf0) > BlockSizeMax {
  277. buf0 = buf0[:BlockSizeMax]
  278. }
  279. b, re, err := Compress4X(buf0, s)
  280. if err != nil {
  281. if err == ErrIncompressible || err == ErrUseRLE || err == ErrTooBig {
  282. t.Log(test.name, err.Error())
  283. return
  284. }
  285. t.Error(test.name, err.Error())
  286. return
  287. }
  288. if b == nil {
  289. t.Error("got no output")
  290. return
  291. }
  292. if len(s.OutTable) == 0 {
  293. t.Error("got no table definition")
  294. }
  295. if re {
  296. t.Error("claimed to have re-used.")
  297. }
  298. if len(s.OutData) == 0 {
  299. t.Error("got no data output")
  300. }
  301. wantRemain := len(s.OutData)
  302. t.Logf("%s: %d -> %d bytes (%.2f:1) %t (table: %d bytes)", test.name, len(buf0), len(b), float64(len(buf0))/float64(len(b)), re, len(s.OutTable))
  303. s.Out = nil
  304. var remain []byte
  305. s, remain, err = ReadTable(b, s)
  306. if err != nil {
  307. t.Error(err)
  308. return
  309. }
  310. var buf bytes.Buffer
  311. if s.matches(s.prevTable, &buf); buf.Len() > 0 {
  312. t.Error(buf.String())
  313. }
  314. if len(remain) != wantRemain {
  315. t.Fatalf("remain mismatch, want %d, got %d bytes", wantRemain, len(remain))
  316. }
  317. t.Logf("remain: %d bytes, ok", len(remain))
  318. dc, err := s.Decompress4X(remain, len(buf0))
  319. if err != nil {
  320. t.Error(err)
  321. return
  322. }
  323. if len(buf0) != len(dc) {
  324. t.Errorf(test.name+"decompressed, want size: %d, got %d", len(buf0), len(dc))
  325. if len(buf0) > len(dc) {
  326. buf0 = buf0[:len(dc)]
  327. } else {
  328. dc = dc[:len(buf0)]
  329. }
  330. if !bytes.Equal(buf0, dc) {
  331. if len(dc) > 1024 {
  332. t.Log(string(dc[:1024]))
  333. t.Errorf(test.name+"decompressed, got delta: \n(in)\t%02x !=\n(out)\t%02x\n", buf0[:1024], dc[:1024])
  334. } else {
  335. t.Log(string(dc))
  336. t.Errorf(test.name+"decompressed, got delta: (in) %v != (out) %v\n", buf0, dc)
  337. }
  338. }
  339. return
  340. }
  341. if !bytes.Equal(buf0, dc) {
  342. if len(buf0) > 1024 {
  343. t.Log(string(dc[:1024]))
  344. } else {
  345. t.Log(string(dc))
  346. }
  347. //t.Errorf(test.name+": decompressed, got delta: \n%s")
  348. t.Errorf(test.name + ": decompressed, got delta")
  349. }
  350. if !t.Failed() {
  351. t.Log("... roundtrip ok!")
  352. }
  353. })
  354. }
  355. }
  356. func BenchmarkDecompress1XTable(b *testing.B) {
  357. for _, tt := range testfiles {
  358. test := tt
  359. if test.err1X != nil {
  360. continue
  361. }
  362. b.Run(test.name, func(b *testing.B) {
  363. var s = &Scratch{}
  364. s.Reuse = ReusePolicyNone
  365. buf0, err := test.fn()
  366. if err != nil {
  367. b.Fatal(err)
  368. }
  369. if len(buf0) > BlockSizeMax {
  370. buf0 = buf0[:BlockSizeMax]
  371. }
  372. compressed, _, err := Compress1X(buf0, s)
  373. if err != test.err1X {
  374. b.Fatal("unexpected error:", err)
  375. }
  376. s.Out = nil
  377. s, remain, _ := ReadTable(compressed, s)
  378. s.Decompress1X(remain)
  379. b.ResetTimer()
  380. b.ReportAllocs()
  381. b.SetBytes(int64(len(buf0)))
  382. for i := 0; i < b.N; i++ {
  383. s, remain, err := ReadTable(compressed, s)
  384. if err != nil {
  385. b.Fatal(err)
  386. }
  387. _, err = s.Decompress1X(remain)
  388. if err != nil {
  389. b.Fatal(err)
  390. }
  391. }
  392. })
  393. }
  394. }
  395. func BenchmarkDecompress1XNoTable(b *testing.B) {
  396. for _, tt := range testfiles {
  397. test := tt
  398. if test.err1X != nil {
  399. continue
  400. }
  401. b.Run(test.name, func(b *testing.B) {
  402. var s = &Scratch{}
  403. s.Reuse = ReusePolicyNone
  404. buf0, err := test.fn()
  405. if err != nil {
  406. b.Fatal(err)
  407. }
  408. if len(buf0) > BlockSizeMax {
  409. buf0 = buf0[:BlockSizeMax]
  410. }
  411. compressed, _, err := Compress1X(buf0, s)
  412. if err != test.err1X {
  413. b.Fatal("unexpected error:", err)
  414. }
  415. s.Out = nil
  416. s, remain, _ := ReadTable(compressed, s)
  417. s.Decompress1X(remain)
  418. b.ResetTimer()
  419. b.ReportAllocs()
  420. b.SetBytes(int64(len(buf0)))
  421. for i := 0; i < b.N; i++ {
  422. _, err = s.Decompress1X(remain)
  423. if err != nil {
  424. b.Fatal(err)
  425. }
  426. }
  427. })
  428. }
  429. }
  430. func BenchmarkDecompress4XNoTable(b *testing.B) {
  431. for _, tt := range testfiles {
  432. test := tt
  433. if test.err4X != nil {
  434. continue
  435. }
  436. b.Run(test.name, func(b *testing.B) {
  437. var s = &Scratch{}
  438. s.Reuse = ReusePolicyNone
  439. buf0, err := test.fn()
  440. if err != nil {
  441. b.Fatal(err)
  442. }
  443. if len(buf0) > BlockSizeMax {
  444. buf0 = buf0[:BlockSizeMax]
  445. }
  446. compressed, _, err := Compress4X(buf0, s)
  447. if err != test.err1X {
  448. b.Fatal("unexpected error:", err)
  449. }
  450. s.Out = nil
  451. s, remain, _ := ReadTable(compressed, s)
  452. s.Decompress4X(remain, len(buf0))
  453. b.ResetTimer()
  454. b.ReportAllocs()
  455. b.SetBytes(int64(len(buf0)))
  456. for i := 0; i < b.N; i++ {
  457. _, err = s.Decompress4X(remain, len(buf0))
  458. if err != nil {
  459. b.Fatal(err)
  460. }
  461. }
  462. })
  463. }
  464. }
  465. func BenchmarkDecompress4XTable(b *testing.B) {
  466. for _, tt := range testfiles {
  467. test := tt
  468. if test.err4X != nil {
  469. continue
  470. }
  471. b.Run(test.name, func(b *testing.B) {
  472. var s = &Scratch{}
  473. s.Reuse = ReusePolicyNone
  474. buf0, err := test.fn()
  475. if err != nil {
  476. b.Fatal(err)
  477. }
  478. if len(buf0) > BlockSizeMax {
  479. buf0 = buf0[:BlockSizeMax]
  480. }
  481. compressed, _, err := Compress4X(buf0, s)
  482. if err != test.err1X {
  483. b.Fatal("unexpected error:", err)
  484. }
  485. s.Out = nil
  486. b.ResetTimer()
  487. b.ReportAllocs()
  488. b.SetBytes(int64(len(buf0)))
  489. for i := 0; i < b.N; i++ {
  490. s, remain, err := ReadTable(compressed, s)
  491. if err != nil {
  492. b.Fatal(err)
  493. }
  494. _, err = s.Decompress4X(remain, len(buf0))
  495. if err != nil {
  496. b.Fatal(err)
  497. }
  498. }
  499. })
  500. }
  501. }