github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/layer/mount_test.go (about)

     1  package layer
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"sort"
     8  	"testing"
     9  
    10  	"github.com/docker/docker/pkg/archive"
    11  )
    12  
    13  func TestMountInit(t *testing.T) {
    14  	ls, cleanup := newTestStore(t)
    15  	defer cleanup()
    16  
    17  	basefile := newTestFile("testfile.txt", []byte("base data!"), 0644)
    18  	initfile := newTestFile("testfile.txt", []byte("init data!"), 0777)
    19  
    20  	li := initWithFiles(basefile)
    21  	layer, err := createLayer(ls, "", li)
    22  	if err != nil {
    23  		t.Fatal(err)
    24  	}
    25  
    26  	mountInit := func(root string) error {
    27  		return initfile.ApplyFile(root)
    28  	}
    29  
    30  	m, err := ls.Mount("fun-mount", layer.ChainID(), "", mountInit)
    31  	if err != nil {
    32  		t.Fatal(err)
    33  	}
    34  
    35  	path, err := m.Path()
    36  	if err != nil {
    37  		t.Fatal(err)
    38  	}
    39  
    40  	f, err := os.Open(filepath.Join(path, "testfile.txt"))
    41  	if err != nil {
    42  		t.Fatal(err)
    43  	}
    44  	defer f.Close()
    45  
    46  	fi, err := f.Stat()
    47  	if err != nil {
    48  		t.Fatal(err)
    49  	}
    50  
    51  	b, err := ioutil.ReadAll(f)
    52  	if err != nil {
    53  		t.Fatal(err)
    54  	}
    55  
    56  	if expected := "init data!"; string(b) != expected {
    57  		t.Fatalf("Unexpected test file contents %q, expected %q", string(b), expected)
    58  	}
    59  
    60  	if fi.Mode().Perm() != 0777 {
    61  		t.Fatalf("Unexpected filemode %o, expecting %o", fi.Mode().Perm(), 0777)
    62  	}
    63  }
    64  
    65  func TestMountSize(t *testing.T) {
    66  	ls, cleanup := newTestStore(t)
    67  	defer cleanup()
    68  
    69  	content1 := []byte("Base contents")
    70  	content2 := []byte("Mutable contents")
    71  	contentInit := []byte("why am I excluded from the size ☹")
    72  
    73  	li := initWithFiles(newTestFile("file1", content1, 0644))
    74  	layer, err := createLayer(ls, "", li)
    75  	if err != nil {
    76  		t.Fatal(err)
    77  	}
    78  
    79  	mountInit := func(root string) error {
    80  		return newTestFile("file-init", contentInit, 0777).ApplyFile(root)
    81  	}
    82  
    83  	m, err := ls.Mount("mount-size", layer.ChainID(), "", mountInit)
    84  	if err != nil {
    85  		t.Fatal(err)
    86  	}
    87  
    88  	path, err := m.Path()
    89  	if err != nil {
    90  		t.Fatal(err)
    91  	}
    92  
    93  	if err := ioutil.WriteFile(filepath.Join(path, "file2"), content2, 0755); err != nil {
    94  		t.Fatal(err)
    95  	}
    96  
    97  	mountSize, err := m.Size()
    98  	if err != nil {
    99  		t.Fatal(err)
   100  	}
   101  
   102  	if expected := len(content2); int(mountSize) != expected {
   103  		t.Fatalf("Unexpected mount size %d, expected %d", int(mountSize), expected)
   104  	}
   105  }
   106  
   107  func TestMountChanges(t *testing.T) {
   108  	ls, cleanup := newTestStore(t)
   109  	defer cleanup()
   110  
   111  	basefiles := []FileApplier{
   112  		newTestFile("testfile1.txt", []byte("base data!"), 0644),
   113  		newTestFile("testfile2.txt", []byte("base data!"), 0644),
   114  		newTestFile("testfile3.txt", []byte("base data!"), 0644),
   115  	}
   116  	initfile := newTestFile("testfile1.txt", []byte("init data!"), 0777)
   117  
   118  	li := initWithFiles(basefiles...)
   119  	layer, err := createLayer(ls, "", li)
   120  	if err != nil {
   121  		t.Fatal(err)
   122  	}
   123  
   124  	mountInit := func(root string) error {
   125  		return initfile.ApplyFile(root)
   126  	}
   127  
   128  	m, err := ls.Mount("mount-changes", layer.ChainID(), "", mountInit)
   129  	if err != nil {
   130  		t.Fatal(err)
   131  	}
   132  
   133  	path, err := m.Path()
   134  	if err != nil {
   135  		t.Fatal(err)
   136  	}
   137  
   138  	if err := os.Chmod(filepath.Join(path, "testfile1.txt"), 0755); err != nil {
   139  		t.Fatal(err)
   140  	}
   141  
   142  	if err := ioutil.WriteFile(filepath.Join(path, "testfile1.txt"), []byte("mount data!"), 0755); err != nil {
   143  		t.Fatal(err)
   144  	}
   145  
   146  	if err := os.Remove(filepath.Join(path, "testfile2.txt")); err != nil {
   147  		t.Fatal(err)
   148  	}
   149  
   150  	if err := os.Chmod(filepath.Join(path, "testfile3.txt"), 0755); err != nil {
   151  		t.Fatal(err)
   152  	}
   153  
   154  	if err := ioutil.WriteFile(filepath.Join(path, "testfile4.txt"), []byte("mount data!"), 0644); err != nil {
   155  		t.Fatal(err)
   156  	}
   157  
   158  	changes, err := ls.Changes("mount-changes")
   159  	if err != nil {
   160  		t.Fatal(err)
   161  	}
   162  
   163  	if expected := 4; len(changes) != expected {
   164  		t.Fatalf("Wrong number of changes %d, expected %d", len(changes), expected)
   165  	}
   166  
   167  	sortChanges(changes)
   168  
   169  	assertChange(t, changes[0], archive.Change{
   170  		Path: "/testfile1.txt",
   171  		Kind: archive.ChangeModify,
   172  	})
   173  	assertChange(t, changes[1], archive.Change{
   174  		Path: "/testfile2.txt",
   175  		Kind: archive.ChangeDelete,
   176  	})
   177  	assertChange(t, changes[2], archive.Change{
   178  		Path: "/testfile3.txt",
   179  		Kind: archive.ChangeModify,
   180  	})
   181  	assertChange(t, changes[3], archive.Change{
   182  		Path: "/testfile4.txt",
   183  		Kind: archive.ChangeAdd,
   184  	})
   185  }
   186  
   187  func assertChange(t *testing.T, actual, expected archive.Change) {
   188  	if actual.Path != expected.Path {
   189  		t.Fatalf("Unexpected change path %s, expected %s", actual.Path, expected.Path)
   190  	}
   191  	if actual.Kind != expected.Kind {
   192  		t.Fatalf("Unexpected change type %s, expected %s", actual.Kind, expected.Kind)
   193  	}
   194  }
   195  
   196  func sortChanges(changes []archive.Change) {
   197  	cs := &changeSorter{
   198  		changes: changes,
   199  	}
   200  	sort.Sort(cs)
   201  }
   202  
   203  type changeSorter struct {
   204  	changes []archive.Change
   205  }
   206  
   207  func (cs *changeSorter) Len() int {
   208  	return len(cs.changes)
   209  }
   210  
   211  func (cs *changeSorter) Swap(i, j int) {
   212  	cs.changes[i], cs.changes[j] = cs.changes[j], cs.changes[i]
   213  }
   214  
   215  func (cs *changeSorter) Less(i, j int) bool {
   216  	return cs.changes[i].Path < cs.changes[j].Path
   217  }