internal/pkg: decompress xz streams
Test / Create distribution (push) Successful in 59s
Test / Sandbox (push) Successful in 2m54s
Test / Hakurei (push) Successful in 4m48s
Test / Sandbox (race detector) (push) Successful in 5m59s
Test / Hakurei (race detector) (push) Successful in 7m35s
Test / ShareFS (push) Successful in 7m42s
Test / Flake checks (push) Successful in 1m18s
Test / Create distribution (push) Successful in 59s
Test / Sandbox (push) Successful in 2m54s
Test / Hakurei (push) Successful in 4m48s
Test / Sandbox (race detector) (push) Successful in 5m59s
Test / Hakurei (race detector) (push) Successful in 7m35s
Test / ShareFS (push) Successful in 7m42s
Test / Flake checks (push) Successful in 1m18s
This uses a port of the public domain xz implementation. Signed-off-by: Ophestra <cat@gensokyo.uk>
This commit is contained in:
@@ -0,0 +1,710 @@
|
||||
/*
|
||||
* Package xz tests
|
||||
*
|
||||
* Author: Michael Cross <https://github.com/xi2>
|
||||
*
|
||||
* This file has been put into the public domain.
|
||||
* You can do whatever you want with this file.
|
||||
*/
|
||||
|
||||
package xz_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/md5"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"testing/iotest"
|
||||
|
||||
"hakurei.app/internal/xz"
|
||||
)
|
||||
|
||||
type testFile struct {
|
||||
file string
|
||||
md5sum string
|
||||
err error
|
||||
}
|
||||
|
||||
// Note that the md5sums below were generated with XZ Utils and
|
||||
// XZ Embedded, not with this package.
|
||||
|
||||
var badFiles = []testFile{
|
||||
{
|
||||
file: "bad-0-backward_size.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-0cat-alone.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrFormat,
|
||||
},
|
||||
{
|
||||
file: "bad-0cat-header_magic.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrFormat,
|
||||
},
|
||||
{
|
||||
file: "bad-0catpad-empty.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-0-empty-truncated.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrBuf,
|
||||
},
|
||||
{
|
||||
file: "bad-0-footer_magic.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-0-header_magic.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrFormat,
|
||||
},
|
||||
{
|
||||
file: "bad-0-nonempty_index.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-0pad-empty.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-block_header-1.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-block_header-2.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-block_header-3.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-block_header-4.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-block_header-5.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-block_header-6.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-check-crc32.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-check-crc64.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-check-sha256.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-lzma2-1.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-lzma2-2.xz",
|
||||
md5sum: "211dbb3d39f3c244585397f6d3c09be3",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-lzma2-3.xz",
|
||||
md5sum: "211dbb3d39f3c244585397f6d3c09be3",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-lzma2-4.xz",
|
||||
md5sum: "6492b8d167aee3ca222d07a49d24015a",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-lzma2-5.xz",
|
||||
md5sum: "6492b8d167aee3ca222d07a49d24015a",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-lzma2-6.xz",
|
||||
md5sum: "09f7e02f1290be211da707a266f153b3",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-lzma2-7.xz",
|
||||
md5sum: "c214a5e586cb3f0673cc6138f7de25ab",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-lzma2-8.xz",
|
||||
md5sum: "211dbb3d39f3c244585397f6d3c09be3",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-stream_flags-1.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-stream_flags-2.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-stream_flags-3.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-vli-1.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-1-vli-2.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-2-compressed_data_padding.xz",
|
||||
md5sum: "09f7e02f1290be211da707a266f153b3",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-2-index-1.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-2-index-2.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-2-index-3.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-2-index-4.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "bad-2-index-5.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
}
|
||||
|
||||
var goodFiles = []testFile{
|
||||
{
|
||||
file: "good-0cat-empty.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-0catpad-empty.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-0-empty.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-0pad-empty.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-3delta-lzma2.xz",
|
||||
md5sum: "c214a5e586cb3f0673cc6138f7de25ab",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-block_header-1.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-block_header-2.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-block_header-3.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-check-crc32.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-check-crc64.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-check-none.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-check-sha256.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-delta-lzma2.tiff.xz",
|
||||
md5sum: "c692be6d1987989af5eeafc329085ad2",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-lzma2-1.xz",
|
||||
md5sum: "c214a5e586cb3f0673cc6138f7de25ab",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-lzma2-2.xz",
|
||||
md5sum: "c214a5e586cb3f0673cc6138f7de25ab",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-lzma2-3.xz",
|
||||
md5sum: "c214a5e586cb3f0673cc6138f7de25ab",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-lzma2-4.xz",
|
||||
md5sum: "c214a5e586cb3f0673cc6138f7de25ab",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-lzma2-5.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-sparc-lzma2.xz",
|
||||
md5sum: "835f2865f1d7c7ad2c7de0d5fd07faef",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-1-x86-lzma2.xz",
|
||||
md5sum: "ce212d6a1cfe73d8395a2b42f94c2419",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-2-lzma2.xz",
|
||||
md5sum: "fbf68a8e34b2ded53bba54e68794b4fe",
|
||||
err: nil,
|
||||
},
|
||||
}
|
||||
|
||||
var unsupportedFiles = []testFile{
|
||||
{
|
||||
file: "unsupported-block_header.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrOptions,
|
||||
},
|
||||
{
|
||||
file: "unsupported-check.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrUnsupportedCheck,
|
||||
},
|
||||
{
|
||||
file: "unsupported-filter_flags-1.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrOptions,
|
||||
},
|
||||
{
|
||||
file: "unsupported-filter_flags-2.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrOptions,
|
||||
},
|
||||
{
|
||||
file: "unsupported-filter_flags-3.xz",
|
||||
md5sum: "d41d8cd98f00b204e9800998ecf8427e",
|
||||
err: xz.ErrOptions,
|
||||
},
|
||||
}
|
||||
|
||||
var otherFiles = []testFile{
|
||||
{
|
||||
file: "good-1-x86-lzma2-offset-2048.xz",
|
||||
md5sum: "ce212d6a1cfe73d8395a2b42f94c2419",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "good-2-lzma2-corrupt.xz",
|
||||
md5sum: "d9c5223e7e6e305e6c1c6ed73789df88",
|
||||
err: xz.ErrData,
|
||||
},
|
||||
{
|
||||
file: "words.xz",
|
||||
md5sum: "00e28a90cb4a975fdaa3b375d3124a66",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "random-1mb.xz",
|
||||
md5sum: "3f04b090e5d26a1cbeea53c21ebcad03",
|
||||
err: nil,
|
||||
},
|
||||
{
|
||||
file: "zeros-100mb.xz",
|
||||
md5sum: "0f86d7c5a6180cf9584c1d21144d85b0",
|
||||
err: nil,
|
||||
},
|
||||
}
|
||||
|
||||
func openTestFile(file string) (*os.File, error) {
|
||||
f, err := os.Open(filepath.Join("testdata", "xz-utils", file))
|
||||
if err == nil {
|
||||
return f, nil
|
||||
}
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
f, err = os.Open(filepath.Join("testdata", "other", file))
|
||||
if err == nil {
|
||||
return f, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func readTestFile(file string) ([]byte, error) {
|
||||
b, err := ioutil.ReadFile(filepath.Join("testdata", "xz-utils", file))
|
||||
if err == nil {
|
||||
return b, nil
|
||||
}
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
b, err = ioutil.ReadFile(filepath.Join("testdata", "other", file))
|
||||
if err == nil {
|
||||
return b, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// testFileData returns the data (md5sum and err) associated with the
|
||||
// named testFile
|
||||
func testFileData(file string) (md5sum string, err error) {
|
||||
fileList := badFiles
|
||||
fileList = append(fileList, goodFiles...)
|
||||
fileList = append(fileList, unsupportedFiles...)
|
||||
fileList = append(fileList, otherFiles...)
|
||||
for _, f := range fileList {
|
||||
if f.file == file {
|
||||
return f.md5sum, f.err
|
||||
}
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// testFileList tests the decoding of a list of files against their
|
||||
// expected error and md5sum.
|
||||
func testFileList(t *testing.T, files []testFile, reuseReader bool) {
|
||||
var r *xz.Reader
|
||||
var err error
|
||||
if reuseReader {
|
||||
r, err = xz.NewReader(nil, 0)
|
||||
}
|
||||
for _, f := range files {
|
||||
func() {
|
||||
var fr *os.File
|
||||
fr, err = openTestFile(f.file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
hash := md5.New()
|
||||
switch reuseReader {
|
||||
case true:
|
||||
err = r.Reset(fr)
|
||||
case false:
|
||||
r, err = xz.NewReader(fr, 0)
|
||||
}
|
||||
if err == nil {
|
||||
_, err = io.Copy(hash, r)
|
||||
}
|
||||
if err != f.err {
|
||||
t.Fatalf("%s: wanted error: %v, got: %v\n", f.file, f.err, err)
|
||||
}
|
||||
md5sum := fmt.Sprintf("%x", hash.Sum(nil))
|
||||
if f.md5sum != md5sum {
|
||||
t.Fatalf(
|
||||
"%s: wanted md5: %v, got: %v\n", f.file, f.md5sum, md5sum)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
// testFileListByteReads tests the decoding of a list of files against
|
||||
// their expected error and md5sum. It uses a one byte input buffer
|
||||
// and one byte output buffer for each run of the decoder.
|
||||
func testFileListByteReads(t *testing.T, files []testFile) {
|
||||
for _, f := range files {
|
||||
func() {
|
||||
fr, err := openTestFile(f.file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fr.Close()
|
||||
hash := md5.New()
|
||||
obr := iotest.OneByteReader(fr)
|
||||
r, err := xz.NewReader(obr, 0)
|
||||
if err == nil {
|
||||
b := make([]byte, 1)
|
||||
var n int
|
||||
for err == nil {
|
||||
n, err = r.Read(b)
|
||||
if n == 1 {
|
||||
_, _ = hash.Write(b)
|
||||
}
|
||||
}
|
||||
if err == io.EOF {
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
if err != f.err {
|
||||
t.Fatalf("%s: wanted error: %v, got: %v\n", f.file, f.err, err)
|
||||
}
|
||||
md5sum := fmt.Sprintf("%x", hash.Sum(nil))
|
||||
if f.md5sum != md5sum {
|
||||
t.Fatalf(
|
||||
"%s: wanted md5: %v, got: %v\n", f.file, f.md5sum, md5sum)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func TestBadFiles(t *testing.T) {
|
||||
testFileList(t, badFiles, false)
|
||||
}
|
||||
|
||||
func TestGoodFiles(t *testing.T) {
|
||||
testFileList(t, goodFiles, false)
|
||||
}
|
||||
|
||||
func TestUnsupportedFiles(t *testing.T) {
|
||||
testFileList(t, unsupportedFiles, false)
|
||||
}
|
||||
|
||||
func TestOtherFiles(t *testing.T) {
|
||||
testFileList(t, otherFiles, false)
|
||||
}
|
||||
|
||||
func TestMemlimit(t *testing.T) {
|
||||
data, err := readTestFile("words.xz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err := xz.NewReader(bytes.NewReader(data), 1<<25)
|
||||
if err == nil {
|
||||
b := new(bytes.Buffer)
|
||||
_, err = io.Copy(b, r)
|
||||
}
|
||||
if err != xz.ErrMemlimit {
|
||||
t.Fatalf("wanted error: %v, got: %v\n", xz.ErrMemlimit, err)
|
||||
}
|
||||
}
|
||||
|
||||
// test to ensure that decoder errors are not returned prematurely
|
||||
// the test file returns 6 decoded bytes before corruption occurs
|
||||
func TestPrematureError(t *testing.T) {
|
||||
data, err := readTestFile("good-2-lzma2-corrupt.xz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err := xz.NewReader(bytes.NewReader(data), 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b := make([]byte, 2)
|
||||
n, err := r.Read(b)
|
||||
if n != 2 || err != nil {
|
||||
t.Fatalf("Read returned: (%d,%v), expected: (2,%v)\n", n, err, nil)
|
||||
}
|
||||
n, err = r.Read(b)
|
||||
if n != 2 || err != nil {
|
||||
t.Fatalf("Read returned: (%d,%v), expected: (2,%v)\n", n, err, nil)
|
||||
}
|
||||
n, err = r.Read(b)
|
||||
if n != 2 || err != xz.ErrData {
|
||||
t.Fatalf("Read returned: (%d,%v), expected: (2,%v)\n",
|
||||
n, err, xz.ErrData)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultipleBadReads(t *testing.T) {
|
||||
data, err := readTestFile("good-2-lzma2-corrupt.xz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err := xz.NewReader(bytes.NewReader(data), 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b := make([]byte, 100)
|
||||
n, err := r.Read(b)
|
||||
if n != 6 || err != xz.ErrData {
|
||||
t.Fatalf("Read returned: (%d,%v), expected: (6,%v)\n",
|
||||
n, err, xz.ErrData)
|
||||
}
|
||||
n, err = r.Read(b)
|
||||
if n != 0 || err != xz.ErrData {
|
||||
t.Fatalf("Read returned: (%d,%v), expected: (0,%v)\n",
|
||||
n, err, xz.ErrData)
|
||||
}
|
||||
n, err = r.Read(b)
|
||||
if n != 0 || err != xz.ErrData {
|
||||
t.Fatalf("Read returned: (%d,%v), expected: (0,%v)\n",
|
||||
n, err, xz.ErrData)
|
||||
}
|
||||
}
|
||||
|
||||
// TestByteReads decodes the test files with a one byte input buffer
|
||||
// and one byte output buffer. This should exercise the stream decoder
|
||||
// and filter code nicely by testing most of the xzOK exits paths.
|
||||
func TestByteReads(t *testing.T) {
|
||||
fileList := badFiles
|
||||
fileList = append(fileList, goodFiles...)
|
||||
fileList = append(fileList, unsupportedFiles...)
|
||||
fileList = append(fileList, otherFiles...)
|
||||
fileListSmall := []testFile{}
|
||||
for _, f := range fileList {
|
||||
if f.file != "zeros-100mb.xz" {
|
||||
fileListSmall = append(fileListSmall, f)
|
||||
}
|
||||
}
|
||||
testFileListByteReads(t, fileListSmall)
|
||||
}
|
||||
|
||||
func TestMultistream(t *testing.T) {
|
||||
files := []string{
|
||||
"good-1-x86-lzma2-offset-2048.xz",
|
||||
"random-1mb.xz",
|
||||
"words.xz",
|
||||
"good-1-x86-lzma2-offset-2048.xz",
|
||||
"random-1mb.xz",
|
||||
"words.xz",
|
||||
}
|
||||
var readers []io.Reader
|
||||
for _, f := range files {
|
||||
data, err := readTestFile(f)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
readers = append(readers, bytes.NewReader(data))
|
||||
}
|
||||
mr := io.MultiReader(readers...)
|
||||
r, err := xz.NewReader(mr, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, f := range files {
|
||||
r.Multistream(false)
|
||||
hash := md5.New()
|
||||
_, err = io.Copy(hash, r)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: wanted copy error: %v, got: %v\n", f, nil, err)
|
||||
}
|
||||
md5sum := fmt.Sprintf("%x", hash.Sum(nil))
|
||||
wantedMD5, _ := testFileData(f)
|
||||
if wantedMD5 != md5sum {
|
||||
t.Fatalf(
|
||||
"%s: wanted md5: %v, got: %v\n", f, wantedMD5, md5sum)
|
||||
}
|
||||
err = r.Reset(nil)
|
||||
var wantedErr error
|
||||
switch {
|
||||
case i < len(files)-1:
|
||||
wantedErr = nil
|
||||
case i == len(files)-1:
|
||||
wantedErr = io.EOF
|
||||
}
|
||||
if wantedErr != err {
|
||||
t.Fatalf("%s: wanted reset error: %v, got: %v\n",
|
||||
f, wantedErr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestReuseReader decodes the test files reusing the same Reader for
|
||||
// all files instead of allocating a new Reader for each file.
|
||||
func TestReuseReader(t *testing.T) {
|
||||
fileList := badFiles
|
||||
fileList = append(fileList, goodFiles...)
|
||||
fileList = append(fileList, unsupportedFiles...)
|
||||
fileList = append(fileList, otherFiles...)
|
||||
testFileList(t, fileList, true)
|
||||
}
|
||||
|
||||
// TestReuseReaderPartialReads repeatedly tests decoding a file with a
|
||||
// reused Reader that has been used immediately before to partially
|
||||
// decode a file. The amount of partial decoding before the full
|
||||
// decode is varied on each loop iteration.
|
||||
func TestReuseReaderPartialReads(t *testing.T) {
|
||||
data, err := readTestFile("words.xz")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
z, err := xz.NewReader(nil, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i := 0; i <= 80000; i += 10000 {
|
||||
err = z.Reset(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
b := make([]byte, i)
|
||||
_, err = io.ReadFull(z, b)
|
||||
if err != nil {
|
||||
t.Fatalf("io.ReadFull: wanted error: %v, got: %v\n", nil, err)
|
||||
}
|
||||
err = z.Reset(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
hash := md5.New()
|
||||
_, err = io.Copy(hash, z)
|
||||
if err != nil {
|
||||
t.Fatalf("io.Copy: wanted error: %v, got: %v\n", nil, err)
|
||||
}
|
||||
md5sum := fmt.Sprintf("%x", hash.Sum(nil))
|
||||
wantedMD5, _ := testFileData("words.xz")
|
||||
if wantedMD5 != md5sum {
|
||||
t.Fatalf(
|
||||
"hash.Sum: wanted md5: %v, got: %v\n", wantedMD5, md5sum)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user