123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- package archive // import "github.com/docker/docker/pkg/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, nil, nil)
- 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, nil, nil)
- 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)
- var 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
- }
|