github.com/rhatdan/storage@v1.12.13/drivers/devmapper/devmapper_test.go (about) 1 // +build linux 2 3 package devmapper 4 5 import ( 6 "fmt" 7 "os" 8 "syscall" 9 "testing" 10 "time" 11 12 "github.com/containers/storage/drivers" 13 "github.com/containers/storage/drivers/graphtest" 14 ) 15 16 func init() { 17 // Reduce the size of the base fs and loopback for the tests 18 defaultDataLoopbackSize = 300 * 1024 * 1024 19 defaultMetaDataLoopbackSize = 200 * 1024 * 1024 20 defaultBaseFsSize = 300 * 1024 * 1024 21 defaultUdevSyncOverride = true 22 if err := initLoopbacks(); err != nil { 23 panic(err) 24 } 25 } 26 27 // initLoopbacks ensures that the loopback devices are properly created within 28 // the system running the device mapper tests. 29 func initLoopbacks() error { 30 statT, err := getBaseLoopStats() 31 if err != nil { 32 return err 33 } 34 // create at least 8 loopback files, ya, that is a good number 35 for i := 0; i < 8; i++ { 36 loopPath := fmt.Sprintf("/dev/loop%d", i) 37 // only create new loopback files if they don't exist 38 if _, err := os.Stat(loopPath); err != nil { 39 if mkerr := syscall.Mknod(loopPath, 40 uint32(statT.Mode|syscall.S_IFBLK), int((7<<8)|(i&0xff)|((i&0xfff00)<<12))); mkerr != nil { 41 return mkerr 42 } 43 os.Chown(loopPath, int(statT.Uid), int(statT.Gid)) 44 } 45 } 46 return nil 47 } 48 49 // getBaseLoopStats inspects /dev/loop0 to collect uid,gid, and mode for the 50 // loop0 device on the system. If it does not exist we assume 0,0,0660 for the 51 // stat data 52 func getBaseLoopStats() (*syscall.Stat_t, error) { 53 loop0, err := os.Stat("/dev/loop0") 54 if err != nil { 55 if os.IsNotExist(err) { 56 return &syscall.Stat_t{ 57 Uid: 0, 58 Gid: 0, 59 Mode: 0660, 60 }, nil 61 } 62 return nil, err 63 } 64 return loop0.Sys().(*syscall.Stat_t), nil 65 } 66 67 // This avoids creating a new driver for each test if all tests are run 68 // Make sure to put new tests between TestDevmapperSetup and TestDevmapperTeardown 69 func TestDevmapperSetup(t *testing.T) { 70 graphtest.GetDriver(t, "devicemapper", "test=1") 71 } 72 73 func TestDevmapperCreateEmpty(t *testing.T) { 74 graphtest.DriverTestCreateEmpty(t, "devicemapper", "test=1") 75 } 76 77 func TestDevmapperCreateBase(t *testing.T) { 78 graphtest.DriverTestCreateBase(t, "devicemapper", "test=1") 79 } 80 81 func TestDevmapperCreateSnap(t *testing.T) { 82 graphtest.DriverTestCreateSnap(t, "devicemapper", "test=1") 83 } 84 85 func TestDevmapperCreateFromTemplate(t *testing.T) { 86 graphtest.DriverTestCreateFromTemplate(t, "devicemapper", "test=1") 87 } 88 89 func TestDevmapperTeardown(t *testing.T) { 90 graphtest.PutDriver(t) 91 } 92 93 func TestDevmapperEcho(t *testing.T) { 94 graphtest.DriverTestEcho(t, "devicemapper", "test=1") 95 } 96 97 func TestDevmapperReduceLoopBackSize(t *testing.T) { 98 tenMB := int64(10 * 1024 * 1024) 99 testChangeLoopBackSize(t, -tenMB, defaultDataLoopbackSize, defaultMetaDataLoopbackSize) 100 } 101 102 func TestDevmapperIncreaseLoopBackSize(t *testing.T) { 103 tenMB := int64(10 * 1024 * 1024) 104 testChangeLoopBackSize(t, tenMB, defaultDataLoopbackSize+tenMB, defaultMetaDataLoopbackSize+tenMB) 105 } 106 107 func testChangeLoopBackSize(t *testing.T, delta, expectDataSize, expectMetaDataSize int64) { 108 driver := graphtest.GetDriver(t, "devicemapper", "test=1").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver) 109 defer graphtest.PutDriver(t) 110 // make sure data or metadata loopback size are the default size 111 if s := driver.DeviceSet.Status(); s.Data.Total != uint64(defaultDataLoopbackSize) || s.Metadata.Total != uint64(defaultMetaDataLoopbackSize) { 112 t.Fatal("data or metadata loop back size is incorrect") 113 } 114 if err := driver.Cleanup(); err != nil { 115 t.Fatal(err) 116 } 117 //Reload 118 d, err := Init(driver.home, graphdriver.Options{DriverOptions: []string{ 119 fmt.Sprintf("dm.loopdatasize=%d", defaultDataLoopbackSize+delta), 120 fmt.Sprintf("dm.loopmetadatasize=%d", defaultMetaDataLoopbackSize+delta), 121 "test=1", 122 }}) 123 if err != nil { 124 t.Fatalf("error creating devicemapper driver: %v", err) 125 } 126 driver = d.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver) 127 if s := driver.DeviceSet.Status(); s.Data.Total != uint64(expectDataSize) || s.Metadata.Total != uint64(expectMetaDataSize) { 128 t.Fatal("data or metadata loop back size is incorrect") 129 } 130 if err := driver.Cleanup(); err != nil { 131 t.Fatal(err) 132 } 133 } 134 135 // Make sure devices.Lock() has been release upon return from cleanupDeletedDevices() function 136 func TestDevmapperLockReleasedDeviceDeletion(t *testing.T) { 137 driver := graphtest.GetDriver(t, "devicemapper", "test=1").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver) 138 defer graphtest.PutDriver(t) 139 140 // Call cleanupDeletedDevices() and after the call take and release 141 // DeviceSet Lock. If lock has not been released, this will hang. 142 driver.DeviceSet.cleanupDeletedDevices() 143 144 doneChan := make(chan bool) 145 146 go func() { 147 driver.DeviceSet.Lock() 148 defer driver.DeviceSet.Unlock() 149 doneChan <- true 150 }() 151 152 select { 153 case <-time.After(time.Second * 5): 154 // Timer expired. That means lock was not released upon 155 // function return and we are deadlocked. Release lock 156 // here so that cleanup could succeed and fail the test. 157 driver.DeviceSet.Unlock() 158 t.Fatal("Could not acquire devices lock after call to cleanupDeletedDevices()") 159 case <-doneChan: 160 } 161 }