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 }