github.com/olljanat/moby@v1.13.1/layer/mount_test.go (about)

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