Skip to content

Commit c19f472

Browse files
ShravaniVangurmergify[bot]
authored andcommitted
e2e: test for PVC with volumeBindingMode on helm installation
Test PVC binding with WaitForFirstConsumer in Helm installation. Signed-off-by: ShravaniVangur <shravanivangur@gmail.com>
1 parent 3fa030e commit c19f472

File tree

4 files changed

+99
-4
lines changed

4 files changed

+99
-4
lines changed

e2e/cephfs.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,26 @@ var _ = Describe(cephfsType, func() {
360360
})
361361
}
362362

363+
By("verify PVC and App Binding with volumeBindingMode:WaitForFirstConsumer", func() {
364+
err := createCephfsStorageClassWaitForFirstConsumer(f.ClientSet, f, true, nil)
365+
if err != nil {
366+
framework.Failf("failed to create CephFS storageclass: %v", err)
367+
}
368+
369+
err = validatePVCAndAppWaitForFirstConsumer(pvcPath, appPath, f)
370+
if err != nil {
371+
framework.Failf("failed to validate CephFS pvc and application binding: %v", err)
372+
}
373+
374+
validateSubvolumeCount(f, 0, fileSystemName, subvolumegroup)
375+
validateOmapCount(f, 0, cephfsType, metadataPool, volumesType)
376+
377+
err = deleteResource(cephFSExamplePath + "storageclass.yaml")
378+
if err != nil {
379+
framework.Failf("failed to delete CephFS storageclass: %v", err)
380+
}
381+
})
382+
363383
By("verify mountOptions support", func() {
364384
err := createCephfsStorageClass(f.ClientSet, f, true, nil)
365385
if err != nil {

e2e/cephfs_helper.go

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626

2727
snapapi "github.com/kubernetes-csi/external-snapshotter/client/v8/apis/volumesnapshot/v1"
2828
v1 "k8s.io/api/core/v1"
29+
scv1 "k8s.io/api/storage/v1"
2930
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3031
"k8s.io/apimachinery/pkg/util/wait"
3132
"k8s.io/client-go/kubernetes"
@@ -67,6 +68,40 @@ func createCephfsStorageClass(
6768
return err
6869
}
6970

71+
err = updateStorageClassParameters(&sc, params, enablePool, f)
72+
if err != nil {
73+
return err
74+
}
75+
76+
return createStorageClass(c, &sc)
77+
}
78+
79+
func createCephfsStorageClassWaitForFirstConsumer(c kubernetes.Interface, f *framework.Framework,
80+
enablePool bool,
81+
params map[string]string) error {
82+
scPath := fmt.Sprintf("%s/%s", cephFSExamplePath, "storageclass.yaml")
83+
sc, err := getStorageClass(scPath)
84+
if err != nil {
85+
return err
86+
}
87+
88+
err = updateStorageClassParameters(&sc, params, enablePool, f)
89+
if err != nil {
90+
return err
91+
}
92+
93+
// Set the volume binding mode to WaitForFirstConsumer
94+
value := scv1.VolumeBindingWaitForFirstConsumer
95+
sc.VolumeBindingMode = &value
96+
97+
return createStorageClass(c, &sc)
98+
}
99+
100+
func updateStorageClassParameters(sc *scv1.StorageClass, params map[string]string, enablePool bool, f *framework.Framework) error {
101+
if sc == nil {
102+
return fmt.Errorf("StorageClass is nil")
103+
}
104+
70105
sc.Parameters["fsName"] = fileSystemName
71106
sc.Parameters["csi.storage.k8s.io/provisioner-secret-namespace"] = cephCSINamespace
72107
sc.Parameters["csi.storage.k8s.io/provisioner-secret-name"] = cephFSProvisionerSecretName
@@ -93,18 +128,20 @@ func createCephfsStorageClass(
93128

94129
// fetch and set fsID from the cluster if not set in params
95130
if _, found := params["clusterID"]; !found {
96-
var fsID string
97-
fsID, err = getClusterID(f)
131+
fsID, err := getClusterID(f)
98132
if err != nil {
99133
return fmt.Errorf("failed to get clusterID: %w", err)
100134
}
101135
sc.Parameters["clusterID"] = fsID
102136
}
103137

104-
timeout := time.Duration(deployTimeout) * time.Minute
138+
return nil
139+
}
105140

141+
func createStorageClass(c kubernetes.Interface, sc *scv1.StorageClass) error {
142+
timeout := time.Duration(deployTimeout) * time.Minute
106143
return wait.PollUntilContextTimeout(context.TODO(), poll, timeout, true, func(ctx context.Context) (bool, error) {
107-
_, err = c.StorageV1().StorageClasses().Create(ctx, &sc, metav1.CreateOptions{})
144+
_, err := c.StorageV1().StorageClasses().Create(ctx, sc, metav1.CreateOptions{})
108145
if err != nil {
109146
framework.Logf("error creating StorageClass %q: %v", sc.Name, err)
110147
if isRetryableAPIError(err) {

e2e/pvc.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,15 @@ func createPVCAndPV(c kubernetes.Interface, pvc *v1.PersistentVolumeClaim, pv *v
130130
return err
131131
}
132132

133+
func createPVC(c kubernetes.Interface, pvc *v1.PersistentVolumeClaim) error {
134+
_, err := c.CoreV1().PersistentVolumeClaims(pvc.Namespace).Create(context.TODO(), pvc, metav1.CreateOptions{})
135+
if err != nil {
136+
return fmt.Errorf("failed to create pvc: %w", err)
137+
}
138+
139+
return nil
140+
}
141+
133142
func deletePVCAndPV(c kubernetes.Interface, pvc *v1.PersistentVolumeClaim, pv *v1.PersistentVolume, t int) error {
134143
ctx := context.TODO()
135144
err := c.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(ctx, pvc.Name, metav1.DeleteOptions{})

e2e/utils.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -557,6 +557,35 @@ func validatePVCAndAppBinding(pvcPath, appPath string, f *framework.Framework) e
557557
return err
558558
}
559559

560+
// validatePVCAndAppWaitForFirstConsumer creates a Pending PVC, starts an app, and verifies it to become Bound.
561+
func validatePVCAndAppWaitForFirstConsumer(pvcPath, appPath string, f *framework.Framework) error {
562+
pvc, err := loadPVC(pvcPath)
563+
if err != nil {
564+
return err
565+
}
566+
pvc.Namespace = f.UniqueName
567+
568+
app, err := loadApp(appPath)
569+
if err != nil {
570+
return err
571+
}
572+
app.Namespace = f.UniqueName
573+
574+
err = createPVC(f.ClientSet, pvc)
575+
if err != nil {
576+
return err
577+
}
578+
579+
err = createApp(f.ClientSet, app, deployTimeout)
580+
if err != nil {
581+
return err
582+
}
583+
584+
err = deletePVCAndApp("", f, pvc, app)
585+
586+
return err
587+
}
588+
560589
func getMountType(selector, mountPath string, f *framework.Framework) (string, error) {
561590
opt := metav1.ListOptions{
562591
LabelSelector: selector,

0 commit comments

Comments
 (0)