github.com/vieux/docker@v0.6.3-0.20161004191708-e097c2a938c7/daemon/graphdriver/graphtest/graphtest_unix.go (about) 1 // +build linux freebsd 2 3 package graphtest 4 5 import ( 6 "bytes" 7 "io/ioutil" 8 "math/rand" 9 "os" 10 "path" 11 "reflect" 12 "syscall" 13 "testing" 14 "unsafe" 15 16 "github.com/docker/docker/daemon/graphdriver" 17 "github.com/docker/docker/pkg/stringid" 18 "github.com/docker/go-units" 19 ) 20 21 var ( 22 drv *Driver 23 ) 24 25 // Driver conforms to graphdriver.Driver interface and 26 // contains information such as root and reference count of the number of clients using it. 27 // This helps in testing drivers added into the framework. 28 type Driver struct { 29 graphdriver.Driver 30 root string 31 refCount int 32 } 33 34 func newDriver(t testing.TB, name string, options []string) *Driver { 35 root, err := ioutil.TempDir("", "docker-graphtest-") 36 if err != nil { 37 t.Fatal(err) 38 } 39 40 if err := os.MkdirAll(root, 0755); err != nil { 41 t.Fatal(err) 42 } 43 44 d, err := graphdriver.GetDriver(name, root, options, nil, nil, nil) 45 if err != nil { 46 t.Logf("graphdriver: %v\n", err) 47 if err == graphdriver.ErrNotSupported || err == graphdriver.ErrPrerequisites || err == graphdriver.ErrIncompatibleFS { 48 t.Skipf("Driver %s not supported", name) 49 } 50 t.Fatal(err) 51 } 52 return &Driver{d, root, 1} 53 } 54 55 func cleanup(t testing.TB, d *Driver) { 56 if err := drv.Cleanup(); err != nil { 57 t.Fatal(err) 58 } 59 os.RemoveAll(d.root) 60 } 61 62 // GetDriver create a new driver with given name or return an existing driver with the name updating the reference count. 63 func GetDriver(t testing.TB, name string, options ...string) graphdriver.Driver { 64 if drv == nil { 65 drv = newDriver(t, name, options) 66 } else { 67 drv.refCount++ 68 } 69 return drv 70 } 71 72 // PutDriver removes the driver if it is no longer used and updates the reference count. 73 func PutDriver(t testing.TB) { 74 if drv == nil { 75 t.Skip("No driver to put!") 76 } 77 drv.refCount-- 78 if drv.refCount == 0 { 79 cleanup(t, drv) 80 drv = nil 81 } 82 } 83 84 // DriverTestCreateEmpty creates a new image and verifies it is empty and the right metadata 85 func DriverTestCreateEmpty(t testing.TB, drivername string, driverOptions ...string) { 86 driver := GetDriver(t, drivername, driverOptions...) 87 defer PutDriver(t) 88 89 if err := driver.Create("empty", "", "", nil); err != nil { 90 t.Fatal(err) 91 } 92 93 defer func() { 94 if err := driver.Remove("empty"); err != nil { 95 t.Fatal(err) 96 } 97 }() 98 99 if !driver.Exists("empty") { 100 t.Fatal("Newly created image doesn't exist") 101 } 102 103 dir, err := driver.Get("empty", "") 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 verifyFile(t, dir, 0755|os.ModeDir, 0, 0) 109 110 // Verify that the directory is empty 111 fis, err := readDir(dir) 112 if err != nil { 113 t.Fatal(err) 114 } 115 116 if len(fis) != 0 { 117 t.Fatal("New directory not empty") 118 } 119 120 driver.Put("empty") 121 } 122 123 // DriverTestCreateBase create a base driver and verify. 124 func DriverTestCreateBase(t testing.TB, drivername string, driverOptions ...string) { 125 driver := GetDriver(t, drivername, driverOptions...) 126 defer PutDriver(t) 127 128 createBase(t, driver, "Base") 129 defer func() { 130 if err := driver.Remove("Base"); err != nil { 131 t.Fatal(err) 132 } 133 }() 134 verifyBase(t, driver, "Base") 135 } 136 137 // DriverTestCreateSnap Create a driver and snap and verify. 138 func DriverTestCreateSnap(t testing.TB, drivername string, driverOptions ...string) { 139 driver := GetDriver(t, drivername, driverOptions...) 140 defer PutDriver(t) 141 142 createBase(t, driver, "Base") 143 144 defer func() { 145 if err := driver.Remove("Base"); err != nil { 146 t.Fatal(err) 147 } 148 }() 149 150 if err := driver.Create("Snap", "Base", "", nil); err != nil { 151 t.Fatal(err) 152 } 153 154 defer func() { 155 if err := driver.Remove("Snap"); err != nil { 156 t.Fatal(err) 157 } 158 }() 159 160 verifyBase(t, driver, "Snap") 161 } 162 163 // DriverTestDeepLayerRead reads a file from a lower layer under a given number of layers 164 func DriverTestDeepLayerRead(t testing.TB, layerCount int, drivername string, driverOptions ...string) { 165 driver := GetDriver(t, drivername, driverOptions...) 166 defer PutDriver(t) 167 168 base := stringid.GenerateRandomID() 169 170 if err := driver.Create(base, "", "", nil); err != nil { 171 t.Fatal(err) 172 } 173 174 content := []byte("test content") 175 if err := addFile(driver, base, "testfile.txt", content); err != nil { 176 t.Fatal(err) 177 } 178 179 topLayer, err := addManyLayers(driver, base, layerCount) 180 if err != nil { 181 t.Fatal(err) 182 } 183 184 err = checkManyLayers(driver, topLayer, layerCount) 185 if err != nil { 186 t.Fatal(err) 187 } 188 189 if err := checkFile(driver, topLayer, "testfile.txt", content); err != nil { 190 t.Fatal(err) 191 } 192 } 193 194 // DriverTestDiffApply tests diffing and applying produces the same layer 195 func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverOptions ...string) { 196 driver := GetDriver(t, drivername, driverOptions...) 197 defer PutDriver(t) 198 base := stringid.GenerateRandomID() 199 upper := stringid.GenerateRandomID() 200 deleteFile := "file-remove.txt" 201 deleteFileContent := []byte("This file should get removed in upper!") 202 deleteDir := "var/lib" 203 204 if err := driver.Create(base, "", "", nil); err != nil { 205 t.Fatal(err) 206 } 207 208 if err := addManyFiles(driver, base, fileCount, 3); err != nil { 209 t.Fatal(err) 210 } 211 212 if err := addFile(driver, base, deleteFile, deleteFileContent); err != nil { 213 t.Fatal(err) 214 } 215 216 if err := addDirectory(driver, base, deleteDir); err != nil { 217 t.Fatal(err) 218 } 219 220 if err := driver.Create(upper, base, "", nil); err != nil { 221 t.Fatal(err) 222 } 223 224 if err := addManyFiles(driver, upper, fileCount, 6); err != nil { 225 t.Fatal(err) 226 } 227 228 if err := removeAll(driver, upper, deleteFile, deleteDir); err != nil { 229 t.Fatal(err) 230 } 231 232 diffSize, err := driver.DiffSize(upper, "") 233 if err != nil { 234 t.Fatal(err) 235 } 236 237 diff := stringid.GenerateRandomID() 238 if err := driver.Create(diff, base, "", nil); err != nil { 239 t.Fatal(err) 240 } 241 242 if err := checkManyFiles(driver, diff, fileCount, 3); err != nil { 243 t.Fatal(err) 244 } 245 246 if err := checkFile(driver, diff, deleteFile, deleteFileContent); err != nil { 247 t.Fatal(err) 248 } 249 250 arch, err := driver.Diff(upper, base) 251 if err != nil { 252 t.Fatal(err) 253 } 254 255 buf := bytes.NewBuffer(nil) 256 if _, err := buf.ReadFrom(arch); err != nil { 257 t.Fatal(err) 258 } 259 if err := arch.Close(); err != nil { 260 t.Fatal(err) 261 } 262 263 applyDiffSize, err := driver.ApplyDiff(diff, base, bytes.NewReader(buf.Bytes())) 264 if err != nil { 265 t.Fatal(err) 266 } 267 268 if applyDiffSize != diffSize { 269 t.Fatalf("Apply diff size different, got %d, expected %d", applyDiffSize, diffSize) 270 } 271 272 if err := checkManyFiles(driver, diff, fileCount, 6); err != nil { 273 t.Fatal(err) 274 } 275 276 if err := checkFileRemoved(driver, diff, deleteFile); err != nil { 277 t.Fatal(err) 278 } 279 280 if err := checkFileRemoved(driver, diff, deleteDir); err != nil { 281 t.Fatal(err) 282 } 283 } 284 285 // DriverTestChanges tests computed changes on a layer matches changes made 286 func DriverTestChanges(t testing.TB, drivername string, driverOptions ...string) { 287 driver := GetDriver(t, drivername, driverOptions...) 288 defer PutDriver(t) 289 base := stringid.GenerateRandomID() 290 upper := stringid.GenerateRandomID() 291 292 if err := driver.Create(base, "", "", nil); err != nil { 293 t.Fatal(err) 294 } 295 296 if err := addManyFiles(driver, base, 20, 3); err != nil { 297 t.Fatal(err) 298 } 299 300 if err := driver.Create(upper, base, "", nil); err != nil { 301 t.Fatal(err) 302 } 303 304 expectedChanges, err := changeManyFiles(driver, upper, 20, 6) 305 if err != nil { 306 t.Fatal(err) 307 } 308 309 changes, err := driver.Changes(upper, base) 310 if err != nil { 311 t.Fatal(err) 312 } 313 314 if err = checkChanges(expectedChanges, changes); err != nil { 315 t.Fatal(err) 316 } 317 } 318 319 func writeRandomFile(path string, size uint64) error { 320 buf := make([]int64, size/8) 321 322 r := rand.NewSource(0) 323 for i := range buf { 324 buf[i] = r.Int63() 325 } 326 327 // Cast to []byte 328 header := *(*reflect.SliceHeader)(unsafe.Pointer(&buf)) 329 header.Len *= 8 330 header.Cap *= 8 331 data := *(*[]byte)(unsafe.Pointer(&header)) 332 333 return ioutil.WriteFile(path, data, 0700) 334 } 335 336 // DriverTestSetQuota Create a driver and test setting quota. 337 func DriverTestSetQuota(t *testing.T, drivername string) { 338 driver := GetDriver(t, drivername) 339 defer PutDriver(t) 340 341 createBase(t, driver, "Base") 342 storageOpt := make(map[string]string, 1) 343 storageOpt["size"] = "50M" 344 if err := driver.Create("zfsTest", "Base", "", storageOpt); err != nil { 345 t.Fatal(err) 346 } 347 348 mountPath, err := driver.Get("zfsTest", "") 349 if err != nil { 350 t.Fatal(err) 351 } 352 353 quota := uint64(50 * units.MiB) 354 err = writeRandomFile(path.Join(mountPath, "file"), quota*2) 355 if pathError, ok := err.(*os.PathError); ok && pathError.Err != syscall.EDQUOT { 356 t.Fatalf("expect write() to fail with %v, got %v", syscall.EDQUOT, err) 357 } 358 359 }