github.com/vmware/govmomi@v0.37.1/cns/simulator/simulator_test.go (about) 1 /* 2 Copyright (c) 2019 VMware, Inc. All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package simulator 18 19 import ( 20 "context" 21 "testing" 22 23 "github.com/google/uuid" 24 25 "github.com/vmware/govmomi" 26 "github.com/vmware/govmomi/cns" 27 cnstypes "github.com/vmware/govmomi/cns/types" 28 "github.com/vmware/govmomi/simulator" 29 vim25types "github.com/vmware/govmomi/vim25/types" 30 ) 31 32 const ( 33 testLabel = "testLabel" 34 testValue = "testValue" 35 simulatorBackingDiskID = "fake-volume-Handle" 36 ) 37 38 func TestSimulator(t *testing.T) { 39 ctx := context.Background() 40 41 model := simulator.VPX() 42 defer model.Remove() 43 44 var err error 45 46 if err = model.Create(); err != nil { 47 t.Fatal(err) 48 } 49 50 s := model.Service.NewServer() 51 defer s.Close() 52 53 model.Service.RegisterSDK(New()) 54 55 c, err := govmomi.NewClient(ctx, s.URL, true) 56 if err != nil { 57 t.Fatal(err) 58 } 59 60 cnsClient, err := cns.NewClient(ctx, c.Client) 61 if err != nil { 62 t.Fatal(err) 63 } 64 // Query 65 queryFilter := cnstypes.CnsQueryFilter{} 66 queryResult, err := cnsClient.QueryVolume(ctx, queryFilter) 67 if err != nil { 68 t.Fatal(err) 69 } 70 existingNumDisks := len(queryResult.Volumes) 71 72 // Get a simulator DS 73 datastore := simulator.Map.Any("Datastore").(*simulator.Datastore) 74 75 // Create volume for static provisioning 76 var capacityInMb int64 = 1024 77 createSpecListForStaticProvision := []cnstypes.CnsVolumeCreateSpec{ 78 { 79 Name: "test", 80 VolumeType: "TestVolumeType", 81 Datastores: []vim25types.ManagedObjectReference{ 82 datastore.Self, 83 }, 84 BackingObjectDetails: &cnstypes.CnsBlockBackingDetails{ 85 CnsBackingObjectDetails: cnstypes.CnsBackingObjectDetails{ 86 CapacityInMb: capacityInMb, 87 }, 88 BackingDiskId: simulatorBackingDiskID, 89 }, 90 Profile: []vim25types.BaseVirtualMachineProfileSpec{ 91 &vim25types.VirtualMachineDefinedProfileSpec{ 92 ProfileId: uuid.New().String(), 93 }, 94 }, 95 }, 96 } 97 createTask, err := cnsClient.CreateVolume(ctx, createSpecListForStaticProvision) 98 if err != nil { 99 t.Fatal(err) 100 } 101 102 createTaskInfo, err := cns.GetTaskInfo(ctx, createTask) 103 if err != nil { 104 t.Fatal(err) 105 } 106 107 createTaskResult, err := cns.GetTaskResult(ctx, createTaskInfo) 108 if err != nil { 109 t.Fatal(err) 110 } 111 if createTaskResult == nil { 112 t.Fatalf("Empty create task results") 113 } 114 createVolumeOperationRes := createTaskResult.GetCnsVolumeOperationResult() 115 if createVolumeOperationRes.Fault != nil { 116 t.Fatalf("Failed to create volume: fault=%+v", createVolumeOperationRes.Fault) 117 } 118 volumeId := createVolumeOperationRes.VolumeId.Id 119 volumeCreateResult := (createTaskResult).(*cnstypes.CnsVolumeCreateResult) 120 t.Logf("volumeCreateResult %+v", volumeCreateResult) 121 122 // Delete the static provisioning volume 123 deleteVolumeList := []cnstypes.CnsVolumeId{ 124 { 125 Id: volumeId, 126 }, 127 } 128 deleteTask, err := cnsClient.DeleteVolume(ctx, deleteVolumeList, true) 129 130 deleteTaskInfo, err := cns.GetTaskInfo(ctx, deleteTask) 131 if err != nil { 132 t.Fatal(err) 133 } 134 135 deleteTaskResult, err := cns.GetTaskResult(ctx, deleteTaskInfo) 136 if err != nil { 137 t.Fatal(err) 138 } 139 if deleteTaskResult == nil { 140 t.Fatalf("Empty delete task results") 141 } 142 143 deleteVolumeOperationRes := deleteTaskResult.GetCnsVolumeOperationResult() 144 if deleteVolumeOperationRes.Fault != nil { 145 t.Fatalf("Failed to delete volume: fault=%+v", deleteVolumeOperationRes.Fault) 146 } 147 148 // Create 149 createSpecList := []cnstypes.CnsVolumeCreateSpec{ 150 { 151 Name: "test", 152 VolumeType: "TestVolumeType", 153 Datastores: []vim25types.ManagedObjectReference{ 154 datastore.Self, 155 }, 156 BackingObjectDetails: &cnstypes.CnsBackingObjectDetails{ 157 CapacityInMb: capacityInMb, 158 }, 159 Profile: []vim25types.BaseVirtualMachineProfileSpec{ 160 &vim25types.VirtualMachineDefinedProfileSpec{ 161 ProfileId: uuid.New().String(), 162 }, 163 }, 164 }, 165 } 166 createTask, err = cnsClient.CreateVolume(ctx, createSpecList) 167 if err != nil { 168 t.Fatal(err) 169 } 170 171 createTaskInfo, err = cns.GetTaskInfo(ctx, createTask) 172 if err != nil { 173 t.Fatal(err) 174 } 175 176 createTaskResult, err = cns.GetTaskResult(ctx, createTaskInfo) 177 if err != nil { 178 t.Fatal(err) 179 } 180 if createTaskResult == nil { 181 t.Fatalf("Empty create task results") 182 } 183 createVolumeOperationRes = createTaskResult.GetCnsVolumeOperationResult() 184 if createVolumeOperationRes.Fault != nil { 185 t.Fatalf("Failed to create volume: fault=%+v", createVolumeOperationRes.Fault) 186 } 187 volumeId = createVolumeOperationRes.VolumeId.Id 188 volumeCreateResult = (createTaskResult).(*cnstypes.CnsVolumeCreateResult) 189 t.Logf("volumeCreateResult %+v", volumeCreateResult) 190 191 // Extend 192 var newCapacityInMb int64 = 2048 193 extendSpecList := []cnstypes.CnsVolumeExtendSpec{ 194 { 195 VolumeId: createVolumeOperationRes.VolumeId, 196 CapacityInMb: newCapacityInMb, 197 }, 198 } 199 extendTask, err := cnsClient.ExtendVolume(ctx, extendSpecList) 200 if err != nil { 201 t.Fatal(err) 202 } 203 204 extendTaskInfo, err := cns.GetTaskInfo(ctx, extendTask) 205 if err != nil { 206 t.Fatal(err) 207 } 208 209 extendTaskResult, err := cns.GetTaskResult(ctx, extendTaskInfo) 210 if err != nil { 211 t.Fatal(err) 212 } 213 if extendTaskResult == nil { 214 t.Fatalf("Empty extend task results") 215 } 216 217 extendVolumeOperationRes := extendTaskResult.GetCnsVolumeOperationResult() 218 if extendVolumeOperationRes.Fault != nil { 219 t.Fatalf("Failed to extend: fault=%+v", extendVolumeOperationRes.Fault) 220 } 221 222 // Attach 223 nodeVM := simulator.Map.Any("VirtualMachine").(*simulator.VirtualMachine) 224 attachSpecList := []cnstypes.CnsVolumeAttachDetachSpec{ 225 { 226 VolumeId: createVolumeOperationRes.VolumeId, 227 Vm: nodeVM.Self, 228 }, 229 } 230 attachTask, err := cnsClient.AttachVolume(ctx, attachSpecList) 231 if err != nil { 232 t.Fatal(err) 233 } 234 235 attachTaskInfo, err := cns.GetTaskInfo(ctx, attachTask) 236 if err != nil { 237 t.Fatal(err) 238 } 239 240 attachTaskResult, err := cns.GetTaskResult(ctx, attachTaskInfo) 241 if err != nil { 242 t.Fatal(err) 243 } 244 if attachTaskResult == nil { 245 t.Fatalf("Empty attach task results") 246 } 247 248 attachVolumeOperationRes := attachTaskResult.GetCnsVolumeOperationResult() 249 if attachVolumeOperationRes.Fault != nil { 250 t.Fatalf("Failed to attach: fault=%+v", attachVolumeOperationRes.Fault) 251 } 252 253 // Detach 254 detachVolumeList := []cnstypes.CnsVolumeAttachDetachSpec{ 255 { 256 VolumeId: createVolumeOperationRes.VolumeId, 257 }, 258 } 259 detachTask, err := cnsClient.DetachVolume(ctx, detachVolumeList) 260 261 detachTaskInfo, err := cns.GetTaskInfo(ctx, detachTask) 262 if err != nil { 263 t.Fatal(err) 264 } 265 266 detachTaskResult, err := cns.GetTaskResult(ctx, detachTaskInfo) 267 if err != nil { 268 t.Fatal(err) 269 } 270 if detachTaskResult == nil { 271 t.Fatalf("Empty detach task results") 272 } 273 274 detachVolumeOperationRes := detachTaskResult.GetCnsVolumeOperationResult() 275 if detachVolumeOperationRes.Fault != nil { 276 t.Fatalf("Failed to detach volume: fault=%+v", detachVolumeOperationRes.Fault) 277 } 278 279 // Query 280 queryFilter = cnstypes.CnsQueryFilter{} 281 queryResult, err = cnsClient.QueryVolume(ctx, queryFilter) 282 if err != nil { 283 t.Fatal(err) 284 } 285 286 if len(queryResult.Volumes) != existingNumDisks+1 { 287 t.Fatal("Number of volumes mismatches after creating a single volume") 288 } 289 290 // QueryAsync 291 queryFilter = cnstypes.CnsQueryFilter{} 292 querySelection := cnstypes.CnsQuerySelection{} 293 queryVolumeAsyncTask, err := cnsClient.QueryVolumeAsync(ctx, queryFilter, &querySelection) 294 if err != nil { 295 t.Fatal(err) 296 } 297 queryVolumeAsyncTaskInfo, err := cns.GetTaskInfo(ctx, queryVolumeAsyncTask) 298 if err != nil { 299 t.Fatal(err) 300 } 301 queryVolumeAsyncTaskResult, err := cns.GetTaskResult(ctx, queryVolumeAsyncTaskInfo) 302 if err != nil { 303 t.Fatal(err) 304 } 305 if queryVolumeAsyncTaskResult == nil { 306 t.Fatalf("Empty queryVolumeAsync Task Result") 307 } 308 queryVolumeAsyncOperationRes := queryVolumeAsyncTaskResult.GetCnsVolumeOperationResult() 309 if queryVolumeAsyncOperationRes.Fault != nil { 310 t.Fatalf("Failed to query volume detail using queryVolumeAsync: fault=%+v", queryVolumeAsyncOperationRes.Fault) 311 } 312 313 // QueryVolume 314 queryFilter = cnstypes.CnsQueryFilter{} 315 queryResult, err = cnsClient.QueryVolume(ctx, queryFilter) 316 if err != nil { 317 t.Fatalf("Failed to query volume with QueryFilter: err=%+v", err) 318 } 319 if len(queryResult.Volumes) != existingNumDisks+1 { 320 t.Fatal("Number of volumes mismatches after deleting a single volume") 321 } 322 // QueryVolumeInfo 323 queryVolumeInfoTask, err := cnsClient.QueryVolumeInfo(ctx, []cnstypes.CnsVolumeId{{Id: createVolumeOperationRes.VolumeId.Id}}) 324 if err != nil { 325 t.Fatal(err) 326 } 327 queryVolumeInfoTaskInfo, err := cns.GetTaskInfo(ctx, queryVolumeInfoTask) 328 if err != nil { 329 t.Fatal(err) 330 } 331 queryVolumeInfoTaskResult, err := cns.GetTaskResult(ctx, queryVolumeInfoTaskInfo) 332 if err != nil { 333 t.Fatal(err) 334 } 335 if queryVolumeInfoTaskResult == nil { 336 t.Fatalf("Empty query VolumeInfo Task Result") 337 } 338 queryVolumeInfoOperationRes := queryVolumeInfoTaskResult.GetCnsVolumeOperationResult() 339 if queryVolumeInfoOperationRes.Fault != nil { 340 t.Fatalf("Failed to query volume detail using QueryVolumeInfo: fault=%+v", queryVolumeInfoOperationRes.Fault) 341 } 342 343 // QueryAll 344 queryFilter = cnstypes.CnsQueryFilter{} 345 querySelection = cnstypes.CnsQuerySelection{} 346 queryResult, err = cnsClient.QueryAllVolume(ctx, queryFilter, querySelection) 347 348 if len(queryResult.Volumes) != existingNumDisks+1 { 349 t.Fatal("Number of volumes mismatches after creating a single volume") 350 } 351 352 // Update 353 var metadataList []cnstypes.BaseCnsEntityMetadata 354 newLabels := []vim25types.KeyValue{ 355 { 356 Key: testLabel, 357 Value: testValue, 358 }, 359 } 360 metadata := &cnstypes.CnsKubernetesEntityMetadata{ 361 362 CnsEntityMetadata: cnstypes.CnsEntityMetadata{ 363 DynamicData: vim25types.DynamicData{}, 364 EntityName: queryResult.Volumes[0].Name, 365 Labels: newLabels, 366 Delete: false, 367 }, 368 EntityType: string(cnstypes.CnsKubernetesEntityTypePV), 369 Namespace: "", 370 } 371 metadataList = append(metadataList, cnstypes.BaseCnsEntityMetadata(metadata)) 372 updateSpecList := []cnstypes.CnsVolumeMetadataUpdateSpec{ 373 { 374 DynamicData: vim25types.DynamicData{}, 375 VolumeId: createVolumeOperationRes.VolumeId, 376 Metadata: cnstypes.CnsVolumeMetadata{ 377 DynamicData: vim25types.DynamicData{}, 378 ContainerCluster: queryResult.Volumes[0].Metadata.ContainerCluster, 379 EntityMetadata: metadataList, 380 }, 381 }, 382 } 383 updateTask, err := cnsClient.UpdateVolumeMetadata(ctx, updateSpecList) 384 if err != nil { 385 t.Fatal(err) 386 } 387 updateTaskInfo, err := cns.GetTaskInfo(ctx, updateTask) 388 if err != nil { 389 t.Fatal(err) 390 } 391 updateTaskResult, err := cns.GetTaskResult(ctx, updateTaskInfo) 392 if err != nil { 393 t.Fatal(err) 394 } 395 if updateTaskResult == nil { 396 t.Fatalf("Empty create task results") 397 } 398 399 updateVolumeOperationRes := updateTaskResult.GetCnsVolumeOperationResult() 400 if updateVolumeOperationRes.Fault != nil { 401 t.Fatalf("Failed to create volume: fault=%+v", updateVolumeOperationRes.Fault) 402 } 403 404 // Create Snapshots 405 desc := "simulator-snapshot" 406 var cnsSnapshotCreateSpecList []cnstypes.CnsSnapshotCreateSpec 407 cnsSnapshotCreateSpec := cnstypes.CnsSnapshotCreateSpec{ 408 VolumeId: cnstypes.CnsVolumeId{ 409 Id: volumeId, 410 }, 411 Description: desc, 412 } 413 cnsSnapshotCreateSpecList = append(cnsSnapshotCreateSpecList, cnsSnapshotCreateSpec) 414 createSnapshotsTask, err := cnsClient.CreateSnapshots(ctx, cnsSnapshotCreateSpecList) 415 if err != nil { 416 t.Fatalf("Failed to get the task of CreateSnapshots. Error: %+v \n", err) 417 } 418 createSnapshotsTaskInfo, err := cns.GetTaskInfo(ctx, createSnapshotsTask) 419 if err != nil { 420 t.Fatalf("Failed to get the task info of CreateSnapshots. Error: %+v \n", err) 421 } 422 createSnapshotsTaskResult, err := cns.GetTaskResult(ctx, createSnapshotsTaskInfo) 423 if err != nil { 424 t.Fatalf("Failed to get the task result of CreateSnapshots. Error: %+v \n", err) 425 } 426 createSnapshotsOperationRes := createSnapshotsTaskResult.GetCnsVolumeOperationResult() 427 if createSnapshotsOperationRes.Fault != nil { 428 t.Fatalf("Failed to create snapshots: fault=%+v", createSnapshotsOperationRes.Fault) 429 } 430 431 snapshotCreateResult := interface{}(createSnapshotsTaskResult).(*cnstypes.CnsSnapshotCreateResult) 432 snapshotId := snapshotCreateResult.Snapshot.SnapshotId.Id 433 t.Logf("snapshotCreateResult %+v", snapshotCreateResult) 434 435 // Query Snapshots 436 var snapshotQueryFilter cnstypes.CnsSnapshotQueryFilter 437 QuerySnapshotsFunc := func(snapshotQueryFilter cnstypes.CnsSnapshotQueryFilter) *cnstypes.CnsSnapshotQueryResult { 438 querySnapshotsTask, err := cnsClient.QuerySnapshots(ctx, snapshotQueryFilter) 439 if err != nil { 440 t.Fatalf("Failed to get the task of QuerySnapshots. Error: %+v \n", err) 441 } 442 querySnapshotsTaskInfo, err := cns.GetTaskInfo(ctx, querySnapshotsTask) 443 if err != nil { 444 t.Fatalf("Failed to get the task info of QuerySnapshots. Error: %+v \n", err) 445 } 446 querySnapshotsTaskResult, err := cns.GetQuerySnapshotsTaskResult(ctx, querySnapshotsTaskInfo) 447 if err != nil { 448 t.Fatalf("Failed to get the task result of QuerySnapshots. Error: %+v \n", err) 449 } 450 return querySnapshotsTaskResult 451 } 452 453 // snapshot query filter 1: empty snapshot query spec => return all snapshots known to CNS 454 snapshotQueryFilter = cnstypes.CnsSnapshotQueryFilter{ 455 SnapshotQuerySpecs: nil, 456 } 457 t.Logf("snapshotQueryFilter with empty SnapshotQuerySpecs: %+v", snapshotQueryFilter) 458 querySnapshotsTaskResult := QuerySnapshotsFunc(snapshotQueryFilter) 459 t.Logf("snapshotQueryResult %+v", querySnapshotsTaskResult) 460 461 // snapshot query filter 2: unknown volumeId 462 snapshotQueryFilter = cnstypes.CnsSnapshotQueryFilter{ 463 SnapshotQuerySpecs: []cnstypes.CnsSnapshotQuerySpec{ 464 { 465 VolumeId: cnstypes.CnsVolumeId{Id: "unknown-volume-id"}, 466 }, 467 }, 468 } 469 t.Logf("snapshotQueryFilter with unknown volumeId in SnapshotQuerySpecs: %+v", snapshotQueryFilter) 470 querySnapshotsTaskResult = QuerySnapshotsFunc(snapshotQueryFilter) 471 _, ok := querySnapshotsTaskResult.Entries[0].Error.Fault.(cnstypes.CnsVolumeNotFoundFault) 472 if !ok { 473 t.Fatalf("Unexpected error returned while CnsVolumeNotFoundFault is expected. Error: %+v \n", querySnapshotsTaskResult.Entries[0].Error.Fault) 474 } 475 t.Logf("snapshotQueryResult with expected CnsVolumeNotFoundFault %+v", querySnapshotsTaskResult) 476 477 // snapshot query filter 3: unknown snapshotId 478 snapshotQueryFilter = cnstypes.CnsSnapshotQueryFilter{ 479 SnapshotQuerySpecs: []cnstypes.CnsSnapshotQuerySpec{ 480 { 481 VolumeId: cnstypes.CnsVolumeId{Id: volumeId}, 482 SnapshotId: &cnstypes.CnsSnapshotId{Id: "unknown-snapshot-id"}, 483 }, 484 }, 485 } 486 t.Logf("snapshotQueryFilter with unknown snapshotId in SnapshotQuerySpecs: %+v", snapshotQueryFilter) 487 querySnapshotsTaskResult = QuerySnapshotsFunc(snapshotQueryFilter) 488 _, ok = querySnapshotsTaskResult.Entries[0].Error.Fault.(cnstypes.CnsSnapshotNotFoundFault) 489 if !ok { 490 t.Fatalf("Unexpected error returned while CnsSnapshotNotFoundFault is expected. Error: %+v \n", querySnapshotsTaskResult.Entries[0].Error.Fault) 491 } 492 t.Logf("snapshotQueryResult with expected CnsSnapshotNotFoundFault %+v", querySnapshotsTaskResult) 493 494 // snapshot query filter 4: expected volumeId 495 snapshotQueryFilter = cnstypes.CnsSnapshotQueryFilter{ 496 SnapshotQuerySpecs: []cnstypes.CnsSnapshotQuerySpec{ 497 { 498 VolumeId: cnstypes.CnsVolumeId{Id: volumeId}, 499 }, 500 }, 501 } 502 t.Logf("snapshotQueryFilter with expected volumeId and empty snapshotId in SnapshotQuerySpecs: %+v", snapshotQueryFilter) 503 querySnapshotsTaskResult = QuerySnapshotsFunc(snapshotQueryFilter) 504 t.Logf("snapshotQueryResult %+v", querySnapshotsTaskResult) 505 506 // snapshot query filter 5: expected volumeId and snapshotId 507 snapshotQueryFilter = cnstypes.CnsSnapshotQueryFilter{ 508 SnapshotQuerySpecs: []cnstypes.CnsSnapshotQuerySpec{ 509 { 510 VolumeId: cnstypes.CnsVolumeId{Id: volumeId}, 511 SnapshotId: &cnstypes.CnsSnapshotId{Id: snapshotId}, 512 }, 513 }, 514 } 515 t.Logf("snapshotQueryFilter with expected volumeId and snapshotId in SnapshotQuerySpecs: %+v", snapshotQueryFilter) 516 querySnapshotsTaskResult = QuerySnapshotsFunc(snapshotQueryFilter) 517 t.Logf("snapshotQueryResult %+v", querySnapshotsTaskResult) 518 519 // Delete Snapshots 520 var cnsSnapshotDeleteSpecList []cnstypes.CnsSnapshotDeleteSpec 521 cnsSnapshotDeleteSpec := cnstypes.CnsSnapshotDeleteSpec{ 522 VolumeId: cnstypes.CnsVolumeId{ 523 Id: volumeId, 524 }, 525 SnapshotId: cnstypes.CnsSnapshotId{ 526 Id: snapshotId, 527 }, 528 } 529 cnsSnapshotDeleteSpecList = append(cnsSnapshotDeleteSpecList, cnsSnapshotDeleteSpec) 530 deleteSnapshotsTask, err := cnsClient.DeleteSnapshots(ctx, cnsSnapshotDeleteSpecList) 531 if err != nil { 532 t.Fatalf("Failed to get the task of DeleteSnapshots. Error: %+v \n", err) 533 } 534 deleteSnapshotsTaskInfo, err := cns.GetTaskInfo(ctx, deleteSnapshotsTask) 535 if err != nil { 536 t.Fatalf("Failed to get the task info of DeleteSnapshots. Error: %+v \n", err) 537 } 538 539 deleteSnapshotsTaskResult, err := cns.GetTaskResult(ctx, deleteSnapshotsTaskInfo) 540 if err != nil { 541 t.Fatalf("Failed to get the task result of DeleteSnapshots. Error: %+v \n", err) 542 } 543 544 deleteSnapshotsOperationRes := deleteSnapshotsTaskResult.GetCnsVolumeOperationResult() 545 if deleteSnapshotsOperationRes.Fault != nil { 546 t.Fatalf("Failed to delete snapshots: fault=%+v", deleteSnapshotsOperationRes.Fault) 547 } 548 549 snapshotDeleteResult := interface{}(deleteSnapshotsTaskResult).(*cnstypes.CnsSnapshotDeleteResult) 550 t.Logf("snapshotDeleteResult %+v", snapshotDeleteResult) 551 552 // Delete 553 deleteVolumeList = []cnstypes.CnsVolumeId{ 554 { 555 Id: volumeId, 556 }, 557 } 558 deleteTask, err = cnsClient.DeleteVolume(ctx, deleteVolumeList, true) 559 560 deleteTaskInfo, err = cns.GetTaskInfo(ctx, deleteTask) 561 if err != nil { 562 t.Fatal(err) 563 } 564 565 deleteTaskResult, err = cns.GetTaskResult(ctx, deleteTaskInfo) 566 if err != nil { 567 t.Fatal(err) 568 } 569 if deleteTaskResult == nil { 570 t.Fatalf("Empty delete task results") 571 } 572 573 deleteVolumeOperationRes = deleteTaskResult.GetCnsVolumeOperationResult() 574 if deleteVolumeOperationRes.Fault != nil { 575 t.Fatalf("Failed to delete volume: fault=%+v", deleteVolumeOperationRes.Fault) 576 } 577 578 queryFilter = cnstypes.CnsQueryFilter{} 579 queryResult, err = cnsClient.QueryVolume(ctx, queryFilter) 580 if err != nil { 581 t.Fatalf("Failed to query volume with QueryFilter: err=%+v", err) 582 } 583 if len(queryResult.Volumes) != existingNumDisks { 584 t.Fatal("Number of volumes mismatches after deleting a single volume") 585 } 586 587 }