diff --git a/ci/ci-test.sh b/ci/ci-test.sh index cae7c33d..008f46bc 100755 --- a/ci/ci-test.sh +++ b/ci/ci-test.sh @@ -42,15 +42,6 @@ cleanup_loopdev() { done } -cleanup_lvmvg() { - if [ -f /tmp/openebs_ci_disk.img ] - then - sudo vgremove lvmvg -y || true - rm /tmp/openebs_ci_disk.img - fi - cleanup_loopdev -} - cleanup_foreign_lvmvg() { if [ -f /tmp/openebs_ci_foreign_disk.img ] then @@ -65,7 +56,6 @@ cleanup() { echo "Cleaning up test resources" - cleanup_lvmvg cleanup_foreign_lvmvg kubectl delete pvc -n openebs lvmpv-pvc @@ -79,12 +69,6 @@ cleanup() { [ -n "${CLEANUP_ONLY}" ] && cleanup 2>/dev/null && exit 0 [ -n "${RESET}" ] && cleanup 2>/dev/null -# setup the lvm volume group to create the volume -cleanup_lvmvg -truncate -s 100G /tmp/openebs_ci_disk.img -disk="$(sudo losetup -f /tmp/openebs_ci_disk.img --show)" -sudo pvcreate "${disk}" -sudo vgcreate lvmvg "${disk}" # setup a foreign lvm to test cleanup_foreign_lvmvg @@ -171,6 +155,8 @@ sudo pvscan --cache sudo lvdisplay +sudo vgdisplay + echo "******************** LVM Controller logs***************************** " dumpControllerLogs 1000 diff --git a/tests/lvm_utils.go b/tests/lvm_utils.go index 09ec9427..6fd211cc 100644 --- a/tests/lvm_utils.go +++ b/tests/lvm_utils.go @@ -20,17 +20,20 @@ import ( "fmt" "strconv" "strings" + "time" + "github.com/onsi/ginkgo" "github.com/onsi/gomega" ) // This creates loopdevice using the size passed as arg, // Uses the new loop device to create PV. returns loopdevice name to the caller. func createPV(size int) string { - fmt.Printf("Creating device\n") + ginkgo.By("Creating Pv") back_file_args := []string{ - "mktemp", "-t", + "mktemp", + "-t", "openebs_lvm_localpv_disk_XXXXX", "--dry-run", } @@ -39,14 +42,16 @@ func createPV(size int) string { file_str := strings.TrimSpace(string(file[:])) size_str := strconv.Itoa(size) + "G" device_args := []string{ - "truncate", "-s", + "truncate", + "-s", size_str, file_str, } _, _, err := execAtLocal("sudo", nil, device_args...) gomega.Expect(err).ShouldNot(gomega.HaveOccurred(), "create device failed") args_loop := []string{ - "losetup", "-f", + "losetup", + "-f", file_str, "--show", } stdout_loop, _, err := execAtLocal("sudo", nil, args_loop...) @@ -62,9 +67,29 @@ func createPV(size int) string { return stdout_loop_str } +// Gets lv_count of a specified vg, returns false if its not empty at the end of poll. +func vgEmpty(name string) bool { + args_lvs := []string{ + "vgs", + name, + "--options", + "lv_count", + "--noheadings", + } + lvs, _, _ := execAtLocal("sudo", nil, args_lvs...) + lvs_str := strings.TrimSpace(string(lvs)) + lv_cnt, _ := strconv.Atoi(lvs_str) + fmt.Printf("lvs cnt is %d\n", lv_cnt) + if lv_cnt != 0 { + return false + } else { + return true + } +} + // Does pvremove on specified device. Deletes loop device and the file backing loop device. func removePV(device string) { - fmt.Printf("remove pv\n") + ginkgo.By("Removing pv") args_pv := []string{ "pvremove", device, @@ -84,7 +109,8 @@ func removePV(device string) { dev_str := strings.TrimSpace(string(dev)) args_loop := []string{ - "losetup", "-d", + "losetup", + "-d", device, } _, _, err_loop := execAtLocal("sudo", nil, args_loop...) @@ -101,7 +127,7 @@ func removePV(device string) { // Creates vg on the specified device, Device passed should be a pv. func createVg(name string, device string) { - fmt.Printf("Creating vg\n") + ginkgo.By("Creating vg") args_vg := []string{ "vgcreate", name, device, @@ -112,7 +138,7 @@ func createVg(name string, device string) { // Takes vg name and pv device, extends vg using the supplied pv. func extendVg(name string, device string) { - fmt.Printf("extending vg\n") + ginkgo.By("Extending vg") args_vg := []string{ "vgextend", name, device, @@ -121,14 +147,31 @@ func extendVg(name string, device string) { gomega.Expect(err_vg).To(gomega.BeNil(), "vg extend failed") } -// Does vhremove on specified vg with force flag, -// lv will be forcedeleted if vg is not empty. +// Does vgremove on specified vg with -y flag if vg isnt empty after fer retires. func removeVg(name string) { - fmt.Printf("Removing vg\n") + ginkgo.By("Removing vg") + retries := 3 + current_retry := 0 args_vg := []string{ "vgremove", name, - "-f", + } + for { + if current_retry < retries { + vg_empty := vgEmpty(name) + if vg_empty { + fmt.Printf("No lv in vg before vg remove\n") + break + } else { + fmt.Printf("lv in vg during retry %d\n", current_retry) + } + } else { + fmt.Printf("vg still not empty after 6 seconds, moving on with force delete\n") + args_vg = append(args_vg, "-f") + break + } + current_retry += 1 + time.Sleep(2 * time.Second) } _, _, err_vg := execAtLocal("sudo", nil, args_vg...) gomega.Expect(err_vg).To(gomega.BeNil(), "vg remove failed") @@ -137,6 +180,7 @@ func removeVg(name string) { // enable the monitoring on thinpool created for test, on local node which // is part of single node cluster. func enableThinpoolMonitoring() { + ginkgo.By("Enable thinpool monitoring") lv := VOLGROUP + "/" + pvcObj.Spec.VolumeName args := []string{ @@ -163,6 +207,7 @@ func enableThinpoolMonitoring() { // verify that the thinpool has extended in capacity to an expected size. func VerifyThinpoolExtend() { + ginkgo.By("Verify thinpool extend") expect_size, _ := strconv.ParseInt(expanded_capacity, 10, 64) lv := VOLGROUP + "/" + pvcObj.Spec.VolumeName diff --git a/tests/provision_test.go b/tests/provision_test.go index 30c388d2..0e21f5c0 100644 --- a/tests/provision_test.go +++ b/tests/provision_test.go @@ -26,6 +26,7 @@ import ( var _ = Describe("[lvmpv] TEST VOLUME PROVISIONING", func() { Context("App is deployed with lvm driver", func() { It("Running volume Creation Tests", volumeCreationTest) + It("Running scheduling Tests", schedulingTest) It("Running volume/snapshot Capacity Tests", capacityTest) }) }) @@ -39,14 +40,27 @@ func deleteAppAndPvc(appnames []string, pvcname string) { deleteAndVerifyPVC(pvcName) } +func setupVg(size int, name string) string { + device := createPV(size) + createVg(name, device) + return device +} + +func cleanupVg(device string, name string) { + removeVg(name) + removePV(device) +} + func fsVolCreationTest() { fstypes := []string{"ext4", "xfs", "btrfs"} for _, fstype := range fstypes { By("####### Creating the storage class : " + fstype + " #######") createFstypeStorageClass(fstype) - By("creating and verifying PVC bound status", createAndVerifyPVC) + By("Creating and verifying PVC bound status") + createAndVerifyPVC(true) By("Creating and deploying app pod", createDeployVerifyApp) - By("verifying LVMVolume object", VerifyLVMVolume) + By("Verifying LVMVolume object to be Ready") + VerifyLVMVolume(true, "") resizeAndVerifyPVC(true, "8Gi") // do not resize after creating the snapshot(not supported) @@ -74,14 +88,16 @@ func fsVolCreationTest() { func blockVolCreationTest() { By("Creating default storage class", createStorageClass) - By("creating and verifying PVC bound status", createAndVerifyBlockPVC) + By("Creating and verifying PVC bound status") + createAndVerifyBlockPVC(true) By("Creating and deploying app pod", createDeployVerifyBlockApp) - By("verifying LVMVolume object", VerifyLVMVolume) + By("Verifying LVMVolume object to be Ready") + VerifyLVMVolume(true, "") By("Online resizing the block volume") resizeAndVerifyPVC(true, "8Gi") - By("create snapshot") + By("Creating snapshot") createSnapshot(pvcName, snapName, snapYAML) - By("verify snapshot") + By("Verifying snapshot") verifySnapshotCreated(snapName) deleteAppAndPvc(appNames, pvcName) By("Verifying that PV exists after PVC deletion") @@ -93,16 +109,91 @@ func blockVolCreationTest() { By("Deleting storage class", deleteStorageClass) } +func vgExtendNeededForProvsioningTest() { + device_0 := setupVg(7, "lvmvgdiff") + device := setupVg(3, "lvmvg") + device_1 := createPV(4) + defer removePV(device_1) + defer cleanupVg(device_0, "lvmvgdiff") + defer cleanupVg(device, "lvmvg") + By("Creating default storage class", createStorageClass) + By("Creating and verifying PVC Not Bound status") + createAndVerifyPVC(false) + By("Verifying LVMVolume object to be not Ready") + VerifyLVMVolume(false, "") + extendVg("lvmvg", device_1) + By("Verifying PVC bound status after vg extend") + VerifyBlockPVC() + By("Verifying LVMVolume object to be Ready after vg extend") + VerifyLVMVolume(true, "") + By("Deleting pvc") + deleteAndVerifyPVC(pvcName) + By("Verifying that PV doesnt exists after PVC deletion") + verifyPVForPVC(false, pvcName) + By("Deleting storage class", deleteStorageClass) +} + +func vgPatternMatchPresentTest() { + device := setupVg(20, "lvmvg112") + device_1 := setupVg(20, "lvmvg") + defer cleanupVg(device_1, "lvmvg") + defer cleanupVg(device, "lvmvg112") + By("Creating custom storage class with non existing vg parameter", createVgPatternStorageClass) + By("Creating and verifying PVC Bound status") + createAndVerifyPVC(true) + By("Verifying LVMVolume object to be Ready") + VerifyLVMVolume(true, "lvmvg112") + deleteAndVerifyPVC(pvcName) + By("Verifying that PV doesnt exists after PVC deletion") + verifyPVForPVC(false, pvcName) + By("Deleting storage class", deleteStorageClass) +} + +func vgPatternNoMatchPresentTest() { + device := setupVg(20, "lvmvg212") + device_1 := setupVg(20, "lvmvg") + defer cleanupVg(device_1, "lvmvg") + defer cleanupVg(device, "lvmvg212") + By("Creating custom storage class with non existing vg parameter", createVgPatternStorageClass) + By("Creating and verifying PVC Not Bound status") + createAndVerifyPVC(false) + By("Verifying LVMVolume object to be Not Ready") + VerifyLVMVolume(false, "") + deleteAndVerifyPVC(pvcName) + By("Verifying that PV doesnt exists after PVC deletion") + verifyPVForPVC(false, pvcName) + By("Deleting storage class", deleteStorageClass) +} + +func vgSpecifiedNotPresentTest() { + device := setupVg(40, "lvmvg") + defer cleanupVg(device, "lvmvg") + By("Creating custom storage class with non existing vg parameter", createStorageClassWithNonExistingVg) + By("creating and verifying PVC Not Bound status") + createAndVerifyPVC(false) + By("Verifying LVMVolume object to be Not Ready") + VerifyLVMVolume(false, "") + By("Deleting pvc") + deleteAndVerifyPVC(pvcName) + By("Verifying that PV doesnt exists after PVC deletion") + verifyPVForPVC(false, pvcName) + By("Deleting storage class", deleteStorageClass) +} + func sharedVolumeTest() { By("Creating shared LV storage class", createSharedVolStorageClass) - By("creating and verifying PVC bound status", createAndVerifyPVC) + By("creating and verifying PVC bound status") + createAndVerifyPVC(true) //we use two fio app pods for this test. appNames = append(appNames, "fio-ci-1") By("Creating and deploying app pod", createDeployVerifyApp) - By("verifying LVMVolume object", VerifyLVMVolume) + By("Verifying LVMVolume object to be Not Ready") + VerifyLVMVolume(true, "") By("Online resizing the shared volume") resizeAndVerifyPVC(true, "8Gi") deleteAppAndPvc(appNames, pvcName) + By("Verifying that PV doesnt exists after PVC deletion") + verifyPVForPVC(false, pvcName) By("Deleting storage class", deleteStorageClass) // Reset the app list back to original appNames = appNames[:len(appNames)-1] @@ -110,9 +201,11 @@ func sharedVolumeTest() { func thinVolCreationTest() { By("Creating thinProvision storage class", createThinStorageClass) - By("creating and verifying PVC bound status", createAndVerifyPVC) + By("creating and verifying PVC bound status") + createAndVerifyPVC(true) By("Creating and deploying app pod", createDeployVerifyApp) - By("verifying LVMVolume object", VerifyLVMVolume) + By("verifying LVMVolume object") + VerifyLVMVolume(true, "") By("Online resizing the block volume") resizeAndVerifyPVC(true, "8Gi") By("create snapshot") @@ -131,36 +224,52 @@ func thinVolCreationTest() { func thinVolCapacityTest() { By("Creating thinProvision storage class", createThinStorageClass) - By("creating and verifying PVC bound status", createAndVerifyPVC) + By("creating and verifying PVC bound status") + createAndVerifyPVC(true) By("enabling monitoring on thinpool", enableThinpoolMonitoring) By("Creating and deploying app pod", createDeployVerifyApp) By("verifying thinpool auto-extended", VerifyThinpoolExtend) - By("verifying LVMVolume object", VerifyLVMVolume) + By("verifying LVMVolume object") + VerifyLVMVolume(true, "") deleteAppAndPvc(appNames, pvcName) + By("Verifying that PV doesnt exists after PVC deletion") + verifyPVForPVC(false, pvcName) By("Deleting thinProvision storage class", deleteStorageClass) } func sizedSnapFSTest() { createFstypeStorageClass("ext4") - By("creating and verifying PVC bound status", createAndVerifyPVC) + By("creating and verifying PVC bound status") + createAndVerifyPVC(true) By("Creating and deploying app pod", createDeployVerifyApp) - By("verifying LVMVolume object", VerifyLVMVolume) + By("verifying LVMVolume object") + VerifyLVMVolume(true, "") createSnapshot(pvcName, snapName, sizedsnapYAML) verifySnapshotCreated(snapName) deleteAppAndPvc(appNames, pvcName) + By("Verifying that PV exists before Snapshot deletion") + verifyPVForPVC(true, pvcName) deleteSnapshot(pvcName, snapName, sizedsnapYAML) + By("Verifying that PV doesnt exists after Snapshot deletion") + verifyPVForPVC(false, pvcName) By("Deleting storage class", deleteStorageClass) } func sizedSnapBlockTest() { By("Creating default storage class", createStorageClass) - By("creating and verifying PVC bound status", createAndVerifyPVC) + By("creating and verifying PVC bound status") + createAndVerifyPVC(true) By("Creating and deploying app pod", createDeployVerifyApp) - By("verifying LVMVolume object", VerifyLVMVolume) + By("verifying LVMVolume object") + VerifyLVMVolume(true, "") createSnapshot(pvcName, snapName, sizedsnapYAML) verifySnapshotCreated(snapName) deleteAppAndPvc(appNames, pvcName) + By("Verifying that PV exists before Snapshot deletion") + verifyPVForPVC(true, pvcName) deleteSnapshot(pvcName, snapName, sizedsnapYAML) + By("Verifying that PV doesnt exists after Snapshot deletion") + verifyPVForPVC(false, pvcName) By("Deleting storage class", deleteStorageClass) } @@ -190,29 +299,26 @@ func leakProtectionTest() { By("Deleting storage class", deleteStorageClass) } -// This acts as a test just to call the new wrapper functions, -// Once we write tests calling them this will not be required. -// This doesnt test any Openebs component. -func lvmOps() { - device := createPV(6) - createVg("newvgcode3", device) - device_1 := createPV(5) - extendVg("newvgcode3", device_1) - removeVg("newvgcode3") - removePV(device) - removePV(device_1) +func volumeCreationTest() { + device := setupVg(40, "lvmvg") + defer cleanupVg(device, "lvmvg") + By("###Running filesystem volume creation test###", fsVolCreationTest) + By("###Running block volume creation test###", blockVolCreationTest) + By("###Running thin volume creation test###", thinVolCreationTest) + By("###Running leak protection test###", leakProtectionTest) + By("###Running shared volume for two app pods on same node test###", sharedVolumeTest) } -func volumeCreationTest() { - By("Running filesystem volume creation test", fsVolCreationTest) - By("Running block volume creation test", blockVolCreationTest) - By("Running thin volume creation test", thinVolCreationTest) - By("Running leak protection test", leakProtectionTest) - By("Running shared volume for two app pods on same node test", sharedVolumeTest) - By("Running Lvm Ops", lvmOps) +func schedulingTest() { + By("###Running vg extend needed to provision test###", vgExtendNeededForProvsioningTest) + By("###Running vg specified in sc not present test###", vgSpecifiedNotPresentTest) + By("###Running lvmnode has vg matching vgpattern test###", vgPatternMatchPresentTest) + By("###Running lvmnode doesnt have vg matching vgpattern test###", vgPatternNoMatchPresentTest) } func capacityTest() { - By("Running thin volume capacity test", thinVolCapacityTest) - By("Running sized snapshot test", sizedSnapshotTest) + device := setupVg(40, "lvmvg") + defer cleanupVg(device, "lvmvg") + By("###Running thin volume capacity test###", thinVolCapacityTest) + By("###Running sized snapshot test###", sizedSnapshotTest) } diff --git a/tests/suite_test.go b/tests/suite_test.go index 4fb8d247..23d6e145 100644 --- a/tests/suite_test.go +++ b/tests/suite_test.go @@ -43,6 +43,8 @@ import ( const ( // volume group name where volume provisioning will happen VOLGROUP = "lvmvg" + // This is supposed to be the volgroup parameter. This will not be available for provisioning in the lvmnode. + NONEXIST_VOLGROUP = "lvmvgn" ) var ( @@ -65,6 +67,7 @@ var ( nodeDaemonSet = "openebs-lvm-node" controllerDeployment = "openebs-lvm-controller" + vgPattern = "lvmvg1.*" nsObj *corev1.Namespace scObj *storagev1.StorageClass diff --git a/tests/utils.go b/tests/utils.go index edd48042..dc16f02d 100644 --- a/tests/utils.go +++ b/tests/utils.go @@ -26,8 +26,9 @@ import ( "k8s.io/apimachinery/pkg/api/resource" ) -// IsPVCBoundEventually checks if the pvc is bound or not eventually +// This checks if the pvc is bound eventually within the poll period. func IsPVCBoundEventually(pvcName string) bool { + ginkgo.By("Verifying pvc status to be bound eventually\n") return gomega.Eventually(func() bool { volume, err := PVCClient. Get(pvcName, metav1.GetOptions{}) @@ -38,6 +39,16 @@ func IsPVCBoundEventually(pvcName string) bool { Should(gomega.BeTrue()) } +// This checks if the pvc is Not bound consistently over polling period. +func IsPVCPendingConsistently(pvcName string) bool { + ginkgo.By("Verifying pvc status to be Pending consistently\n") + return gomega.Consistently(func() bool { + volume, err := PVCClient.Get(pvcName, metav1.GetOptions{}) + gomega.Expect(err).ToNot(gomega.HaveOccurred()) + return !pvc.NewForAPIObject(volume).IsBound() + }, 30, 5).Should(gomega.BeTrue()) +} + // IsPVCResizedEventually checks if the pvc is bound or not eventually func IsPVCResizedEventually(pvcName string, newCapacity string, shouldPass bool) bool { newStorage, err := resource.ParseQuantity(newCapacity) @@ -131,6 +142,48 @@ func createStorageClass() { gomega.Expect(err).To(gomega.BeNil(), "while creating a default storageclass {%s}", scName) } +func createVgPatternStorageClass() { + var ( + err error + ) + + parameters := map[string]string{ + "vgpattern": vgPattern, + } + + ginkgo.By("building a vgpattern based storage class") + scObj, err = sc.NewBuilder(). + WithGenerateName(scName). + WithParametersNew(parameters). + WithProvisioner(LocalProvisioner).Build() + gomega.Expect(err).ShouldNot(gomega.HaveOccurred(), + "while building default storageclass obj with prefix {%s}", scName) + + scObj, err = SCClient.Create(scObj) + gomega.Expect(err).To(gomega.BeNil(), "while creating a default storageclass {%s}", scName) +} + +func createStorageClassWithNonExistingVg() { + var ( + err error + ) + + parameters := map[string]string{ + "volgroup": NONEXIST_VOLGROUP, + } + + ginkgo.By("building a default storage class") + scObj, err = sc.NewBuilder(). + WithGenerateName(scName). + WithParametersNew(parameters). + WithProvisioner(LocalProvisioner).Build() + gomega.Expect(err).ShouldNot(gomega.HaveOccurred(), + "while building default storageclass obj with prefix {%s}", scName) + + scObj, err = SCClient.Create(scObj) + gomega.Expect(err).To(gomega.BeNil(), "while creating a default storageclass {%s}", scName) +} + func createSharedVolStorageClass() { var ( err error @@ -178,19 +231,43 @@ func createThinStorageClass() { } // VerifyLVMVolume verify the properties of a lvm-volume -func VerifyLVMVolume() { +// expected_vg is supposed to be passed only when vgpatten was used for scheduling. +// If its volgroup in sc then we can just match volgroup with lvmvolume's vg field. +func VerifyLVMVolume(expect_ready bool, expected_vg string) { ginkgo.By("fetching lvm volume") + vol_name := "" + if !expect_ready { + vol_name = pvcObj.ObjectMeta.Annotations["local.csi.openebs.io/csi-volume-name"] + } else { + vol_name = pvcObj.Spec.VolumeName + } vol, err := LVMClient.WithNamespace(OpenEBSNamespace). - Get(pvcObj.Spec.VolumeName, metav1.GetOptions{}) - gomega.Expect(err).To(gomega.BeNil(), "while fetching the lvm volume {%s}", pvcObj.Spec.VolumeName) - - ginkgo.By("verifying lvm volume") - gomega.Expect(vol.Spec.VolGroup).To(gomega.Equal(scObj.Parameters["volgroup"]), - "while checking volume group of lvm volume", pvcObj.Spec.VolumeName) - - gomega.Expect(vol.Status.State).To(gomega.Equal("Ready"), - "While checking if lvmvolume: %s is in Ready state", pvcObj.Spec.VolumeName) - gomega.Expect(vol.Finalizers[0]).To(gomega.Equal(lvm.LVMFinalizer), "while checking finializer to be set {%s}", pvcObj.Spec.VolumeName) + Get(vol_name, metav1.GetOptions{}) + + if !expect_ready { + if vol != nil && vol.ObjectMeta.Name == vol_name { + // Even if scheduler cant find the vg for scheduling it creates lvmvolume cr anyway, + // It gets deleted, by the csi provisioner only when the owner node of cr marks is + // as Failed. So incase, we do a get of cr when the cr was being handled then we expect + // state to be either Pending or Failed. + fmt.Printf("checking vol object as vol is non nil, vol is %v\n", vol) + gomega.Expect(vol.Status.State).To(gomega.Or(gomega.Equal("Pending"), gomega.Equal("Failed")), + "While checking if lvmvolume: %s is in Pending or Failed state", pvcObj.Spec.VolumeName) + } + } else { + gomega.Expect(err).To(gomega.BeNil(), "while fetching the lvm volume {%s}", pvcObj.Spec.VolumeName) + if expected_vg != "" { + fmt.Printf("vol is %v\n", vol) + gomega.Expect(vol.Spec.VolGroup).To(gomega.Equal(expected_vg), + "while checking volume group of lvm volume", pvcObj.Spec.VolumeName) + } else { + gomega.Expect(vol.Spec.VolGroup).To(gomega.Equal(scObj.Parameters["volgroup"]), + "while checking volume group of lvm volume", pvcObj.Spec.VolumeName) + } + gomega.Expect(vol.Status.State).To(gomega.Equal("Ready"), + "While checking if lvmvolume: %s is in Ready state", pvcObj.Spec.VolumeName) + gomega.Expect(vol.Finalizers[0]).To(gomega.Equal(lvm.LVMFinalizer), "while checking finializer to be set {%s}", pvcObj.Spec.VolumeName) + } } func deleteStorageClass() { @@ -199,7 +276,7 @@ func deleteStorageClass() { "while deleting lvm storageclass {%s}", scObj.Name) } -func createAndVerifyPVC() { +func createAndVerifyPVC(expect_bound bool) { var ( err error pvcName = "lvmpv-pvc" @@ -226,12 +303,14 @@ func createAndVerifyPVC() { pvcName, OpenEBSNamespace, ) - - ginkgo.By("verifying pvc status as bound") - - status := IsPVCBoundEventually(pvcName) - gomega.Expect(status).To(gomega.Equal(true), - "while checking status equal to bound") + ok := false + if !expect_bound { + ok = IsPVCPendingConsistently(pvcName) + } else { + ok = IsPVCBoundEventually(pvcName) + } + gomega.Expect(ok).To(gomega.Equal(true), + "while checking the pvc status") pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Get(pvcObj.Name, metav1.GetOptions{}) gomega.Expect(err).To( @@ -242,7 +321,7 @@ func createAndVerifyPVC() { ) } -func createAndVerifyBlockPVC() { +func createAndVerifyBlockPVC(expect_bound bool) { var ( err error pvcName = "lvmpv-pvc" @@ -274,10 +353,34 @@ func createAndVerifyBlockPVC() { OpenEBSNamespace, ) - ginkgo.By("verifying pvc status as bound") + ginkgo.By("verifying pvc status as bound\n") - status := IsPVCBoundEventually(pvcName) - gomega.Expect(status).To(gomega.Equal(true), + ok := false + if !expect_bound { + ok = IsPVCPendingConsistently(pvcName) + } else { + ok = IsPVCBoundEventually(pvcName) + } + gomega.Expect(ok).To(gomega.Equal(true), + "while checking the pvc status") + + pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Get(pvcObj.Name, metav1.GetOptions{}) + gomega.Expect(err).To( + gomega.BeNil(), + "while retrieving pvc {%s} in namespace {%s}", + pvcName, + OpenEBSNamespace, + ) +} + +func VerifyBlockPVC() { + var ( + err error + pvcName = "lvmpv-pvc" + ) + + ok := IsPVCBoundEventually(pvcName) + gomega.Expect(ok).To(gomega.Equal(true), "while checking status equal to bound") pvcObj, err = PVCClient.WithNamespace(OpenEBSNamespace).Get(pvcObj.Name, metav1.GetOptions{})