github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/internal/acceptance/openstack/blockstorage/v3/volumes_test.go (about) 1 //go:build acceptance || blockstorage || volumes 2 3 package v3 4 5 import ( 6 "context" 7 "testing" 8 "time" 9 10 "github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/clients" 11 compute "github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/openstack/compute/v2" 12 "github.com/vnpaycloud-console/gophercloud/v2/internal/acceptance/tools" 13 "github.com/vnpaycloud-console/gophercloud/v2/openstack/blockstorage/v3/snapshots" 14 "github.com/vnpaycloud-console/gophercloud/v2/openstack/blockstorage/v3/volumes" 15 "github.com/vnpaycloud-console/gophercloud/v2/pagination" 16 th "github.com/vnpaycloud-console/gophercloud/v2/testhelper" 17 ) 18 19 func TestVolumes(t *testing.T) { 20 clients.RequireLong(t) 21 22 client, err := clients.NewBlockStorageV3Client() 23 th.AssertNoErr(t, err) 24 25 volume1, err := CreateVolume(t, client) 26 th.AssertNoErr(t, err) 27 defer DeleteVolume(t, client, volume1) 28 29 volume2, err := CreateVolume(t, client) 30 th.AssertNoErr(t, err) 31 defer DeleteVolume(t, client, volume2) 32 33 // Update volume 34 updatedVolumeName := "" 35 updatedVolumeDescription := "" 36 updateOpts := volumes.UpdateOpts{ 37 Name: &updatedVolumeName, 38 Description: &updatedVolumeDescription, 39 } 40 updatedVolume, err := volumes.Update(context.TODO(), client, volume1.ID, updateOpts).Extract() 41 th.AssertNoErr(t, err) 42 43 tools.PrintResource(t, updatedVolume) 44 th.AssertEquals(t, updatedVolume.Name, updatedVolumeName) 45 th.AssertEquals(t, updatedVolume.Description, updatedVolumeDescription) 46 47 listOpts := volumes.ListOpts{ 48 Limit: 1, 49 } 50 51 err = volumes.List(client, listOpts).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { 52 actual, err := volumes.ExtractVolumes(page) 53 th.AssertNoErr(t, err) 54 th.AssertEquals(t, 1, len(actual)) 55 56 var found bool 57 for _, v := range actual { 58 if v.ID == volume1.ID || v.ID == volume2.ID { 59 found = true 60 } 61 } 62 63 th.AssertEquals(t, found, true) 64 65 return true, nil 66 }) 67 68 th.AssertNoErr(t, err) 69 } 70 71 func TestVolumesMultiAttach(t *testing.T) { 72 clients.RequireAdmin(t) 73 clients.RequireLong(t) 74 75 client, err := clients.NewBlockStorageV3Client() 76 th.AssertNoErr(t, err) 77 78 vt, err := CreateVolumeTypeMultiAttach(t, client) 79 th.AssertNoErr(t, err) 80 defer DeleteVolumeType(t, client, vt) 81 82 volumeName := tools.RandomString("ACPTTEST", 16) 83 84 volOpts := volumes.CreateOpts{ 85 Size: 1, 86 Name: volumeName, 87 Description: "Testing creation of multiattach enabled volume", 88 VolumeType: vt.ID, 89 } 90 91 vol, err := volumes.Create(context.TODO(), client, volOpts, nil).Extract() 92 th.AssertNoErr(t, err) 93 defer DeleteVolume(t, client, vol) 94 95 ctx, cancel := context.WithTimeout(context.TODO(), 60*time.Second) 96 defer cancel() 97 98 err = volumes.WaitForStatus(ctx, client, vol.ID, "available") 99 th.AssertNoErr(t, err) 100 101 th.AssertEquals(t, vol.Multiattach, true) 102 } 103 104 func TestVolumesCascadeDelete(t *testing.T) { 105 clients.RequireLong(t) 106 107 client, err := clients.NewBlockStorageV3Client() 108 th.AssertNoErr(t, err) 109 110 vol, err := CreateVolume(t, client) 111 th.AssertNoErr(t, err) 112 113 ctx, cancel := context.WithTimeout(context.TODO(), 60*time.Second) 114 defer cancel() 115 116 err = volumes.WaitForStatus(ctx, client, vol.ID, "available") 117 th.AssertNoErr(t, err) 118 119 snapshot1, err := CreateSnapshot(t, client, vol) 120 th.AssertNoErr(t, err) 121 122 snapshot2, err := CreateSnapshot(t, client, vol) 123 th.AssertNoErr(t, err) 124 125 t.Logf("Attempting to delete volume: %s", vol.ID) 126 127 deleteOpts := volumes.DeleteOpts{Cascade: true} 128 err = volumes.Delete(context.TODO(), client, vol.ID, deleteOpts).ExtractErr() 129 if err != nil { 130 t.Fatalf("Unable to delete volume %s: %v", vol.ID, err) 131 } 132 133 for _, sid := range []string{snapshot1.ID, snapshot2.ID} { 134 err := tools.WaitFor(func(ctx context.Context) (bool, error) { 135 _, err := snapshots.Get(ctx, client, sid).Extract() 136 if err != nil { 137 return true, nil 138 } 139 return false, nil 140 }) 141 th.AssertNoErr(t, err) 142 t.Logf("Successfully deleted snapshot: %s", sid) 143 } 144 145 err = tools.WaitFor(func(ctx context.Context) (bool, error) { 146 _, err := volumes.Get(ctx, client, vol.ID).Extract() 147 if err != nil { 148 return true, nil 149 } 150 return false, nil 151 }) 152 th.AssertNoErr(t, err) 153 154 t.Logf("Successfully deleted volume: %s", vol.ID) 155 } 156 157 func TestVolumeActionsUploadImageDestroy(t *testing.T) { 158 blockClient, err := clients.NewBlockStorageV3Client() 159 th.AssertNoErr(t, err) 160 161 imageClient, err := clients.NewImageV2Client() 162 th.AssertNoErr(t, err) 163 164 volume, err := CreateVolume(t, blockClient) 165 th.AssertNoErr(t, err) 166 defer DeleteVolume(t, blockClient, volume) 167 168 volumeImage, err := CreateUploadImage(t, blockClient, volume) 169 th.AssertNoErr(t, err) 170 171 tools.PrintResource(t, volumeImage) 172 173 err = DeleteUploadedImage(t, imageClient, volumeImage.ImageID) 174 th.AssertNoErr(t, err) 175 } 176 177 func TestVolumeActionsAttachCreateDestroy(t *testing.T) { 178 blockClient, err := clients.NewBlockStorageV3Client() 179 th.AssertNoErr(t, err) 180 181 computeClient, err := clients.NewComputeV2Client() 182 th.AssertNoErr(t, err) 183 184 server, err := compute.CreateServer(t, computeClient) 185 th.AssertNoErr(t, err) 186 defer compute.DeleteServer(t, computeClient, server) 187 188 volume, err := CreateVolume(t, blockClient) 189 th.AssertNoErr(t, err) 190 defer DeleteVolume(t, blockClient, volume) 191 192 err = CreateVolumeAttach(t, blockClient, volume, server) 193 th.AssertNoErr(t, err) 194 195 newVolume, err := volumes.Get(context.TODO(), blockClient, volume.ID).Extract() 196 th.AssertNoErr(t, err) 197 198 DeleteVolumeAttach(t, blockClient, newVolume) 199 } 200 201 func TestVolumeActionsReserveUnreserve(t *testing.T) { 202 client, err := clients.NewBlockStorageV3Client() 203 th.AssertNoErr(t, err) 204 205 volume, err := CreateVolume(t, client) 206 th.AssertNoErr(t, err) 207 defer DeleteVolume(t, client, volume) 208 209 err = CreateVolumeReserve(t, client, volume) 210 th.AssertNoErr(t, err) 211 defer DeleteVolumeReserve(t, client, volume) 212 } 213 214 func TestVolumeActionsExtendSize(t *testing.T) { 215 blockClient, err := clients.NewBlockStorageV3Client() 216 th.AssertNoErr(t, err) 217 218 volume, err := CreateVolume(t, blockClient) 219 th.AssertNoErr(t, err) 220 defer DeleteVolume(t, blockClient, volume) 221 222 tools.PrintResource(t, volume) 223 224 err = ExtendVolumeSize(t, blockClient, volume) 225 th.AssertNoErr(t, err) 226 227 newVolume, err := volumes.Get(context.TODO(), blockClient, volume.ID).Extract() 228 th.AssertNoErr(t, err) 229 230 tools.PrintResource(t, newVolume) 231 } 232 233 func TestVolumeActionsImageMetadata(t *testing.T) { 234 blockClient, err := clients.NewBlockStorageV3Client() 235 th.AssertNoErr(t, err) 236 237 volume, err := CreateVolume(t, blockClient) 238 th.AssertNoErr(t, err) 239 defer DeleteVolume(t, blockClient, volume) 240 241 err = SetImageMetadata(t, blockClient, volume) 242 th.AssertNoErr(t, err) 243 } 244 245 func TestVolumeActionsSetBootable(t *testing.T) { 246 blockClient, err := clients.NewBlockStorageV3Client() 247 th.AssertNoErr(t, err) 248 249 volume, err := CreateVolume(t, blockClient) 250 th.AssertNoErr(t, err) 251 defer DeleteVolume(t, blockClient, volume) 252 253 err = SetBootable(t, blockClient, volume) 254 th.AssertNoErr(t, err) 255 } 256 257 func TestVolumeActionsChangeType(t *testing.T) { 258 // clients.RequireAdmin(t) 259 260 client, err := clients.NewBlockStorageV3Client() 261 th.AssertNoErr(t, err) 262 263 volumeType1, err := CreateVolumeTypeNoExtraSpecs(t, client) 264 th.AssertNoErr(t, err) 265 defer DeleteVolumeType(t, client, volumeType1) 266 267 volumeType2, err := CreateVolumeTypeNoExtraSpecs(t, client) 268 th.AssertNoErr(t, err) 269 defer DeleteVolumeType(t, client, volumeType2) 270 271 volume, err := CreateVolumeWithType(t, client, volumeType1) 272 th.AssertNoErr(t, err) 273 defer DeleteVolume(t, client, volume) 274 275 tools.PrintResource(t, volume) 276 277 err = ChangeVolumeType(t, client, volume, volumeType2) 278 th.AssertNoErr(t, err) 279 280 newVolume, err := volumes.Get(context.TODO(), client, volume.ID).Extract() 281 th.AssertNoErr(t, err) 282 th.AssertEquals(t, newVolume.VolumeType, volumeType2.Name) 283 284 tools.PrintResource(t, newVolume) 285 } 286 287 func TestVolumeActionsResetStatus(t *testing.T) { 288 client, err := clients.NewBlockStorageV3Client() 289 th.AssertNoErr(t, err) 290 291 volume, err := CreateVolume(t, client) 292 th.AssertNoErr(t, err) 293 defer DeleteVolume(t, client, volume) 294 295 tools.PrintResource(t, volume) 296 297 err = ResetVolumeStatus(t, client, volume, "error") 298 th.AssertNoErr(t, err) 299 300 err = ResetVolumeStatus(t, client, volume, "available") 301 th.AssertNoErr(t, err) 302 } 303 304 func TestVolumeActionsReImage(t *testing.T) { 305 clients.SkipReleasesBelow(t, "stable/yoga") 306 307 choices, err := clients.AcceptanceTestChoicesFromEnv() 308 if err != nil { 309 t.Fatal(err) 310 } 311 312 blockClient, err := clients.NewBlockStorageV3Client() 313 th.AssertNoErr(t, err) 314 blockClient.Microversion = "3.68" 315 316 volume, err := CreateVolume(t, blockClient) 317 th.AssertNoErr(t, err) 318 defer DeleteVolume(t, blockClient, volume) 319 320 err = ReImage(t, blockClient, volume, choices.ImageID) 321 th.AssertNoErr(t, err) 322 } 323 324 // Note(jtopjian): I plan to work on this at some point, but it requires 325 // setting up a server with iscsi utils. 326 /* 327 func TestVolumeConns(t *testing.T) { 328 client, err := newClient() 329 th.AssertNoErr(t, err) 330 331 t.Logf("Creating volume") 332 cv, err := volumes.Create(context.TODO(), client, &volumes.CreateOpts{ 333 Size: 1, 334 Name: "blockv2-volume", 335 }, nil).Extract() 336 th.AssertNoErr(t, err) 337 338 defer func() { 339 err = volumes.WaitForStatus(context.TODO(), client, cv.ID, "available", 60) 340 th.AssertNoErr(t, err) 341 342 t.Logf("Deleting volume") 343 err = volumes.Delete(context.TODO(), client, cv.ID, volumes.DeleteOpts{}).ExtractErr() 344 th.AssertNoErr(t, err) 345 }() 346 347 err = volumes.WaitForStatus(context.TODO(), client, cv.ID, "available", 60) 348 th.AssertNoErr(t, err) 349 350 connOpts := &ConnectorOpts{ 351 IP: "127.0.0.1", 352 Host: "stack", 353 Initiator: "iqn.1994-05.com.redhat:17cf566367d2", 354 Multipath: false, 355 Platform: "x86_64", 356 OSType: "linux2", 357 } 358 359 t.Logf("Initializing connection") 360 _, err = InitializeConnection(client, cv.ID, connOpts).Extract() 361 th.AssertNoErr(t, err) 362 363 t.Logf("Terminating connection") 364 err = TerminateConnection(client, cv.ID, connOpts).ExtractErr() 365 th.AssertNoErr(t, err) 366 } 367 */