From 3282c1666a73620b31b6f8272c1d34bbb51a2ef2 Mon Sep 17 00:00:00 2001 From: Raghavendra Talur Date: Wed, 11 Dec 2024 17:01:49 -0500 Subject: [PATCH] tests: refactor tests for VRG KubeObject Protection - Consolidated test data initialization into a `testData` struct and a helper function `newTestData()` - Add helper functions to check for conditions Signed-off-by: Raghavendra Talur --- internal/controller/vrg_kubeobjects_test.go | 281 +++++++++++--------- 1 file changed, 158 insertions(+), 123 deletions(-) diff --git a/internal/controller/vrg_kubeobjects_test.go b/internal/controller/vrg_kubeobjects_test.go index 1948f1389..1dff89038 100644 --- a/internal/controller/vrg_kubeobjects_test.go +++ b/internal/controller/vrg_kubeobjects_test.go @@ -15,157 +15,192 @@ import ( Recipe "github.com/ramendr/recipe/api/v1alpha1" ) -var _ = Describe("VRG_KubeObjectProtection", func() { - const namespaceName = "my-ns" - - var hook *Recipe.Hook - var group *Recipe.Group - - BeforeEach(func() { - duration := 30 - - hook = &Recipe.Hook{ - Namespace: namespaceName, - Name: "hook-single", - Type: "exec", - LabelSelector: &metav1.LabelSelector{ - MatchLabels: map[string]string{ - "myapp": "testapp", - }, +const testNamespaceName = "my-ns" + +// testData holds all the test fixtures +type testData struct { + hook *Recipe.Hook + group *Recipe.Group +} + +// newTestData creates a new instance of test data with default values +func newTestData() *testData { + duration := 30 + essential := new(bool) + + hook := &Recipe.Hook{ + Namespace: testNamespaceName, + Name: "hook-single", + Type: "exec", + LabelSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "myapp": "testapp", + }, + }, + SinglePodOnly: false, + Ops: []*Recipe.Operation{ + { + Name: "checkpoint", + Container: "main", + Timeout: duration, + Command: "bash /scripts/checkpoint.sh", }, - SinglePodOnly: false, - Ops: []*Recipe.Operation{ + }, + Chks: []*Recipe.Check{}, + Essential: essential, + } + + group := &Recipe.Group{ + Name: "test-group", + BackupRef: "test-backup-ref", + Type: "resource", + IncludedNamespaces: []string{testNamespaceName}, + IncludedResourceTypes: []string{"deployment", "replicaset"}, + ExcludedResourceTypes: nil, + LabelSelector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ { - Name: "checkpoint", - Container: "main", - Timeout: duration, - Command: "bash /scripts/checkpoint.sh", + Key: "test", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{"empty-on-backup notin", "ignore-on-backup"}, }, }, - Chks: []*Recipe.Check{}, - Essential: new(bool), - } - - group = &Recipe.Group{ - Name: "test-group", - BackupRef: "test-backup-ref", - Type: "resource", - IncludedNamespaces: []string{namespaceName}, - IncludedResourceTypes: []string{"deployment", "replicaset"}, - ExcludedResourceTypes: nil, - LabelSelector: &metav1.LabelSelector{ - MatchExpressions: []metav1.LabelSelectorRequirement{ - { - Key: "test", - Operator: metav1.LabelSelectorOpNotIn, - Values: []string{"empty-on-backup notin", "ignore-on-backup"}, + }, + } + + return &testData{ + hook: hook, + group: group, + } +} + +// getExpectedHookCaptureSpec returns the expected CaptureSpec for a hook +func getExpectedHookCaptureSpec(hook *Recipe.Hook, opName string) *kubeobjects.CaptureSpec { + return &kubeobjects.CaptureSpec{ + Name: hook.Name + "-" + opName, + Spec: kubeobjects.Spec{ + KubeResourcesSpec: kubeobjects.KubeResourcesSpec{ + IncludedNamespaces: []string{hook.Namespace}, + IncludedResources: []string{"pod"}, + ExcludedResources: []string{}, + Hook: kubeobjects.HookSpec{ + Name: hook.Name, + Namespace: hook.Namespace, + Type: hook.Type, + LabelSelector: hook.LabelSelector, + Op: kubeobjects.Operation{ + Name: hook.Ops[0].Name, + Command: hook.Ops[0].Command, + Container: hook.Ops[0].Container, }, }, + IsHook: true, }, - } + LabelSelector: hook.LabelSelector, + IncludeClusterResources: new(bool), + }, + } +} + +// getExpectedHookRecoverSpec returns the expected RecoverSpec for a hook +func getExpectedHookRecoverSpec(hook *Recipe.Hook, opName string) *kubeobjects.RecoverSpec { + return &kubeobjects.RecoverSpec{ + Spec: kubeobjects.Spec{ + KubeResourcesSpec: kubeobjects.KubeResourcesSpec{ + IncludedNamespaces: []string{hook.Namespace}, + IncludedResources: []string{"pod"}, + ExcludedResources: []string{}, + Hook: kubeobjects.HookSpec{ + Name: hook.Name, + Type: hook.Type, + Namespace: hook.Namespace, + LabelSelector: hook.LabelSelector, + Op: kubeobjects.Operation{ + Name: hook.Ops[0].Name, + Command: hook.Ops[0].Command, + Container: hook.Ops[0].Container, + }, + }, + IsHook: true, + }, + LabelSelector: hook.LabelSelector, + IncludeClusterResources: new(bool), + }, + } +} + +// getExpectedGroupCaptureSpec returns the expected CaptureSpec for a group +func getExpectedGroupCaptureSpec(group *Recipe.Group) *kubeobjects.CaptureSpec { + return &kubeobjects.CaptureSpec{ + Name: group.Name, + Spec: kubeobjects.Spec{ + KubeResourcesSpec: kubeobjects.KubeResourcesSpec{ + IncludedNamespaces: group.IncludedNamespaces, + IncludedResources: group.IncludedResourceTypes, + ExcludedResources: group.ExcludedResourceTypes, + }, + LabelSelector: group.LabelSelector, + IncludeClusterResources: group.IncludeClusterResources, + OrLabelSelectors: []*metav1.LabelSelector{}, + }, + } +} + +// getExpectedGroupRecoverSpec returns the expected RecoverSpec for a group +func getExpectedGroupRecoverSpec(group *Recipe.Group) *kubeobjects.RecoverSpec { + return &kubeobjects.RecoverSpec{ + BackupName: group.BackupRef, + Spec: kubeobjects.Spec{ + KubeResourcesSpec: kubeobjects.KubeResourcesSpec{ + IncludedNamespaces: group.IncludedNamespaces, + IncludedResources: group.IncludedResourceTypes, + ExcludedResources: group.ExcludedResourceTypes, + }, + LabelSelector: group.LabelSelector, + IncludeClusterResources: group.IncludeClusterResources, + OrLabelSelectors: []*metav1.LabelSelector{}, + }, + } +} + +var _ = Describe("VRG_KubeObjectProtection", func() { + var td *testData + + BeforeEach(func() { + td = newTestData() }) Context("Conversion", func() { It("Hook to CaptureSpec", func() { - targetCaptureSpec := &kubeobjects.CaptureSpec{ - Name: hook.Name + "-" + hook.Ops[0].Name, - Spec: kubeobjects.Spec{ - KubeResourcesSpec: kubeobjects.KubeResourcesSpec{ - IncludedNamespaces: []string{namespaceName}, - IncludedResources: []string{"pod"}, - ExcludedResources: []string{}, - Hook: kubeobjects.HookSpec{ - Name: hook.Name, - Namespace: namespaceName, - Type: hook.Type, - LabelSelector: hook.LabelSelector, - Op: kubeobjects.Operation{ - Name: hook.Ops[0].Name, - Command: hook.Ops[0].Command, - Container: hook.Ops[0].Container, - }, - }, - IsHook: true, - }, - LabelSelector: hook.LabelSelector, - IncludeClusterResources: new(bool), - }, - } - converted, err := convertRecipeHookToCaptureSpec(*hook, hook.Ops[0].Name) + expected := getExpectedHookCaptureSpec(td.hook, td.hook.Ops[0].Name) + converted, err := convertRecipeHookToCaptureSpec(*td.hook, td.hook.Ops[0].Name) Expect(err).To(BeNil()) - Expect(converted).To(Equal(targetCaptureSpec)) + Expect(converted).To(Equal(expected)) }) It("Hook to RecoverSpec", func() { - targetRecoverSpec := &kubeobjects.RecoverSpec{ - Spec: kubeobjects.Spec{ - KubeResourcesSpec: kubeobjects.KubeResourcesSpec{ - IncludedNamespaces: []string{namespaceName}, - IncludedResources: []string{"pod"}, - ExcludedResources: []string{}, - Hook: kubeobjects.HookSpec{ - Name: hook.Name, - Type: hook.Type, - Namespace: namespaceName, - // Timeout: hook.Ops[0].Timeout, - LabelSelector: hook.LabelSelector, - Op: kubeobjects.Operation{ - Name: hook.Ops[0].Name, - Command: hook.Ops[0].Command, - Container: hook.Ops[0].Container, - }, - }, - IsHook: true, - }, - LabelSelector: hook.LabelSelector, - IncludeClusterResources: new(bool), - }, - } - converted, err := convertRecipeHookToRecoverSpec(*hook, hook.Ops[0].Name) + expected := getExpectedHookRecoverSpec(td.hook, td.hook.Ops[0].Name) + converted, err := convertRecipeHookToRecoverSpec(*td.hook, td.hook.Ops[0].Name) Expect(err).To(BeNil()) - Expect(converted).To(Equal(targetRecoverSpec)) + Expect(converted).To(Equal(expected)) }) It("Group to CaptureSpec", func() { - targetCaptureSpec := &kubeobjects.CaptureSpec{ - Name: group.Name, - Spec: kubeobjects.Spec{ - KubeResourcesSpec: kubeobjects.KubeResourcesSpec{ - IncludedNamespaces: group.IncludedNamespaces, - IncludedResources: group.IncludedResourceTypes, - ExcludedResources: group.ExcludedResourceTypes, - }, - LabelSelector: group.LabelSelector, - IncludeClusterResources: group.IncludeClusterResources, - OrLabelSelectors: []*metav1.LabelSelector{}, - }, - } - converted, err := convertRecipeGroupToCaptureSpec(*group) + expected := getExpectedGroupCaptureSpec(td.group) + converted, err := convertRecipeGroupToCaptureSpec(*td.group) Expect(err).To(BeNil()) - Expect(converted).To(Equal(targetCaptureSpec)) + Expect(converted).To(Equal(expected)) }) It("Group to RecoverSpec", func() { - targetRecoverSpec := &kubeobjects.RecoverSpec{ - BackupName: group.BackupRef, - Spec: kubeobjects.Spec{ - KubeResourcesSpec: kubeobjects.KubeResourcesSpec{ - IncludedNamespaces: group.IncludedNamespaces, - IncludedResources: group.IncludedResourceTypes, - ExcludedResources: group.ExcludedResourceTypes, - }, - LabelSelector: group.LabelSelector, - IncludeClusterResources: group.IncludeClusterResources, - OrLabelSelectors: []*metav1.LabelSelector{}, - }, - } - converted, err := convertRecipeGroupToRecoverSpec(*group) + expected := getExpectedGroupRecoverSpec(td.group) + converted, err := convertRecipeGroupToRecoverSpec(*td.group) Expect(err).To(BeNil()) - Expect(converted).To(Equal(targetRecoverSpec)) + Expect(converted).To(Equal(expected)) }) }) })