diff --git a/pkg/common/health_test.go b/pkg/common/health_test.go index 42de12b4..121b9bfb 100644 --- a/pkg/common/health_test.go +++ b/pkg/common/health_test.go @@ -1,6 +1,8 @@ package common_test import ( + "os" + "path/filepath" "time" . "github.com/onsi/ginkgo/v2" @@ -8,8 +10,6 @@ import ( deploymentsv1alpha1 "github.com/pluralsh/deployment-operator/api/v1alpha1" "github.com/pluralsh/deployment-operator/pkg/common" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" ) var _ = Describe("Health Test", Ordered, func() { @@ -21,9 +21,9 @@ var _ = Describe("Health Test", Ordered, func() { } It("should get default status from CRD without condition block", func() { - obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(customResource) + obj, err := common.ToUnstructured(customResource) Expect(err).NotTo(HaveOccurred()) - status, err := common.GetResourceHealth(&unstructured.Unstructured{Object: obj}) + status, err := common.GetResourceHealth(obj) Expect(err).NotTo(HaveOccurred()) Expect(status).To(Not(BeNil())) Expect(*status).To(Equal(common.HealthStatus{ @@ -39,9 +39,9 @@ var _ = Describe("Health Test", Ordered, func() { }, }, } - obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(customResource) + obj, err := common.ToUnstructured(customResource) Expect(err).NotTo(HaveOccurred()) - status, err := common.GetResourceHealth(&unstructured.Unstructured{Object: obj}) + status, err := common.GetResourceHealth(obj) Expect(err).NotTo(HaveOccurred()) Expect(status).To(Not(BeNil())) Expect(*status).To(Equal(common.HealthStatus{ @@ -58,9 +58,9 @@ var _ = Describe("Health Test", Ordered, func() { }, }, } - obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(customResource) + obj, err := common.ToUnstructured(customResource) Expect(err).NotTo(HaveOccurred()) - status, err := common.GetResourceHealth(&unstructured.Unstructured{Object: obj}) + status, err := common.GetResourceHealth(obj) Expect(err).NotTo(HaveOccurred()) Expect(status).To(Not(BeNil())) Expect(*status).To(Equal(common.HealthStatus{ @@ -72,9 +72,9 @@ var _ = Describe("Health Test", Ordered, func() { customResource.DeletionTimestamp = &metav1.Time{ Time: time.Now(), } - obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(customResource) + obj, err := common.ToUnstructured(customResource) Expect(err).NotTo(HaveOccurred()) - status, err := common.GetResourceHealth(&unstructured.Unstructured{Object: obj}) + status, err := common.GetResourceHealth(obj) Expect(err).NotTo(HaveOccurred()) Expect(status).To(Not(BeNil())) Expect(*status).To(Equal(common.HealthStatus{ @@ -83,5 +83,21 @@ var _ = Describe("Health Test", Ordered, func() { })) }) + It("should get status from Lua script", func() { + customResource.DeletionTimestamp = nil + obj, err := common.ToUnstructured(customResource) + Expect(err).NotTo(HaveOccurred()) + scriptPath := filepath.Join("..", "..", "test", "lua", "test.lua") + script, err := os.ReadFile(scriptPath) + Expect(err).NotTo(HaveOccurred()) + common.GetLuaScript().SetValue(string(script)) + status, err := common.GetResourceHealth(obj) + Expect(err).NotTo(HaveOccurred()) + Expect(status).To(Not(BeNil())) + Expect(*status).To(Equal(common.HealthStatus{ + Status: common.HealthStatusProgressing, + })) + }) + }) }) diff --git a/pkg/controller/namespaces/reconciler_test.go b/pkg/controller/namespaces/reconciler_test.go new file mode 100644 index 00000000..03fd3816 --- /dev/null +++ b/pkg/controller/namespaces/reconciler_test.go @@ -0,0 +1,60 @@ +package namespaces_test + +import ( + "context" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + console "github.com/pluralsh/console/go/client" + "github.com/pluralsh/deployment-operator/pkg/controller/namespaces" + "github.com/pluralsh/deployment-operator/pkg/test/mocks" + "github.com/stretchr/testify/mock" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" +) + +var _ = Describe("Reconciler", Ordered, func() { + Context("When reconciling a resource", func() { + const ( + namespaceId = "1" + namespaceName = "test" + ) + clusterNamespace := &console.ManagedNamespaceFragment{ + ID: namespaceId, + Name: namespaceName, + } + ctx := context.Background() + + It("should create Namespace", func() { + fakeConsoleClient := mocks.NewClientMock(mocks.TestingT) + fakeConsoleClient.On("GetNamespace", mock.Anything).Return(clusterNamespace, nil) + + reconciler := namespaces.NewNamespaceReconciler(fakeConsoleClient, kClient, time.Minute) + _, err := reconciler.Reconcile(ctx, namespaceId) + Expect(err).NotTo(HaveOccurred()) + + existing := &v1.Namespace{} + Expect(kClient.Get(ctx, types.NamespacedName{Name: namespaceName}, existing)).NotTo(HaveOccurred()) + }) + + It("should Update Namespace", func() { + clusterNamespace.Labels = map[string]interface{}{ + "a": "b", + } + + fakeConsoleClient := mocks.NewClientMock(mocks.TestingT) + fakeConsoleClient.On("GetNamespace", mock.Anything).Return(clusterNamespace, nil) + + reconciler := namespaces.NewNamespaceReconciler(fakeConsoleClient, kClient, time.Minute) + _, err := reconciler.Reconcile(ctx, namespaceId) + Expect(err).NotTo(HaveOccurred()) + + existing := &v1.Namespace{} + Expect(kClient.Get(ctx, types.NamespacedName{Name: namespaceName}, existing)).NotTo(HaveOccurred()) + Expect(existing.Labels).To(Not(BeNil())) + Expect(existing.Labels["a"]).To(Equal("b")) + }) + + }) +}) diff --git a/pkg/controller/namespaces/suite_test.go b/pkg/controller/namespaces/suite_test.go new file mode 100644 index 00000000..d80a6793 --- /dev/null +++ b/pkg/controller/namespaces/suite_test.go @@ -0,0 +1,65 @@ +/* +Copyright 2024. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package namespaces_test + +import ( + "fmt" + "path/filepath" + "runtime" + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. +var testEnv *envtest.Environment +var kClient client.Client + +func TestStacks(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Stack Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s", fmt.Sprintf("1.28.3-%s-%s", runtime.GOOS, runtime.GOARCH)), + } + + cfg, err := testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + kClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(kClient).NotTo(BeNil()) +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/pkg/controller/restore/reconciler_test.go b/pkg/controller/restore/reconciler_test.go new file mode 100644 index 00000000..eeaee84f --- /dev/null +++ b/pkg/controller/restore/reconciler_test.go @@ -0,0 +1,61 @@ +package restore_test + +import ( + "context" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + console "github.com/pluralsh/console/go/client" + "github.com/pluralsh/deployment-operator/pkg/controller/restore" + "github.com/pluralsh/deployment-operator/pkg/test/mocks" + "github.com/stretchr/testify/mock" + velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + "k8s.io/apimachinery/pkg/types" +) + +var _ = Describe("Reconciler", Ordered, func() { + Context("When reconciling a resource", func() { + const ( + namespace = "default" + restoreId = "1" + backupName = "test" + ) + clusterRestore := &console.ClusterRestoreFragment{ + ID: restoreId, + Status: console.RestoreStatusPending, + Backup: &console.ClusterBackupFragment{ + Name: backupName, + }, + } + ctx := context.Background() + + It("should create Restore object", func() { + fakeConsoleClient := mocks.NewClientMock(mocks.TestingT) + fakeConsoleClient.On("GetClusterRestore", mock.Anything).Return(clusterRestore, nil) + + reconciler := restore.NewRestoreReconciler(fakeConsoleClient, kClient, time.Minute, namespace) + _, err := reconciler.Reconcile(ctx, restoreId) + Expect(err).NotTo(HaveOccurred()) + + veleroRestore := &velerov1.Restore{} + Expect(kClient.Get(ctx, types.NamespacedName{Name: restoreId, Namespace: namespace}, veleroRestore)).NotTo(HaveOccurred()) + }) + + It("should Update Cluster Restore", func() { + + veleroRestore := &velerov1.Restore{} + Expect(kClient.Get(ctx, types.NamespacedName{Name: restoreId, Namespace: namespace}, veleroRestore)).NotTo(HaveOccurred()) + + fakeConsoleClient := mocks.NewClientMock(mocks.TestingT) + fakeConsoleClient.On("GetClusterRestore", mock.Anything).Return(clusterRestore, nil) + fakeConsoleClient.On("UpdateClusterRestore", mock.AnythingOfType("string"), mock.Anything).Return(nil, nil) + + reconciler := restore.NewRestoreReconciler(fakeConsoleClient, kClient, time.Minute, namespace) + _, err := reconciler.Reconcile(ctx, restoreId) + Expect(err).NotTo(HaveOccurred()) + Expect(kClient.Delete(ctx, veleroRestore)).To(Succeed()) + }) + + }) +}) diff --git a/pkg/controller/restore/suite_test.go b/pkg/controller/restore/suite_test.go new file mode 100644 index 00000000..829306eb --- /dev/null +++ b/pkg/controller/restore/suite_test.go @@ -0,0 +1,72 @@ +/* +Copyright 2024. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package restore_test + +import ( + "fmt" + "path/filepath" + "runtime" + "testing" + + velerov1 "github.com/vmware-tanzu/velero/pkg/apis/velero/v1" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes/scheme" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" +) + +// These tests use Ginkgo (BDD-style Go testing framework). Refer to +// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. +var testEnv *envtest.Environment +var kClient client.Client + +func TestStacks(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Stack Suite") +} + +var _ = BeforeSuite(func() { + logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) + + By("bootstrapping test environment") + testEnv = &envtest.Environment{ + CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "test", "crd")}, + ErrorIfCRDPathMissing: true, + BinaryAssetsDirectory: filepath.Join("..", "..", "bin", "k8s", fmt.Sprintf("1.28.3-%s-%s", runtime.GOOS, runtime.GOARCH)), + } + + cfg, err := testEnv.Start() + Expect(err).NotTo(HaveOccurred()) + Expect(cfg).NotTo(BeNil()) + + err = velerov1.AddToScheme(scheme.Scheme) + Expect(err).NotTo(HaveOccurred()) + + kClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) + Expect(err).NotTo(HaveOccurred()) + Expect(kClient).NotTo(BeNil()) +}) + +var _ = AfterSuite(func() { + By("tearing down the test environment") + err := testEnv.Stop() + Expect(err).NotTo(HaveOccurred()) +})