瀏覽代碼

pkg/archive: test that confirms hardlink ordering

This test was written against
master(abdfb21e3a761efdd70614de42905ff7911c5372) as a failing test, but
works with this patch set.

Signed-off-by: Vincent Batts <vbatts@redhat.com>
Vincent Batts 10 年之前
父節點
當前提交
899a2dda09
共有 1 個文件被更改,包括 127 次插入0 次删除
  1. 127 0
      pkg/archive/changes_posix_test.go

+ 127 - 0
pkg/archive/changes_posix_test.go

@@ -0,0 +1,127 @@
+package archive
+
+import (
+	"archive/tar"
+	"fmt"
+	"io"
+	"io/ioutil"
+	"os"
+	"path"
+	"sort"
+	"testing"
+)
+
+func TestHardLinkOrder(t *testing.T) {
+	names := []string{"file1.txt", "file2.txt", "file3.txt"}
+	msg := []byte("Hey y'all")
+
+	// Create dir
+	src, err := ioutil.TempDir("", "docker-hardlink-test-src-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	//defer os.RemoveAll(src)
+	for _, name := range names {
+		func() {
+			fh, err := os.Create(path.Join(src, name))
+			if err != nil {
+				t.Fatal(err)
+			}
+			defer fh.Close()
+			if _, err = fh.Write(msg); err != nil {
+				t.Fatal(err)
+			}
+		}()
+	}
+	// Create dest, with changes that includes hardlinks
+	dest, err := ioutil.TempDir("", "docker-hardlink-test-dest-")
+	if err != nil {
+		t.Fatal(err)
+	}
+	os.RemoveAll(dest) // we just want the name, at first
+	if err := copyDir(src, dest); err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(dest)
+	for _, name := range names {
+		for i := 0; i < 5; i++ {
+			if err := os.Link(path.Join(dest, name), path.Join(dest, fmt.Sprintf("%s.link%d", name, i))); err != nil {
+				t.Fatal(err)
+			}
+		}
+	}
+
+	// get changes
+	changes, err := ChangesDirs(dest, src)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// sort
+	sort.Sort(changesByPath(changes))
+
+	// ExportChanges
+	ar, err := ExportChanges(dest, changes)
+	if err != nil {
+		t.Fatal(err)
+	}
+	hdrs, err := walkHeaders(ar)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// reverse sort
+	sort.Sort(sort.Reverse(changesByPath(changes)))
+	// ExportChanges
+	arRev, err := ExportChanges(dest, changes)
+	if err != nil {
+		t.Fatal(err)
+	}
+	hdrsRev, err := walkHeaders(arRev)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// line up the two sets
+	sort.Sort(tarHeaders(hdrs))
+	sort.Sort(tarHeaders(hdrsRev))
+
+	// compare Size and LinkName
+	for i := range hdrs {
+		if hdrs[i].Name != hdrsRev[i].Name {
+			t.Errorf("headers - expected name %q; but got %q", hdrs[i].Name, hdrsRev[i].Name)
+		}
+		if hdrs[i].Size != hdrsRev[i].Size {
+			t.Errorf("headers - %q expected size %d; but got %d", hdrs[i].Name, hdrs[i].Size, hdrsRev[i].Size)
+		}
+		if hdrs[i].Typeflag != hdrsRev[i].Typeflag {
+			t.Errorf("headers - %q expected type %d; but got %d", hdrs[i].Name, hdrs[i].Typeflag, hdrsRev[i].Typeflag)
+		}
+		if hdrs[i].Linkname != hdrsRev[i].Linkname {
+			t.Errorf("headers - %q expected linkname %q; but got %q", hdrs[i].Name, hdrs[i].Linkname, hdrsRev[i].Linkname)
+		}
+	}
+
+}
+
+type tarHeaders []tar.Header
+
+func (th tarHeaders) Len() int           { return len(th) }
+func (th tarHeaders) Swap(i, j int)      { th[j], th[i] = th[i], th[j] }
+func (th tarHeaders) Less(i, j int) bool { return th[i].Name < th[j].Name }
+
+func walkHeaders(r io.Reader) ([]tar.Header, error) {
+	t := tar.NewReader(r)
+	headers := []tar.Header{}
+	for {
+		hdr, err := t.Next()
+		if err != nil {
+			if err == io.EOF {
+				break
+			}
+			return headers, err
+		}
+		headers = append(headers, *hdr)
+	}
+	return headers, nil
+}