route/vendor/github.com/ulikunitz/xz/lzma/reader_test.go

313 lines
6.7 KiB
Go

// Copyright 2014-2017 Ulrich Kunitz. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package lzma
import (
"bufio"
"bytes"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"testing"
"testing/iotest"
)
func TestNewReader(t *testing.T) {
f, err := os.Open("examples/a.lzma")
if err != nil {
t.Fatalf("open examples/a.lzma: %s", err)
}
defer f.Close()
_, err = NewReader(bufio.NewReader(f))
if err != nil {
t.Fatalf("NewReader: %s", err)
}
}
const (
dirname = "examples"
origname = "a.txt"
)
func readOrigFile(t *testing.T) []byte {
orig, err := ioutil.ReadFile(filepath.Join(dirname, origname))
if err != nil {
t.Fatalf("ReadFile: %s", err)
}
return orig
}
func testDecodeFile(t *testing.T, filename string, orig []byte) {
pathname := filepath.Join(dirname, filename)
f, err := os.Open(pathname)
if err != nil {
t.Fatalf("Open(%q): %s", pathname, err)
}
defer func() {
if err = f.Close(); err != nil {
t.Fatalf("f.Close() error %s", err)
}
}()
t.Logf("file %s opened", filename)
l, err := NewReader(bufio.NewReader(f))
if err != nil {
t.Fatalf("NewReader: %s", err)
}
decoded, err := ioutil.ReadAll(l)
if err != nil {
t.Fatalf("ReadAll: %s", err)
}
t.Logf("%s", decoded)
if len(orig) != len(decoded) {
t.Fatalf("length decoded is %d; want %d",
len(decoded), len(orig))
}
if !bytes.Equal(orig, decoded) {
t.Fatalf("decoded file differs from original")
}
}
func TestReaderSimple(t *testing.T) {
// DebugOn(os.Stderr)
// defer DebugOff()
testDecodeFile(t, "a.lzma", readOrigFile(t))
}
func TestReaderAll(t *testing.T) {
dirname := "examples"
dir, err := os.Open(dirname)
if err != nil {
t.Fatalf("Open: %s", err)
}
defer func() {
if err := dir.Close(); err != nil {
t.Fatalf("dir.Close() error %s", err)
}
}()
all, err := dir.Readdirnames(0)
if err != nil {
t.Fatalf("Readdirnames: %s", err)
}
// filter now all file with the pattern "a*.lzma"
files := make([]string, 0, len(all))
for _, fn := range all {
match, err := filepath.Match("a*.lzma", fn)
if err != nil {
t.Fatalf("Match: %s", err)
}
if match {
files = append(files, fn)
}
}
t.Log("files:", files)
orig := readOrigFile(t)
// actually test the files
for _, fn := range files {
testDecodeFile(t, fn, orig)
}
}
//
func Example_reader() {
f, err := os.Open("fox.lzma")
if err != nil {
log.Fatal(err)
}
// no need for defer; Fatal calls os.Exit(1) that doesn't execute deferred functions
r, err := NewReader(bufio.NewReader(f))
if err != nil {
log.Fatal(err)
}
_, err = io.Copy(os.Stdout, r)
if err != nil {
log.Fatal(err)
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
// Output:
// The quick brown fox jumps over the lazy dog.
}
type wrapTest struct {
name string
wrap func(io.Reader) io.Reader
}
func (w *wrapTest) testFile(t *testing.T, filename string, orig []byte) {
pathname := filepath.Join(dirname, filename)
f, err := os.Open(pathname)
if err != nil {
t.Fatalf("Open(\"%s\"): %s", pathname, err)
}
defer func() {
if err := f.Close(); err != nil {
log.Fatal(err)
}
}()
t.Logf("%s file %s opened", w.name, filename)
l, err := NewReader(w.wrap(f))
if err != nil {
t.Fatalf("%s NewReader: %s", w.name, err)
}
decoded, err := ioutil.ReadAll(l)
if err != nil {
t.Fatalf("%s ReadAll: %s", w.name, err)
}
t.Logf("%s", decoded)
if len(orig) != len(decoded) {
t.Fatalf("%s length decoded is %d; want %d",
w.name, len(decoded), len(orig))
}
if !bytes.Equal(orig, decoded) {
t.Fatalf("%s decoded file differs from original", w.name)
}
}
func TestReaderWrap(t *testing.T) {
tests := [...]wrapTest{
{"DataErrReader", iotest.DataErrReader},
{"HalfReader", iotest.HalfReader},
{"OneByteReader", iotest.OneByteReader},
// TimeOutReader would require buffer
}
orig := readOrigFile(t)
for _, tst := range tests {
tst.testFile(t, "a.lzma", orig)
}
}
func TestReaderBadFiles(t *testing.T) {
dirname := "examples"
dir, err := os.Open(dirname)
if err != nil {
t.Fatalf("Open: %s", err)
}
defer func() {
if err := dir.Close(); err != nil {
t.Fatalf("dir.Close() error %s", err)
}
}()
all, err := dir.Readdirnames(0)
if err != nil {
t.Fatalf("Readdirnames: %s", err)
}
// filter now all file with the pattern "bad*.lzma"
files := make([]string, 0, len(all))
for _, fn := range all {
match, err := filepath.Match("bad*.lzma", fn)
if err != nil {
t.Fatalf("Match: %s", err)
}
if match {
files = append(files, fn)
}
}
t.Log("files:", files)
for _, filename := range files {
pathname := filepath.Join(dirname, filename)
f, err := os.Open(pathname)
if err != nil {
t.Fatalf("Open(\"%s\"): %s", pathname, err)
}
defer func(f *os.File) {
if err := f.Close(); err != nil {
t.Fatalf("f.Close() error %s", err)
}
}(f)
t.Logf("file %s opened", filename)
l, err := NewReader(f)
if err != nil {
t.Fatalf("NewReader: %s", err)
}
decoded, err := ioutil.ReadAll(l)
if err == nil {
t.Errorf("ReadAll for %s: no error", filename)
t.Logf("%s", decoded)
continue
}
t.Logf("%s: error %s", filename, err)
}
}
type repReader byte
func (r repReader) Read(p []byte) (n int, err error) {
for i := range p {
p[i] = byte(r)
}
return len(p), nil
}
func newRepReader(c byte, n int64) *io.LimitedReader {
return &io.LimitedReader{R: repReader(c), N: n}
}
func newCodeReader(r io.Reader) *io.PipeReader {
pr, pw := io.Pipe()
go func() {
bw := bufio.NewWriter(pw)
lw, err := NewWriter(bw)
if err != nil {
log.Fatalf("NewWriter error %s", err)
}
if _, err = io.Copy(lw, r); err != nil {
log.Fatalf("io.Copy error %s", err)
}
if err = lw.Close(); err != nil {
log.Fatalf("lw.Close error %s", err)
}
if err = bw.Flush(); err != nil {
log.Fatalf("bw.Flush() error %s", err)
}
if err = pw.CloseWithError(io.EOF); err != nil {
log.Fatalf("pw.CloseWithError(io.EOF) error %s", err)
}
}()
return pr
}
func TestReaderErrAgain(t *testing.T) {
lengths := []int64{0, 128, 1024, 4095, 4096, 4097, 8191, 8192, 8193}
buf := make([]byte, 128)
const c = 'A'
for _, n := range lengths {
t.Logf("n: %d", n)
pr := newCodeReader(newRepReader(c, n))
r, err := NewReader(pr)
if err != nil {
t.Fatalf("NewReader(pr) error %s", err)
}
k := int64(0)
for {
m, err := r.Read(buf)
k += int64(m)
if err == io.EOF {
break
}
if err != nil {
t.Errorf("r.Read(buf) error %s", err)
break
}
if m > len(buf) {
t.Fatalf("r.Read(buf) %d; want <= %d", m,
len(buf))
}
for i, b := range buf[:m] {
if b != c {
t.Fatalf("buf[%d]=%c; want %c", i, b,
c)
}
}
}
if k != n {
t.Errorf("Read %d bytes; want %d", k, n)
}
}
}