Browse Source

Add test on archive.go (#11603)

- Trying to add or complete unit test to each ``func``
- Removing dead code (``escapeName``)

Signed-off-by: Vincent Demeester <vincent@sbr.pm>
Vincent Demeester 10 years ago
parent
commit
c4fe5dad1d
2 changed files with 242 additions and 17 deletions
  1. 0 16
      pkg/archive/archive.go
  2. 242 1
      pkg/archive/archive_test.go

+ 0 - 16
pkg/archive/archive.go

@@ -388,22 +388,6 @@ func Tar(path string, compression Compression) (io.ReadCloser, error) {
 	return TarWithOptions(path, &TarOptions{Compression: compression})
 	return TarWithOptions(path, &TarOptions{Compression: compression})
 }
 }
 
 
-func escapeName(name string) string {
-	escaped := make([]byte, 0)
-	for i, c := range []byte(name) {
-		if i == 0 && c == '/' {
-			continue
-		}
-		// all printable chars except "-" which is 0x2d
-		if (0x20 <= c && c <= 0x7E) && c != 0x2d {
-			escaped = append(escaped, c)
-		} else {
-			escaped = append(escaped, fmt.Sprintf("\\%03o", c)...)
-		}
-	}
-	return string(escaped)
-}
-
 // TarWithOptions creates an archive from the directory at `path`, only including files whose relative
 // TarWithOptions creates an archive from the directory at `path`, only including files whose relative
 // paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`.
 // paths are included in `options.IncludeFiles` (if non-nil) or not in `options.ExcludePatterns`.
 func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) {
 func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) {

+ 242 - 1
pkg/archive/archive_test.go

@@ -14,9 +14,150 @@ import (
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
+	"github.com/docker/docker/pkg/system"
 	"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
 	"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
 )
 )
 
 
+func TestIsArchiveNilHeader(t *testing.T) {
+	out := IsArchive(nil)
+	if out {
+		t.Fatalf("isArchive should return false as nil is not a valid archive header")
+	}
+}
+
+func TestIsArchiveInvalidHeader(t *testing.T) {
+	header := []byte{0x00, 0x01, 0x02}
+	out := IsArchive(header)
+	if out {
+		t.Fatalf("isArchive should return false as %s is not a valid archive header", header)
+	}
+}
+
+func TestIsArchiveBzip2(t *testing.T) {
+	header := []byte{0x42, 0x5A, 0x68}
+	out := IsArchive(header)
+	if !out {
+		t.Fatalf("isArchive should return true as %s is a bz2 header", header)
+	}
+}
+
+func TestIsArchive7zip(t *testing.T) {
+	header := []byte{0x50, 0x4b, 0x03, 0x04}
+	out := IsArchive(header)
+	if out {
+		t.Fatalf("isArchive should return false as %s is a 7z header and it is not supported", header)
+	}
+}
+
+func TestDecompressStreamGzip(t *testing.T) {
+	cmd := exec.Command("/bin/sh", "-c", "touch /tmp/archive && gzip -f /tmp/archive")
+	output, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("Fail to create an archive file for test : %s.", output)
+	}
+	archive, err := os.Open("/tmp/archive.gz")
+	_, err = DecompressStream(archive)
+	if err != nil {
+		t.Fatalf("Failed to decompress a gzip file.")
+	}
+}
+
+func TestDecompressStreamBzip2(t *testing.T) {
+	cmd := exec.Command("/bin/sh", "-c", "touch /tmp/archive && bzip2 -f /tmp/archive")
+	output, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("Fail to create an archive file for test : %s.", output)
+	}
+	archive, err := os.Open("/tmp/archive.bz2")
+	_, err = DecompressStream(archive)
+	if err != nil {
+		t.Fatalf("Failed to decompress a bzip2 file.")
+	}
+}
+
+func TestDecompressStreamXz(t *testing.T) {
+	cmd := exec.Command("/bin/sh", "-c", "touch /tmp/archive && xz -f /tmp/archive")
+	output, err := cmd.CombinedOutput()
+	if err != nil {
+		t.Fatalf("Fail to create an archive file for test : %s.", output)
+	}
+	archive, err := os.Open("/tmp/archive.xz")
+	_, err = DecompressStream(archive)
+	if err != nil {
+		t.Fatalf("Failed to decompress a xz file.")
+	}
+}
+
+func TestCompressStreamXzUnsuported(t *testing.T) {
+	dest, err := os.Create("/tmp/dest")
+	if err != nil {
+		t.Fatalf("Fail to create the destination file")
+	}
+	_, err = CompressStream(dest, Xz)
+	if err == nil {
+		t.Fatalf("Should fail as xz is unsupported for compression format.")
+	}
+}
+
+func TestCompressStreamBzip2Unsupported(t *testing.T) {
+	dest, err := os.Create("/tmp/dest")
+	if err != nil {
+		t.Fatalf("Fail to create the destination file")
+	}
+	_, err = CompressStream(dest, Xz)
+	if err == nil {
+		t.Fatalf("Should fail as xz is unsupported for compression format.")
+	}
+}
+
+func TestCompressStreamInvalid(t *testing.T) {
+	dest, err := os.Create("/tmp/dest")
+	if err != nil {
+		t.Fatalf("Fail to create the destination file")
+	}
+	_, err = CompressStream(dest, -1)
+	if err == nil {
+		t.Fatalf("Should fail as xz is unsupported for compression format.")
+	}
+}
+
+func TestExtensionInvalid(t *testing.T) {
+	compression := Compression(-1)
+	output := compression.Extension()
+	if output != "" {
+		t.Fatalf("The extension of an invalid compression should be an empty string.")
+	}
+}
+
+func TestExtensionUncompressed(t *testing.T) {
+	compression := Uncompressed
+	output := compression.Extension()
+	if output != "tar" {
+		t.Fatalf("The extension of a uncompressed archive should be 'tar'.")
+	}
+}
+func TestExtensionBzip2(t *testing.T) {
+	compression := Bzip2
+	output := compression.Extension()
+	if output != "tar.bz2" {
+		t.Fatalf("The extension of a bzip2 archive should be 'tar.bz2'")
+	}
+}
+func TestExtensionGzip(t *testing.T) {
+	compression := Gzip
+	output := compression.Extension()
+	if output != "tar.gz" {
+		t.Fatalf("The extension of a bzip2 archive should be 'tar.gz'")
+	}
+}
+func TestExtensionXz(t *testing.T) {
+	compression := Xz
+	output := compression.Extension()
+	if output != "tar.xz" {
+		t.Fatalf("The extension of a bzip2 archive should be 'tar.xz'")
+	}
+}
+
 func TestCmdStreamLargeStderr(t *testing.T) {
 func TestCmdStreamLargeStderr(t *testing.T) {
 	cmd := exec.Command("/bin/sh", "-c", "dd if=/dev/zero bs=1k count=1000 of=/dev/stderr; echo hello")
 	cmd := exec.Command("/bin/sh", "-c", "dd if=/dev/zero bs=1k count=1000 of=/dev/stderr; echo hello")
 	out, err := CmdStream(cmd, nil)
 	out, err := CmdStream(cmd, nil)
@@ -179,11 +320,56 @@ func TestTarUntar(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestTarUntarWithXattr(t *testing.T) {
+	origin, err := ioutil.TempDir("", "docker-test-untar-origin")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(origin)
+	if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil {
+		t.Fatal(err)
+	}
+	if err := ioutil.WriteFile(path.Join(origin, "2"), []byte("welcome!"), 0700); err != nil {
+		t.Fatal(err)
+	}
+	if err := ioutil.WriteFile(path.Join(origin, "3"), []byte("will be ignored"), 0700); err != nil {
+		t.Fatal(err)
+	}
+	if err := system.Lsetxattr(path.Join(origin, "2"), "security.capability", []byte{0x00}, 0); err != nil {
+		t.Fatal(err)
+	}
+
+	for _, c := range []Compression{
+		Uncompressed,
+		Gzip,
+	} {
+		changes, err := tarUntar(t, origin, &TarOptions{
+			Compression:     c,
+			ExcludePatterns: []string{"3"},
+		})
+
+		if err != nil {
+			t.Fatalf("Error tar/untar for compression %s: %s", c.Extension(), err)
+		}
+
+		if len(changes) != 1 || changes[0].Path != "/3" {
+			t.Fatalf("Unexpected differences after tarUntar: %v", changes)
+		}
+		capability, _ := system.Lgetxattr(path.Join(origin, "2"), "security.capability")
+		if capability == nil && capability[0] != 0x00 {
+			t.Fatalf("Untar should have kept the 'security.capability' xattr.")
+		}
+	}
+}
+
 func TestTarWithOptions(t *testing.T) {
 func TestTarWithOptions(t *testing.T) {
 	origin, err := ioutil.TempDir("", "docker-test-untar-origin")
 	origin, err := ioutil.TempDir("", "docker-test-untar-origin")
 	if err != nil {
 	if err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
 	}
 	}
+	if _, err := ioutil.TempDir(origin, "folder"); err != nil {
+		t.Fatal(err)
+	}
 	defer os.RemoveAll(origin)
 	defer os.RemoveAll(origin)
 	if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil {
 	if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil {
 		t.Fatal(err)
 		t.Fatal(err)
@@ -196,8 +382,11 @@ func TestTarWithOptions(t *testing.T) {
 		opts       *TarOptions
 		opts       *TarOptions
 		numChanges int
 		numChanges int
 	}{
 	}{
-		{&TarOptions{IncludeFiles: []string{"1"}}, 1},
+		{&TarOptions{IncludeFiles: []string{"1"}}, 2},
 		{&TarOptions{ExcludePatterns: []string{"2"}}, 1},
 		{&TarOptions{ExcludePatterns: []string{"2"}}, 1},
+		{&TarOptions{ExcludePatterns: []string{"1", "folder*"}}, 2},
+		{&TarOptions{IncludeFiles: []string{"1", "1"}}, 2},
+		{&TarOptions{Name: "test", IncludeFiles: []string{"1"}}, 4},
 	}
 	}
 	for _, testCase := range cases {
 	for _, testCase := range cases {
 		changes, err := tarUntar(t, origin, testCase.opts)
 		changes, err := tarUntar(t, origin, testCase.opts)
@@ -256,6 +445,58 @@ func TestUntarUstarGnuConflict(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestTarWithBlockCharFifo(t *testing.T) {
+	origin, err := ioutil.TempDir("", "docker-test-tar-hardlink")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(origin)
+	if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil {
+		t.Fatal(err)
+	}
+	if err := system.Mknod(path.Join(origin, "2"), syscall.S_IFBLK, int(system.Mkdev(int64(12), int64(5)))); err != nil {
+		t.Fatal(err)
+	}
+	if err := system.Mknod(path.Join(origin, "3"), syscall.S_IFCHR, int(system.Mkdev(int64(12), int64(5)))); err != nil {
+		t.Fatal(err)
+	}
+	if err := system.Mknod(path.Join(origin, "4"), syscall.S_IFIFO, int(system.Mkdev(int64(12), int64(5)))); err != nil {
+		t.Fatal(err)
+	}
+
+	dest, err := ioutil.TempDir("", "docker-test-tar-hardlink-dest")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dest)
+
+	// we'll do this in two steps to separate failure
+	fh, err := Tar(origin, Uncompressed)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// ensure we can read the whole thing with no error, before writing back out
+	buf, err := ioutil.ReadAll(fh)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	bRdr := bytes.NewReader(buf)
+	err = Untar(bRdr, dest, &TarOptions{Compression: Uncompressed})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	changes, err := ChangesDirs(origin, dest)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(changes) > 0 {
+		t.Fatalf("Tar with special device (block, char, fifo) should keep them (recreate them when untar) : %s", changes)
+	}
+}
+
 func TestTarWithHardLink(t *testing.T) {
 func TestTarWithHardLink(t *testing.T) {
 	origin, err := ioutil.TempDir("", "docker-test-tar-hardlink")
 	origin, err := ioutil.TempDir("", "docker-test-tar-hardlink")
 	if err != nil {
 	if err != nil {