gopkg.in/dotcloud/docker.v1@v1.13.1/daemon/graphdriver/graphtest/graphtest_unix.go (about) 1 // +build linux freebsd solaris 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, nil, graphdriver.Options{DriverOptions: options, Root: root}) 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 if err := driver.Create(base, "", nil); err != nil { 170 t.Fatal(err) 171 } 172 173 content := []byte("test content") 174 if err := addFile(driver, base, "testfile.txt", content); err != nil { 175 t.Fatal(err) 176 } 177 178 topLayer, err := addManyLayers(driver, base, layerCount) 179 if err != nil { 180 t.Fatal(err) 181 } 182 183 err = checkManyLayers(driver, topLayer, layerCount) 184 if err != nil { 185 t.Fatal(err) 186 } 187 188 if err := checkFile(driver, topLayer, "testfile.txt", content); err != nil { 189 t.Fatal(err) 190 } 191 } 192 193 // DriverTestDiffApply tests diffing and applying produces the same layer 194 func DriverTestDiffApply(t testing.TB, fileCount int, drivername string, driverOptions ...string) { 195 driver := GetDriver(t, drivername, driverOptions...) 196 defer PutDriver(t) 197 base := stringid.GenerateRandomID() 198 upper := stringid.GenerateRandomID() 199 deleteFile := "file-remove.txt" 200 deleteFileContent := []byte("This file should get removed in upper!") 201 deleteDir := "var/lib" 202 203 if err := driver.Create(base, "", nil); err != nil { 204 t.Fatal(err) 205 } 206 207 if err := addManyFiles(driver, base, fileCount, 3); err != nil { 208 t.Fatal(err) 209 } 210 211 if err := addFile(driver, base, deleteFile, deleteFileContent); err != nil { 212 t.Fatal(err) 213 } 214 215 if err := addDirectory(driver, base, deleteDir); err != nil { 216 t.Fatal(err) 217 } 218 219 if err := driver.Create(upper, base, nil); err != nil { 220 t.Fatal(err) 221 } 222 223 if err := addManyFiles(driver, upper, fileCount, 6); err != nil { 224 t.Fatal(err) 225 } 226 227 if err := removeAll(driver, upper, deleteFile, deleteDir); err != nil { 228 t.Fatal(err) 229 } 230 231 diffSize, err := driver.DiffSize(upper, "") 232 if err != nil { 233 t.Fatal(err) 234 } 235 236 diff := stringid.GenerateRandomID() 237 if err := driver.Create(diff, base, nil); err != nil { 238 t.Fatal(err) 239 } 240 241 if err := checkManyFiles(driver, diff, fileCount, 3); err != nil { 242 t.Fatal(err) 243 } 244 245 if err := checkFile(driver, diff, deleteFile, deleteFileContent); err != nil { 246 t.Fatal(err) 247 } 248 249 arch, err := driver.Diff(upper, base) 250 if err != nil { 251 t.Fatal(err) 252 } 253 254 buf := bytes.NewBuffer(nil) 255 if _, err := buf.ReadFrom(arch); err != nil { 256 t.Fatal(err) 257 } 258 if err := arch.Close(); err != nil { 259 t.Fatal(err) 260 } 261 262 applyDiffSize, err := driver.ApplyDiff(diff, base, bytes.NewReader(buf.Bytes())) 263 if err != nil { 264 t.Fatal(err) 265 } 266 267 if applyDiffSize != diffSize { 268 t.Fatalf("Apply diff size different, got %d, expected %d", applyDiffSize, diffSize) 269 } 270 271 if err := checkManyFiles(driver, diff, fileCount, 6); err != nil { 272 t.Fatal(err) 273 } 274 275 if err := checkFileRemoved(driver, diff, deleteFile); err != nil { 276 t.Fatal(err) 277 } 278 279 if err := checkFileRemoved(driver, diff, deleteDir); err != nil { 280 t.Fatal(err) 281 } 282 } 283 284 // DriverTestChanges tests computed changes on a layer matches changes made 285 func DriverTestChanges(t testing.TB, drivername string, driverOptions ...string) { 286 driver := GetDriver(t, drivername, driverOptions...) 287 defer PutDriver(t) 288 base := stringid.GenerateRandomID() 289 upper := stringid.GenerateRandomID() 290 if err := driver.Create(base, "", nil); err != nil { 291 t.Fatal(err) 292 } 293 294 if err := addManyFiles(driver, base, 20, 3); err != nil { 295 t.Fatal(err) 296 } 297 298 if err := driver.Create(upper, base, nil); err != nil { 299 t.Fatal(err) 300 } 301 302 expectedChanges, err := changeManyFiles(driver, upper, 20, 6) 303 if err != nil { 304 t.Fatal(err) 305 } 306 307 changes, err := driver.Changes(upper, base) 308 if err != nil { 309 t.Fatal(err) 310 } 311 312 if err = checkChanges(expectedChanges, changes); err != nil { 313 t.Fatal(err) 314 } 315 } 316 317 func writeRandomFile(path string, size uint64) error { 318 buf := make([]int64, size/8) 319 320 r := rand.NewSource(0) 321 for i := range buf { 322 buf[i] = r.Int63() 323 } 324 325 // Cast to []byte 326 header := *(*reflect.SliceHeader)(unsafe.Pointer(&buf)) 327 header.Len *= 8 328 header.Cap *= 8 329 data := *(*[]byte)(unsafe.Pointer(&header)) 330 331 return ioutil.WriteFile(path, data, 0700) 332 } 333 334 // DriverTestSetQuota Create a driver and test setting quota. 335 func DriverTestSetQuota(t *testing.T, drivername string) { 336 driver := GetDriver(t, drivername) 337 defer PutDriver(t) 338 339 createBase(t, driver, "Base") 340 createOpts := &graphdriver.CreateOpts{} 341 createOpts.StorageOpt = make(map[string]string, 1) 342 createOpts.StorageOpt["size"] = "50M" 343 if err := driver.Create("zfsTest", "Base", createOpts); err != nil { 344 t.Fatal(err) 345 } 346 347 mountPath, err := driver.Get("zfsTest", "") 348 if err != nil { 349 t.Fatal(err) 350 } 351 352 quota := uint64(50 * units.MiB) 353 err = writeRandomFile(path.Join(mountPath, "file"), quota*2) 354 if pathError, ok := err.(*os.PathError); ok && pathError.Err != syscall.EDQUOT { 355 t.Fatalf("expect write() to fail with %v, got %v", syscall.EDQUOT, err) 356 } 357 358 }