| // +build linux |
| |
| package devmapper |
| |
| import ( |
| "fmt" |
| "testing" |
| "time" |
| |
| "github.com/docker/docker/daemon/graphdriver" |
| "github.com/docker/docker/daemon/graphdriver/graphtest" |
| ) |
| |
| func init() { |
| // Reduce the size the the base fs and loopback for the tests |
| defaultDataLoopbackSize = 300 * 1024 * 1024 |
| defaultMetaDataLoopbackSize = 200 * 1024 * 1024 |
| defaultBaseFsSize = 300 * 1024 * 1024 |
| defaultUdevSyncOverride = true |
| if err := graphtest.InitLoopbacks(); err != nil { |
| panic(err) |
| } |
| } |
| |
| // This avoids creating a new driver for each test if all tests are run |
| // Make sure to put new tests between TestDevmapperSetup and TestDevmapperTeardown |
| func TestDevmapperSetup(t *testing.T) { |
| graphtest.GetDriver(t, "devicemapper") |
| } |
| |
| func TestDevmapperCreateEmpty(t *testing.T) { |
| graphtest.DriverTestCreateEmpty(t, "devicemapper") |
| } |
| |
| func TestDevmapperCreateBase(t *testing.T) { |
| graphtest.DriverTestCreateBase(t, "devicemapper") |
| } |
| |
| func TestDevmapperCreateSnap(t *testing.T) { |
| graphtest.DriverTestCreateSnap(t, "devicemapper") |
| } |
| |
| func TestDevmapperTeardown(t *testing.T) { |
| graphtest.PutDriver(t) |
| } |
| |
| func TestDevmapperReduceLoopBackSize(t *testing.T) { |
| tenMB := int64(10 * 1024 * 1024) |
| testChangeLoopBackSize(t, -tenMB, defaultDataLoopbackSize, defaultMetaDataLoopbackSize) |
| } |
| |
| func TestDevmapperIncreaseLoopBackSize(t *testing.T) { |
| tenMB := int64(10 * 1024 * 1024) |
| testChangeLoopBackSize(t, tenMB, defaultDataLoopbackSize+tenMB, defaultMetaDataLoopbackSize+tenMB) |
| } |
| |
| func testChangeLoopBackSize(t *testing.T, delta, expectDataSize, expectMetaDataSize int64) { |
| driver := graphtest.GetDriver(t, "devicemapper").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver) |
| defer graphtest.PutDriver(t) |
| // make sure data or metadata loopback size are the default size |
| if s := driver.DeviceSet.Status(); s.Data.Total != uint64(defaultDataLoopbackSize) || s.Metadata.Total != uint64(defaultMetaDataLoopbackSize) { |
| t.Fatalf("data or metadata loop back size is incorrect") |
| } |
| if err := driver.Cleanup(); err != nil { |
| t.Fatal(err) |
| } |
| //Reload |
| d, err := Init(driver.home, []string{ |
| fmt.Sprintf("dm.loopdatasize=%d", defaultDataLoopbackSize+delta), |
| fmt.Sprintf("dm.loopmetadatasize=%d", defaultMetaDataLoopbackSize+delta), |
| }, nil, nil) |
| if err != nil { |
| t.Fatalf("error creating devicemapper driver: %v", err) |
| } |
| driver = d.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver) |
| if s := driver.DeviceSet.Status(); s.Data.Total != uint64(expectDataSize) || s.Metadata.Total != uint64(expectMetaDataSize) { |
| t.Fatalf("data or metadata loop back size is incorrect") |
| } |
| if err := driver.Cleanup(); err != nil { |
| t.Fatal(err) |
| } |
| } |
| |
| // Make sure devices.Lock() has been release upon return from cleanupDeletedDevices() function |
| func TestDevmapperLockReleasedDeviceDeletion(t *testing.T) { |
| driver := graphtest.GetDriver(t, "devicemapper").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver) |
| defer graphtest.PutDriver(t) |
| |
| // Call cleanupDeletedDevices() and after the call take and release |
| // DeviceSet Lock. If lock has not been released, this will hang. |
| driver.DeviceSet.cleanupDeletedDevices() |
| |
| doneChan := make(chan bool) |
| |
| go func() { |
| driver.DeviceSet.Lock() |
| defer driver.DeviceSet.Unlock() |
| doneChan <- true |
| }() |
| |
| select { |
| case <-time.After(time.Second * 5): |
| // Timer expired. That means lock was not released upon |
| // function return and we are deadlocked. Release lock |
| // here so that cleanup could succeed and fail the test. |
| driver.DeviceSet.Unlock() |
| t.Fatalf("Could not acquire devices lock after call to cleanupDeletedDevices()") |
| case <-doneChan: |
| } |
| } |