github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/pkg/archive/archive_linux_test.go (about) 1 package archive 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "syscall" 8 "testing" 9 10 "github.com/docker/docker/pkg/system" 11 ) 12 13 // setupOverlayTestDir creates files in a directory with overlay whiteouts 14 // Tree layout 15 // . 16 // ├── d1 # opaque, 0700 17 // │ └── f1 # empty file, 0600 18 // ├── d2 # opaque, 0750 19 // │ └── f1 # empty file, 0660 20 // └── d3 # 0700 21 // └── f1 # whiteout, 0644 22 func setupOverlayTestDir(t *testing.T, src string) { 23 // Create opaque directory containing single file and permission 0700 24 if err := os.Mkdir(filepath.Join(src, "d1"), 0700); err != nil { 25 t.Fatal(err) 26 } 27 28 if err := system.Lsetxattr(filepath.Join(src, "d1"), "trusted.overlay.opaque", []byte("y"), 0); err != nil { 29 t.Fatal(err) 30 } 31 32 if err := ioutil.WriteFile(filepath.Join(src, "d1", "f1"), []byte{}, 0600); err != nil { 33 t.Fatal(err) 34 } 35 36 // Create another opaque directory containing single file but with permission 0750 37 if err := os.Mkdir(filepath.Join(src, "d2"), 0750); err != nil { 38 t.Fatal(err) 39 } 40 41 if err := system.Lsetxattr(filepath.Join(src, "d2"), "trusted.overlay.opaque", []byte("y"), 0); err != nil { 42 t.Fatal(err) 43 } 44 45 if err := ioutil.WriteFile(filepath.Join(src, "d2", "f1"), []byte{}, 0660); err != nil { 46 t.Fatal(err) 47 } 48 49 // Create regular directory with deleted file 50 if err := os.Mkdir(filepath.Join(src, "d3"), 0700); err != nil { 51 t.Fatal(err) 52 } 53 54 if err := system.Mknod(filepath.Join(src, "d3", "f1"), syscall.S_IFCHR, 0); err != nil { 55 t.Fatal(err) 56 } 57 } 58 59 func checkOpaqueness(t *testing.T, path string, opaque string) { 60 xattrOpaque, err := system.Lgetxattr(path, "trusted.overlay.opaque") 61 if err != nil { 62 t.Fatal(err) 63 } 64 if string(xattrOpaque) != opaque { 65 t.Fatalf("Unexpected opaque value: %q, expected %q", string(xattrOpaque), opaque) 66 } 67 68 } 69 70 func checkOverlayWhiteout(t *testing.T, path string) { 71 stat, err := os.Stat(path) 72 if err != nil { 73 t.Fatal(err) 74 } 75 statT, ok := stat.Sys().(*syscall.Stat_t) 76 if !ok { 77 t.Fatalf("Unexpected type: %t, expected *syscall.Stat_t", stat.Sys()) 78 } 79 if statT.Rdev != 0 { 80 t.Fatalf("Non-zero device number for whiteout") 81 } 82 } 83 84 func checkFileMode(t *testing.T, path string, perm os.FileMode) { 85 stat, err := os.Stat(path) 86 if err != nil { 87 t.Fatal(err) 88 } 89 if stat.Mode() != perm { 90 t.Fatalf("Unexpected file mode for %s: %o, expected %o", path, stat.Mode(), perm) 91 } 92 } 93 94 func TestOverlayTarUntar(t *testing.T) { 95 oldmask, err := system.Umask(0) 96 if err != nil { 97 t.Fatal(err) 98 } 99 defer system.Umask(oldmask) 100 101 src, err := ioutil.TempDir("", "docker-test-overlay-tar-src") 102 if err != nil { 103 t.Fatal(err) 104 } 105 defer os.RemoveAll(src) 106 107 setupOverlayTestDir(t, src) 108 109 dst, err := ioutil.TempDir("", "docker-test-overlay-tar-dst") 110 if err != nil { 111 t.Fatal(err) 112 } 113 defer os.RemoveAll(dst) 114 115 options := &TarOptions{ 116 Compression: Uncompressed, 117 WhiteoutFormat: OverlayWhiteoutFormat, 118 } 119 archive, err := TarWithOptions(src, options) 120 if err != nil { 121 t.Fatal(err) 122 } 123 defer archive.Close() 124 125 if err := Untar(archive, dst, options); err != nil { 126 t.Fatal(err) 127 } 128 129 checkFileMode(t, filepath.Join(dst, "d1"), 0700|os.ModeDir) 130 checkFileMode(t, filepath.Join(dst, "d2"), 0750|os.ModeDir) 131 checkFileMode(t, filepath.Join(dst, "d3"), 0700|os.ModeDir) 132 checkFileMode(t, filepath.Join(dst, "d1", "f1"), 0600) 133 checkFileMode(t, filepath.Join(dst, "d2", "f1"), 0660) 134 checkFileMode(t, filepath.Join(dst, "d3", "f1"), os.ModeCharDevice|os.ModeDevice) 135 136 checkOpaqueness(t, filepath.Join(dst, "d1"), "y") 137 checkOpaqueness(t, filepath.Join(dst, "d2"), "y") 138 checkOpaqueness(t, filepath.Join(dst, "d3"), "") 139 checkOverlayWhiteout(t, filepath.Join(dst, "d3", "f1")) 140 } 141 142 func TestOverlayTarAUFSUntar(t *testing.T) { 143 oldmask, err := system.Umask(0) 144 if err != nil { 145 t.Fatal(err) 146 } 147 defer system.Umask(oldmask) 148 149 src, err := ioutil.TempDir("", "docker-test-overlay-tar-src") 150 if err != nil { 151 t.Fatal(err) 152 } 153 defer os.RemoveAll(src) 154 155 setupOverlayTestDir(t, src) 156 157 dst, err := ioutil.TempDir("", "docker-test-overlay-tar-dst") 158 if err != nil { 159 t.Fatal(err) 160 } 161 defer os.RemoveAll(dst) 162 163 archive, err := TarWithOptions(src, &TarOptions{ 164 Compression: Uncompressed, 165 WhiteoutFormat: OverlayWhiteoutFormat, 166 }) 167 if err != nil { 168 t.Fatal(err) 169 } 170 defer archive.Close() 171 172 if err := Untar(archive, dst, &TarOptions{ 173 Compression: Uncompressed, 174 WhiteoutFormat: AUFSWhiteoutFormat, 175 }); err != nil { 176 t.Fatal(err) 177 } 178 179 checkFileMode(t, filepath.Join(dst, "d1"), 0700|os.ModeDir) 180 checkFileMode(t, filepath.Join(dst, "d1", WhiteoutOpaqueDir), 0700) 181 checkFileMode(t, filepath.Join(dst, "d2"), 0750|os.ModeDir) 182 checkFileMode(t, filepath.Join(dst, "d2", WhiteoutOpaqueDir), 0750) 183 checkFileMode(t, filepath.Join(dst, "d3"), 0700|os.ModeDir) 184 checkFileMode(t, filepath.Join(dst, "d1", "f1"), 0600) 185 checkFileMode(t, filepath.Join(dst, "d2", "f1"), 0660) 186 checkFileMode(t, filepath.Join(dst, "d3", WhiteoutPrefix+"f1"), 0600) 187 }