From c6bc84d8477473d4a309abfc93182d3b2e3e98db Mon Sep 17 00:00:00 2001 From: Madhu Rajanna Date: Tue, 15 Jun 2021 10:38:38 +0530 Subject: [PATCH] e2e: validate images in trash when all the PVC and associated images are deleted, the images should also get deleted from the trash. This commit adds the validation check for the same. Signed-off-by: Madhu Rajanna --- e2e/rbd.go | 17 ++++++++++++++++ e2e/rbd_helper.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/e2e/rbd.go b/e2e/rbd.go index c0756c7fe..26abed41c 100644 --- a/e2e/rbd.go +++ b/e2e/rbd.go @@ -1250,6 +1250,15 @@ var _ = Describe("RBD", func() { if err != nil { e2elog.Failf("failed to delete snapshotclass with error %v", err) } + // validate images in trash + err = waitToRemoveImagesFromTrash(f, clonePool, deployTimeout) + if err != nil { + e2elog.Failf("failed to validate rbd images in pool %s trash with error %v", clonePool, err) + } + err = waitToRemoveImagesFromTrash(f, defaultRBDPool, deployTimeout) + if err != nil { + e2elog.Failf("failed to validate rbd images in pool %s trash with error %v", defaultRBDPool, err) + } err = deletePool(clonePool, false, f) if err != nil { @@ -1812,6 +1821,14 @@ var _ = Describe("RBD", func() { } }) + + By("validate stale images in trash", func() { + err := waitToRemoveImagesFromTrash(f, defaultRBDPool, deployTimeout) + if err != nil { + e2elog.Failf("failed to validate rbd images in pool %s trash with error %v", defaultRBDPool, err) + } + }) + // Make sure this should be last testcase in this file, because // it deletes pool By("Create a PVC and delete PVC when backend pool deleted", func() { diff --git a/e2e/rbd_helper.go b/e2e/rbd_helper.go index 500acb302..c917a77cd 100644 --- a/e2e/rbd_helper.go +++ b/e2e/rbd_helper.go @@ -3,16 +3,19 @@ package e2e import ( "context" "encoding/json" + "errors" "fmt" "regexp" "strings" "sync" + "time" "github.com/kubernetes-csi/external-snapshotter/v2/pkg/apis/volumesnapshot/v1beta1" v1 "k8s.io/api/core/v1" scv1 "k8s.io/api/storage/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/test/e2e/framework" e2elog "k8s.io/kubernetes/test/e2e/framework/log" @@ -762,3 +765,50 @@ func validateThickPVC(f *framework.Framework, pvc *v1.PersistentVolumeClaim, siz return nil } + +// trashInfo contains the image details in trash. +type trashInfo struct { + Name string `json:"name"` +} + +// listRBDImagesInTrash lists images in the trash. +func listRBDImagesInTrash(f *framework.Framework, poolName string) ([]trashInfo, error) { + var trashInfos []trashInfo + + stdout, stdErr, err := execCommandInToolBoxPod(f, + fmt.Sprintf("rbd trash ls --format=json %s", poolName), rookNamespace) + if err != nil { + return trashInfos, err + } + if stdErr != "" { + return trashInfos, fmt.Errorf("failed to list images in trash %v", stdErr) + } + + err = json.Unmarshal([]byte(stdout), &trashInfos) + if err != nil { + return trashInfos, err + } + return trashInfos, nil +} + +func waitToRemoveImagesFromTrash(f *framework.Framework, poolName string, t int) error { + var errReason error + timeout := time.Duration(t) * time.Minute + err := wait.PollImmediate(poll, timeout, func() (bool, error) { + imagesInTrash, err := listRBDImagesInTrash(f, poolName) + if err != nil { + return false, err + } + if len(imagesInTrash) == 0 { + return true, nil + } + errReason = fmt.Errorf("found %d images found in trash. Image details %v", len(imagesInTrash), imagesInTrash) + e2elog.Logf(errReason.Error()) + return false, nil + }) + + if errors.Is(err, wait.ErrWaitTimeout) { + err = errReason + } + return err +}