Skip to content

Commit

Permalink
Add integration tests for queue controller
Browse files Browse the repository at this point in the history
  • Loading branch information
ChunyiLyu committed Apr 14, 2021
1 parent d7ddc35 commit 2d5b1f8
Showing 1 changed file with 218 additions and 0 deletions.
218 changes: 218 additions & 0 deletions controllers/queue_controller_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
package controllers_test

import (
"bytes"
"errors"
"io/ioutil"
"net/http"
"time"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gstruct"
topology "github.com/rabbitmq/messaging-topology-operator/api/v1alpha2"
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("queue-controller", func() {
var q topology.Queue
var qName string

JustBeforeEach(func() {
q = topology.Queue{
ObjectMeta: metav1.ObjectMeta{
Name: qName,
Namespace: "default",
},
Spec: topology.QueueSpec{
RabbitmqClusterReference: topology.RabbitmqClusterReference{
Name: "example-rabbit",
},
},
}
})

Context("creation", func() {
When("the RabbitMQ Client returns a HTTP error response", func() {
BeforeEach(func() {
qName = "test-http-error"
fakeRabbitMQClient.DeclareQueueReturns(&http.Response{
Status: "418 I'm a teapot",
StatusCode: 418,
}, errors.New("a failure"))
})

It("sets the status condition", func() {
Expect(client.Create(ctx, &q)).To(Succeed())
EventuallyWithOffset(1, func() []topology.Condition {
_ = client.Get(
ctx,
types.NamespacedName{Name: q.Name, Namespace: q.Namespace},
&q,
)

return q.Status.Conditions
}, 10*time.Second, 1*time.Second).Should(ContainElement(MatchFields(IgnoreExtras, Fields{
"Type": Equal(topology.ConditionType("Ready")),
"Reason": Equal("FailedCreateOrUpdate"),
"Status": Equal(corev1.ConditionFalse),
"Message": ContainSubstring("a failure"),
})))
})
})

When("the RabbitMQ Client returns a Go error response", func() {
BeforeEach(func() {
qName = "test-go-error"
fakeRabbitMQClient.DeclareQueueReturns(nil, errors.New("a go failure"))
})

It("sets the status condition to indicate a failure to reconcile", func() {
Expect(client.Create(ctx, &q)).To(Succeed())
EventuallyWithOffset(1, func() []topology.Condition {
_ = client.Get(
ctx,
types.NamespacedName{Name: q.Name, Namespace: q.Namespace},
&q,
)

return q.Status.Conditions
}, 10*time.Second, 1*time.Second).Should(ContainElement(MatchFields(IgnoreExtras, Fields{
"Type": Equal(topology.ConditionType("Ready")),
"Reason": Equal("FailedCreateOrUpdate"),
"Status": Equal(corev1.ConditionFalse),
"Message": ContainSubstring("a go failure"),
})))
})
})

When("success", func() {
BeforeEach(func() {
qName = "test-create-success"
fakeRabbitMQClient.DeclareQueueReturns(&http.Response{
Status: "201 Created",
StatusCode: http.StatusCreated,
}, nil)
})

It("sets the status condition 'Ready' to 'true' ", func() {
Expect(client.Create(ctx, &q)).To(Succeed())
EventuallyWithOffset(1, func() []topology.Condition {
_ = client.Get(
ctx,
types.NamespacedName{Name: q.Name, Namespace: q.Namespace},
&q,
)

return q.Status.Conditions
}, 10*time.Second, 1*time.Second).Should(ContainElement(MatchFields(IgnoreExtras, Fields{
"Type": Equal(topology.ConditionType("Ready")),
"Reason": Equal("SuccessfulCreateOrUpdate"),
"Status": Equal(corev1.ConditionTrue),
})))
})
})
})

Context("deletion", func() {
JustBeforeEach(func() {
fakeRabbitMQClient.DeclareQueueReturns(&http.Response{
Status: "201 Created",
StatusCode: http.StatusCreated,
}, nil)
Expect(client.Create(ctx, &q)).To(Succeed())
EventuallyWithOffset(1, func() []topology.Condition {
_ = client.Get(
ctx,
types.NamespacedName{Name: q.Name, Namespace: q.Namespace},
&q,
)

return q.Status.Conditions
}, 10*time.Second, 1*time.Second).Should(ContainElement(MatchFields(IgnoreExtras, Fields{
"Type": Equal(topology.ConditionType("Ready")),
"Reason": Equal("SuccessfulCreateOrUpdate"),
"Status": Equal(corev1.ConditionTrue),
})))
})

When("the RabbitMQ Client returns a HTTP error response", func() {
BeforeEach(func() {
qName = "delete-q-http-error"
fakeRabbitMQClient.DeleteQueueReturns(&http.Response{
Status: "502 Bad Gateway",
StatusCode: http.StatusBadGateway,
Body: ioutil.NopCloser(bytes.NewBufferString("Hello World")),
}, nil)
})

It("publishes a 'warning' event", func() {
Expect(client.Delete(ctx, &q)).To(Succeed())
Consistently(func() bool {
err := client.Get(ctx, types.NamespacedName{Name: q.Name, Namespace: q.Namespace}, &topology.Queue{})
return apierrors.IsNotFound(err)
}, 5).Should(BeFalse())
Expect(observedEvents()).To(ContainElement("Warning FailedDelete failed to delete queue"))
})
})

When("the RabbitMQ Client returns a Go error response", func() {
BeforeEach(func() {
qName = "delete-go-error"
fakeRabbitMQClient.DeleteQueueReturns(nil, errors.New("some error"))
})

It("publishes a 'warning' event", func() {
Expect(client.Delete(ctx, &q)).To(Succeed())
Consistently(func() bool {
err := client.Get(ctx, types.NamespacedName{Name: q.Name, Namespace: q.Namespace}, &topology.Queue{})
return apierrors.IsNotFound(err)
}, 5).Should(BeFalse())
Expect(observedEvents()).To(ContainElement("Warning FailedDelete failed to delete queue"))
})
})

When("the RabbitMQ cluster is nil", func() {
BeforeEach(func() {
qName = "delete-client-not-found-error"
})

JustBeforeEach(func() {
prepareNoSuchClusterError()
})

It("successfully deletes the queue regardless", func() {
Expect(client.Delete(ctx, &q)).To(Succeed())
Eventually(func() bool {
err := client.Get(ctx, types.NamespacedName{Name: q.Name, Namespace: q.Namespace}, &topology.Queue{})
return apierrors.IsNotFound(err)
}, 5).Should(BeTrue())
Expect(observedEvents()).To(ContainElement("Normal SuccessfulDelete successfully deleted queue"))
})
})

When("the RabbitMQ Client successfully deletes a q", func() {
BeforeEach(func() {
qName = "delete-q-success"
fakeRabbitMQClient.DeleteQueueReturns(&http.Response{
Status: "204 No Content",
StatusCode: http.StatusNoContent,
}, nil)
})

It("publishes a normal event", func() {
Expect(client.Delete(ctx, &q)).To(Succeed())
Eventually(func() bool {
err := client.Get(ctx, types.NamespacedName{Name: q.Name, Namespace: q.Namespace}, &topology.Queue{})
return apierrors.IsNotFound(err)
}, 5).Should(BeTrue())
observedEvents := observedEvents()
Expect(observedEvents).NotTo(ContainElement("Warning FailedDelete failed to delete queue"))
Expect(observedEvents).To(ContainElement("Normal SuccessfulDelete successfully deleted queue"))
})
})
})
})

0 comments on commit 2d5b1f8

Please sign in to comment.