diff --git a/tests/e2e/csi_snapshot_utils.go b/tests/e2e/csi_snapshot_utils.go index 17c8cbab19..c47c619552 100644 --- a/tests/e2e/csi_snapshot_utils.go +++ b/tests/e2e/csi_snapshot_utils.go @@ -349,7 +349,7 @@ func deleteVolumeSnapshot(ctx context.Context, snapc *snapclient.Clientset, name } snapshotContentCreated := false - if performCnsQueryVolumeSnapshot { + if performCnsQueryVolumeSnapshot && !latebinding { framework.Logf("Verify snapshot entry %v is deleted from CNS for volume %v", snapshotID, volHandle) err = waitForCNSSnapshotToBeDeleted(volHandle, snapshotID) if err != nil { @@ -489,7 +489,7 @@ func createDynamicVolumeSnapshot(ctx context.Context, namespace string, return volumeSnapshot, snapshotContent, false, false, snapshotId, "", err } - if performCnsQueryVolumeSnapshot { + if performCnsQueryVolumeSnapshot && !latebinding { ginkgo.By("Query CNS and check the volume snapshot entry") err = waitForCNSSnapshotToBeCreated(volHandle, snapshotId) if err != nil { @@ -684,6 +684,8 @@ func verifyVolumeRestoreOperation(ctx context.Context, client clientset.Interfac volumeSnapshot *snapV1.VolumeSnapshot, diskSize string, verifyPodCreation bool) (*v1.PersistentVolumeClaim, []*v1.PersistentVolume, *v1.Pod) { + var volHandle2 string + var persistentvolumes2 []*v1.PersistentVolume ginkgo.By("Create PVC from snapshot") pvcSpec := getPersistentVolumeClaimSpecWithDatasource(namespace, diskSize, storageclass, nil, v1.ReadWriteOnce, volumeSnapshot.Name, snapshotapigroup) @@ -691,14 +693,17 @@ func verifyVolumeRestoreOperation(ctx context.Context, client clientset.Interfac pvclaim2, err := fpv.CreatePVC(ctx, client, namespace, pvcSpec) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - persistentvolumes2, err := fpv.WaitForPVClaimBoundPhase(ctx, client, - []*v1.PersistentVolumeClaim{pvclaim2}, framework.ClaimProvisionTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle2 := persistentvolumes2[0].Spec.CSI.VolumeHandle - if guestCluster { - volHandle2 = getVolumeIDFromSupervisorCluster(volHandle2) + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + persistentvolumes2, err = fpv.WaitForPVClaimBoundPhase(ctx, client, + []*v1.PersistentVolumeClaim{pvclaim2}, framework.ClaimProvisionTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + volHandle2 = persistentvolumes2[0].Spec.CSI.VolumeHandle + if guestCluster { + volHandle2 = getVolumeIDFromSupervisorCluster(volHandle2) + } + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) } - gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) var pod *v1.Pod if verifyPodCreation { @@ -770,35 +775,38 @@ func createPVCAndQueryVolumeInCNS(ctx context.Context, client clientset.Interfac return pvclaim, nil, fmt.Errorf("failed to create PVC: %w", err) } - // Wait for PVC to be bound to a PV - persistentvolumes, err := fpv.WaitForPVClaimBoundPhase(ctx, client, - []*v1.PersistentVolumeClaim{pvclaim}, framework.ClaimProvisionTimeout*2) - if err != nil { - return pvclaim, persistentvolumes, fmt.Errorf("failed to wait for PVC to bind to a PV: %w", err) - } - - // Get VolumeHandle from the PV - volHandle := persistentvolumes[0].Spec.CSI.VolumeHandle - if guestCluster { - volHandle = getVolumeIDFromSupervisorCluster(volHandle) - } - if volHandle == "" { - return pvclaim, persistentvolumes, fmt.Errorf("volume handle is empty") - } - - // Verify the volume in CNS if required - if verifyCNSVolume { - ginkgo.By(fmt.Sprintf("Invoking QueryCNSVolumeWithResult with VolumeID: %s", volHandle)) - queryResult, err := e2eVSphere.queryCNSVolumeWithResult(volHandle) + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + persistentvolumes, err := fpv.WaitForPVClaimBoundPhase(ctx, client, + []*v1.PersistentVolumeClaim{pvclaim}, framework.ClaimProvisionTimeout*2) if err != nil { - return pvclaim, persistentvolumes, fmt.Errorf("failed to query CNS volume: %w", err) + return pvclaim, persistentvolumes, fmt.Errorf("failed to wait for PVC to bind to a PV: %w", err) + } + + // Get VolumeHandle from the PV + volHandle := persistentvolumes[0].Spec.CSI.VolumeHandle + if guestCluster { + volHandle = getVolumeIDFromSupervisorCluster(volHandle) + } + if volHandle == "" { + return pvclaim, persistentvolumes, fmt.Errorf("volume handle is empty") } - if len(queryResult.Volumes) == 0 || queryResult.Volumes[0].VolumeId.Id != volHandle { - return pvclaim, persistentvolumes, fmt.Errorf("CNS query returned unexpected result") + + // Verify the volume in CNS if required + if verifyCNSVolume { + ginkgo.By(fmt.Sprintf("Invoking QueryCNSVolumeWithResult with VolumeID: %s", volHandle)) + queryResult, err := e2eVSphere.queryCNSVolumeWithResult(volHandle) + if err != nil { + return pvclaim, persistentvolumes, fmt.Errorf("failed to query CNS volume: %w", err) + } + if len(queryResult.Volumes) == 0 || queryResult.Volumes[0].VolumeId.Id != volHandle { + return pvclaim, persistentvolumes, fmt.Errorf("CNS query returned unexpected result") + } } + return pvclaim, persistentvolumes, nil } - return pvclaim, persistentvolumes, nil + return pvclaim, nil, nil } // waitForVolumeSnapshotContentReadyToUse waits for the volume's snapshot content to be in ReadyToUse diff --git a/tests/e2e/e2e_common.go b/tests/e2e/e2e_common.go index b4fe559faa..0e3306306b 100644 --- a/tests/e2e/e2e_common.go +++ b/tests/e2e/e2e_common.go @@ -364,6 +364,7 @@ var ( multipleSvc bool multivc bool stretchedSVC bool + latebinding bool ) // For busybox pod image @@ -635,6 +636,12 @@ func setClusterFlavor(clusterFlavor cnstypes.CnsClusterFlavor) { if strings.TrimSpace(string(testbedType)) == "1" { stretchedSVC = true } + + //Check if policy given is latebinding + bindingModeType := os.Getenv("BINDING_MODE_TYPE") + if strings.TrimSpace(string(bindingModeType)) == "WFFC" { + latebinding = true + } } var ( diff --git a/tests/e2e/snapshot_vmservice_vm.go b/tests/e2e/snapshot_vmservice_vm.go index 9a3fd28095..2f674f3233 100644 --- a/tests/e2e/snapshot_vmservice_vm.go +++ b/tests/e2e/snapshot_vmservice_vm.go @@ -71,6 +71,7 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pandoraSyncWaitTime int dsRef types.ManagedObjectReference labelsMap map[string]string + volHandle string ) ginkgo.BeforeEach(func() { @@ -100,7 +101,16 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vcRestSessionId = createVcSession4RestApis(ctx) // reading storage class name for wcp setup "wcpglobal_storage_profile" - storageClassName = strings.ReplaceAll(storagePolicyName, "_", "-") // since this is a wcp setup + if latebinding { + framework.Logf("Reading late binding mode storage policy") + storageClassName = strings.ReplaceAll(storagePolicyName, "_", "-") + storageClassName = storageClassName + "-latebinding" + framework.Logf("storageClassName: %s", storageClassName) + } else { + framework.Logf("Reading Immediate binding mode storage policy") + storageClassName = strings.ReplaceAll(storagePolicyName, "_", "-") + framework.Logf("storageClassName: %s", storageClassName) + } // fetching shared datastore url datastoreURL = GetAndExpectStringEnvVar(envSharedDatastoreURL) @@ -216,8 +226,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc, pvs, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle := pvs[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + if pvs != nil && !latebinding { + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -260,6 +272,15 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) @@ -441,7 +462,7 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { /* Testcase-3 - Dynamic PVC  → VM → Snapshot → RestoreVol → VM + Dynamic PVC → VM → Snapshot → RestoreVol → VM Steps: 1. Create a dynamic PVC using the storage class (storage policy) tagged to the supervisor namespace 2. Wait for dynamic PVC to reach the Bound state. @@ -467,6 +488,7 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var volHandle2 string ginkgo.By("Create a storageclass") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) @@ -476,8 +498,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc, pvs, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle := pvs[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + if pvs != nil && !latebinding { + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -520,6 +544,15 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) @@ -561,8 +594,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create a volume from a snapshot") pvc2, pv2, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot, diskSize, false) - volHandle2 := pv2[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + if pv2 != nil && !latebinding { + volHandle2 = pv2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc2.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -597,6 +632,15 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs2, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc2}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv2 := pvs2[0] + volHandle2 = pv2.Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm2, []*v1.PersistentVolumeClaim{pvc2})).NotTo(gomega.HaveOccurred()) @@ -644,6 +688,8 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var volHandle2 string + var volHandle3 string ginkgo.By("Create a storageclass") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) @@ -653,8 +699,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc, pvs, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle := pvs[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + if pvs != nil && !latebinding { + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -697,6 +745,15 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) @@ -760,13 +817,17 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create a volume from a snapshot") pvc2, pv2, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot1, diskSize, false) - volHandle2 := pv2[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + if pv2 != nil && !latebinding { + volHandle2 = pv2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } ginkgo.By("Create a volume from a snapshot") pvc3, pv3, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot2, diskSize, false) - volHandle3 := pv3[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle3).NotTo(gomega.BeEmpty()) + if pv3 != nil && !latebinding { + volHandle3 = pv3[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle3).NotTo(gomega.BeEmpty()) + } ginkgo.By("Creating VM") vm2 := createVmServiceVmWithPvcs( @@ -795,6 +856,16 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + restorePvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc2, pvc3}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + volHandle2 = restorePvs[0].Spec.CSI.VolumeHandle + volHandle3 = restorePvs[1].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + gomega.Expect(volHandle3).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm2, []*v1.PersistentVolumeClaim{pvc2, pvc3})).NotTo(gomega.HaveOccurred()) @@ -853,6 +924,8 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var volHandle2 string + ginkgo.By("Create a storageclass") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -861,8 +934,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc, pvs, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle := pvs[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + if pvs != nil && !latebinding { + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -905,6 +980,14 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) @@ -946,8 +1029,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create a volume from a snapshot") pvc2, pv2, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot1, diskSize, false) - volHandle2 := pv2[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + if pv2 != nil && !latebinding { + volHandle2 = pv2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc2.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1016,6 +1101,14 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pv2, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc2}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + volHandle2 = pv2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm2, []*v1.PersistentVolumeClaim{pvc2})).NotTo(gomega.HaveOccurred()) @@ -1096,6 +1189,9 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var volHandle1, volHandle2 string + var restorevolHandle1, restorevolHandle2 string + ginkgo.By("Create a storageclass") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1104,8 +1200,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc1, pvs1, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle1 := pvs1[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle1).NotTo(gomega.BeEmpty()) + if pvs1 != nil && !latebinding { + volHandle1 = pvs1[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle1).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc1.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1117,8 +1215,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc2, pvs2, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle2 := pvs2[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + if pvs2 != nil && !latebinding { + volHandle2 = pvs2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc2.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1213,6 +1313,20 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp3, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm3.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs1, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc1}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + volHandle1 = pvs1[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle1).NotTo(gomega.BeEmpty()) + + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs2, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc2}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + volHandle2 = pvs2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to respective VMs") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm1, []*v1.PersistentVolumeClaim{pvc1})).To(gomega.Succeed()) @@ -1278,8 +1392,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create restorevol1 from snapshot1") restorepvc1, restorepv1, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot1, diskSize, false) - restorevolHandle1 := restorepv1[0].Spec.CSI.VolumeHandle - gomega.Expect(restorevolHandle1).NotTo(gomega.BeEmpty()) + if restorepv1 != nil && !latebinding { + restorevolHandle1 = restorepv1[0].Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle1).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, restorepvc1.Name, namespace) @@ -1291,8 +1407,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create restorevol2 from snapshot2") restorepvc2, restorepv2, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot2, diskSize, false) - restorevolHandle2 := restorepv2[0].Spec.CSI.VolumeHandle - gomega.Expect(restorevolHandle2).NotTo(gomega.BeEmpty()) + if restorepv2 != nil && !latebinding { + restorevolHandle2 = restorepv2[0].Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle2).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, restorepvc2.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1312,6 +1430,16 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm1, []*v1.PersistentVolumeClaim{pvc1, restorepvc2})).To(gomega.Succeed()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + restoredpvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{restorepvc1, restorepvc2}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + restorevolHandle1 = restoredpvs[0].Spec.CSI.VolumeHandle + restorevolHandle2 = restoredpvs[1].Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle1).NotTo(gomega.BeEmpty()) + gomega.Expect(restorevolHandle2).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Verify PVCs are accessible to the VM") ginkgo.By("Write some IO to the CSI volumes and read it back from them and verify the data integrity") // Refresh VM information @@ -1405,6 +1533,8 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var volHandle2 string + ginkgo.By("Create a storageclass") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1413,8 +1543,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvclaim, pvs, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle := pvs[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + if pvs != nil && !latebinding { + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvclaim.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1444,6 +1576,14 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { _, err = e2eVSphere.getVMByUUID(ctx, vmUUID) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvclaim}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + isDiskAttached, err := e2eVSphere.isVolumeAttachedToVM(client, pvs[0].Spec.CSI.VolumeHandle, vmUUID) gomega.Expect(err).NotTo(gomega.HaveOccurred()) gomega.Expect(isDiskAttached).To(gomega.BeTrue(), "Volume is not attached to the node") @@ -1551,7 +1691,11 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create volume using the snapshot") pvclaim2, pvs2, pod2 := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot, diskSize, true) - volHandle2 := pvs2[0].Spec.CSI.VolumeHandle + if pvs2 != nil && !latebinding { + volHandle2 = pvs2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } + defer func() { ginkgo.By(fmt.Sprintf("Deleting the pod %s in namespace %s", pod2.Name, namespace)) err = fpod.DeletePodWithWait(ctx, client, pod2) @@ -1563,6 +1707,14 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) }() + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs2, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvclaim2}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + volHandle2 = pvs2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Verify volume metadata for deployment pod, pvc and pv") err = waitAndVerifyCnsVolumeMetadata(ctx, volHandle2, pvclaim2, pvs2[0], pod2) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1607,6 +1759,8 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var volHandle2 string + ginkgo.By("Create a storageclass") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1615,8 +1769,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc, pvs, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle := pvs[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + if pvs != nil && !latebinding { + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1667,6 +1823,14 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVC is attached to the VM1") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm1, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) @@ -1733,8 +1897,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create a volume from a snapshot") pvc2, pv2, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot, diskSize, false) - volHandle2 := pv2[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + if pv2 != nil && !latebinding { + volHandle2 = pv2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc2.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1760,6 +1926,14 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) }() + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pv2, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc2}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + volHandle2 = pv2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVC2 is attached to the VM2") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm2, []*v1.PersistentVolumeClaim{pvc2})).To(gomega.Succeed()) @@ -1825,6 +1999,7 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var volHandle1, volHandle2, volHandle3 string volumeOpsScale := 3 var snapshotIds []string volumesnapshots := make([]*snapV1.VolumeSnapshot, volumeOpsScale) @@ -1838,8 +2013,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc, pvs, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle := pvs[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + if pvs != nil && !latebinding { + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1904,8 +2081,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create volume-1 from snapshot-1") pvc1, pv1, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumesnapshots[0], diskSize, false) - volHandle1 := pv1[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle1).NotTo(gomega.BeEmpty()) + if pv1 != nil && !latebinding { + volHandle1 = pv1[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle1).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc1.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1916,8 +2095,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create volume-2 from snapshot-2") pvc2, pv2, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumesnapshots[1], diskSize, false) - volHandle2 := pv2[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle1).NotTo(gomega.BeEmpty()) + if pv2 != nil && !latebinding { + volHandle2 = pv2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc2.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -1928,8 +2109,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create volume-3 from snapshot-3") pvc3, pv3, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumesnapshots[2], diskSize, false) - volHandle3 := pv3[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle3).NotTo(gomega.BeEmpty()) + if pv3 != nil && !latebinding { + volHandle3 = pv3[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle3).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc3.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2018,6 +2201,22 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, + []*v1.PersistentVolumeClaim{pvc1, pvc2, pvc3}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv1 := pvs[0] + pv2 := pvs[1] + pv3 := pvs[2] + volHandle1 = pv1.Spec.CSI.VolumeHandle + gomega.Expect(volHandle1).NotTo(gomega.BeEmpty()) + volHandle2 = pv2.Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + volHandle3 = pv3.Spec.CSI.VolumeHandle + gomega.Expect(volHandle3).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Verify pvc1 and pvc2 is attached to VM1") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm1, []*v1.PersistentVolumeClaim{pvc1, pvc2})).To(gomega.Succeed()) @@ -2074,6 +2273,7 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { defer cancel() var datastoreUrls []string + var restoreVolHandle string ginkgo.By("Create a storageclass") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) @@ -2083,8 +2283,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc, pvs, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle := pvs[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + if pvs != nil && !latebinding { + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2158,6 +2360,15 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp1, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm1.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to respective VMs") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm1, []*v1.PersistentVolumeClaim{pvc})).To(gomega.Succeed()) @@ -2196,8 +2407,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create volume from snapshot") restorepvc, restorepv, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot1, diskSize, false) - restoreVolHandle := restorepv[0].Spec.CSI.VolumeHandle - gomega.Expect(restoreVolHandle).NotTo(gomega.BeEmpty()) + if restorepv != nil && !latebinding { + restoreVolHandle = restorepv[0].Spec.CSI.VolumeHandle + gomega.Expect(restoreVolHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, restorepvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2272,6 +2485,16 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + restorepvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{restorepvc}, + pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + restorepv := restorepvs[0] + restoreVolHandle = restorepv.Spec.CSI.VolumeHandle + gomega.Expect(restoreVolHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to respective VMs") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm2, []*v1.PersistentVolumeClaim{restorepvc})).To(gomega.Succeed()) @@ -2321,6 +2544,9 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var volHandle1, volHandle2 string + var restorevolHandle1, restorevolHandle2 string + ginkgo.By("Create a storageclass") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2329,8 +2555,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc1, pvs1, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle1 := pvs1[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle1).NotTo(gomega.BeEmpty()) + if pvs1 != nil && !latebinding { + volHandle1 = pvs1[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle1).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc1.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2342,8 +2570,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc2, pvs2, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle2 := pvs2[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + if pvs2 != nil && !latebinding { + volHandle2 = pvs2[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc2.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2415,6 +2645,19 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, + []*v1.PersistentVolumeClaim{pvc1, pvc2}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv1 := pvs[0] + pv2 := pvs[1] + volHandle1 = pv1.Spec.CSI.VolumeHandle + gomega.Expect(volHandle1).NotTo(gomega.BeEmpty()) + volHandle2 = pv2.Spec.CSI.VolumeHandle + gomega.Expect(volHandle2).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to respective VMs") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm1, []*v1.PersistentVolumeClaim{pvc1})).To(gomega.Succeed()) @@ -2480,8 +2723,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create restorevol1 from snapshot1") restorepvc1, restorepv1, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot1, diskSize, false) - restorevolHandle1 := restorepv1[0].Spec.CSI.VolumeHandle - gomega.Expect(restorevolHandle1).NotTo(gomega.BeEmpty()) + if restorepv1 != nil && !latebinding { + restorevolHandle1 = restorepv1[0].Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle1).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, restorepvc1.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2492,8 +2737,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Create restorevol2 from snapshot2") restorepvc2, restorepv2, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot2, diskSize, false) - restorevolHandle2 := restorepv2[0].Spec.CSI.VolumeHandle - gomega.Expect(restorevolHandle2).NotTo(gomega.BeEmpty()) + if restorepv2 != nil && !latebinding { + restorevolHandle2 = restorepv2[0].Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle2).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, restorepvc2.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2605,6 +2852,8 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var restorevolHandle string + ginkgo.By("Create a storageclass") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2613,8 +2862,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvc, pvs, err := createPVCAndQueryVolumeInCNS(ctx, client, namespace, labelsMap, "", diskSize, storageclass, true) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volHandle := pvs[0].Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + if pvs != nil && !latebinding { + volHandle = pvs[0].Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2657,6 +2908,16 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp1, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm1.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, + pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm1, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) @@ -2755,8 +3016,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Restore volume from latest snapshot") restorepvc, restorepv, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot3, diskSize, false) - restorevolHandle := restorepv[0].Spec.CSI.VolumeHandle - gomega.Expect(restorevolHandle).NotTo(gomega.BeEmpty()) + if restorepv != nil && !latebinding { + restorevolHandle = restorepv[0].Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, restorepvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2791,6 +3054,16 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + restorepvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{restorepvc}, + pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + restorepv := restorepvs[0] + restorevolHandle = restorepv.Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm2, []*v1.PersistentVolumeClaim{restorepvc})).NotTo(gomega.HaveOccurred()) @@ -2857,6 +3130,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { allowedTopologyHAMap := createAllowedTopologiesMap(allowedTopos) pvcAnnotations := make(map[string]string) topoList := []string{} + var topologykey string + var volumeID string + var pvs []*v1.PersistentVolume + var restorevolHandle string for key, val := range allowedTopologyHAMap { for _, topoVal := range val { @@ -2869,20 +3146,22 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvcAnnotations[tkgHARequestedAnnotationKey] = annotationVal framework.Logf("annotationVal :%s, pvcAnnotations: %v", annotationVal, pvcAnnotations) - ginkgo.By("Creating Pvc with Immediate topology storageclass") + ginkgo.By("Creating Pvc") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) pvcSpec := getPersistentVolumeClaimSpecWithStorageClass(namespace, "", storageclass, nil, "") pvcSpec.Annotations = pvcAnnotations pvc, err := client.CoreV1().PersistentVolumeClaims(namespace).Create(ctx, pvcSpec, metav1.CreateOptions{}) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + gomega.Expect(err).To(gomega.HaveOccurred()) - ginkgo.By("Wait for SV PVC to come to bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, - framework.ClaimProvisionTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - topologykey := pvs[0].Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Values[0] - volumeID := pvs[0].Spec.CSI.VolumeHandle + if !latebinding { + ginkgo.By("Wait for SV PVC to come to bound state") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, + framework.ClaimProvisionTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + topologykey = pvs[0].Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Values[0] + volumeID = pvs[0].Spec.CSI.VolumeHandle + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) @@ -2894,11 +3173,6 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { "kubernetes", volumeID)) }() - ginkgo.By("Verify SV PV has has required PV node affinity details") - _, err = verifyVolumeTopologyForLevel5(pvs[0], allowedTopologyHAMap) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - framework.Logf("SVC PV: %s has required PV node affinity details", pvs[0].Name) - ginkgo.By("Creating VM bootstrap data") secretName := createBootstrapSecretForVmsvcVms(ctx, client, namespace) defer func() { @@ -2934,6 +3208,20 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Wait for SV PVC to come to bound state") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, + framework.ClaimProvisionTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + topologykey = pvs[0].Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Values[0] + volumeID = pvs[0].Spec.CSI.VolumeHandle + } + + ginkgo.By("Verify SV PV has has required PV node affinity details") + _, err = verifyVolumeTopologyForLevel5(pvs[0], allowedTopologyHAMap) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + framework.Logf("SVC PV: %s has required PV node affinity details", pvs[0].Name) + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) @@ -2974,8 +3262,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Restore volume from snapshot") restorepvc, restorepv, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot, diskSize, false) - restorevolHandle := restorepv[0].Spec.CSI.VolumeHandle - gomega.Expect(restorevolHandle).NotTo(gomega.BeEmpty()) + if restorepv != nil && !latebinding { + restorevolHandle = restorepv[0].Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, restorepvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -2983,11 +3273,6 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) }() - ginkgo.By("Verify SV PV has has required PV node affinity details") - _, err = verifyVolumeTopologyForLevel5(restorepv[0], allowedTopologyHAMap) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - framework.Logf("SVC PV: %s has required PV node affinity details", restorepv[0].Name) - ginkgo.By("Creating VM") vm2 := createVmServiceVmWithPvcsWithZone(ctx, vmopC, namespace, vmClass, []*v1.PersistentVolumeClaim{restorepvc}, vmi, storageClassName, secretName, topologykey) @@ -3015,6 +3300,21 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + restorepvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{restorepvc}, + pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + restorepv := restorepvs[0] + restorevolHandle = restorepv.Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle).NotTo(gomega.BeEmpty()) + } + + ginkgo.By("Verify SV PV has has required PV node affinity details") + _, err = verifyVolumeTopologyForLevel5(restorepv[0], allowedTopologyHAMap) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + framework.Logf("SVC PV: %s has required PV node affinity details", restorepv[0].Name) + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm2, []*v1.PersistentVolumeClaim{restorepvc})).NotTo(gomega.HaveOccurred()) @@ -3080,6 +3380,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { allowedTopologyHAMap := createAllowedTopologiesMap(allowedTopos) pvcAnnotations := make(map[string]string) topoList := []string{} + var topologykey string + var volumeId string + var pvs []*v1.PersistentVolume + var restorevolHandle1, restorevolHandle2 string for key, val := range allowedTopologyHAMap { for _, topoVal := range val { @@ -3092,20 +3396,22 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { pvcAnnotations[tkgHARequestedAnnotationKey] = annotationVal framework.Logf("annotationVal :%s, pvcAnnotations: %v", annotationVal, pvcAnnotations) - ginkgo.By("Creating Pvc with Immediate topology storageclass") + ginkgo.By("Creating Pvc") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) pvcSpec := getPersistentVolumeClaimSpecWithStorageClass(namespace, "", storageclass, nil, "") pvcSpec.Annotations = pvcAnnotations pvc, err := client.CoreV1().PersistentVolumeClaims(namespace).Create(ctx, pvcSpec, metav1.CreateOptions{}) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + gomega.Expect(err).To(gomega.HaveOccurred()) - ginkgo.By("Wait for SV PVC to come to bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, - framework.ClaimProvisionTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - topologykey := pvs[0].Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Values[0] - volumeId := pvs[0].Spec.CSI.VolumeHandle + if !latebinding { + ginkgo.By("Wait for SV PVC to come to bound state") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, + framework.ClaimProvisionTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + topologykey = pvs[0].Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Values[0] + volumeId = pvs[0].Spec.CSI.VolumeHandle + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) @@ -3117,11 +3423,6 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { "kubernetes", volumeId)) }() - ginkgo.By("Verify SV PV has has required PV node affinity details") - _, err = verifyVolumeTopologyForLevel5(pvs[0], allowedTopologyHAMap) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - framework.Logf("SVC PV: %s has required PV node affinity details", pvs[0].Name) - ginkgo.By("Creating VM bootstrap data") secretName := createBootstrapSecretForVmsvcVms(ctx, client, namespace) defer func() { @@ -3157,6 +3458,20 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Wait for SV PVC to come to bound state") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, + framework.ClaimProvisionTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + topologykey = pvs[0].Spec.NodeAffinity.Required.NodeSelectorTerms[0].MatchExpressions[0].Values[0] + volumeId = pvs[0].Spec.CSI.VolumeHandle + } + + ginkgo.By("Verify SV PV has has required PV node affinity details") + _, err = verifyVolumeTopologyForLevel5(pvs[0], allowedTopologyHAMap) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + framework.Logf("SVC PV: %s has required PV node affinity details", pvs[0].Name) + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) @@ -3197,8 +3512,11 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Restore volume from snapshot-1") restorepvc1, restorepv1, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot1, diskSize, false) - restorevolHandle1 := restorepv1[0].Spec.CSI.VolumeHandle - gomega.Expect(restorevolHandle1).NotTo(gomega.BeEmpty()) + if restorepv1 != nil && !latebinding { + restorevolHandle1 = restorepv1[0].Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle1).NotTo(gomega.BeEmpty()) + } + defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, restorepvc1.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -3206,11 +3524,6 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) }() - ginkgo.By("Verify SV PV has has required PV node affinity details") - _, err = verifyVolumeTopologyForLevel5(restorepv1[0], allowedTopologyHAMap) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - framework.Logf("SVC PV: %s has required PV node affinity details", restorepv1[0].Name) - ginkgo.By("Creating VM") vm2 := createVmServiceVmWithPvcsWithZone(ctx, vmopC, namespace, vmClass, []*v1.PersistentVolumeClaim{restorepvc1}, vmi, storageClassName, secretName, topologykey) @@ -3238,6 +3551,21 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + restorepvs1, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{restorepvc1}, + pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + restorepv1 := restorepvs1[0] + restorevolHandle1 = restorepv1.Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle1).NotTo(gomega.BeEmpty()) + } + + ginkgo.By("Verify SV PV has has required PV node affinity details") + _, err = verifyVolumeTopologyForLevel5(restorepv1[0], allowedTopologyHAMap) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + framework.Logf("SVC PV: %s has required PV node affinity details", restorepv1[0].Name) + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm2, []*v1.PersistentVolumeClaim{restorepvc1})).NotTo(gomega.HaveOccurred()) @@ -3276,8 +3604,10 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { ginkgo.By("Restore volume from snapshot-2") restorepvc2, restorepv2, _ := verifyVolumeRestoreOperation(ctx, client, namespace, storageclass, volumeSnapshot2, diskSize, false) - restorevolHandle2 := restorepv2[0].Spec.CSI.VolumeHandle - gomega.Expect(restorevolHandle2).NotTo(gomega.BeEmpty()) + if restorepv1 != nil && !latebinding { + restorevolHandle2 = restorepv2[0].Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle2).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, restorepvc2.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) @@ -3285,11 +3615,6 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) }() - ginkgo.By("Verify SV PV has has required PV node affinity details") - _, err = verifyVolumeTopologyForLevel5(restorepv2[0], allowedTopologyHAMap) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - framework.Logf("SVC PV: %s has required PV node affinity details", restorepv2[0].Name) - ginkgo.By("Creating VM") vm3 := createVmServiceVmWithPvcsWithZone(ctx, vmopC, namespace, vmClass, []*v1.PersistentVolumeClaim{restorepvc2}, vmi, storageClassName, secretName, topologykey) @@ -3317,6 +3642,21 @@ var _ bool = ginkgo.Describe("[snapshot-vmsvc] Snapshot VM Service VM", func() { vmIp3, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm3.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + ginkgo.By("Verify SV PV has has required PV node affinity details") + _, err = verifyVolumeTopologyForLevel5(restorepv2[0], allowedTopologyHAMap) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + framework.Logf("SVC PV: %s has required PV node affinity details", restorepv2[0].Name) + + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + restorepvs2, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{restorepvc2}, + pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + restorepv2 := restorepvs2[0] + restorevolHandle2 = restorepv2.Spec.CSI.VolumeHandle + gomega.Expect(restorevolHandle2).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm3, []*v1.PersistentVolumeClaim{restorepvc2})).NotTo(gomega.HaveOccurred()) diff --git a/tests/e2e/vm_service_vsan_stretch_cluster.go b/tests/e2e/vm_service_vsan_stretch_cluster.go index ecb0b5f6c6..4a5860009d 100644 --- a/tests/e2e/vm_service_vsan_stretch_cluster.go +++ b/tests/e2e/vm_service_vsan_stretch_cluster.go @@ -36,7 +36,6 @@ import ( "k8s.io/kubernetes/test/e2e/framework" fnodes "k8s.io/kubernetes/test/e2e/framework/node" - fpod "k8s.io/kubernetes/test/e2e/framework/pod" fpv "k8s.io/kubernetes/test/e2e/framework/pv" admissionapi "k8s.io/pod-security-admission/api" ctlrclient "sigs.k8s.io/controller-runtime/pkg/client" @@ -50,16 +49,16 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests f.NamespacePodSecurityEnforceLevel = admissionapi.LevelPrivileged f.SkipNamespaceCreation = true // tests will create their own namespaces var ( - client clientset.Interface - namespace string - datastoreURL string - storagePolicyName string - storageClassName string - storageProfileId string - vcRestSessionId string - vmi string - vmClass string - csiNs string + client clientset.Interface + namespace string + datastoreURL string + storagePolicyName string + storageClassName string + storageProfileId string + vcRestSessionId string + vmi string + vmClass string + //csiNs string vmopC ctlrclient.Client cnsopC ctlrclient.Client isVsanHealthServiceStopped bool @@ -87,9 +86,18 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests vcRestSessionId = createVcSession4RestApis(ctx) - storageClassName = strings.ReplaceAll(storagePolicyName, " ", "-") // since this is a wcp setup - storageClassName = strings.ToLower(storageClassName) - framework.Logf("storageClassName: %s", storageClassName) + if !latebinding { + ginkgo.By("Reading Immediate binding mode storage policy") + storageClassName = strings.ReplaceAll(storagePolicyName, " ", "-") + storageClassName = strings.ToLower(storageClassName) + framework.Logf("storageClassName: %s", storageClassName) + } else { + ginkgo.By("Reading late binding mode storage policy") + storageClassName = strings.ReplaceAll(storagePolicyName, " ", "-") + storageClassName = strings.ToLower(storageClassName) + storageClassName = storageClassName + "-latebinding" + framework.Logf("storageClassName: %s", storageClassName) + } datastoreURL = GetAndExpectStringEnvVar(envSharedDatastoreURL) dsRef := getDsMoRefFromURL(ctx, datastoreURL) @@ -167,6 +175,7 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests defer cancel() var pvcCount int = 5 var err error + var pvs []*v1.PersistentVolume ginkgo.By("Creating StorageClass") @@ -176,9 +185,11 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests ginkgo.By("Create multiple PVCs") pvclaimsList := createMultiplePVCsInParallel(ctx, client, namespace, sc, pvcCount, nil) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if !latebinding { + ginkgo.By("Verify PVCs bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } defer func() { for i, pvc := range pvclaimsList { @@ -219,8 +230,14 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests "and waits for VM IP to come up to come up and verify PVCs are accessible in the VM") createVMServiceandWaitForVMtoGetIP(ctx, vmopC, cnsopC, namespace, vms, pvclaimsList, true, true) - csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + + // csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Bring down the primary site") siteFailover(ctx, true) @@ -244,10 +261,10 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests time.Sleep(5 * time.Minute) // Check if csi pods are running fine after site failure - ginkgo.By("Check if csi pods are running fine after site failure") - err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), - time.Duration(pollTimeout*2)) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // ginkgo.By("Check if csi pods are running fine after site failure") + // err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), + // time.Duration(pollTimeout*2)) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Waiting for all claims to be in bound state") pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) @@ -296,6 +313,7 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests defer cancel() var pvcCount int = 10 var err error + var pvs []*v1.PersistentVolume ginkgo.By("Get StorageClass for volume creation") @@ -305,9 +323,11 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests ginkgo.By("Create multiple PVCs") pvclaimsList := createMultiplePVCsInParallel(ctx, client, namespace, sc, pvcCount, nil) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } defer func() { for i, pvc := range pvclaimsList { @@ -348,8 +368,14 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests "and waits for VM IP to come up to come up and verify PVCs are accessible in the VM") createVMServiceandWaitForVMtoGetIP(ctx, vmopC, cnsopC, namespace, vms, pvclaimsList, true, true) - csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + + // csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Bring down the secondary site") siteFailover(ctx, false) @@ -372,11 +398,11 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests } time.Sleep(5 * time.Minute) - // Check if csi pods are running fine after site failure - ginkgo.By("Check if csi pods are running fine after site failure") - err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), - time.Duration(pollTimeout*2)) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // // Check if csi pods are running fine after site failure + // ginkgo.By("Check if csi pods are running fine after site failure") + // err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), + // time.Duration(pollTimeout*2)) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Waiting for all claims to be in bound state") pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) @@ -425,6 +451,7 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests var vmCount = 9 var err error var vms []*vmopv1.VirtualMachine + var pvs []*v1.PersistentVolume ginkgo.By("Creating StorageClass") sc, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) @@ -433,9 +460,11 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests ginkgo.By("Create multiple PVCs") pvclaimsList := createMultiplePVCsInParallel(ctx, client, namespace, sc, pvcCount, nil) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if !latebinding { + ginkgo.By("Verify PVCs bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } defer func() { for i, pvc := range pvclaimsList { @@ -458,8 +487,8 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests gomega.Expect(err).NotTo(gomega.HaveOccurred()) }() - csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ch := make(chan *vmopv1.VirtualMachine) var wg sync.WaitGroup @@ -505,20 +534,22 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests gomega.Expect(err).NotTo(gomega.HaveOccurred()) } - // Check if csi pods are running fine after site failure - ginkgo.By("Check if csi pods are running fine after site failure") - err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), - time.Duration(pollTimeout*2)) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // // Check if csi pods are running fine after site failure + // ginkgo.By("Check if csi pods are running fine after site failure") + // err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), + // time.Duration(pollTimeout*2)) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Creates a loadbalancing service for ssh with each VM" + "and waits for VM IP to come up to come up and verify PVCs are accessible in the VM") createVMServiceandWaitForVMtoGetIP(ctx, vmopC, cnsopC, namespace, vms, pvclaimsList, true, true) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + ginkgo.By("Verify volume lifecycle actions when there is a fault induced") performVolumeLifecycleActionForVmServiceVM(ctx, client, vmopC, cnsopC, vmClass, namespace, vmi, sc, secretName) @@ -559,6 +590,7 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests defer cancel() var pvcCount int = 10 var err error + var pvs []*v1.PersistentVolume ginkgo.By("Creating StorageClass") @@ -568,9 +600,11 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests ginkgo.By("Create multiple PVCs") pvclaimsList := createMultiplePVCsInParallel(ctx, client, namespace, sc, pvcCount, nil) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if !latebinding { + ginkgo.By("Verify PVCs bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } defer func() { for i, pvc := range pvclaimsList { @@ -593,8 +627,8 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests gomega.Expect(err).NotTo(gomega.HaveOccurred()) }() - csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Creating VM") vms := createVMServiceVmWithMultiplePvcs( @@ -617,6 +651,12 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests "and waits for VM IP to come up to come up and verify PVCs are accessible in the VM") createVMServiceandWaitForVMtoGetIP(ctx, vmopC, cnsopC, namespace, vms, pvclaimsList, true, true) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + var wg sync.WaitGroup ginkgo.By("Deleting VM in parallel to secondary site failure") wg.Add(2) @@ -642,11 +682,11 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests } time.Sleep(5 * time.Minute) - // Check if csi pods are running fine after site failure - ginkgo.By("Check if csi pods are running fine after site failure") - err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), - time.Duration(pollTimeout*2)) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // // Check if csi pods are running fine after site failure + // ginkgo.By("Check if csi pods are running fine after site failure") + // err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), + // time.Duration(pollTimeout*2)) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Waiting for all claims to be in bound state") pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) @@ -695,6 +735,7 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests ctx, cancel := context.WithCancel(context.Background()) defer cancel() var vms []*vmopv1.VirtualMachine + var pvs []*v1.PersistentVolume ginkgo.By("Creating StorageClass") sc, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) @@ -703,9 +744,11 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests ginkgo.By("Create multiple PVCs") pvclaimsList := createMultiplePVCsInParallel(ctx, client, namespace, sc, 10, nil) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } defer func() { for i, pvc := range pvclaimsList { @@ -728,8 +771,8 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests gomega.Expect(err).NotTo(gomega.HaveOccurred()) }() - csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ch := make(chan *vmopv1.VirtualMachine) var wg sync.WaitGroup @@ -756,19 +799,21 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests } time.Sleep(5 * time.Minute) - ginkgo.By("Check if csi pods are running fine after site recovery") - err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), - time.Duration(pollTimeout*2)) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // ginkgo.By("Check if csi pods are running fine after site recovery") + // err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), + // time.Duration(pollTimeout*2)) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Creates a loadbalancing service for ssh with each VM" + "and waits for VM IP to come up to come up and verify PVCs are accessible in the VM") createVMServiceandWaitForVMtoGetIP(ctx, vmopC, cnsopC, namespace, vms, pvclaimsList, true, true) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + ginkgo.By("Verify volume lifecycle actions when there is a fault induced") performVolumeLifecycleActionForVmServiceVM(ctx, client, vmopC, cnsopC, vmClass, namespace, vmi, sc, secretName) @@ -803,13 +848,14 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests defer cancel() var pvcCount int = 10 var err error + var pvs []*v1.PersistentVolume ginkgo.By("Creating StorageClass") sc, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Wait for k8s cluster to be healthy") if vanillaCluster { @@ -829,18 +875,20 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests } }() - // Check if csi pods are running fine after site failure - ginkgo.By("Check if csi pods are running fine after site failure") - err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), - time.Duration(pollTimeout*2)) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // // Check if csi pods are running fine after site failure + // ginkgo.By("Check if csi pods are running fine after site failure") + // err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), + // time.Duration(pollTimeout*2)) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Create multiple PVCs") pvclaimsList := createMultiplePVCsInParallel(ctx, client, namespace, sc, pvcCount, nil) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } defer func() { for i, pvc := range pvclaimsList { @@ -882,6 +930,12 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests "and waits for VM IP to come up to come up and verify PVCs are accessible in the VM") createVMServiceandWaitForVMtoGetIP(ctx, vmopC, cnsopC, namespace, vms, pvclaimsList, true, true) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + ginkgo.By("Check storage compliance") comp := checkVmStorageCompliance(storagePolicyName) if comp { @@ -926,6 +980,7 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests defer cancel() var pvcCount int = 10 var err error + var pvs []*v1.PersistentVolume ginkgo.By("Creating StorageClass") @@ -935,9 +990,11 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests ginkgo.By("Create multiple PVCs") pvclaimsList := createMultiplePVCsInParallel(ctx, client, namespace, sc, pvcCount, nil) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } defer func() { for i, pvc := range pvclaimsList { @@ -978,8 +1035,13 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests "and waits for VM IP to come up to come up and verify PVCs are accessible in the VM") createVMServiceandWaitForVMtoGetIP(ctx, vmopC, cnsopC, namespace, vms, pvclaimsList, true, true) - csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + // csipods, err := client.CoreV1().Pods(csiNs).List(ctx, metav1.ListOptions{}) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) // Cause a network failure on primary site ginkgo.By("Isolate secondary site from witness and primary site") @@ -998,11 +1060,11 @@ var _ bool = ginkgo.Describe("[vsan-stretch-vmsvc] vm service with csi vol tests gomega.Expect(err).NotTo(gomega.HaveOccurred()) } - // Check if csi pods are running fine after site failure - ginkgo.By("Check if csi pods are running fine after site failure") - err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), - time.Duration(pollTimeout*2)) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + // // Check if csi pods are running fine after site failure + // ginkgo.By("Check if csi pods are running fine after site failure") + // err = fpod.WaitForPodsRunningReady(ctx, client, csiNs, len(csipods.Items), + // time.Duration(pollTimeout*2)) + // gomega.Expect(err).NotTo(gomega.HaveOccurred()) ginkgo.By("Waiting for all claims to be in bound state") pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvclaimsList, pollTimeout) diff --git a/tests/e2e/vmservice_utils.go b/tests/e2e/vmservice_utils.go index 0c62b585a8..64b142469f 100644 --- a/tests/e2e/vmservice_utils.go +++ b/tests/e2e/vmservice_utils.go @@ -1130,25 +1130,29 @@ func deleteVMServiceVmInParallel(ctx context.Context, c ctlrclient.Client, func performVolumeLifecycleActionForVmServiceVM(ctx context.Context, client clientset.Interface, vmopC ctlrclient.Client, cnsopC ctlrclient.Client, vmClass string, namespace string, vmi string, sc *storagev1.StorageClass, secretName string) { + var volHandle string ginkgo.By("Create a PVC") pvc, err := createPVC(ctx, client, namespace, nil, "", sc, "") gomega.Expect(err).NotTo(gomega.HaveOccurred()) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - pv := pvs[0] - volHandle := pv.Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) - defer func() { - ginkgo.By("Delete PVCs") - err = fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) + if !latebinding { + ginkgo.By("Waiting for all claims to be in bound state") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + defer func() { + ginkgo.By("Delete PVCs") + err = fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) - ginkgo.By("Waiting for CNS volumes to be deleted") - err = e2eVSphere.waitForCNSVolumeToBeDeleted(volHandle) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + ginkgo.By("Waiting for CNS volumes to be deleted") + err = e2eVSphere.waitForCNSVolumeToBeDeleted(volHandle) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) - }() + }() + + } ginkgo.By("Creating VM") vm := createVmServiceVmWithPvcs( @@ -1173,6 +1177,15 @@ func performVolumeLifecycleActionForVmServiceVM(ctx context.Context, client clie gomega.Expect(err).NotTo(gomega.HaveOccurred()) }() + if latebinding { + ginkgo.By("Waiting for all claims to be in bound state") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + + } ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) diff --git a/tests/e2e/vmservice_vm.go b/tests/e2e/vmservice_vm.go index 24c56602d6..a6ee2468c5 100644 --- a/tests/e2e/vmservice_vm.go +++ b/tests/e2e/vmservice_vm.go @@ -66,6 +66,7 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { isSPSserviceStopped bool isQuotaValidationSupported bool defaultDatastore *object.Datastore + volHandle string ) ginkgo.BeforeEach(func() { @@ -90,7 +91,16 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { vcRestSessionId = createVcSession4RestApis(ctx) - storageClassName = strings.ReplaceAll(storagePolicyName, "_", "-") // since this is a wcp setup + // reading storage policy + if latebinding { + framework.Logf("Reading late binding mode storage policy") + storageClassName = strings.ReplaceAll(storagePolicyName, "_", "-") + storageClassName = storageClassName + "-latebinding" + framework.Logf("storageClassName: %s", storageClassName) + } else { + storageClassName = strings.ReplaceAll(storagePolicyName, "_", "-") + framework.Logf("storageClassName: %s", storageClassName) + } datastoreURL = GetAndExpectStringEnvVar(envSharedDatastoreURL) dsRef := getDsMoRefFromURL(ctx, datastoreURL) @@ -195,7 +205,7 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { 3 Create a static PV/PVC using cns register volume API 4 Create a VMservice VM and with the pvcs created in step 3 5 Verify CNS metadata for pvcs. - 6 Write some IO to the CSI volumes and read it back from them and verify the data integrity + 6 Write some IO to the CSI volumes and read it back from them and verify the data integrity 7 Delete VM service VM 8 delete pvcs 9 Remove spbm policy attached to test namespace @@ -248,12 +258,15 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { ginkgo.By("Create a PVC") pvc, err := createPVC(ctx, client, namespace, nil, "", storageclass, "") gomega.Expect(err).NotTo(gomega.HaveOccurred()) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc, staticPvc}, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - pv := pvs[0] - volHandle := pv.Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + + if !latebinding { + ginkgo.By("Verify PVCs bound state created with Immediate binding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc, staticPvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { ginkgo.By("Delete PVCs") err = fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) @@ -300,6 +313,15 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { vmIp, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc, staticPvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm, []*v1.PersistentVolumeClaim{pvc, staticPvc})).NotTo(gomega.HaveOccurred()) @@ -339,12 +361,14 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { ginkgo.By("Create a PVC") pvc, err := createPVC(ctx, client, namespace, nil, "", storageclass, "") gomega.Expect(err).NotTo(gomega.HaveOccurred()) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - pv := pvs[0] - volHandle := pv.Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { ginkgo.By("Delete PVCs") err = fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) @@ -403,6 +427,15 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVC is attached to the VM2") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm2, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) @@ -524,6 +557,7 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { vmServiceVm, block, wcp, negative, vc80), func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var pvs []*v1.PersistentVolume ginkgo.By("Create a storageclass") storageclass, err := client.StorageV1().StorageClasses().Get(ctx, storageClassName, metav1.GetOptions{}) @@ -533,10 +567,12 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { gomega.Expect(err).NotTo(gomega.HaveOccurred()) pvc2, err := createPVC(ctx, client, namespace, nil, "", storageclass, "") gomega.Expect(err).NotTo(gomega.HaveOccurred()) - pvcs := []*v1.PersistentVolumeClaim{pvc1, pvc2} - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, pvcs, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + if !latebinding { + ginkgo.By("Verify PVCs bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc1, pvc2}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } defer func() { ginkgo.By("Delete PVCs") @@ -600,6 +636,12 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { vmIp2, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm2.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc1, pvc2}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + ginkgo.By("Wait and verify PVCs are attached to respective VMs") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm1, []*v1.PersistentVolumeClaim{pvc1})).To(gomega.Succeed()) @@ -716,6 +758,7 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { topoList := []string{} zones := []string{} rand.NewSource(time.Now().UnixNano()) + var pvs []*v1.PersistentVolume for key, val := range allowedTopologyHAMap { for _, topoVal := range val { @@ -737,20 +780,23 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { pvc, err := client.CoreV1().PersistentVolumeClaims(namespace).Create(ctx, pvcSpec, metav1.CreateOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - ginkgo.By("Wait for SV PVC to come to bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, - framework.ClaimProvisionTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volumeID := pvs[0].Spec.CSI.VolumeHandle + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - err = e2eVSphere.waitForCNSVolumeToBeDeleted(volumeID) + err = e2eVSphere.waitForCNSVolumeToBeDeleted(volHandle) gomega.Expect(err).NotTo(gomega.HaveOccurred(), fmt.Sprintf("Volume: %s should not be present in the CNS after it is deleted from "+ - "kubernetes", volumeID)) + "kubernetes", volHandle)) }() ginkgo.By("Verify SV PV has has required PV node affinity details") @@ -793,6 +839,15 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { vmIp, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Wait and verify PVCs are attached to the VM") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm, []*v1.PersistentVolumeClaim{pvc})).NotTo(gomega.HaveOccurred()) @@ -831,6 +886,7 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { topoList := []string{} zones := []string{} rand.NewSource(time.Now().UnixNano()) + var pvs []*v1.PersistentVolume for key, val := range allowedTopologyHAMap { for _, topoVal := range val { @@ -852,20 +908,23 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { pvc, err := client.CoreV1().PersistentVolumeClaims(namespace).Create(ctx, pvcSpec, metav1.CreateOptions{}) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - ginkgo.By("Wait for PVC to come to bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, - framework.ClaimProvisionTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - volumeID := pvs[0].Spec.CSI.VolumeHandle + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } defer func() { err := fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) gomega.Expect(err).NotTo(gomega.HaveOccurred()) - err = e2eVSphere.waitForCNSVolumeToBeDeleted(volumeID) + err = e2eVSphere.waitForCNSVolumeToBeDeleted(volHandle) gomega.Expect(err).NotTo(gomega.HaveOccurred(), fmt.Sprintf("Volume: %s should not be present in the CNS after it is deleted from "+ - "kubernetes", volumeID)) + "kubernetes", volHandle)) }() ginkgo.By("Verify PV has required PV node affinity details") @@ -968,12 +1027,16 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { ginkgo.By("Create a PVC") pvc, err := createPVC(ctx, client, namespace, nil, "", storageclass, "") gomega.Expect(err).NotTo(gomega.HaveOccurred()) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - pv := pvs[0] - volHandle := pv.Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + defer func() { ginkgo.By("Delete PVC") err = fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) @@ -1017,6 +1080,15 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { vmIp, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("create a pod say pod1 with pvc2") pods := createMultiplePods(ctx, client, [][]*v1.PersistentVolumeClaim{{pvc}}, true) defer func() { @@ -1097,6 +1169,7 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() + var pvs []*v1.PersistentVolume pvcs := []*v1.PersistentVolumeClaim{} vms := []*vmopv1.VirtualMachine{} vmlbsvcs := []*vmopv1.VirtualMachineService{} @@ -1111,9 +1184,11 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { pvcs = append(pvcs, pvc) } - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, pvcs, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if !latebinding { + ginkgo.By("Verify PVCs bound state created with Immediate binding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvcs, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } defer func() { ginkgo.By("Delete PVCs") @@ -1177,6 +1252,12 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { } }() + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvcs[2]}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + ginkgo.By("Verify pvc3 is attached to vm3") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm3, []*v1.PersistentVolumeClaim{pvcs[2]})).To(gomega.Succeed()) @@ -1253,6 +1334,12 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { vmlbsvc1 := createService4Vm(ctx, vmopC, namespace, vm1.Name) vmlbsvcs = append(vmlbsvcs, vmlbsvc1) + if latebinding { + ginkgo.By("Verify PVCs bound state created with latebinding mode storage policy") + pvs, err = fpv.WaitForPVClaimBoundPhase(ctx, client, pvcs, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + } + ginkgo.By("Verify pvc1 is attached to VM1") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm1, []*v1.PersistentVolumeClaim{pvcs[0]})).To(gomega.Succeed()) @@ -1302,12 +1389,16 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { ginkgo.By("Create a PVC") pvc, err := createPVC(ctx, client, namespace, nil, "", storageclass, "") gomega.Expect(err).NotTo(gomega.HaveOccurred()) - ginkgo.By("Waiting for all claims to be in bound state") - pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) - gomega.Expect(err).NotTo(gomega.HaveOccurred()) - pv := pvs[0] - volHandle := pv.Spec.CSI.VolumeHandle - gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + + if !latebinding { + ginkgo.By("Verify PVC bound state created with Immediate binding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + defer func() { ginkgo.By("Delete PVC") err = fpv.DeletePersistentVolumeClaim(ctx, client, pvc.Name, namespace) @@ -1375,6 +1466,15 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { vmIp, err := waitNgetVmsvcVmIp(ctx, vmopC, namespace, vm.Name) gomega.Expect(err).NotTo(gomega.HaveOccurred()) + if latebinding { + ginkgo.By("Verify PVC bound state created with latebinding mode storage policy") + pvs, err := fpv.WaitForPVClaimBoundPhase(ctx, client, []*v1.PersistentVolumeClaim{pvc}, pollTimeout) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + pv := pvs[0] + volHandle = pv.Spec.CSI.VolumeHandle + gomega.Expect(volHandle).NotTo(gomega.BeEmpty()) + } + ginkgo.By("Verify pvc1 is attached to VM1") gomega.Expect(waitNverifyPvcsAreAttachedToVmsvcVm(ctx, vmopC, cnsopC, vm, []*v1.PersistentVolumeClaim{pvc})).To(gomega.Succeed()) @@ -1404,7 +1504,7 @@ var _ bool = ginkgo.Describe("[vmsvc] vm service with csi vol tests", func() { 3 Create a static PV/PVC using cns register volume API 4 Create a VMservice VM and with the pvcs created in step 3 5 Verify CNS metadata for pvcs. - 6 Write some IO to the CSI volumes and read it back from them and verify the data integrity + 6 Write some IO to the CSI volumes and read it back from them and verify the data integrity 7 Delete VM service VM 8 delete pvcs 9 Remove spbm policy attached to test namespace