// 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) } }() } }
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) } }
// 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) } }() } }
// Need to uncompress the file to be able to generate the Image ID func (r Registry) uncompress() error { acifile, err := os.Open(r.tmppath()) if err != nil { return err } defer acifile.Close() typ, err := aci.DetectFileType(acifile) if err != nil { return err } // In case DetectFileType changed the cursor _, err = acifile.Seek(0, 0) if err != nil { return err } var in io.Reader switch typ { case aci.TypeGzip: in, err = gzip.NewReader(acifile) if err != nil { return err } case aci.TypeBzip2: in = bzip2.NewReader(acifile) case aci.TypeXz: in, err = xz.NewReader(acifile, 0) if err != nil { return err } case aci.TypeTar: in = acifile case aci.TypeText: return fmt.Errorf("downloaded ACI is text, not a tarball") case aci.TypeUnknown: return fmt.Errorf("downloaded ACI is of an unknown type") } out, err := os.OpenFile(r.tmpuncompressedpath(), os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644) if err != nil { return err } defer out.Close() _, err = io.Copy(out, in) if err != nil { return fmt.Errorf("error copying: %v", err) } err = out.Sync() if err != nil { return fmt.Errorf("error writing: %v", err) } return nil }
func ExampleReader_Multistream() { // load some XZ data into memory data, err := ioutil.ReadFile( filepath.Join("testdata", "xz-utils", "good-1-check-sha256.xz")) if err != nil { log.Fatal(err) } // create a MultiReader that will read the data twice mr := io.MultiReader(bytes.NewReader(data), bytes.NewReader(data)) // create an xz.Reader from the MultiReader r, err := xz.NewReader(mr, 0) if err != nil { log.Fatal(err) } // set Multistream mode to false r.Multistream(false) // decompress the first stream _, err = io.Copy(os.Stdout, r) if err != nil { log.Fatal(err) } fmt.Println("Read first stream") // reset the XZ reader so it is ready to read the second stream err = r.Reset(nil) if err != nil { log.Fatal(err) } // set Multistream mode to false again r.Multistream(false) // decompress the second stream _, err = io.Copy(os.Stdout, r) if err != nil { log.Fatal(err) } fmt.Println("Read second stream") // reset the XZ reader so it is ready to read further streams err = r.Reset(nil) // confirm that the second stream was the last one if err == io.EOF { fmt.Println("No more streams") } // Output: // Hello // World! // Read first stream // Hello // World! // Read second stream // No more streams }
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) } }
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) } } }
func ExampleNewReader() { // load some XZ data into memory data, err := ioutil.ReadFile( filepath.Join("testdata", "xz-utils", "good-1-check-sha256.xz")) if err != nil { log.Fatal(err) } // create an xz.Reader to decompress the data r, err := xz.NewReader(bytes.NewReader(data), 0) if err != nil { log.Fatal(err) } // write the decompressed data to os.Stdout _, err = io.Copy(os.Stdout, r) if err != nil { log.Fatal(err) } // Output: // Hello // World! }
// 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) } } }
// 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) } }