reader_test.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. package lz4_test
  2. import (
  3. "bytes"
  4. "errors"
  5. "io"
  6. "io/ioutil"
  7. "os"
  8. "reflect"
  9. "strings"
  10. "testing"
  11. "github.com/pierrec/lz4/v4"
  12. )
  13. func TestReader(t *testing.T) {
  14. goldenFiles := []string{
  15. "testdata/e.txt.lz4",
  16. "testdata/gettysburg.txt.lz4",
  17. "testdata/Mark.Twain-Tom.Sawyer.txt.lz4",
  18. "testdata/Mark.Twain-Tom.Sawyer_long.txt.lz4",
  19. "testdata/pg1661.txt.lz4",
  20. "testdata/pi.txt.lz4",
  21. "testdata/random.data.lz4",
  22. "testdata/repeat.txt.lz4",
  23. "testdata/pg_control.tar.lz4",
  24. }
  25. for _, fname := range goldenFiles {
  26. t.Run(fname, func(t *testing.T) {
  27. fname := fname
  28. t.Parallel()
  29. f, err := os.Open(fname)
  30. if err != nil {
  31. t.Fatal(err)
  32. }
  33. defer f.Close()
  34. rawfile := strings.TrimSuffix(fname, ".lz4")
  35. raw, err := ioutil.ReadFile(rawfile)
  36. if err != nil {
  37. t.Fatal(err)
  38. }
  39. out := new(bytes.Buffer)
  40. zr := lz4.NewReader(f)
  41. n, err := io.Copy(out, zr)
  42. if err != nil {
  43. t.Fatal(err)
  44. }
  45. if got, want := int(n), len(raw); got != want {
  46. t.Errorf("invalid size: got %d; want %d", got, want)
  47. }
  48. if got, want := out.Bytes(), raw; !reflect.DeepEqual(got, want) {
  49. t.Fatal("uncompressed data does not match original")
  50. }
  51. if len(raw) < 20 {
  52. return
  53. }
  54. f2, err := os.Open(fname)
  55. if err != nil {
  56. t.Fatal(err)
  57. }
  58. defer f2.Close()
  59. out.Reset()
  60. zr = lz4.NewReader(f2)
  61. _, err = io.CopyN(out, zr, 10)
  62. if err != nil {
  63. t.Fatal(err)
  64. }
  65. if !reflect.DeepEqual(out.Bytes(), raw[:10]) {
  66. t.Fatal("partial read does not match original")
  67. }
  68. })
  69. }
  70. }
  71. func TestReader_Reset(t *testing.T) {
  72. data := pg1661LZ4
  73. buf := new(bytes.Buffer)
  74. src := bytes.NewReader(data)
  75. zr := lz4.NewReader(src)
  76. // Partial read.
  77. _, _ = io.CopyN(buf, zr, int64(len(data))/2)
  78. buf.Reset()
  79. src.Reset(data)
  80. // Another time to maybe trigger some edge case.
  81. src.Reset(data)
  82. zr.Reset(src)
  83. if _, err := io.Copy(buf, zr); err != nil {
  84. t.Fatal(err)
  85. }
  86. if !reflect.DeepEqual(buf.Bytes(), pg1661) {
  87. t.Fatal("result does not match original")
  88. }
  89. }
  90. type brokenWriter int
  91. func (w *brokenWriter) Write(p []byte) (n int, err error) {
  92. n = len(p)
  93. if n > int(*w) {
  94. n = int(*w)
  95. err = errors.New("broken")
  96. }
  97. *w -= brokenWriter(n)
  98. return
  99. }
  100. // WriteTo should report the number of bytes successfully written,
  101. // not the number successfully decompressed.
  102. func TestWriteToBrokenWriter(t *testing.T) {
  103. const capacity = 10
  104. w := brokenWriter(capacity)
  105. r := lz4.NewReader(bytes.NewReader(pg1661LZ4))
  106. n, err := r.WriteTo(&w)
  107. switch {
  108. case n > capacity:
  109. t.Errorf("reported number of bytes written %d too big", n)
  110. case err == nil:
  111. t.Error("no error from broken Writer")
  112. case err.Error() != "broken":
  113. t.Errorf("unexpected error %q", err.Error())
  114. }
  115. }