Skip to content

Commit c0a4ff3

Browse files
authored
Merge pull request #7 from thaJeztah/move_compression
move compression to a separate package
2 parents a17ea4b + b19a81b commit c0a4ff3

16 files changed

+686
-612
lines changed

Diff for: archive.go

+32-315
Large diffs are not rendered by default.

Diff for: archive_linux_test.go

-3
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ func TestOverlayTarUntar(t *testing.T) {
105105
defer os.RemoveAll(dst)
106106

107107
options := &TarOptions{
108-
Compression: Uncompressed,
109108
WhiteoutFormat: OverlayWhiteoutFormat,
110109
}
111110
reader, err := TarWithOptions(src, options)
@@ -171,14 +170,12 @@ func TestOverlayTarAUFSUntar(t *testing.T) {
171170
defer os.RemoveAll(dst)
172171

173172
archive, err := TarWithOptions(src, &TarOptions{
174-
Compression: Uncompressed,
175173
WhiteoutFormat: OverlayWhiteoutFormat,
176174
})
177175
assert.NilError(t, err)
178176
defer archive.Close()
179177

180178
err = Untar(archive, dst, &TarOptions{
181-
Compression: Uncompressed,
182179
WhiteoutFormat: AUFSWhiteoutFormat,
183180
})
184181
assert.NilError(t, err)

Diff for: archive_test.go

+6-267
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,24 @@ package archive
33
import (
44
"archive/tar"
55
"bytes"
6-
"compress/gzip"
76
"errors"
87
"fmt"
98
"io"
109
"io/fs"
1110
"os"
1211
"os/exec"
1312
"path/filepath"
14-
"reflect"
1513
"runtime"
1614
"strings"
1715
"testing"
18-
"time"
1916

2017
"github.com/moby/sys/user"
2118
"github.com/moby/sys/userns"
2219
"gotest.tools/v3/assert"
2320
is "gotest.tools/v3/assert/cmp"
2421
"gotest.tools/v3/skip"
22+
23+
"github.com/moby/go-archive/compression"
2524
)
2625

2726
var defaultArchiver = NewDefaultArchiver()
@@ -104,205 +103,6 @@ func TestIsArchivePathTar(t *testing.T) {
104103
}
105104
}
106105

107-
func testDecompressStream(t *testing.T, ext, compressCommand string) io.Reader {
108-
tmp := t.TempDir()
109-
archivePath := toUnixPath(filepath.Join(tmp, "archive"))
110-
cmd := exec.Command("sh", "-c", fmt.Sprintf("touch %[1]s && %[2]s %[1]s", archivePath, compressCommand))
111-
output, err := cmd.CombinedOutput()
112-
if err != nil {
113-
t.Fatalf("Failed to create archive file (%v):\ncommand: %s\noutput: %s", err, cmd.String(), output)
114-
}
115-
filename := "archive." + ext
116-
archive, err := os.Open(filepath.Join(tmp, filename))
117-
if err != nil {
118-
t.Fatalf("Failed to open file %s: %v", filename, err)
119-
}
120-
defer archive.Close()
121-
122-
r, err := DecompressStream(archive)
123-
if err != nil {
124-
t.Fatalf("Failed to decompress %s: %v", filename, err)
125-
}
126-
if _, err = io.ReadAll(r); err != nil {
127-
t.Fatalf("Failed to read the decompressed stream: %v ", err)
128-
}
129-
if err = r.Close(); err != nil {
130-
t.Fatalf("Failed to close the decompressed stream: %v ", err)
131-
}
132-
133-
return r
134-
}
135-
136-
func TestDecompressStreamGzip(t *testing.T) {
137-
testDecompressStream(t, "gz", "gzip -f")
138-
}
139-
140-
func TestDecompressStreamBzip2(t *testing.T) {
141-
// TODO Windows: Failing with "bzip2.exe: Can't open input file (...)/archive: No such file or directory."
142-
if runtime.GOOS == "windows" {
143-
t.Skip("Failing on Windows CI machines")
144-
}
145-
testDecompressStream(t, "bz2", "bzip2 -f")
146-
}
147-
148-
func TestDecompressStreamXz(t *testing.T) {
149-
if runtime.GOOS == "windows" {
150-
t.Skip("Xz not present in msys2")
151-
}
152-
testDecompressStream(t, "xz", "xz -f")
153-
}
154-
155-
func TestDecompressStreamZstd(t *testing.T) {
156-
// TODO Windows: Failing with "zstd: can't stat (...)/archive : No such file or directory -- ignored"
157-
if runtime.GOOS == "windows" {
158-
t.Skip("Failing on Windows CI machines")
159-
}
160-
if _, err := exec.LookPath("zstd"); err != nil {
161-
t.Skip("zstd not installed")
162-
}
163-
testDecompressStream(t, "zst", "zstd -f")
164-
}
165-
166-
func TestCompressStreamXzUnsupported(t *testing.T) {
167-
dest, err := os.Create(filepath.Join(t.TempDir(), "dest"))
168-
if err != nil {
169-
t.Fatalf("Fail to create the destination file")
170-
}
171-
defer dest.Close()
172-
173-
_, err = CompressStream(dest, Xz)
174-
if err == nil {
175-
t.Fatalf("Should fail as xz is unsupported for compression format.")
176-
}
177-
}
178-
179-
func TestCompressStreamBzip2Unsupported(t *testing.T) {
180-
dest, err := os.Create(filepath.Join(t.TempDir(), "dest"))
181-
if err != nil {
182-
t.Fatalf("Fail to create the destination file")
183-
}
184-
defer dest.Close()
185-
186-
_, err = CompressStream(dest, Bzip2)
187-
if err == nil {
188-
t.Fatalf("Should fail as bzip2 is unsupported for compression format.")
189-
}
190-
}
191-
192-
func TestCompressStreamInvalid(t *testing.T) {
193-
dest, err := os.Create(filepath.Join(t.TempDir(), "dest"))
194-
if err != nil {
195-
t.Fatalf("Fail to create the destination file")
196-
}
197-
defer dest.Close()
198-
199-
_, err = CompressStream(dest, -1)
200-
if err == nil {
201-
t.Fatalf("Should fail as xz is unsupported for compression format.")
202-
}
203-
}
204-
205-
func TestExtensionInvalid(t *testing.T) {
206-
compression := Compression(-1)
207-
output := compression.Extension()
208-
if output != "" {
209-
t.Fatalf("The extension of an invalid compression should be an empty string.")
210-
}
211-
}
212-
213-
func TestExtensionUncompressed(t *testing.T) {
214-
compression := Uncompressed
215-
output := compression.Extension()
216-
if output != "tar" {
217-
t.Fatalf("The extension of an uncompressed archive should be 'tar'.")
218-
}
219-
}
220-
221-
func TestExtensionBzip2(t *testing.T) {
222-
compression := Bzip2
223-
output := compression.Extension()
224-
if output != "tar.bz2" {
225-
t.Fatalf("The extension of a bzip2 archive should be 'tar.bz2'")
226-
}
227-
}
228-
229-
func TestExtensionGzip(t *testing.T) {
230-
compression := Gzip
231-
output := compression.Extension()
232-
if output != "tar.gz" {
233-
t.Fatalf("The extension of a gzip archive should be 'tar.gz'")
234-
}
235-
}
236-
237-
func TestExtensionXz(t *testing.T) {
238-
compression := Xz
239-
output := compression.Extension()
240-
if output != "tar.xz" {
241-
t.Fatalf("The extension of a xz archive should be 'tar.xz'")
242-
}
243-
}
244-
245-
func TestExtensionZstd(t *testing.T) {
246-
compression := Zstd
247-
output := compression.Extension()
248-
if output != "tar.zst" {
249-
t.Fatalf("The extension of a zstd archive should be 'tar.zst'")
250-
}
251-
}
252-
253-
func TestCmdStreamLargeStderr(t *testing.T) {
254-
cmd := exec.Command("sh", "-c", "dd if=/dev/zero bs=1k count=1000 of=/dev/stderr; echo hello")
255-
out, err := cmdStream(cmd, nil)
256-
if err != nil {
257-
t.Fatalf("Failed to start command: %s, output: %s", err, out)
258-
}
259-
errCh := make(chan error, 1)
260-
go func() {
261-
_, err := io.Copy(io.Discard, out)
262-
errCh <- err
263-
}()
264-
select {
265-
case err := <-errCh:
266-
if err != nil {
267-
t.Fatalf("Command should not have failed (err=%.100s...)", err)
268-
}
269-
case <-time.After(5 * time.Second):
270-
t.Fatalf("Command did not complete in 5 seconds; probable deadlock")
271-
}
272-
}
273-
274-
func TestCmdStreamBad(t *testing.T) {
275-
// TODO Windows: Figure out why this is failing in CI but not locally
276-
if runtime.GOOS == "windows" {
277-
t.Skip("Failing on Windows CI machines")
278-
}
279-
badCmd := exec.Command("sh", "-c", "echo hello; echo >&2 error couldn\\'t reverse the phase pulser; exit 1")
280-
out, err := cmdStream(badCmd, nil)
281-
if err != nil {
282-
t.Fatalf("Failed to start command: %s", err)
283-
}
284-
if output, err := io.ReadAll(out); err == nil {
285-
t.Fatalf("Command should have failed")
286-
} else if err.Error() != "exit status 1: error couldn't reverse the phase pulser\n" {
287-
t.Fatalf("Wrong error value (%s)", err)
288-
} else if s := string(output); s != "hello\n" {
289-
t.Fatalf("Command output should be '%s', not '%s'", "hello\\n", output)
290-
}
291-
}
292-
293-
func TestCmdStreamGood(t *testing.T) {
294-
cmd := exec.Command("sh", "-c", "echo hello; exit 0")
295-
out, err := cmdStream(cmd, nil)
296-
if err != nil {
297-
t.Fatal(err)
298-
}
299-
if output, err := io.ReadAll(out); err != nil {
300-
t.Fatalf("Command should not have failed (err=%s)", err)
301-
} else if s := string(output); s != "hello\n" {
302-
t.Fatalf("Command output should be '%s', not '%s'", "hello\\n", output)
303-
}
304-
}
305-
306106
func TestUntarPathWithInvalidDest(t *testing.T) {
307107
tempFolder := t.TempDir()
308108
invalidDestFolder := filepath.Join(tempFolder, "invalidDest")
@@ -649,7 +449,7 @@ func tarUntar(t *testing.T, origin string, options *TarOptions) ([]Change, error
649449
}
650450
wrap := io.MultiReader(bytes.NewReader(buf), archive)
651451

652-
detectedCompression := DetectCompression(buf)
452+
detectedCompression := compression.Detect(buf)
653453
expected := options.Compression
654454
if detectedCompression.Extension() != expected.Extension() {
655455
return nil, fmt.Errorf("wrong compression detected; expected: %s, got: %s", expected.Extension(), detectedCompression.Extension())
@@ -666,34 +466,6 @@ func tarUntar(t *testing.T, origin string, options *TarOptions) ([]Change, error
666466
return ChangesDirs(origin, tmp)
667467
}
668468

669-
func TestDetectCompressionZstd(t *testing.T) {
670-
// test zstd compression without skippable frames.
671-
compressedData := []byte{
672-
0x28, 0xb5, 0x2f, 0xfd, // magic number of Zstandard frame: 0xFD2FB528
673-
0x04, 0x00, 0x31, 0x00, 0x00, // frame header
674-
0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, // data block "docker"
675-
0x16, 0x0e, 0x21, 0xc3, // content checksum
676-
}
677-
compression := DetectCompression(compressedData)
678-
if compression != Zstd {
679-
t.Fatal("Unexpected compression")
680-
}
681-
// test zstd compression with skippable frames.
682-
hex := []byte{
683-
0x50, 0x2a, 0x4d, 0x18, // magic number of skippable frame: 0x184D2A50 to 0x184D2A5F
684-
0x04, 0x00, 0x00, 0x00, // frame size
685-
0x5d, 0x00, 0x00, 0x00, // user data
686-
0x28, 0xb5, 0x2f, 0xfd, // magic number of Zstandard frame: 0xFD2FB528
687-
0x04, 0x00, 0x31, 0x00, 0x00, // frame header
688-
0x64, 0x6f, 0x63, 0x6b, 0x65, 0x72, // data block "docker"
689-
0x16, 0x0e, 0x21, 0xc3, // content checksum
690-
}
691-
compression = DetectCompression(hex)
692-
if compression != Zstd {
693-
t.Fatal("Unexpected compression")
694-
}
695-
}
696-
697469
func TestTarUntar(t *testing.T) {
698470
origin := t.TempDir()
699471
if err := os.WriteFile(filepath.Join(origin, "1"), []byte("hello world"), 0o700); err != nil {
@@ -706,9 +478,9 @@ func TestTarUntar(t *testing.T) {
706478
t.Fatal(err)
707479
}
708480

709-
for _, c := range []Compression{
710-
Uncompressed,
711-
Gzip,
481+
for _, c := range []compression.Compression{
482+
compression.None,
483+
compression.Gzip,
712484
} {
713485
changes, err := tarUntar(t, origin, &TarOptions{
714486
Compression: c,
@@ -1352,39 +1124,6 @@ func readFileFromArchive(t *testing.T, archive io.ReadCloser, name string, expec
13521124
return string(content)
13531125
}
13541126

1355-
func TestDisablePigz(t *testing.T) {
1356-
_, err := exec.LookPath("unpigz")
1357-
if err != nil {
1358-
t.Log("Test will not check full path when Pigz not installed")
1359-
}
1360-
1361-
t.Setenv("MOBY_DISABLE_PIGZ", "true")
1362-
1363-
r := testDecompressStream(t, "gz", "gzip -f")
1364-
1365-
// wrapped in closer to cancel contex and release buffer to pool
1366-
wrapper := r.(*readCloserWrapper)
1367-
1368-
assert.Equal(t, reflect.TypeOf(wrapper.Reader), reflect.TypeOf(&gzip.Reader{}))
1369-
}
1370-
1371-
func TestPigz(t *testing.T) {
1372-
r := testDecompressStream(t, "gz", "gzip -f")
1373-
// wrapper for buffered reader and context cancel
1374-
wrapper := r.(*readCloserWrapper)
1375-
1376-
_, err := exec.LookPath("unpigz")
1377-
if err == nil {
1378-
t.Log("Tested whether Pigz is used, as it installed")
1379-
// For the command wait wrapper
1380-
cmdWaitCloserWrapper := wrapper.Reader.(*readCloserWrapper)
1381-
assert.Equal(t, reflect.TypeOf(cmdWaitCloserWrapper.Reader), reflect.TypeOf(&io.PipeReader{}))
1382-
} else {
1383-
t.Log("Tested whether Pigz is not used, as it not installed")
1384-
assert.Equal(t, reflect.TypeOf(wrapper.Reader), reflect.TypeOf(&gzip.Reader{}))
1385-
}
1386-
}
1387-
13881127
func TestNosysFileInfo(t *testing.T) {
13891128
st, err := os.Stat("archive_test.go")
13901129
assert.NilError(t, err)

0 commit comments

Comments
 (0)