github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/layer/mount_test.go (about)

     1  package layer // import "github.com/demonoid81/moby/layer"
     2  
     3  import (
     4  	"io/ioutil"
     5  	"runtime"
     6  	"sort"
     7  	"testing"
     8  
     9  	"github.com/containerd/continuity/driver"
    10  	"github.com/demonoid81/moby/pkg/archive"
    11  	"github.com/demonoid81/moby/pkg/containerfs"
    12  )
    13  
    14  func TestMountInit(t *testing.T) {
    15  	// TODO Windows: Figure out why this is failing
    16  	if runtime.GOOS == "windows" {
    17  		t.Skip("Failing on Windows")
    18  	}
    19  	ls, _, cleanup := newTestStore(t)
    20  	defer cleanup()
    21  
    22  	basefile := newTestFile("testfile.txt", []byte("base data!"), 0644)
    23  	initfile := newTestFile("testfile.txt", []byte("init data!"), 0777)
    24  
    25  	li := initWithFiles(basefile)
    26  	layer, err := createLayer(ls, "", li)
    27  	if err != nil {
    28  		t.Fatal(err)
    29  	}
    30  
    31  	mountInit := func(root containerfs.ContainerFS) error {
    32  		return initfile.ApplyFile(root)
    33  	}
    34  
    35  	rwLayerOpts := &CreateRWLayerOpts{
    36  		InitFunc: mountInit,
    37  	}
    38  	m, err := ls.CreateRWLayer("fun-mount", layer.ChainID(), rwLayerOpts)
    39  	if err != nil {
    40  		t.Fatal(err)
    41  	}
    42  
    43  	pathFS, err := m.Mount("")
    44  	if err != nil {
    45  		t.Fatal(err)
    46  	}
    47  
    48  	fi, err := pathFS.Stat(pathFS.Join(pathFS.Path(), "testfile.txt"))
    49  	if err != nil {
    50  		t.Fatal(err)
    51  	}
    52  
    53  	f, err := pathFS.Open(pathFS.Join(pathFS.Path(), "testfile.txt"))
    54  	if err != nil {
    55  		t.Fatal(err)
    56  	}
    57  	defer f.Close()
    58  
    59  	b, err := ioutil.ReadAll(f)
    60  	if err != nil {
    61  		t.Fatal(err)
    62  	}
    63  
    64  	if expected := "init data!"; string(b) != expected {
    65  		t.Fatalf("Unexpected test file contents %q, expected %q", string(b), expected)
    66  	}
    67  
    68  	if fi.Mode().Perm() != 0777 {
    69  		t.Fatalf("Unexpected filemode %o, expecting %o", fi.Mode().Perm(), 0777)
    70  	}
    71  }
    72  
    73  func TestMountSize(t *testing.T) {
    74  	// TODO Windows: Figure out why this is failing
    75  	if runtime.GOOS == "windows" {
    76  		t.Skip("Failing on Windows")
    77  	}
    78  	ls, _, cleanup := newTestStore(t)
    79  	defer cleanup()
    80  
    81  	content1 := []byte("Base contents")
    82  	content2 := []byte("Mutable contents")
    83  	contentInit := []byte("why am I excluded from the size ☹")
    84  
    85  	li := initWithFiles(newTestFile("file1", content1, 0644))
    86  	layer, err := createLayer(ls, "", li)
    87  	if err != nil {
    88  		t.Fatal(err)
    89  	}
    90  
    91  	mountInit := func(root containerfs.ContainerFS) error {
    92  		return newTestFile("file-init", contentInit, 0777).ApplyFile(root)
    93  	}
    94  	rwLayerOpts := &CreateRWLayerOpts{
    95  		InitFunc: mountInit,
    96  	}
    97  
    98  	m, err := ls.CreateRWLayer("mount-size", layer.ChainID(), rwLayerOpts)
    99  	if err != nil {
   100  		t.Fatal(err)
   101  	}
   102  
   103  	pathFS, err := m.Mount("")
   104  	if err != nil {
   105  		t.Fatal(err)
   106  	}
   107  
   108  	if err := driver.WriteFile(pathFS, pathFS.Join(pathFS.Path(), "file2"), content2, 0755); err != nil {
   109  		t.Fatal(err)
   110  	}
   111  
   112  	mountSize, err := m.Size()
   113  	if err != nil {
   114  		t.Fatal(err)
   115  	}
   116  
   117  	if expected := len(content2); int(mountSize) != expected {
   118  		t.Fatalf("Unexpected mount size %d, expected %d", int(mountSize), expected)
   119  	}
   120  }
   121  
   122  func TestMountChanges(t *testing.T) {
   123  	// TODO Windows: Figure out why this is failing
   124  	if runtime.GOOS == "windows" {
   125  		t.Skip("Failing on Windows")
   126  	}
   127  	ls, _, cleanup := newTestStore(t)
   128  	defer cleanup()
   129  
   130  	basefiles := []FileApplier{
   131  		newTestFile("testfile1.txt", []byte("base data!"), 0644),
   132  		newTestFile("testfile2.txt", []byte("base data!"), 0644),
   133  		newTestFile("testfile3.txt", []byte("base data!"), 0644),
   134  	}
   135  	initfile := newTestFile("testfile1.txt", []byte("init data!"), 0777)
   136  
   137  	li := initWithFiles(basefiles...)
   138  	layer, err := createLayer(ls, "", li)
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  
   143  	mountInit := func(root containerfs.ContainerFS) error {
   144  		return initfile.ApplyFile(root)
   145  	}
   146  	rwLayerOpts := &CreateRWLayerOpts{
   147  		InitFunc: mountInit,
   148  	}
   149  
   150  	m, err := ls.CreateRWLayer("mount-changes", layer.ChainID(), rwLayerOpts)
   151  	if err != nil {
   152  		t.Fatal(err)
   153  	}
   154  
   155  	pathFS, err := m.Mount("")
   156  	if err != nil {
   157  		t.Fatal(err)
   158  	}
   159  
   160  	if err := pathFS.Lchmod(pathFS.Join(pathFS.Path(), "testfile1.txt"), 0755); err != nil {
   161  		t.Fatal(err)
   162  	}
   163  
   164  	if err := driver.WriteFile(pathFS, pathFS.Join(pathFS.Path(), "testfile1.txt"), []byte("mount data!"), 0755); err != nil {
   165  		t.Fatal(err)
   166  	}
   167  
   168  	if err := pathFS.Remove(pathFS.Join(pathFS.Path(), "testfile2.txt")); err != nil {
   169  		t.Fatal(err)
   170  	}
   171  
   172  	if err := pathFS.Lchmod(pathFS.Join(pathFS.Path(), "testfile3.txt"), 0755); err != nil {
   173  		t.Fatal(err)
   174  	}
   175  
   176  	if err := driver.WriteFile(pathFS, pathFS.Join(pathFS.Path(), "testfile4.txt"), []byte("mount data!"), 0644); err != nil {
   177  		t.Fatal(err)
   178  	}
   179  
   180  	changes, err := m.Changes()
   181  	if err != nil {
   182  		t.Fatal(err)
   183  	}
   184  
   185  	if expected := 4; len(changes) != expected {
   186  		t.Fatalf("Wrong number of changes %d, expected %d", len(changes), expected)
   187  	}
   188  
   189  	sortChanges(changes)
   190  
   191  	assertChange(t, changes[0], archive.Change{
   192  		Path: "/testfile1.txt",
   193  		Kind: archive.ChangeModify,
   194  	})
   195  	assertChange(t, changes[1], archive.Change{
   196  		Path: "/testfile2.txt",
   197  		Kind: archive.ChangeDelete,
   198  	})
   199  	assertChange(t, changes[2], archive.Change{
   200  		Path: "/testfile3.txt",
   201  		Kind: archive.ChangeModify,
   202  	})
   203  	assertChange(t, changes[3], archive.Change{
   204  		Path: "/testfile4.txt",
   205  		Kind: archive.ChangeAdd,
   206  	})
   207  }
   208  
   209  func TestMountApply(t *testing.T) {
   210  	// TODO Windows: Figure out why this is failing
   211  	if runtime.GOOS == "windows" {
   212  		t.Skip("Failing on Windows")
   213  	}
   214  	ls, _, cleanup := newTestStore(t)
   215  	defer cleanup()
   216  
   217  	basefile := newTestFile("testfile.txt", []byte("base data!"), 0644)
   218  	newfile := newTestFile("newfile.txt", []byte("new data!"), 0755)
   219  
   220  	li := initWithFiles(basefile)
   221  	layer, err := createLayer(ls, "", li)
   222  	if err != nil {
   223  		t.Fatal(err)
   224  	}
   225  
   226  	di := initWithFiles(newfile)
   227  	diffLayer, err := createLayer(ls, "", di)
   228  	if err != nil {
   229  		t.Fatal(err)
   230  	}
   231  
   232  	m, err := ls.CreateRWLayer("fun-mount", layer.ChainID(), nil)
   233  	if err != nil {
   234  		t.Fatal(err)
   235  	}
   236  
   237  	r, err := diffLayer.TarStream()
   238  	if err != nil {
   239  		t.Fatal(err)
   240  	}
   241  
   242  	if _, err := m.ApplyDiff(r); err != nil {
   243  		t.Fatal(err)
   244  	}
   245  
   246  	pathFS, err := m.Mount("")
   247  	if err != nil {
   248  		t.Fatal(err)
   249  	}
   250  
   251  	f, err := pathFS.Open(pathFS.Join(pathFS.Path(), "newfile.txt"))
   252  	if err != nil {
   253  		t.Fatal(err)
   254  	}
   255  	defer f.Close()
   256  
   257  	b, err := ioutil.ReadAll(f)
   258  	if err != nil {
   259  		t.Fatal(err)
   260  	}
   261  
   262  	if expected := "new data!"; string(b) != expected {
   263  		t.Fatalf("Unexpected test file contents %q, expected %q", string(b), expected)
   264  	}
   265  }
   266  
   267  func assertChange(t *testing.T, actual, expected archive.Change) {
   268  	if actual.Path != expected.Path {
   269  		t.Fatalf("Unexpected change path %s, expected %s", actual.Path, expected.Path)
   270  	}
   271  	if actual.Kind != expected.Kind {
   272  		t.Fatalf("Unexpected change type %s, expected %s", actual.Kind, expected.Kind)
   273  	}
   274  }
   275  
   276  func sortChanges(changes []archive.Change) {
   277  	cs := &changeSorter{
   278  		changes: changes,
   279  	}
   280  	sort.Sort(cs)
   281  }
   282  
   283  type changeSorter struct {
   284  	changes []archive.Change
   285  }
   286  
   287  func (cs *changeSorter) Len() int {
   288  	return len(cs.changes)
   289  }
   290  
   291  func (cs *changeSorter) Swap(i, j int) {
   292  	cs.changes[i], cs.changes[j] = cs.changes[j], cs.changes[i]
   293  }
   294  
   295  func (cs *changeSorter) Less(i, j int) bool {
   296  	return cs.changes[i].Path < cs.changes[j].Path
   297  }