Skip to content

Commit 5d478a6

Browse files
authored
Merge pull request kubernetes#129581 from carlory/e2e-honor-pv-relaim-policy
storage e2e tests: add more tests for pv relaim policy
2 parents 5da7563 + 2c58e27 commit 5d478a6

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

test/e2e/storage/csimock/csi_honor_pv_reclaim_policy.go

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/onsi/gomega"
2626
v1 "k8s.io/api/core/v1"
2727
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
"k8s.io/client-go/util/retry"
2829
storagehelpers "k8s.io/component-helpers/storage/volume"
2930
"k8s.io/kubernetes/pkg/features"
3031
"k8s.io/kubernetes/test/e2e/feature"
@@ -189,4 +190,120 @@ var _ = utils.SIGDescribe("CSI Mock honor pv reclaim policy", feature.HonorPVRec
189190
gomega.Expect(m.driver.GetCalls(ctx)).NotTo(gomega.ContainElement(gomega.HaveField("Method", gomega.Equal("DeleteVolume"))))
190191
})
191192
})
193+
194+
ginkgo.Context("CSI honor pv reclaim policy changes using mock driver", func() {
195+
ginkgo.It("should honor pv reclaim policy after it is changed from retain to deleted", func(ctx context.Context) {
196+
m.init(ctx, testParameters{
197+
registerDriver: true,
198+
enableHonorPVReclaimPolicy: true,
199+
reclaimPolicy: ptr.To(v1.PersistentVolumeReclaimRetain),
200+
})
201+
ginkgo.DeferCleanup(m.cleanup)
202+
203+
_, pvc := m.createPVC(ctx)
204+
205+
ginkgo.By(fmt.Sprintf("Waiting for PVC %s to be bound", pvc.Name))
206+
pvs, err := e2epv.WaitForPVClaimBoundPhase(ctx, f.ClientSet, []*v1.PersistentVolumeClaim{pvc}, framework.ClaimProvisionTimeout)
207+
framework.ExpectNoError(err, "failed to wait for PVC to be bound")
208+
gomega.Expect(pvs).To(gomega.HaveLen(1), "expected 1 PV to be bound to PVC, got %d", len(pvs))
209+
210+
pv := pvs[0]
211+
ginkgo.By(fmt.Sprintf("PVC %s is bound to PV %s", pvc.Name, pv.Name))
212+
gomega.Expect(pv.Spec.PersistentVolumeReclaimPolicy).To(gomega.Equal(v1.PersistentVolumeReclaimRetain),
213+
"expected PV %s to have reclaim policy %s, got %s", pv.Name, v1.PersistentVolumeReclaimRetain, pv.Spec.PersistentVolumeReclaimPolicy)
214+
215+
ginkgo.By(fmt.Sprintf("Verifying that the PV %s does not have finalizer %s after creation", pv.Name, storagehelpers.PVDeletionProtectionFinalizer))
216+
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",
218+
gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer)), "pv unexpectedly has the finalizer %s", storagehelpers.PVDeletionProtectionFinalizer)
219+
220+
ginkgo.By(fmt.Sprintf("Changing the reclaim policy of PV %s to %s", pv.Name, v1.PersistentVolumeReclaimDelete))
221+
err = retry.RetryOnConflict(retry.DefaultRetry, func() error {
222+
pv, err := f.ClientSet.CoreV1().PersistentVolumes().Get(ctx, pv.Name, metav1.GetOptions{})
223+
if err != nil {
224+
return err
225+
}
226+
pv.Spec.PersistentVolumeReclaimPolicy = v1.PersistentVolumeReclaimDelete
227+
_, err = f.ClientSet.CoreV1().PersistentVolumes().Update(ctx, pv, metav1.UpdateOptions{})
228+
return err
229+
})
230+
framework.ExpectNoError(err, "failed to update PV %s", pv.Name)
231+
232+
ginkgo.By(fmt.Sprintf("Verifying that the PV %s has finalizer %s after reclaim policy is changed", pv.Name, storagehelpers.PVDeletionProtectionFinalizer))
233+
gomega.Eventually(ctx, framework.GetObject(f.ClientSet.CoreV1().PersistentVolumes().Get, pv.Name, metav1.GetOptions{})).
234+
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionTimeout).Should(gomega.HaveField("Finalizers",
235+
gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer)), "failed to wait for PV to have finalizer %s", storagehelpers.PVDeletionProtectionFinalizer)
236+
237+
ginkgo.By(fmt.Sprintf("Deleting PV %s", pv.Name))
238+
err = f.ClientSet.CoreV1().PersistentVolumes().Delete(ctx, pv.Name, metav1.DeleteOptions{})
239+
framework.ExpectNoError(err, "failed to delete PV %s", pv.Name)
240+
241+
ginkgo.By(fmt.Sprintf("Deleting PVC %s", pvc.Name))
242+
err = f.ClientSet.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(ctx, pvc.Name, metav1.DeleteOptions{})
243+
framework.ExpectNoError(err, "failed to delete PVC %s", pvc.Name)
244+
245+
ginkgo.By(fmt.Sprintf("Waiting for PV %s to be deleted", pv.Name))
246+
err = e2epv.WaitForPersistentVolumeDeleted(ctx, f.ClientSet, pv.Name, framework.Poll, 2*time.Minute)
247+
framework.ExpectNoError(err, "failed to wait for PV to be deleted")
248+
249+
ginkgo.By(fmt.Sprintf("Verifying that the driver received DeleteVolume call for PV %s", pv.Name))
250+
gomega.Expect(m.driver.GetCalls(ctx)).To(gomega.ContainElement(gomega.HaveField("Method", gomega.Equal("DeleteVolume"))))
251+
})
252+
253+
ginkgo.It("should honor pv reclaim policy after it is changed from deleted to retain", func(ctx context.Context) {
254+
m.init(ctx, testParameters{
255+
registerDriver: true,
256+
enableHonorPVReclaimPolicy: true,
257+
reclaimPolicy: ptr.To(v1.PersistentVolumeReclaimDelete),
258+
})
259+
ginkgo.DeferCleanup(m.cleanup)
260+
261+
_, pvc := m.createPVC(ctx)
262+
263+
ginkgo.By(fmt.Sprintf("Waiting for PVC %s to be bound", pvc.Name))
264+
pvs, err := e2epv.WaitForPVClaimBoundPhase(ctx, f.ClientSet, []*v1.PersistentVolumeClaim{pvc}, framework.ClaimProvisionTimeout)
265+
framework.ExpectNoError(err, "failed to wait for PVC to be bound")
266+
gomega.Expect(pvs).To(gomega.HaveLen(1), "expected 1 PV to be bound to PVC, got %d", len(pvs))
267+
268+
pv := pvs[0]
269+
ginkgo.By(fmt.Sprintf("PVC %s is bound to PV %s", pvc.Name, pv.Name))
270+
gomega.Expect(pv.Spec.PersistentVolumeReclaimPolicy).To(gomega.Equal(v1.PersistentVolumeReclaimDelete),
271+
"expected PV %s to have reclaim policy %s, got %s", pv.Name, v1.PersistentVolumeReclaimDelete, pv.Spec.PersistentVolumeReclaimPolicy)
272+
// For dynamic provisioning, the PV should be created with the deletion protection finalizer.
273+
gomega.Expect(pv.Finalizers).To(gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer),
274+
"expected PV %s to have finalizer %s", pv.Name, storagehelpers.PVDeletionProtectionFinalizer)
275+
276+
ginkgo.By(fmt.Sprintf("Changing the reclaim policy of PV %s to %s", pv.Name, v1.PersistentVolumeReclaimRetain))
277+
err = retry.RetryOnConflict(retry.DefaultRetry, func() error {
278+
pv, err := f.ClientSet.CoreV1().PersistentVolumes().Get(ctx, pv.Name, metav1.GetOptions{})
279+
if err != nil {
280+
return err
281+
}
282+
pv.Spec.PersistentVolumeReclaimPolicy = v1.PersistentVolumeReclaimRetain
283+
_, err = f.ClientSet.CoreV1().PersistentVolumes().Update(ctx, pv, metav1.UpdateOptions{})
284+
return err
285+
})
286+
framework.ExpectNoError(err, "failed to update PV %s", pv.Name)
287+
288+
ginkgo.By(fmt.Sprintf("Verifying that the PV %s drops finalizer %s after reclaim policy is changed", pv.Name, storagehelpers.PVDeletionProtectionFinalizer))
289+
gomega.Eventually(ctx, framework.GetObject(f.ClientSet.CoreV1().PersistentVolumes().Get, pv.Name, metav1.GetOptions{})).
290+
WithPolling(framework.Poll).WithTimeout(framework.ClaimProvisionTimeout).ShouldNot(gomega.HaveField("Finalizers",
291+
gomega.ContainElement(storagehelpers.PVDeletionProtectionFinalizer)), "pv unexpectedly has the finalizer %s", storagehelpers.PVDeletionProtectionFinalizer)
292+
293+
ginkgo.By(fmt.Sprintf("Deleting PV %s", pv.Name))
294+
err = f.ClientSet.CoreV1().PersistentVolumes().Delete(ctx, pv.Name, metav1.DeleteOptions{})
295+
framework.ExpectNoError(err, "failed to delete PV %s", pv.Name)
296+
297+
ginkgo.By(fmt.Sprintf("Deleting PVC %s", pvc.Name))
298+
err = f.ClientSet.CoreV1().PersistentVolumeClaims(pvc.Namespace).Delete(ctx, pvc.Name, metav1.DeleteOptions{})
299+
framework.ExpectNoError(err, "failed to delete PVC %s", pvc.Name)
300+
301+
ginkgo.By(fmt.Sprintf("Waiting for PV %s to be deleted", pv.Name))
302+
err = e2epv.WaitForPersistentVolumeDeleted(ctx, f.ClientSet, pv.Name, framework.Poll, 2*time.Minute)
303+
framework.ExpectNoError(err, "failed to wait for PV to be deleted")
304+
305+
ginkgo.By(fmt.Sprintf("Verifying that the driver did not receive DeleteVolume call for PV %s", pv.Name))
306+
gomega.Expect(m.driver.GetCalls(ctx)).NotTo(gomega.ContainElement(gomega.HaveField("Method", gomega.Equal("DeleteVolume"))))
307+
})
308+
})
192309
})

0 commit comments

Comments
 (0)