Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 $@
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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"
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta1/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
package v1beta1

import (
"fmt"
"path/filepath"
"testing"

Expand Down Expand Up @@ -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)
Expand Down
90 changes: 20 additions & 70 deletions controllers/rabbitmqcluster_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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"
)

Expand Down Expand Up @@ -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))
})

Expand All @@ -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())
})

Expand Down Expand Up @@ -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"))
Expand Down Expand Up @@ -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())
Expand All @@ -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)))
})
})
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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{
Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -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{
Expand All @@ -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,
},
}
Expand All @@ -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"}
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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")
Expand All @@ -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"))
Expand Down Expand Up @@ -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{
Expand Down Expand Up @@ -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)}
Expand Down Expand Up @@ -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())
})
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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)

}

Expand Down
Loading