Skip to content

Commit 25fa179

Browse files
authored
Merge pull request #1942 from rabbitmq/parallel-integration-suite
Make unit and integration tests run in parallel
2 parents 01d088f + ec27bfa commit 25fa179

18 files changed

+79
-211
lines changed

Makefile

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ __check_defined = \
2727
###
2828

2929
# The latest 1.25 available for envtest
30-
ENVTEST_K8S_VERSION ?= 1.26.1
30+
ENVTEST_K8S_VERSION ?= 1.29.5
3131
LOCAL_TESTBIN = $(CURDIR)/testbin
3232
$(LOCAL_TESTBIN):
3333
mkdir -p $@
@@ -66,10 +66,11 @@ unit-tests::manifests
6666
unit-tests::just-unit-tests ## Run unit tests
6767

6868
GINKGO ?= go run github.com/onsi/ginkgo/v2/ginkgo
69+
GINKGO_PROCS ?= 4
6970

7071
.PHONY: just-unit-tests
7172
just-unit-tests:
72-
$(GINKGO) -r --randomize-all api/ internal/ pkg/
73+
$(GINKGO) -r -p --randomize-all --fail-on-pending --procs=$(GINKGO_PROCS) $(GINKGO_EXTRA) api/ internal/ pkg/
7374

7475
.PHONY: integration-tests
7576
integration-tests::install-tools
@@ -83,7 +84,7 @@ integration-tests::just-integration-tests ## Run integration tests
8384

8485
.PHONY: just-integration-tests
8586
just-integration-tests:
86-
$(GINKGO) -r controllers/
87+
$(GINKGO) -r -p --fail-on-pending --randomize-all --procs=$(GINKGO_PROCS) $(GINKGO_EXTRA) controllers/
8788

8889
manifests: install-tools ## Generate manifests e.g. CRD, RBAC etc.
8990
controller-gen crd rbac:roleName=operator-role paths="./api/...;./controllers/..." output:crd:artifacts:config=config/crd/bases
@@ -236,7 +237,7 @@ cert-manager-rm:
236237
kubectl delete -f https://github.com/cert-manager/cert-manager/releases/download/v$(CERT_MANAGER_VERSION)/cert-manager.yaml --ignore-not-found
237238

238239
system-tests: install-tools ## Run end-to-end tests against Kubernetes cluster defined in ~/.kube/config
239-
NAMESPACE="$(SYSTEM_TEST_NAMESPACE)" K8S_OPERATOR_NAMESPACE="$(K8S_OPERATOR_NAMESPACE)" $(GINKGO) -nodes=3 --randomize-all -r system_tests/
240+
NAMESPACE="$(SYSTEM_TEST_NAMESPACE)" K8S_OPERATOR_NAMESPACE="$(K8S_OPERATOR_NAMESPACE)" $(GINKGO) -nodes=3 --randomize-all -r $(GINKGO_EXTRA) system_tests/
240241

241242
kubectl-plugin-tests: ## Run kubectl-rabbitmq tests
242243
@echo "running kubectl plugin tests"

api/v1beta1/suite_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
package v1beta1
1010

1111
import (
12+
"fmt"
1213
"path/filepath"
1314
"testing"
1415

@@ -41,6 +42,9 @@ var _ = BeforeSuite(func() {
4142
By("bootstrapping test environment")
4243
testEnv = &envtest.Environment{
4344
CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")},
45+
Config: &rest.Config{
46+
Host: fmt.Sprintf("http://localhost:218%d", GinkgoParallelProcess()),
47+
},
4448
}
4549

4650
err := SchemeBuilder.AddToScheme(scheme.Scheme)

controllers/rabbitmqcluster_controller_test.go

Lines changed: 20 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717

1818
"k8s.io/utils/ptr"
1919

20+
"k8s.io/apimachinery/pkg/types"
2021
"k8s.io/apimachinery/pkg/util/intstr"
2122

2223
. "github.com/onsi/ginkgo/v2"
@@ -30,7 +31,6 @@ import (
3031
apierrors "k8s.io/apimachinery/pkg/api/errors"
3132
k8sresource "k8s.io/apimachinery/pkg/api/resource"
3233
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
33-
"k8s.io/apimachinery/pkg/types"
3434
runtimeClient "sigs.k8s.io/controller-runtime/pkg/client"
3535
)
3636

@@ -60,18 +60,10 @@ var _ = Describe("RabbitmqClusterController", func() {
6060
waitForClusterCreation(ctx, cluster, client)
6161
})
6262

63-
AfterEach(func() {
64-
Expect(client.Delete(ctx, cluster)).To(Succeed())
65-
Eventually(func() bool {
66-
err := client.Get(ctx, types.NamespacedName{Name: cluster.Name, Namespace: cluster.Namespace}, cluster)
67-
return apierrors.IsNotFound(err)
68-
}, 5).Should(BeTrue())
69-
})
70-
7163
It("works", func() {
7264
By("populating the image spec with the default image", func() {
7365
fetchedCluster := &rabbitmqv1beta1.RabbitmqCluster{}
74-
Expect(client.Get(ctx, types.NamespacedName{Name: "rabbitmq-one", Namespace: defaultNamespace}, fetchedCluster)).To(Succeed())
66+
Expect(client.Get(ctx, runtimeClient.ObjectKeyFromObject(cluster), fetchedCluster)).To(Succeed())
7567
Expect(fetchedCluster.Spec.Image).To(Equal(defaultRabbitmqImage))
7668
})
7769

@@ -81,7 +73,7 @@ var _ = Describe("RabbitmqClusterController", func() {
8173

8274
Expect(sts.Name).To(Equal(cluster.ChildResourceName("server")))
8375

84-
Expect(len(sts.Spec.VolumeClaimTemplates)).To(Equal(1))
76+
Expect(sts.Spec.VolumeClaimTemplates).To(HaveLen(1))
8577
Expect(sts.Spec.VolumeClaimTemplates[0].Spec.StorageClassName).To(BeNil())
8678
})
8779

@@ -199,10 +191,6 @@ var _ = Describe("RabbitmqClusterController", func() {
199191
waitForClusterCreation(ctx, cluster, client)
200192
})
201193

202-
AfterEach(func() {
203-
Expect(client.Delete(ctx, cluster)).To(Succeed())
204-
})
205-
206194
It("adds annotations to child resources", func() {
207195
headlessSvc := service(ctx, cluster, "nodes")
208196
Expect(headlessSvc.Annotations).Should(HaveKeyWithValue("my-annotation", "this-annotation"))
@@ -234,10 +222,6 @@ var _ = Describe("RabbitmqClusterController", func() {
234222
waitForClusterCreation(ctx, cluster, client)
235223
})
236224

237-
AfterEach(func() {
238-
Expect(client.Delete(ctx, cluster)).To(Succeed())
239-
})
240-
241225
It("applies the Vault configuration", func() {
242226
By("not exposing DefaultUser or its Binding as status")
243227
Expect(cluster).NotTo(BeNil())
@@ -246,7 +230,7 @@ var _ = Describe("RabbitmqClusterController", func() {
246230
Expect(cluster.Status.Binding).To(BeNil())
247231
By("setting the default user updater image to the controller default")
248232
fetchedCluster := &rabbitmqv1beta1.RabbitmqCluster{}
249-
Expect(client.Get(ctx, types.NamespacedName{Name: "rabbitmq-vault", Namespace: defaultNamespace}, fetchedCluster)).To(Succeed())
233+
Expect(client.Get(ctx, runtimeClient.ObjectKeyFromObject(cluster), fetchedCluster)).To(Succeed())
250234
Expect(fetchedCluster.Spec.SecretBackend.Vault.DefaultUserUpdaterImage).To(PointTo(Equal(defaultUserUpdaterImage)))
251235
})
252236
})
@@ -267,10 +251,6 @@ var _ = Describe("RabbitmqClusterController", func() {
267251
waitForClusterCreation(ctx, cluster, client)
268252
})
269253

270-
AfterEach(func() {
271-
Expect(client.Delete(ctx, cluster)).To(Succeed())
272-
})
273-
274254
It("configures the imagePullSecret on sts correctly", func() {
275255
By("using the instance spec secret", func() {
276256
sts := statefulSet(ctx, cluster)
@@ -307,10 +287,6 @@ var _ = Describe("RabbitmqClusterController", func() {
307287
Expect(client.Create(ctx, cluster)).To(Succeed())
308288
})
309289

310-
AfterEach(func() {
311-
Expect(client.Delete(ctx, cluster)).To(Succeed())
312-
})
313-
314290
It("adds the affinity rules to pod spec", func() {
315291
sts := statefulSet(ctx, cluster)
316292
podSpecAffinity := sts.Spec.Template.Spec.Affinity
@@ -319,11 +295,6 @@ var _ = Describe("RabbitmqClusterController", func() {
319295
})
320296

321297
Context("Service configurations", func() {
322-
AfterEach(func() {
323-
Expect(client.Delete(ctx, cluster)).To(Succeed())
324-
Expect(clientSet.CoreV1().Services(cluster.Namespace).Delete(ctx, cluster.ChildResourceName(""), metav1.DeleteOptions{}))
325-
})
326-
327298
It("creates the service type and annotations as configured in instance spec", func() {
328299
cluster = &rabbitmqv1beta1.RabbitmqCluster{
329300
ObjectMeta: metav1.ObjectMeta{
@@ -360,10 +331,6 @@ var _ = Describe("RabbitmqClusterController", func() {
360331
})
361332

362333
Context("Resource requirements configurations", func() {
363-
AfterEach(func() {
364-
Expect(client.Delete(ctx, cluster)).To(Succeed())
365-
})
366-
367334
It("uses resource requirements from instance spec when provided", func() {
368335
cluster = &rabbitmqv1beta1.RabbitmqCluster{
369336
ObjectMeta: metav1.ObjectMeta{
@@ -400,10 +367,6 @@ var _ = Describe("RabbitmqClusterController", func() {
400367
})
401368

402369
Context("Persistence configurations", func() {
403-
AfterEach(func() {
404-
Expect(client.Delete(ctx, cluster)).To(Succeed())
405-
})
406-
407370
It("creates the RabbitmqCluster with the specified storage from instance spec", func() {
408371
cluster = &rabbitmqv1beta1.RabbitmqCluster{
409372
ObjectMeta: metav1.ObjectMeta{
@@ -419,18 +382,18 @@ var _ = Describe("RabbitmqClusterController", func() {
419382

420383
sts := statefulSet(ctx, cluster)
421384

422-
Expect(len(sts.Spec.VolumeClaimTemplates)).To(Equal(1))
385+
Expect(sts.Spec.VolumeClaimTemplates).To(HaveLen(1))
423386
Expect(*sts.Spec.VolumeClaimTemplates[0].Spec.StorageClassName).To(Equal("my-storage-class"))
424387
actualStorageCapacity := sts.Spec.VolumeClaimTemplates[0].Spec.Resources.Requests[corev1.ResourceStorage]
425388
Expect(actualStorageCapacity).To(Equal(k8sresource.MustParse("100Gi")))
426389
})
427390
})
428391

429-
Context("Custom Resource updates", func() {
392+
Context("Custom Resource updates", FlakeAttempts(3), func() {
430393
BeforeEach(func() {
431394
cluster = &rabbitmqv1beta1.RabbitmqCluster{
432395
ObjectMeta: metav1.ObjectMeta{
433-
Name: "rabbitmq-cr-update",
396+
Name: fmt.Sprintf("cr-update-%d-%d", GinkgoParallelProcess(), time.Now().Unix()),
434397
Namespace: defaultNamespace,
435398
},
436399
}
@@ -439,11 +402,6 @@ var _ = Describe("RabbitmqClusterController", func() {
439402
waitForClusterCreation(ctx, cluster, client)
440403
})
441404

442-
AfterEach(func() {
443-
Expect(client.Delete(ctx, cluster)).To(Succeed())
444-
waitForClusterDeletion(ctx, cluster, client)
445-
})
446-
447405
It("the service annotations are updated", func() {
448406
Expect(updateWithRetry(cluster, func(r *rabbitmqv1beta1.RabbitmqCluster) {
449407
r.Spec.Service.Annotations = map[string]string{"test-key": "test-value"}
@@ -488,8 +446,12 @@ var _ = Describe("RabbitmqClusterController", func() {
488446
Expect(resourceRequirements.Limits).To(HaveKeyWithValue(corev1.ResourceMemory, expectedRequirements.Limits[corev1.ResourceMemory]))
489447

490448
// verify that SuccessfulUpdate event is recorded for the StatefulSet
491-
Expect(aggregateEventMsgs(ctx, cluster, "SuccessfulUpdate")).To(
492-
ContainSubstring("updated resource %s of Type *v1.StatefulSet", cluster.ChildResourceName("server")))
449+
Eventually(func() string {
450+
return aggregateEventMsgs(ctx, cluster, "SuccessfulUpdate")
451+
}).
452+
Within(5 * time.Second).
453+
WithPolling(time.Second).
454+
Should(ContainSubstring("updated resource %s of Type *v1.StatefulSet", cluster.ChildResourceName("server")))
493455
})
494456

495457
It("the rabbitmq image is updated", func() {
@@ -863,11 +825,6 @@ var _ = Describe("RabbitmqClusterController", func() {
863825
waitForClusterCreation(ctx, cluster, client)
864826
})
865827

866-
AfterEach(func() {
867-
Expect(client.Delete(ctx, cluster)).To(Succeed())
868-
waitForClusterDeletion(ctx, cluster, client)
869-
})
870-
871828
It("creates a StatefulSet with the override applied", func() {
872829
sts := statefulSet(ctx, cluster)
873830
myStorage := k8sresource.MustParse("100Gi")
@@ -885,7 +842,7 @@ var _ = Describe("RabbitmqClusterController", func() {
885842
"app.kubernetes.io/name": "rabbitmq-sts-override" + suffix,
886843
}))
887844

888-
Expect(len(sts.Spec.VolumeClaimTemplates)).To(Equal(2))
845+
Expect(sts.Spec.VolumeClaimTemplates).To(HaveLen(2))
889846

890847
Expect(sts.Spec.VolumeClaimTemplates[0].ObjectMeta.Name).To(Equal("persistence"))
891848
Expect(sts.Spec.VolumeClaimTemplates[0].ObjectMeta.Namespace).To(Equal("default"))
@@ -1077,11 +1034,13 @@ var _ = Describe("RabbitmqClusterController", func() {
10771034
})
10781035

10791036
Context("Service Override", func() {
1080-
1037+
var clusterName string
10811038
BeforeEach(func() {
1039+
suffix = fmt.Sprintf("-%d", time.Now().UnixNano())
1040+
clusterName = "svc-override" + suffix
10821041
cluster = &rabbitmqv1beta1.RabbitmqCluster{
10831042
ObjectMeta: metav1.ObjectMeta{
1084-
Name: "svc-override",
1043+
Name: clusterName,
10851044
Namespace: defaultNamespace,
10861045
},
10871046
Spec: rabbitmqv1beta1.RabbitmqClusterSpec{
@@ -1114,11 +1073,6 @@ var _ = Describe("RabbitmqClusterController", func() {
11141073
waitForClusterCreation(ctx, cluster, client)
11151074
})
11161075

1117-
AfterEach(func() {
1118-
Expect(client.Delete(ctx, cluster)).To(Succeed())
1119-
waitForClusterDeletion(ctx, cluster, client)
1120-
})
1121-
11221076
It("creates a Service with the override applied", func() {
11231077
amqpTargetPort := intstr.IntOrString{IntVal: int32(5672)}
11241078
managementTargetPort := intstr.IntOrString{IntVal: int32(15672)}
@@ -1155,7 +1109,7 @@ var _ = Describe("RabbitmqClusterController", func() {
11551109
TargetPort: additionalTargetPort,
11561110
},
11571111
))
1158-
Expect(svc.Spec.Selector).To(Equal(map[string]string{"a-selector": "a-label", "app.kubernetes.io/name": "svc-override"}))
1112+
Expect(svc.Spec.Selector).To(Equal(map[string]string{"a-selector": "a-label", "app.kubernetes.io/name": clusterName}))
11591113
Expect(svc.Spec.SessionAffinity).To(Equal(corev1.ServiceAffinityClientIP))
11601114
Expect(svc.Spec.PublishNotReadyAddresses).To(BeFalse())
11611115
})
@@ -1184,10 +1138,6 @@ var _ = Describe("RabbitmqClusterController", func() {
11841138
waitForClusterCreation(ctx, cluster, client)
11851139
})
11861140

1187-
AfterEach(func() {
1188-
Expect(client.Delete(ctx, cluster)).To(Succeed())
1189-
})
1190-
11911141
It("works", func() {
11921142
By("skipping reconciling if label is set to true", func() {
11931143
Expect(updateWithRetry(cluster, func(r *rabbitmqv1beta1.RabbitmqCluster) {
@@ -1362,7 +1312,7 @@ func waitForClusterDeletion(ctx context.Context, rabbitmqCluster *rabbitmqv1beta
13621312
&rabbitmqClusterCreated,
13631313
)
13641314
return apierrors.IsNotFound(err)
1365-
}, ClusterDeletionTimeout, 1*time.Second).Should(BeTrue())
1315+
}, ClusterDeletionTimeout, 1*time.Second).Should(BeTrue(), "expected to delete cluster '%s' but it still exists", rabbitmqCluster.Name)
13661316

13671317
}
13681318

0 commit comments

Comments
 (0)