Skip to content

Commit 1b79b89

Browse files
authored
Merge pull request kubernetes#129997 from carlory/HonorPVReclaimPolicy-e2e
HonorPVReclaimPolicy: add more e2e tests
2 parents 2527854 + c83a5e0 commit 1b79b89

File tree

1 file changed

+160
-7
lines changed

1 file changed

+160
-7
lines changed

test/e2e/storage/csimock/csi_honor_pv_reclaim_policy.go

Lines changed: 160 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"github.com/onsi/ginkgo/v2"
2525
"github.com/onsi/gomega"
2626
v1 "k8s.io/api/core/v1"
27+
apierrors "k8s.io/apimachinery/pkg/api/errors"
2728
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2829
"k8s.io/client-go/util/retry"
2930
storagehelpers "k8s.io/component-helpers/storage/volume"
@@ -42,7 +43,42 @@ var _ = utils.SIGDescribe("CSI Mock honor pv reclaim policy", feature.HonorPVRec
4243
m := newMockDriverSetup(f)
4344

4445
ginkgo.Context("CSI honor pv reclaim policy using mock driver", func() {
45-
ginkgo.It("Dynamic provisioning should honor pv delete reclaim policy", func(ctx context.Context) {
46+
ginkgo.It("Dynamic provisioning should honor pv delete reclaim policy when deleting pvc", func(ctx context.Context) {
47+
m.init(ctx, testParameters{
48+
registerDriver: true,
49+
enableHonorPVReclaimPolicy: true,
50+
reclaimPolicy: ptr.To(v1.PersistentVolumeReclaimDelete),
51+
})
52+
ginkgo.DeferCleanup(m.cleanup)
53+
54+
_, pvc := m.createPVC(ctx)
55+
56+
ginkgo.By(fmt.Sprintf("Waiting for PVC %s to be bound", pvc.Name))
57+
pvs, err := e2epv.WaitForPVClaimBoundPhase(ctx, f.ClientSet, []*v1.PersistentVolumeClaim{pvc}, framework.ClaimProvisionTimeout)
58+
framework.ExpectNoError(err, "failed to wait for PVC to be bound")
59+
gomega.Expect(pvs).To(gomega.HaveLen(1), "expected 1 PV to be bound to PVC, got %d", len(pvs))
60+
61+
pv := pvs[0]
62+
ginkgo.By(fmt.Sprintf("PVC %s is bound to PV %s", pvc.Name, pv.Name))
63+
gomega.Expect(pv.Spec.PersistentVolumeReclaimPolicy).To(gomega.Equal(v1.PersistentVolumeReclaimDelete),
64+
"expected PV %s to have reclaim policy %s, got %s", pv.Name, v1.PersistentVolumeReclaimDelete, pv.Spec.PersistentVolumeReclaimPolicy)
65+
// For dynamic provisioning, the PV should be created with the deletion protection finalizer.
66+
gomega.Expect(pv.Finalizers).To(gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer),
67+
"expected PV %s to have finalizer %s", pv.Name, storagehelpers.PVDeletionProtectionFinalizer)
68+
69+
ginkgo.By(fmt.Sprintf("Deleting PVC %s", pvc.Name))
70+
err = f.ClientSet.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(ctx, pvc.Name, metav1.DeleteOptions{})
71+
framework.ExpectNoError(err, "failed to delete PVC %s", pvc.Name)
72+
73+
ginkgo.By(fmt.Sprintf("Waiting for PV %s to be deleted", pv.Name))
74+
err = e2epv.WaitForPersistentVolumeDeleted(ctx, f.ClientSet, pv.Name, framework.Poll, 2*time.Minute)
75+
framework.ExpectNoError(err, "failed to wait for PV to be deleted")
76+
77+
ginkgo.By(fmt.Sprintf("Verifying that the driver received DeleteVolume call for PV %s", pv.Name))
78+
gomega.Expect(m.driver.GetCalls(ctx)).To(gomega.ContainElement(gomega.HaveField("Method", gomega.Equal("DeleteVolume"))))
79+
})
80+
81+
ginkgo.It("Dynamic provisioning should honor pv delete reclaim policy when deleting pv then pvc", func(ctx context.Context) {
4682
m.init(ctx, testParameters{
4783
registerDriver: true,
4884
enableHonorPVReclaimPolicy: true,
@@ -81,7 +117,7 @@ var _ = utils.SIGDescribe("CSI Mock honor pv reclaim policy", feature.HonorPVRec
81117
gomega.Expect(m.driver.GetCalls(ctx)).To(gomega.ContainElement(gomega.HaveField("Method", gomega.Equal("DeleteVolume"))))
82118
})
83119

84-
ginkgo.It("Dynamic provisioning should honor pv retain reclaim policy", func(ctx context.Context) {
120+
ginkgo.It("Dynamic provisioning should honor pv retain reclaim policy when deleting pvc then pv", func(ctx context.Context) {
85121
m.init(ctx, testParameters{
86122
registerDriver: true,
87123
enableHonorPVReclaimPolicy: true,
@@ -103,7 +139,54 @@ var _ = utils.SIGDescribe("CSI Mock honor pv reclaim policy", feature.HonorPVRec
103139

104140
ginkgo.By(fmt.Sprintf("Verifying that the PV %s does not have finalizer %s after creation", pv.Name, storagehelpers.PVDeletionProtectionFinalizer))
105141
gomega.Consistently(ctx, framework.GetObject(f.ClientSet.CoreV1().PersistentVolumes().Get, pv.Name, metav1.GetOptions{})).
106-
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionTimeout).ShouldNot(gomega.HaveField("Finalizers",
142+
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionShortTimeout).ShouldNot(gomega.HaveField("Finalizers",
143+
gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer)), "pv unexpectedly has the finalizer %s", storagehelpers.PVDeletionProtectionFinalizer)
144+
145+
ginkgo.By(fmt.Sprintf("Deleting PVC %s", pvc.Name))
146+
err = f.ClientSet.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(ctx, pvc.Name, metav1.DeleteOptions{})
147+
framework.ExpectNoError(err, "failed to delete PVC %s", pvc.Name)
148+
149+
ginkgo.By(fmt.Sprintf("Waiting for PVC %s to be deleted", pvc.Name))
150+
gomega.Eventually(ctx, func(ctx context.Context) error {
151+
_, err := f.ClientSet.CoreV1().PersistentVolumeClaims(pvc.Namespace).Get(ctx, pvc.Name, metav1.GetOptions{})
152+
return err
153+
}).WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionTimeout).Should(gomega.MatchError(apierrors.IsNotFound, "pvc unexpectedly exists"))
154+
155+
ginkgo.By(fmt.Sprintf("Deleting PV %s", pv.Name))
156+
err = f.ClientSet.CoreV1().PersistentVolumes().Delete(ctx, pv.Name, metav1.DeleteOptions{})
157+
framework.ExpectNoError(err, "failed to delete PV %s", pv.Name)
158+
159+
ginkgo.By(fmt.Sprintf("Waiting for PV %s to be deleted", pv.Name))
160+
err = e2epv.WaitForPersistentVolumeDeleted(ctx, f.ClientSet, pv.Name, framework.Poll, 2*time.Minute)
161+
framework.ExpectNoError(err, "failed to wait for PV to be deleted")
162+
163+
ginkgo.By(fmt.Sprintf("Verifying that the driver did not receive DeleteVolume call for PV %s", pv.Name))
164+
gomega.Expect(m.driver.GetCalls(ctx)).NotTo(gomega.ContainElement(gomega.HaveField("Method", gomega.Equal("DeleteVolume"))))
165+
})
166+
167+
ginkgo.It("Dynamic provisioning should honor pv retain reclaim policy when deleting pv then pvc", func(ctx context.Context) {
168+
m.init(ctx, testParameters{
169+
registerDriver: true,
170+
enableHonorPVReclaimPolicy: true,
171+
reclaimPolicy: ptr.To(v1.PersistentVolumeReclaimRetain),
172+
})
173+
ginkgo.DeferCleanup(m.cleanup)
174+
175+
_, pvc := m.createPVC(ctx)
176+
177+
ginkgo.By(fmt.Sprintf("Waiting for PVC %s to be bound", pvc.Name))
178+
pvs, err := e2epv.WaitForPVClaimBoundPhase(ctx, f.ClientSet, []*v1.PersistentVolumeClaim{pvc}, framework.ClaimProvisionTimeout)
179+
framework.ExpectNoError(err, "failed to wait for PVC to be bound")
180+
gomega.Expect(pvs).To(gomega.HaveLen(1), "expected 1 PV to be bound to PVC, got %d", len(pvs))
181+
182+
pv := pvs[0]
183+
ginkgo.By(fmt.Sprintf("PVC %s is bound to PV %s", pvc.Name, pv.Name))
184+
gomega.Expect(pv.Spec.PersistentVolumeReclaimPolicy).To(gomega.Equal(v1.PersistentVolumeReclaimRetain),
185+
"expected PV %s to have reclaim policy %s, got %s", pv.Name, v1.PersistentVolumeReclaimRetain, pv.Spec.PersistentVolumeReclaimPolicy)
186+
187+
ginkgo.By(fmt.Sprintf("Verifying that the PV %s does not have finalizer %s after creation", pv.Name, storagehelpers.PVDeletionProtectionFinalizer))
188+
gomega.Consistently(ctx, framework.GetObject(f.ClientSet.CoreV1().PersistentVolumes().Get, pv.Name, metav1.GetOptions{})).
189+
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionShortTimeout).ShouldNot(gomega.HaveField("Finalizers",
107190
gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer)), "pv unexpectedly has the finalizer %s", storagehelpers.PVDeletionProtectionFinalizer)
108191

109192
ginkgo.By(fmt.Sprintf("Deleting PV %s", pv.Name))
@@ -122,7 +205,37 @@ var _ = utils.SIGDescribe("CSI Mock honor pv reclaim policy", feature.HonorPVRec
122205
gomega.Expect(m.driver.GetCalls(ctx)).NotTo(gomega.ContainElement(gomega.HaveField("Method", gomega.Equal("DeleteVolume"))))
123206
})
124207

125-
ginkgo.It("Static provisioning should honor pv delete reclaim policy", func(ctx context.Context) {
208+
ginkgo.It("Static provisioning should honor pv delete reclaim policy when deleting pvc", func(ctx context.Context) {
209+
m.init(ctx, testParameters{
210+
registerDriver: true,
211+
enableHonorPVReclaimPolicy: true,
212+
reclaimPolicy: ptr.To(v1.PersistentVolumeReclaimDelete),
213+
})
214+
ginkgo.DeferCleanup(m.cleanup)
215+
216+
sc, pv, pvc := m.createPVPVC(ctx)
217+
gomega.Expect(pv.Spec.PersistentVolumeReclaimPolicy).To(gomega.Equal(v1.PersistentVolumeReclaimDelete),
218+
"expected PV %s to have reclaim policy %s, got %s", pv.Name, v1.PersistentVolumeReclaimDelete, pv.Spec.PersistentVolumeReclaimPolicy)
219+
gomega.Expect(pv.Annotations).NotTo(gomega.HaveKeyWithValue(storagehelpers.AnnDynamicallyProvisioned, sc.Provisioner), "expected PV %s to not have annotation %s", pv.Name, storagehelpers.AnnDynamicallyProvisioned)
220+
221+
ginkgo.By(fmt.Sprintf("Verifying that the PV %s has finalizer %s after creation", pv.Name, storagehelpers.PVDeletionProtectionFinalizer))
222+
gomega.Eventually(ctx, framework.GetObject(f.ClientSet.CoreV1().PersistentVolumes().Get, pv.Name, metav1.GetOptions{})).
223+
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionTimeout).Should(gomega.HaveField("Finalizers",
224+
gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer)), "failed to wait for PV to have finalizer %s", storagehelpers.PVDeletionProtectionFinalizer)
225+
226+
ginkgo.By(fmt.Sprintf("Deleting PVC %s", pvc.Name))
227+
err := f.ClientSet.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(ctx, pvc.Name, metav1.DeleteOptions{})
228+
framework.ExpectNoError(err, "failed to delete PVC %s", pvc.Name)
229+
230+
ginkgo.By(fmt.Sprintf("Waiting for PV %s to be deleted", pv.Name))
231+
err = e2epv.WaitForPersistentVolumeDeleted(ctx, f.ClientSet, pv.Name, framework.Poll, 2*time.Minute)
232+
framework.ExpectNoError(err, "failed to wait for PV to be deleted")
233+
234+
ginkgo.By(fmt.Sprintf("Verifying that the driver received DeleteVolume call for PV %s", pv.Name))
235+
gomega.Expect(m.driver.GetCalls(ctx)).To(gomega.ContainElement(gomega.HaveField("Method", gomega.Equal("DeleteVolume"))))
236+
})
237+
238+
ginkgo.It("Static provisioning should honor pv delete reclaim policy when deleting pv then pvc", func(ctx context.Context) {
126239
m.init(ctx, testParameters{
127240
registerDriver: true,
128241
enableHonorPVReclaimPolicy: true,
@@ -156,7 +269,7 @@ var _ = utils.SIGDescribe("CSI Mock honor pv reclaim policy", feature.HonorPVRec
156269
gomega.Expect(m.driver.GetCalls(ctx)).To(gomega.ContainElement(gomega.HaveField("Method", gomega.Equal("DeleteVolume"))))
157270
})
158271

159-
ginkgo.It("Static provisioning should honor pv retain reclaim policy", func(ctx context.Context) {
272+
ginkgo.It("Static provisioning should honor pv retain reclaim policy when deleting pvc then pv", func(ctx context.Context) {
160273
m.init(ctx, testParameters{
161274
registerDriver: true,
162275
enableHonorPVReclaimPolicy: true,
@@ -171,7 +284,47 @@ var _ = utils.SIGDescribe("CSI Mock honor pv reclaim policy", feature.HonorPVRec
171284

172285
ginkgo.By(fmt.Sprintf("Verifying that the PV %s does not have finalizer %s after creation", pv.Name, storagehelpers.PVDeletionProtectionFinalizer))
173286
gomega.Consistently(ctx, framework.GetObject(f.ClientSet.CoreV1().PersistentVolumes().Get, pv.Name, metav1.GetOptions{})).
174-
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionTimeout).ShouldNot(gomega.HaveField("Finalizers",
287+
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionShortTimeout).ShouldNot(gomega.HaveField("Finalizers",
288+
gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer)), "pv unexpectedly has the finalizer %s", storagehelpers.PVDeletionProtectionFinalizer)
289+
290+
ginkgo.By(fmt.Sprintf("Deleting PVC %s", pvc.Name))
291+
err := f.ClientSet.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(ctx, pvc.Name, metav1.DeleteOptions{})
292+
framework.ExpectNoError(err, "failed to delete PVC %s", pvc.Name)
293+
294+
ginkgo.By(fmt.Sprintf("Waiting for PVC %s to be deleted", pvc.Name))
295+
gomega.Eventually(ctx, func(ctx context.Context) error {
296+
_, err := f.ClientSet.CoreV1().PersistentVolumeClaims(pvc.Namespace).Get(ctx, pvc.Name, metav1.GetOptions{})
297+
return err
298+
}).WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionTimeout).Should(gomega.MatchError(apierrors.IsNotFound, "pvc unexpectedly exists"))
299+
300+
ginkgo.By(fmt.Sprintf("Deleting PV %s", pv.Name))
301+
err = f.ClientSet.CoreV1().PersistentVolumes().Delete(ctx, pv.Name, metav1.DeleteOptions{})
302+
framework.ExpectNoError(err, "failed to delete PV %s", pv.Name)
303+
304+
ginkgo.By(fmt.Sprintf("Waiting for PV %s to be deleted", pv.Name))
305+
err = e2epv.WaitForPersistentVolumeDeleted(ctx, f.ClientSet, pv.Name, framework.Poll, 2*time.Minute)
306+
framework.ExpectNoError(err, "failed to wait for PV to be deleted")
307+
308+
ginkgo.By(fmt.Sprintf("Verifying that the driver did not receive DeleteVolume call for PV %s", pv.Name))
309+
gomega.Expect(m.driver.GetCalls(ctx)).NotTo(gomega.ContainElement(gomega.HaveField("Method", gomega.Equal("DeleteVolume"))))
310+
})
311+
312+
ginkgo.It("Static provisioning should honor pv retain reclaim policy when deleting pv then pvc", func(ctx context.Context) {
313+
m.init(ctx, testParameters{
314+
registerDriver: true,
315+
enableHonorPVReclaimPolicy: true,
316+
reclaimPolicy: ptr.To(v1.PersistentVolumeReclaimRetain),
317+
})
318+
ginkgo.DeferCleanup(m.cleanup)
319+
320+
sc, pv, pvc := m.createPVPVC(ctx)
321+
gomega.Expect(pv.Spec.PersistentVolumeReclaimPolicy).To(gomega.Equal(v1.PersistentVolumeReclaimRetain),
322+
"expected PV %s to have reclaim policy %s, got %s", pv.Name, v1.PersistentVolumeReclaimRetain, pv.Spec.PersistentVolumeReclaimPolicy)
323+
gomega.Expect(pv.Annotations).NotTo(gomega.HaveKeyWithValue(storagehelpers.AnnDynamicallyProvisioned, sc.Provisioner), "expected PV %s to not have annotation %s", pv.Name, storagehelpers.AnnDynamicallyProvisioned)
324+
325+
ginkgo.By(fmt.Sprintf("Verifying that the PV %s does not have finalizer %s after creation", pv.Name, storagehelpers.PVDeletionProtectionFinalizer))
326+
gomega.Consistently(ctx, framework.GetObject(f.ClientSet.CoreV1().PersistentVolumes().Get, pv.Name, metav1.GetOptions{})).
327+
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionShortTimeout).ShouldNot(gomega.HaveField("Finalizers",
175328
gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer)), "pv unexpectedly has the finalizer %s", storagehelpers.PVDeletionProtectionFinalizer)
176329

177330
ginkgo.By(fmt.Sprintf("Deleting PV %s", pv.Name))
@@ -214,7 +367,7 @@ var _ = utils.SIGDescribe("CSI Mock honor pv reclaim policy", feature.HonorPVRec
214367

215368
ginkgo.By(fmt.Sprintf("Verifying that the PV %s does not have finalizer %s after creation", pv.Name, storagehelpers.PVDeletionProtectionFinalizer))
216369
gomega.Consistently(ctx, framework.GetObject(f.ClientSet.CoreV1().PersistentVolumes().Get, pv.Name, metav1.GetOptions{})).
217-
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionTimeout).ShouldNot(gomega.HaveField("Finalizers",
370+
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionShortTimeout).ShouldNot(gomega.HaveField("Finalizers",
218371
gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer)), "pv unexpectedly has the finalizer %s", storagehelpers.PVDeletionProtectionFinalizer)
219372

220373
ginkgo.By(fmt.Sprintf("Changing the reclaim policy of PV %s to %s", pv.Name, v1.PersistentVolumeReclaimDelete))

0 commit comments

Comments
 (0)