From 874c76c0c9e0061819f400587c91f43c627c731b Mon Sep 17 00:00:00 2001 From: Shubham Gupta Date: Fri, 10 Nov 2023 23:28:03 +0530 Subject: [PATCH] Add Test Signed-off-by: Shubham Gupta --- controllers/rediscluster_controller.go | 2 +- k8sutils/finalizer.go | 20 ++--- k8sutils/finalizers_test.go | 109 ++++++++++++++++++++++++- 3 files changed, 115 insertions(+), 16 deletions(-) diff --git a/controllers/rediscluster_controller.go b/controllers/rediscluster_controller.go index 4b12aae69..634560949 100644 --- a/controllers/rediscluster_controller.go +++ b/controllers/rediscluster_controller.go @@ -65,7 +65,7 @@ func (r *RedisClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request followerReplicas := instance.Spec.GetReplicaCounts("follower") totalReplicas := leaderReplicas + followerReplicas - if err = k8sutils.HandleRedisClusterFinalizer(instance, r.Client); err != nil { + if err = k8sutils.HandleRedisClusterFinalizer(r.Client, r.K8sClient, r.Log, instance); err != nil { return ctrl.Result{RequeueAfter: time.Second * 60}, err } diff --git a/k8sutils/finalizer.go b/k8sutils/finalizer.go index a7d4711b9..0131b24fa 100644 --- a/k8sutils/finalizer.go +++ b/k8sutils/finalizer.go @@ -3,7 +3,6 @@ package k8sutils import ( "context" "fmt" - "strconv" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" "github.com/go-logr/logr" @@ -45,15 +44,14 @@ func HandleRedisFinalizer(ctrlclient client.Client, k8sClient kubernetes.Interfa } // HandleRedisClusterFinalizer finalize resource if instance is marked to be deleted -func HandleRedisClusterFinalizer(cr *redisv1beta2.RedisCluster, cl client.Client) error { - logger := finalizerLogger(cr.Namespace, RedisClusterFinalizer) +func HandleRedisClusterFinalizer(ctrlclient client.Client, k8sClient kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisCluster) error { if cr.GetDeletionTimestamp() != nil { if controllerutil.ContainsFinalizer(cr, RedisClusterFinalizer) { - if err := finalizeRedisClusterPVC(cr); err != nil { + if err := finalizeRedisClusterPVC(k8sClient, logger, cr); err != nil { return err } controllerutil.RemoveFinalizer(cr, RedisClusterFinalizer) - if err := cl.Update(context.TODO(), cr); err != nil { + if err := ctrlclient.Update(context.TODO(), cr); err != nil { logger.Error(err, "Could not remove finalizer "+RedisClusterFinalizer) return err } @@ -145,16 +143,10 @@ func finalizeRedisPVC(client kubernetes.Interface, logger logr.Logger, cr *redis } // finalizeRedisClusterPVC delete PVCs -func finalizeRedisClusterPVC(cr *redisv1beta2.RedisCluster) error { - logger := finalizerLogger(cr.Namespace, RedisClusterFinalizer) - client, err := GenerateK8sClient(GenerateK8sConfig) - if err != nil { - logger.Error(err, "Could not generate kubernetes client") - return err - } +func finalizeRedisClusterPVC(client kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisCluster) error { for _, role := range []string{"leader", "follower"} { for i := 0; i < int(cr.Spec.GetReplicaCounts(role)); i++ { - PVCName := cr.Name + "-" + cr.Name + "-" + role + "-" + strconv.Itoa(i) + PVCName := fmt.Sprintf("%s-%s-%s-%d", cr.Name, cr.Name, role, i) err := client.CoreV1().PersistentVolumeClaims(cr.Namespace).Delete(context.TODO(), PVCName, metav1.DeleteOptions{}) if err != nil && !errors.IsNotFound(err) { logger.Error(err, "Could not delete Persistent Volume Claim "+PVCName) @@ -163,7 +155,7 @@ func finalizeRedisClusterPVC(cr *redisv1beta2.RedisCluster) error { } if cr.Spec.Storage.NodeConfVolume { for i := 0; i < int(cr.Spec.GetReplicaCounts(role)); i++ { - PVCName := "node-conf" + cr.Name + "-" + role + "-" + strconv.Itoa(i) + PVCName := fmt.Sprintf("%s-%s-%s-%d", "node-conf", cr.Name, role, i) err := client.CoreV1().PersistentVolumeClaims(cr.Namespace).Delete(context.TODO(), PVCName, metav1.DeleteOptions{}) if err != nil && !errors.IsNotFound(err) { logger.Error(err, "Could not delete Persistent Volume Claim "+PVCName) diff --git a/k8sutils/finalizers_test.go b/k8sutils/finalizers_test.go index f223b1ddd..b1e822a27 100644 --- a/k8sutils/finalizers_test.go +++ b/k8sutils/finalizers_test.go @@ -9,8 +9,10 @@ import ( "github.com/go-logr/logr/testr" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" k8sClientFake "k8s.io/client-go/kubernetes/fake" "k8s.io/utils/pointer" ) @@ -183,7 +185,7 @@ func TestFinalizeRedisReplicationPVC(t *testing.T) { logger := testr.New(t) var k8sClient *k8sClientFake.Clientset if tc.existingPVCs != nil { - k8sClient = k8sClientFake.NewSimpleClientset(tc.existingPVCs[0].DeepCopyObject(), tc.existingPVCs[1].DeepCopyObject(), tc.existingPVCs[2].DeepCopyObject()) + k8sClient = k8sClientFake.NewSimpleClientset(helperToRuntimeObjects(tc.existingPVCs)...) } else { k8sClient = k8sClientFake.NewSimpleClientset() } @@ -205,3 +207,108 @@ func TestFinalizeRedisReplicationPVC(t *testing.T) { }) } } + +func TestFinalizeRedisClusterPVC(t *testing.T) { + tests := []struct { + name string + existingPVCs []*corev1.PersistentVolumeClaim + redisCluster *v1beta2.RedisCluster + expectError bool + }{ + { + name: "Successful deletion of Redis Cluster PVCs", + redisCluster: &v1beta2.RedisCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "redis-cluster", + Namespace: "redis", + }, + Spec: v1beta2.RedisClusterSpec{ + Size: pointer.Int32(3), + Storage: &v1beta2.ClusterStorage{ + NodeConfVolume: true, + }, + }, + }, + existingPVCs: helperRedisClusterPVCs("redis-cluster", "redis"), + expectError: false, + }, + { + name: "PVC does not exist and no error should be returned", + existingPVCs: nil, + redisCluster: &v1beta2.RedisCluster{ + ObjectMeta: metav1.ObjectMeta{ + Name: "redis-cluster", + Namespace: "redis", + }, + Spec: v1beta2.RedisClusterSpec{ + Size: pointer.Int32(3), + Storage: &v1beta2.ClusterStorage{ + NodeConfVolume: false, + }, + }, + }, + expectError: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + logger := testr.New(t) + var k8sClient *k8sClientFake.Clientset + if tc.existingPVCs != nil { + k8sClient = k8sClientFake.NewSimpleClientset(helperToRuntimeObjects(tc.existingPVCs)...) + } else { + k8sClient = k8sClientFake.NewSimpleClientset() + } + + err := finalizeRedisClusterPVC(k8sClient, logger, tc.redisCluster) + if tc.expectError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + + // Verify PVCs are deleted + if !tc.expectError { + for _, pvc := range tc.existingPVCs { + _, err := k8sClient.CoreV1().PersistentVolumeClaims(pvc.Namespace).Get(context.TODO(), pvc.Name, metav1.GetOptions{}) + assert.True(t, k8serrors.IsNotFound(err)) + } + } + }) + } +} + +func helperToRuntimeObjects(pvcs []*corev1.PersistentVolumeClaim) []runtime.Object { + objs := make([]runtime.Object, len(pvcs)) + for i, pvc := range pvcs { + objs[i] = pvc.DeepCopyObject() + } + return objs +} + +func helperRedisClusterPVCs(clusterName string, namespace string) []*v1.PersistentVolumeClaim { + var pvcs []*v1.PersistentVolumeClaim + roles := []string{"leader", "follower"} + for _, role := range roles { + for i := 0; i < 3; i++ { + clusterPVCName := fmt.Sprintf("%s-%s-%s-%d", clusterName, clusterName, role, i) + clusterPVC := &v1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: clusterPVCName, + Namespace: namespace, + }, + } + pvcs = append(pvcs, clusterPVC) + nodeConfPVCName := fmt.Sprintf("node-conf-%s-%s-%d", clusterName, role, i) + nodeConfPVC := &v1.PersistentVolumeClaim{ + ObjectMeta: metav1.ObjectMeta{ + Name: nodeConfPVCName, + Namespace: namespace, + }, + } + pvcs = append(pvcs, nodeConfPVC) + } + } + return pvcs +}