diff --git a/Makefile b/Makefile index b7c50723d..1a37f68b5 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ __check_defined = \ ### # The latest 1.25 available for envtest -ENVTEST_K8S_VERSION ?= 1.26.1 +ENVTEST_K8S_VERSION ?= 1.29.5 LOCAL_TESTBIN = $(CURDIR)/testbin $(LOCAL_TESTBIN): mkdir -p $@ @@ -66,10 +66,11 @@ unit-tests::manifests unit-tests::just-unit-tests ## Run unit tests GINKGO ?= go run github.com/onsi/ginkgo/v2/ginkgo +GINKGO_PROCS ?= 4 .PHONY: just-unit-tests just-unit-tests: - $(GINKGO) -r --randomize-all api/ internal/ pkg/ + $(GINKGO) -r -p --randomize-all --fail-on-pending --procs=$(GINKGO_PROCS) $(GINKGO_EXTRA) api/ internal/ pkg/ .PHONY: integration-tests integration-tests::install-tools @@ -83,7 +84,7 @@ integration-tests::just-integration-tests ## Run integration tests .PHONY: just-integration-tests just-integration-tests: - $(GINKGO) -r controllers/ + $(GINKGO) -r -p --fail-on-pending --randomize-all --procs=$(GINKGO_PROCS) $(GINKGO_EXTRA) controllers/ manifests: install-tools ## Generate manifests e.g. CRD, RBAC etc. controller-gen crd rbac:roleName=operator-role paths="./api/...;./controllers/..." output:crd:artifacts:config=config/crd/bases @@ -236,7 +237,7 @@ cert-manager-rm: kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/v$(CERT_MANAGER_VERSION)/cert-manager.yaml --ignore-not-found system-tests: install-tools ## Run end-to-end tests against Kubernetes cluster defined in ~/.kube/config - NAMESPACE="$(SYSTEM_TEST_NAMESPACE)" K8S_OPERATOR_NAMESPACE="$(K8S_OPERATOR_NAMESPACE)" $(GINKGO) -nodes=3 --randomize-all -r system_tests/ + NAMESPACE="$(SYSTEM_TEST_NAMESPACE)" K8S_OPERATOR_NAMESPACE="$(K8S_OPERATOR_NAMESPACE)" $(GINKGO) -nodes=3 --randomize-all -r $(GINKGO_EXTRA) system_tests/ kubectl-plugin-tests: ## Run kubectl-rabbitmq tests @echo "running kubectl plugin tests" diff --git a/api/v1beta1/suite_test.go b/api/v1beta1/suite_test.go index 1a12dd189..dc893015a 100644 --- a/api/v1beta1/suite_test.go +++ b/api/v1beta1/suite_test.go @@ -9,6 +9,7 @@ package v1beta1 import ( + "fmt" "path/filepath" "testing" @@ -41,6 +42,9 @@ var _ = BeforeSuite(func() { By("bootstrapping test environment") testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, + Config: &rest.Config{ + Host: fmt.Sprintf("http://localhost:218%d", GinkgoParallelProcess()), + }, } err := SchemeBuilder.AddToScheme(scheme.Scheme) diff --git a/controllers/rabbitmqcluster_controller_test.go b/controllers/rabbitmqcluster_controller_test.go index 9e710d003..087670b8e 100644 --- a/controllers/rabbitmqcluster_controller_test.go +++ b/controllers/rabbitmqcluster_controller_test.go @@ -17,6 +17,7 @@ import ( "k8s.io/utils/ptr" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" . "github.com/onsi/ginkgo/v2" @@ -30,7 +31,6 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" k8sresource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -60,18 +60,10 @@ var _ = Describe("RabbitmqClusterController", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - Eventually(func() bool { - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, cluster) - return apierrors.IsNotFound(err) - }, 5).Should(BeTrue()) - }) - It("works", func() { By("populating the image spec with the default image", func() { fetchedCluster := &rabbitmqv1beta1.RabbitmqCluster{} - Expect(client.Get(ctx, types.NamespacedName{Name: "rabbitmq-one", Namespace: defaultNamespace}, fetchedCluster)).To(Succeed()) + Expect(client.Get(ctx, runtimeClient.ObjectKeyFromObject(cluster), fetchedCluster)).To(Succeed()) Expect(fetchedCluster.Spec.Image).To(Equal(defaultRabbitmqImage)) }) @@ -81,7 +73,7 @@ var _ = Describe("RabbitmqClusterController", func() { Expect(sts.Name).To(Equal(cluster.ChildResourceName("server"))) - Expect(len(sts.Spec.VolumeClaimTemplates)).To(Equal(1)) + Expect(sts.Spec.VolumeClaimTemplates).To(HaveLen(1)) Expect(sts.Spec.VolumeClaimTemplates[0].Spec.StorageClassName).To(BeNil()) }) @@ -199,10 +191,6 @@ var _ = Describe("RabbitmqClusterController", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - }) - It("adds annotations to child resources", func() { headlessSvc := service(ctx, cluster, "nodes") Expect(headlessSvc.Annotations).Should(HaveKeyWithValue("my-annotation", "this-annotation")) @@ -234,10 +222,6 @@ var _ = Describe("RabbitmqClusterController", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - }) - It("applies the Vault configuration", func() { By("not exposing DefaultUser or its Binding as status") Expect(cluster).NotTo(BeNil()) @@ -246,7 +230,7 @@ var _ = Describe("RabbitmqClusterController", func() { Expect(cluster.Status.Binding).To(BeNil()) By("setting the default user updater image to the controller default") fetchedCluster := &rabbitmqv1beta1.RabbitmqCluster{} - Expect(client.Get(ctx, types.NamespacedName{Name: "rabbitmq-vault", Namespace: defaultNamespace}, fetchedCluster)).To(Succeed()) + Expect(client.Get(ctx, runtimeClient.ObjectKeyFromObject(cluster), fetchedCluster)).To(Succeed()) Expect(fetchedCluster.Spec.SecretBackend.Vault.DefaultUserUpdaterImage).To(PointTo(Equal(defaultUserUpdaterImage))) }) }) @@ -267,10 +251,6 @@ var _ = Describe("RabbitmqClusterController", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - }) - It("configures the imagePullSecret on sts correctly", func() { By("using the instance spec secret", func() { sts := statefulSet(ctx, cluster) @@ -307,10 +287,6 @@ var _ = Describe("RabbitmqClusterController", func() { Expect(client.Create(ctx, cluster)).To(Succeed()) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - }) - It("adds the affinity rules to pod spec", func() { sts := statefulSet(ctx, cluster) podSpecAffinity := sts.Spec.Template.Spec.Affinity @@ -319,11 +295,6 @@ var _ = Describe("RabbitmqClusterController", func() { }) Context("Service configurations", func() { - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - Expect(clientSet.CoreV1().Services(cluster.Namespace).Delete(ctx, cluster.ChildResourceName(""), metav1.DeleteOptions{})) - }) - It("creates the service type and annotations as configured in instance spec", func() { cluster = &rabbitmqv1beta1.RabbitmqCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -360,10 +331,6 @@ var _ = Describe("RabbitmqClusterController", func() { }) Context("Resource requirements configurations", func() { - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - }) - It("uses resource requirements from instance spec when provided", func() { cluster = &rabbitmqv1beta1.RabbitmqCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -400,10 +367,6 @@ var _ = Describe("RabbitmqClusterController", func() { }) Context("Persistence configurations", func() { - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - }) - It("creates the RabbitmqCluster with the specified storage from instance spec", func() { cluster = &rabbitmqv1beta1.RabbitmqCluster{ ObjectMeta: metav1.ObjectMeta{ @@ -419,18 +382,18 @@ var _ = Describe("RabbitmqClusterController", func() { sts := statefulSet(ctx, cluster) - Expect(len(sts.Spec.VolumeClaimTemplates)).To(Equal(1)) + Expect(sts.Spec.VolumeClaimTemplates).To(HaveLen(1)) Expect(*sts.Spec.VolumeClaimTemplates[0].Spec.StorageClassName).To(Equal("my-storage-class")) actualStorageCapacity := sts.Spec.VolumeClaimTemplates[0].Spec.Resources.Requests[corev1.ResourceStorage] Expect(actualStorageCapacity).To(Equal(k8sresource.MustParse("100Gi"))) }) }) - Context("Custom Resource updates", func() { + Context("Custom Resource updates", FlakeAttempts(3), func() { BeforeEach(func() { cluster = &rabbitmqv1beta1.RabbitmqCluster{ ObjectMeta: metav1.ObjectMeta{ - Name: "rabbitmq-cr-update", + Name: fmt.Sprintf("cr-update-%d-%d", GinkgoParallelProcess(), time.Now().Unix()), Namespace: defaultNamespace, }, } @@ -439,11 +402,6 @@ var _ = Describe("RabbitmqClusterController", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - waitForClusterDeletion(ctx, cluster, client) - }) - It("the service annotations are updated", func() { Expect(updateWithRetry(cluster, func(r *rabbitmqv1beta1.RabbitmqCluster) { r.Spec.Service.Annotations = map[string]string{"test-key": "test-value"} @@ -488,8 +446,12 @@ var _ = Describe("RabbitmqClusterController", func() { Expect(resourceRequirements.Limits).To(HaveKeyWithValue(corev1.ResourceMemory, expectedRequirements.Limits[corev1.ResourceMemory])) // verify that SuccessfulUpdate event is recorded for the StatefulSet - Expect(aggregateEventMsgs(ctx, cluster, "SuccessfulUpdate")).To( - ContainSubstring("updated resource %s of Type *v1.StatefulSet", cluster.ChildResourceName("server"))) + Eventually(func() string { + return aggregateEventMsgs(ctx, cluster, "SuccessfulUpdate") + }). + Within(5 * time.Second). + WithPolling(time.Second). + Should(ContainSubstring("updated resource %s of Type *v1.StatefulSet", cluster.ChildResourceName("server"))) }) It("the rabbitmq image is updated", func() { @@ -863,11 +825,6 @@ var _ = Describe("RabbitmqClusterController", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - waitForClusterDeletion(ctx, cluster, client) - }) - It("creates a StatefulSet with the override applied", func() { sts := statefulSet(ctx, cluster) myStorage := k8sresource.MustParse("100Gi") @@ -885,7 +842,7 @@ var _ = Describe("RabbitmqClusterController", func() { "app.kubernetes.io/name": "rabbitmq-sts-override" + suffix, })) - Expect(len(sts.Spec.VolumeClaimTemplates)).To(Equal(2)) + Expect(sts.Spec.VolumeClaimTemplates).To(HaveLen(2)) Expect(sts.Spec.VolumeClaimTemplates[0].ObjectMeta.Name).To(Equal("persistence")) Expect(sts.Spec.VolumeClaimTemplates[0].ObjectMeta.Namespace).To(Equal("default")) @@ -1077,11 +1034,13 @@ var _ = Describe("RabbitmqClusterController", func() { }) Context("Service Override", func() { - + var clusterName string BeforeEach(func() { + suffix = fmt.Sprintf("-%d", time.Now().UnixNano()) + clusterName = "svc-override" + suffix cluster = &rabbitmqv1beta1.RabbitmqCluster{ ObjectMeta: metav1.ObjectMeta{ - Name: "svc-override", + Name: clusterName, Namespace: defaultNamespace, }, Spec: rabbitmqv1beta1.RabbitmqClusterSpec{ @@ -1114,11 +1073,6 @@ var _ = Describe("RabbitmqClusterController", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - waitForClusterDeletion(ctx, cluster, client) - }) - It("creates a Service with the override applied", func() { amqpTargetPort := intstr.IntOrString{IntVal: int32(5672)} managementTargetPort := intstr.IntOrString{IntVal: int32(15672)} @@ -1155,7 +1109,7 @@ var _ = Describe("RabbitmqClusterController", func() { TargetPort: additionalTargetPort, }, )) - Expect(svc.Spec.Selector).To(Equal(map[string]string{"a-selector": "a-label", "app.kubernetes.io/name": "svc-override"})) + Expect(svc.Spec.Selector).To(Equal(map[string]string{"a-selector": "a-label", "app.kubernetes.io/name": clusterName})) Expect(svc.Spec.SessionAffinity).To(Equal(corev1.ServiceAffinityClientIP)) Expect(svc.Spec.PublishNotReadyAddresses).To(BeFalse()) }) @@ -1184,10 +1138,6 @@ var _ = Describe("RabbitmqClusterController", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - }) - It("works", func() { By("skipping reconciling if label is set to true", func() { Expect(updateWithRetry(cluster, func(r *rabbitmqv1beta1.RabbitmqCluster) { @@ -1362,7 +1312,7 @@ func waitForClusterDeletion(ctx context.Context, rabbitmqCluster *rabbitmqv1beta &rabbitmqClusterCreated, ) return apierrors.IsNotFound(err) - }, ClusterDeletionTimeout, 1*time.Second).Should(BeTrue()) + }, ClusterDeletionTimeout, 1*time.Second).Should(BeTrue(), "expected to delete cluster '%s' but it still exists", rabbitmqCluster.Name) } diff --git a/controllers/reconcile_cli_test.go b/controllers/reconcile_cli_test.go index 9d8db1229..eb25a3321 100644 --- a/controllers/reconcile_cli_test.go +++ b/controllers/reconcile_cli_test.go @@ -1,9 +1,11 @@ package controllers_test import ( - "sigs.k8s.io/controller-runtime/pkg/envtest/komega" + "fmt" "time" + "sigs.k8s.io/controller-runtime/pkg/envtest/komega" + "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" @@ -21,11 +23,6 @@ var _ = Describe("Reconcile CLI", func() { defaultNamespace = "default" ) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - waitForClusterDeletion(ctx, cluster, client) - }) - When("cluster is created", func() { var sts *appsv1.StatefulSet BeforeEach(func() { @@ -62,10 +59,19 @@ var _ = Describe("Reconcile CLI", func() { }) When("the cluster is configured to run post-deploy steps", func() { + const ( + rmqNamePrefix = "rabbitmq-three" + ) + + var ( + rmqName string + ) + BeforeEach(func() { + rmqName = fmt.Sprintf("%s-%d", rmqNamePrefix, time.Now().Unix()) cluster = &rabbitmqv1beta1.RabbitmqCluster{ ObjectMeta: metav1.ObjectMeta{ - Name: "rabbitmq-three", + Name: rmqName, Namespace: defaultNamespace, }, Spec: rabbitmqv1beta1.RabbitmqClusterSpec{ @@ -82,6 +88,8 @@ var _ = Describe("Reconcile CLI", func() { BeforeEach(func() { sts = statefulSet(ctx, cluster) sts.Status.Replicas = 3 + sts.Status.AvailableReplicas = 2 + sts.Status.ReadyReplicas = 2 sts.Status.CurrentReplicas = 2 sts.Status.CurrentRevision = "some-old-revision" sts.Status.UpdatedReplicas = 1 @@ -95,7 +103,7 @@ var _ = Describe("Reconcile CLI", func() { By("setting an annotation on the CR", func() { rmq := &rabbitmqv1beta1.RabbitmqCluster{} - rmq.Name = "rabbitmq-three" + rmq.Name = rmqName rmq.Namespace = defaultNamespace Eventually(k.Object(rmq)).Within(time.Second * 5).WithPolling(time.Second).Should(HaveField("ObjectMeta.Annotations", HaveKey("rabbitmq.com/queueRebalanceNeededAt"))) @@ -111,11 +119,12 @@ var _ = Describe("Reconcile CLI", func() { sts.Status.UpdatedReplicas = 3 sts.Status.UpdateRevision = "some-new-revision" sts.Status.ReadyReplicas = 2 + sts.Status.AvailableReplicas = 2 })).Should(Succeed()) // by not removing the annotation rmq := &rabbitmqv1beta1.RabbitmqCluster{} - rmq.Name = "rabbitmq-three" + rmq.Name = rmqName rmq.Namespace = defaultNamespace Eventually(k.Object(rmq)).Within(time.Second * 5).WithPolling(time.Second).Should(HaveField("ObjectMeta.Annotations", HaveKey("rabbitmq.com/queueRebalanceNeededAt"))) @@ -129,11 +138,12 @@ var _ = Describe("Reconcile CLI", func() { By("removing the annotation once all Pods are up, and triggering the queue rebalance", func() { // setup transition to all pods ready sts.Status.ReadyReplicas = 3 + sts.Status.AvailableReplicas = 3 Expect(client.Status().Update(ctx, sts)).To(Succeed()) // by not having the annotation rmq := &rabbitmqv1beta1.RabbitmqCluster{} - rmq.Name = "rabbitmq-three" + rmq.Name = rmqName rmq.Namespace = defaultNamespace Eventually(k.Object(rmq)).Within(time.Second * 5).WithPolling(time.Second).ShouldNot(HaveField("ObjectMeta.Annotations", HaveKey("rabbitmq.com/queueRebalanceNeededAt"))) @@ -238,7 +248,7 @@ var _ = Describe("Reconcile CLI", func() { Consistently(func() map[string]string { rmq := &rabbitmqv1beta1.RabbitmqCluster{} err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - Expect(err).To(BeNil()) + Expect(err).ToNot(HaveOccurred()) return rmq.ObjectMeta.Annotations }, 5).ShouldNot(HaveKey("rabbitmq.com/queueRebalanceNeededAt")) }) @@ -253,7 +263,7 @@ var _ = Describe("Reconcile CLI", func() { Consistently(func() map[string]string { rmq := &rabbitmqv1beta1.RabbitmqCluster{} err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - Expect(err).To(BeNil()) + Expect(err).ToNot(HaveOccurred()) return rmq.ObjectMeta.Annotations }, 5).ShouldNot(HaveKey("rabbitmq.com/queueRebalanceNeededAt")) Expect(fakeExecutor.ExecutedCommands()).NotTo(ContainElement(command{"sh", "-c", "rabbitmq-queues rebalance all"})) @@ -297,7 +307,7 @@ var _ = Describe("Reconcile CLI", func() { Consistently(func() map[string]string { rmq := &rabbitmqv1beta1.RabbitmqCluster{} err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - Expect(err).To(BeNil()) + Expect(err).ToNot(HaveOccurred()) return rmq.ObjectMeta.Annotations }, 5).ShouldNot(HaveKey("rabbitmq.com/queueRebalanceNeededAt")) }) @@ -312,7 +322,7 @@ var _ = Describe("Reconcile CLI", func() { Consistently(func() map[string]string { rmq := &rabbitmqv1beta1.RabbitmqCluster{} err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - Expect(err).To(BeNil()) + Expect(err).ToNot(HaveOccurred()) return rmq.ObjectMeta.Annotations }, 5).ShouldNot(HaveKey("rabbitmq.com/queueRebalanceNeededAt")) Expect(fakeExecutor.ExecutedCommands()).NotTo(ContainElement(command{"sh", "-c", "rabbitmq-queues rebalance all"})) diff --git a/controllers/reconcile_finalizer_test.go b/controllers/reconcile_finalizer_test.go index 320e6db44..fcdf48a38 100644 --- a/controllers/reconcile_finalizer_test.go +++ b/controllers/reconcile_finalizer_test.go @@ -7,7 +7,7 @@ import ( . "github.com/onsi/gomega" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" + k8sclient "sigs.k8s.io/controller-runtime/pkg/client" ) var _ = Describe("Reconcile finalizer", func() { @@ -31,7 +31,7 @@ var _ = Describe("Reconcile finalizer", func() { It("adds the deletion finalizer", func() { rmq := &rabbitmqv1beta1.RabbitmqCluster{} Eventually(func() string { - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) + err := client.Get(ctx, k8sclient.ObjectKeyFromObject(cluster), rmq) if err != nil { return "" } diff --git a/controllers/reconcile_no_persistence_test.go b/controllers/reconcile_no_persistence_test.go index efc90c7f4..2fc8bc543 100644 --- a/controllers/reconcile_no_persistence_test.go +++ b/controllers/reconcile_no_persistence_test.go @@ -9,10 +9,8 @@ import ( rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/v2/api/v1beta1" "github.com/rabbitmq/cluster-operator/v2/internal/status" v1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" k8sresource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -42,15 +40,6 @@ var _ = Describe("Persistence", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - Eventually(func() bool { - rmq := &rabbitmqv1beta1.RabbitmqCluster{} - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - return apierrors.IsNotFound(err) - }, 5).Should(BeTrue()) - }) - It("does not allow changing the capcity from zero (no persistence)", func() { By("failing a statefulSet update", func() { Expect(updateWithRetry(cluster, func(r *rabbitmqv1beta1.RabbitmqCluster) { @@ -72,10 +61,7 @@ var _ = Describe("Persistence", func() { By("setting ReconcileSuccess to 'false' with failed reason and message", func() { Eventually(func() string { rabbit := &rabbitmqv1beta1.RabbitmqCluster{} - Expect(client.Get(ctx, runtimeClient.ObjectKey{ - Name: cluster.Name, - Namespace: defaultNamespace, - }, rabbit)).To(Succeed()) + Expect(client.Get(ctx, runtimeClient.ObjectKeyFromObject(cluster), rabbit)).To(Succeed()) for i := range rabbit.Status.Conditions { if rabbit.Status.Conditions[i].Type == status.ReconcileSuccess { diff --git a/controllers/reconcile_operator_defaults_test.go b/controllers/reconcile_operator_defaults_test.go index 7c233b7d8..8a5c56f44 100644 --- a/controllers/reconcile_operator_defaults_test.go +++ b/controllers/reconcile_operator_defaults_test.go @@ -7,7 +7,7 @@ import ( rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/v2/api/v1beta1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" + k8sclient "sigs.k8s.io/controller-runtime/pkg/client" ) var _ = Describe("ReconcileOperatorDefaults", func() { @@ -32,13 +32,9 @@ var _ = Describe("ReconcileOperatorDefaults", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - }) - It("handles operator defaults correctly", func() { fetchedCluster := &rabbitmqv1beta1.RabbitmqCluster{} - Expect(client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, fetchedCluster)).To(Succeed()) + Expect(client.Get(ctx, k8sclient.ObjectKeyFromObject(cluster), fetchedCluster)).To(Succeed()) By("setting the image spec with the default image") Expect(fetchedCluster.Spec.Image).To(Equal(defaultRabbitmqImage)) diff --git a/controllers/reconcile_persistence_test.go b/controllers/reconcile_persistence_test.go index 26c627e69..a28e6e6a1 100644 --- a/controllers/reconcile_persistence_test.go +++ b/controllers/reconcile_persistence_test.go @@ -9,10 +9,8 @@ import ( rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/v2/api/v1beta1" "github.com/rabbitmq/cluster-operator/v2/internal/status" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" k8sresource "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -38,15 +36,6 @@ var _ = Describe("Persistence", func() { waitForClusterCreation(ctx, cluster, client) }) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - Eventually(func() bool { - rmq := &rabbitmqv1beta1.RabbitmqCluster{} - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - return apierrors.IsNotFound(err) - }, 5).Should(BeTrue()) - }) - It("does not allow PVC shrink", func() { By("not updating statefulSet volume claim storage capacity", func() { tenG := k8sresource.MustParse("10Gi") diff --git a/controllers/reconcile_scale_down_test.go b/controllers/reconcile_scale_down_test.go index bb2d2892a..499767b83 100644 --- a/controllers/reconcile_scale_down_test.go +++ b/controllers/reconcile_scale_down_test.go @@ -8,9 +8,7 @@ import ( . "github.com/onsi/gomega" rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/v2/api/v1beta1" "github.com/rabbitmq/cluster-operator/v2/internal/status" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -22,15 +20,6 @@ var _ = Describe("Cluster scale down", func() { ctx = context.Background() ) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - Eventually(func() bool { - rmq := &rabbitmqv1beta1.RabbitmqCluster{} - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - return apierrors.IsNotFound(err) - }, 5).Should(BeTrue()) - }) - It("does not allow cluster scale down", func() { By("not updating statefulSet replicas", func() { cluster = &rabbitmqv1beta1.RabbitmqCluster{ diff --git a/controllers/reconcile_scale_zero_test.go b/controllers/reconcile_scale_zero_test.go index 6bed247a0..4bd14597d 100644 --- a/controllers/reconcile_scale_zero_test.go +++ b/controllers/reconcile_scale_zero_test.go @@ -8,9 +8,7 @@ import ( . "github.com/onsi/gomega" rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/v2/api/v1beta1" "github.com/rabbitmq/cluster-operator/v2/internal/status" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" "k8s.io/utils/ptr" runtimeClient "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -22,16 +20,6 @@ var _ = Describe("Cluster scale to zero", func() { ctx = context.Background() ) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - waitForClusterDeletion(ctx, cluster, client) - Eventually(func() bool { - rmq := &rabbitmqv1beta1.RabbitmqCluster{} - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - return apierrors.IsNotFound(err) - }).Should(BeTrue()) - }) - It("scale to zero", func() { By("update statefulSet replicas to zero", func() { cluster = &rabbitmqv1beta1.RabbitmqCluster{ @@ -90,16 +78,6 @@ var _ = Describe("Cluster scale from zero", func() { ctx = context.Background() ) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - waitForClusterDeletion(ctx, cluster, client) - Eventually(func() bool { - rmq := &rabbitmqv1beta1.RabbitmqCluster{} - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - return apierrors.IsNotFound(err) - }).Should(BeTrue()) - }) - It("scale from zero", func() { By("update statefulSet replicas from zero", func() { cluster = &rabbitmqv1beta1.RabbitmqCluster{ @@ -161,16 +139,6 @@ var _ = Describe("Cluster scale from zero to less replicas configured", Ordered, ctx = context.Background() ) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - waitForClusterDeletion(ctx, cluster, client) - Eventually(func() bool { - rmq := &rabbitmqv1beta1.RabbitmqCluster{} - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - return apierrors.IsNotFound(err) - }).Should(BeTrue()) - }) - It("scale from zero to less replicas", func() { By("update statefulSet replicas from zero", func() { cluster = &rabbitmqv1beta1.RabbitmqCluster{ diff --git a/controllers/reconcile_status_test.go b/controllers/reconcile_status_test.go index a5a9d9aa1..44f185ea9 100644 --- a/controllers/reconcile_status_test.go +++ b/controllers/reconcile_status_test.go @@ -4,7 +4,6 @@ import ( rabbitmqv1beta1 "github.com/rabbitmq/cluster-operator/v2/api/v1beta1" "github.com/rabbitmq/cluster-operator/v2/internal/resource" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/types" . "github.com/onsi/ginkgo/v2" @@ -19,15 +18,6 @@ var _ = Describe("Reconcile status", func() { defaultNamespace = "default" ) - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - Eventually(func() bool { - rmq := &rabbitmqv1beta1.RabbitmqCluster{} - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - return apierrors.IsNotFound(err) - }, 5).Should(BeTrue()) - }) - It("reconciles the custom resource status", func() { cluster = &rabbitmqv1beta1.RabbitmqCluster{ ObjectMeta: metav1.ObjectMeta{ diff --git a/controllers/reconcile_tls_test.go b/controllers/reconcile_tls_test.go index c80f8179c..9e0fb7159 100644 --- a/controllers/reconcile_tls_test.go +++ b/controllers/reconcile_tls_test.go @@ -17,7 +17,6 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" ) var _ = Describe("Reconcile TLS", func() { @@ -27,21 +26,14 @@ var _ = Describe("Reconcile TLS", func() { ctx = context.Background() ) Context("Mutual TLS", func() { - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - Eventually(func() bool { - rmq := &rabbitmqv1beta1.RabbitmqCluster{} - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - return apierrors.IsNotFound(err) - }, 10).Should(BeTrue()) - }) - Context("Mutual TLS with single secret", func() { + const tlsSecretName = "tls-secret-success" + It("Deploys successfully", func() { - tlsSecretWithCACert(ctx, "tls-secret", defaultNamespace) + tlsSecretWithCACert(ctx, tlsSecretName, defaultNamespace) tlsSpec := rabbitmqv1beta1.TLSSpec{ - SecretName: "tls-secret", - CaSecretName: "tls-secret", + SecretName: tlsSecretName, + CaSecretName: tlsSecretName, } cluster = rabbitmqClusterWithTLS(ctx, "mutual-tls-success", defaultNamespace, tlsSpec) waitForClusterCreation(ctx, cluster, client) @@ -57,7 +49,7 @@ var _ = Describe("Reconcile TLS", func() { { Secret: &corev1.SecretProjection{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + Name: tlsSecretName, }, Optional: ptr.To(true), Items: []corev1.KeyToPath{ @@ -69,7 +61,7 @@ var _ = Describe("Reconcile TLS", func() { { Secret: &corev1.SecretProjection{ LocalObjectReference: corev1.LocalObjectReference{ - Name: "tls-secret", + Name: tlsSecretName, }, Optional: ptr.To(true), Items: []corev1.KeyToPath{{Key: "ca.crt", Path: "ca.crt"}}, @@ -161,15 +153,6 @@ var _ = Describe("Reconcile TLS", func() { }) Context("TLS set on the instance", func() { - AfterEach(func() { - Expect(client.Delete(ctx, cluster)).To(Succeed()) - Eventually(func() bool { - rmq := &rabbitmqv1beta1.RabbitmqCluster{} - err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, rmq) - return apierrors.IsNotFound(err) - }, 5).Should(BeTrue()) - }) - BeforeEach(func() { tlsSecretWithoutCACert(ctx, "tls-secret", defaultNamespace) }) @@ -262,11 +245,8 @@ var _ = Describe("Reconcile TLS", func() { func verifyReconcileSuccessFalse(name, namespace string) bool { return EventuallyWithOffset(1, func() string { - rabbit := &rabbitmqv1beta1.RabbitmqCluster{} - Expect(client.Get(ctx, runtimeClient.ObjectKey{ - Name: name, - Namespace: namespace, - }, rabbit)).To(Succeed()) + rabbit := &rabbitmqv1beta1.RabbitmqCluster{ObjectMeta: metav1.ObjectMeta{Name: name, Namespace: namespace}} + Expect(client.Get(ctx, runtimeClient.ObjectKeyFromObject(rabbit), rabbit)).To(Succeed()) for i := range rabbit.Status.Conditions { if rabbit.Status.Conditions[i].Type == status.ReconcileSuccess { diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 2d02d944d..f2f42abb1 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -12,6 +12,7 @@ package controllers_test import ( "context" + "fmt" "path/filepath" "testing" @@ -73,6 +74,9 @@ var _ = BeforeSuite(func() { By("bootstrapping test environment") testEnv = &envtest.Environment{ CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, + Config: &rest.Config{ + Host: fmt.Sprintf("http://localhost:218%d", GinkgoParallelProcess()), + }, } cfg, err := testEnv.Start() diff --git a/go.mod b/go.mod index 08c1e5218..97e85c705 100644 --- a/go.mod +++ b/go.mod @@ -132,6 +132,7 @@ require ( github.com/prometheus/common v0.66.1 // indirect github.com/prometheus/procfs v0.17.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/rubenv/sql-migrate v1.8.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect diff --git a/go.sum b/go.sum index fbaee72ab..11468b365 100644 --- a/go.sum +++ b/go.sum @@ -439,8 +439,8 @@ github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRl github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= -github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= -github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rubenv/sql-migrate v1.8.0 h1:dXnYiJk9k3wetp7GfQbKJcPHjVJL6YK19tKj8t2Ns0o= github.com/rubenv/sql-migrate v1.8.0/go.mod h1:F2bGFBwCU+pnmbtNYDeKvSuvL6lBVtXDXUUv5t+u1qw= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= diff --git a/internal/resource/erlang_cookie_test.go b/internal/resource/erlang_cookie_test.go index d78ba008c..bfc4741ce 100644 --- a/internal/resource/erlang_cookie_test.go +++ b/internal/resource/erlang_cookie_test.go @@ -67,7 +67,7 @@ var _ = Describe("ErlangCookie", func() { It("creates an erlang cookie that is base64 encoded and 24 characters", func() { cookie, ok := secret.Data[".erlang.cookie"] - Expect(ok).NotTo(BeFalse()) + Expect(ok).To(BeTrue()) decodedCookie, err := b64.URLEncoding.DecodeString(string(cookie)) Expect(err).NotTo(HaveOccurred()) Expect(decodedCookie).To(HaveLen(24)) diff --git a/internal/resource/statefulset_test.go b/internal/resource/statefulset_test.go index c3cc885a1..efe68cd38 100644 --- a/internal/resource/statefulset_test.go +++ b/internal/resource/statefulset_test.go @@ -266,7 +266,7 @@ var _ = Describe("StatefulSet", func() { stsBuilder := builder.StatefulSet() Expect(stsBuilder.Update(statefulSet)).To(Succeed()) - Expect(len(statefulSet.OwnerReferences)).To(Equal(1)) + Expect(statefulSet.OwnerReferences).To(HaveLen(1)) Expect(statefulSet.OwnerReferences[0].Name).To(Equal(builder.Instance.Name)) }) @@ -1496,8 +1496,8 @@ default_pass = {{ .Data.data.password }} Expect(stsBuilder.Update(statefulSet)).To(Succeed()) container := extractContainer(statefulSet.Spec.Template.Spec.Containers, "rabbitmq") - Expect(len(container.Resources.Requests)).To(Equal(0)) - Expect(len(container.Resources.Limits)).To(Equal(0)) + Expect(container.Resources.Requests).To(BeEmpty()) + Expect(container.Resources.Limits).To(BeEmpty()) }) }) diff --git a/system_tests/utils_test.go b/system_tests/utils_test.go index a90310cee..fe11322cd 100644 --- a/system_tests/utils_test.go +++ b/system_tests/utils_test.go @@ -502,7 +502,7 @@ func kubernetesNodeIp(ctx context.Context, clientSet *kubernetes.Clientset) stri nodes, err := clientSet.CoreV1().Nodes().List(ctx, metav1.ListOptions{}) ExpectWithOffset(1, err).NotTo(HaveOccurred()) ExpectWithOffset(1, nodes).ToNot(BeNil()) - ExpectWithOffset(1, len(nodes.Items)).To(BeNumerically(">", 0)) + ExpectWithOffset(1, nodes.Items).ToNot(BeEmpty()) var nodeIp string for _, address := range nodes.Items[0].Status.Addresses {