2024-09-10 17:26:46 +08:00
|
|
|
package rabbitmq_amqp
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
2024-10-02 05:39:33 +08:00
|
|
|
"strconv"
|
|
|
|
|
|
|
|
|
|
"github.com/Azure/go-amqp"
|
2024-09-10 17:26:46 +08:00
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
|
|
|
. "github.com/onsi/gomega"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var _ = Describe("AMQP Queue test ", func() {
|
2025-01-16 22:26:12 +08:00
|
|
|
var connection *AmqpConnection
|
|
|
|
|
var management *AmqpManagement
|
2024-09-10 17:26:46 +08:00
|
|
|
BeforeEach(func() {
|
2025-01-16 22:26:12 +08:00
|
|
|
conn, err := Dial(context.TODO(), []string{"amqp://"}, nil)
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
2024-11-21 17:34:08 +08:00
|
|
|
connection = conn
|
2024-09-10 17:26:46 +08:00
|
|
|
management = connection.Management()
|
|
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
AfterEach(func() {
|
|
|
|
|
Expect(connection.Close(context.Background())).To(BeNil())
|
|
|
|
|
})
|
|
|
|
|
|
2024-10-02 06:25:12 +08:00
|
|
|
It("AMQP Queue Declare With Response and Get/Delete should succeed", func() {
|
2025-01-30 18:29:44 +08:00
|
|
|
var queueName = generateName("AMQP Queue Declare With Response and Delete should succeed")
|
|
|
|
|
queueInfo, err := management.DeclareQueue(context.TODO(), &QuorumQueueSpecification{
|
2024-11-15 15:37:28 +08:00
|
|
|
Name: queueName,
|
|
|
|
|
})
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
Expect(queueInfo).NotTo(BeNil())
|
2024-11-15 15:37:28 +08:00
|
|
|
Expect(queueInfo.Name()).To(Equal(queueName))
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(queueInfo.IsDurable()).To(BeTrue())
|
|
|
|
|
Expect(queueInfo.IsAutoDelete()).To(BeFalse())
|
2024-09-18 00:59:33 +08:00
|
|
|
Expect(queueInfo.IsExclusive()).To(BeFalse())
|
2025-01-30 18:29:44 +08:00
|
|
|
Expect(queueInfo.Type()).To(Equal(Quorum))
|
2024-10-02 06:25:12 +08:00
|
|
|
|
|
|
|
|
// validate GET (query queue info)
|
|
|
|
|
queueInfoReceived, err := management.QueueInfo(context.TODO(), queueName)
|
|
|
|
|
Expect(queueInfoReceived).To(Equal(queueInfo))
|
|
|
|
|
|
2024-11-15 15:37:28 +08:00
|
|
|
err = management.DeleteQueue(context.TODO(), queueName)
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
})
|
|
|
|
|
|
2024-10-02 06:25:12 +08:00
|
|
|
It("AMQP Queue Declare With Parameters and Get/Delete should succeed", func() {
|
2025-01-30 18:29:44 +08:00
|
|
|
var queueName = generateName("AMQP Queue Declare With Parameters and Delete should succeed")
|
2024-11-15 15:37:28 +08:00
|
|
|
|
2025-01-30 18:29:44 +08:00
|
|
|
queueInfo, err := management.DeclareQueue(context.TODO(), &ClassicQueueSpecification{
|
2024-11-15 15:37:28 +08:00
|
|
|
Name: queueName,
|
|
|
|
|
IsAutoDelete: true,
|
|
|
|
|
IsExclusive: true,
|
2025-01-30 18:29:44 +08:00
|
|
|
AutoExpire: 1000,
|
|
|
|
|
MessageTTL: 1000,
|
|
|
|
|
OverflowStrategy: &DropHeadOverflowStrategy{},
|
|
|
|
|
SingleActiveConsumer: true,
|
2024-11-15 15:37:28 +08:00
|
|
|
DeadLetterExchange: "dead-letter-exchange",
|
|
|
|
|
DeadLetterRoutingKey: "dead-letter-routing-key",
|
2025-01-30 18:29:44 +08:00
|
|
|
MaxLength: 9_000,
|
|
|
|
|
MaxLengthBytes: CapacityGB(1),
|
|
|
|
|
MaxPriority: 2,
|
|
|
|
|
LeaderLocator: &BalancedLeaderLocator{},
|
2024-11-15 15:37:28 +08:00
|
|
|
})
|
|
|
|
|
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
Expect(queueInfo).NotTo(BeNil())
|
2024-11-15 15:37:28 +08:00
|
|
|
Expect(queueInfo.Name()).To(Equal(queueName))
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(queueInfo.IsDurable()).To(BeTrue())
|
|
|
|
|
Expect(queueInfo.IsAutoDelete()).To(BeTrue())
|
2024-09-18 00:59:33 +08:00
|
|
|
Expect(queueInfo.IsExclusive()).To(BeTrue())
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(queueInfo.Type()).To(Equal(Classic))
|
2024-11-15 15:37:28 +08:00
|
|
|
Expect(queueInfo.Leader()).To(ContainSubstring("rabbit"))
|
|
|
|
|
Expect(len(queueInfo.Members())).To(BeNumerically(">", 0))
|
2024-09-10 17:26:46 +08:00
|
|
|
|
2024-11-15 15:37:28 +08:00
|
|
|
Expect(queueInfo.Arguments()).To(HaveKeyWithValue("x-dead-letter-exchange", "dead-letter-exchange"))
|
|
|
|
|
Expect(queueInfo.Arguments()).To(HaveKeyWithValue("x-dead-letter-routing-key", "dead-letter-routing-key"))
|
2025-01-30 18:29:44 +08:00
|
|
|
Expect(queueInfo.Arguments()).To(HaveKeyWithValue("x-max-length-bytes", int64(1000000000)))
|
|
|
|
|
Expect(queueInfo.Arguments()).To(HaveKeyWithValue("x-max-length", int64(9000)))
|
|
|
|
|
Expect(queueInfo.Arguments()).To(HaveKeyWithValue("x-message-ttl", int64(1000)))
|
|
|
|
|
Expect(queueInfo.Arguments()).To(HaveKeyWithValue("x-single-active-consumer", true))
|
|
|
|
|
Expect(queueInfo.Arguments()).To(HaveKeyWithValue("x-overflow", "drop-head"))
|
|
|
|
|
Expect(queueInfo.Arguments()).To(HaveKeyWithValue("x-expires", int64(1000)))
|
|
|
|
|
Expect(queueInfo.Arguments()).To(HaveKeyWithValue("x-max-priority", int64(2)))
|
|
|
|
|
Expect(queueInfo.Arguments()).To(HaveKeyWithValue("x-queue-leader-locator", "random"))
|
2024-09-10 17:26:46 +08:00
|
|
|
|
2024-10-02 06:25:12 +08:00
|
|
|
// validate GET (query queue info)
|
|
|
|
|
queueInfoReceived, err := management.QueueInfo(context.TODO(), queueName)
|
|
|
|
|
Expect(queueInfoReceived).To(Equal(queueInfo))
|
|
|
|
|
|
2024-11-15 15:37:28 +08:00
|
|
|
err = management.DeleteQueue(context.TODO(), queueName)
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
2024-11-15 15:37:28 +08:00
|
|
|
|
2024-09-10 17:26:46 +08:00
|
|
|
})
|
|
|
|
|
|
2024-10-02 06:25:12 +08:00
|
|
|
It("AMQP Declare Quorum Queue and Get/Delete should succeed", func() {
|
2025-01-30 18:29:44 +08:00
|
|
|
var queueName = generateName("AMQP Declare Quorum Queue and Delete should succeed")
|
2024-09-10 17:26:46 +08:00
|
|
|
// Quorum queue will ignore Exclusive and AutoDelete settings
|
|
|
|
|
// since they are not supported by quorum queues
|
2025-01-30 18:29:44 +08:00
|
|
|
queueInfo, err := management.DeclareQueue(context.TODO(), &QuorumQueueSpecification{
|
|
|
|
|
Name: queueName,
|
2024-11-15 15:37:28 +08:00
|
|
|
})
|
|
|
|
|
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
Expect(queueInfo).NotTo(BeNil())
|
2024-11-15 15:37:28 +08:00
|
|
|
Expect(queueInfo.Name()).To(Equal(queueName))
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(queueInfo.IsDurable()).To(BeTrue())
|
|
|
|
|
Expect(queueInfo.IsAutoDelete()).To(BeFalse())
|
2024-09-18 00:59:33 +08:00
|
|
|
Expect(queueInfo.IsExclusive()).To(BeFalse())
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(queueInfo.Type()).To(Equal(Quorum))
|
2024-10-02 06:25:12 +08:00
|
|
|
// validate GET (query queue info)
|
|
|
|
|
queueInfoReceived, err := management.QueueInfo(context.TODO(), queueName)
|
|
|
|
|
Expect(queueInfoReceived).To(Equal(queueInfo))
|
|
|
|
|
|
2024-11-15 15:37:28 +08:00
|
|
|
err = management.DeleteQueue(context.TODO(), queueName)
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
2024-11-15 15:37:28 +08:00
|
|
|
|
2024-09-10 17:26:46 +08:00
|
|
|
})
|
|
|
|
|
|
2024-10-02 06:25:12 +08:00
|
|
|
It("AMQP Declare Stream Queue and Get/Delete should succeed", func() {
|
2024-09-18 00:59:33 +08:00
|
|
|
const queueName = "AMQP Declare Stream Queue and Delete should succeed"
|
2024-09-10 17:26:46 +08:00
|
|
|
// Stream queue will ignore Exclusive and AutoDelete settings
|
|
|
|
|
// since they are not supported by quorum queues
|
2024-11-15 15:37:28 +08:00
|
|
|
|
2025-01-30 18:29:44 +08:00
|
|
|
queueInfo, err := management.DeclareQueue(context.TODO(), &ClassicQueueSpecification{
|
2024-11-15 15:37:28 +08:00
|
|
|
Name: queueName,
|
2025-01-30 18:29:44 +08:00
|
|
|
IsAutoDelete: false,
|
|
|
|
|
IsExclusive: false})
|
2024-11-15 15:37:28 +08:00
|
|
|
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
Expect(queueInfo).NotTo(BeNil())
|
2024-11-15 15:37:28 +08:00
|
|
|
Expect(queueInfo.Name()).To(Equal(queueName))
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(queueInfo.IsDurable()).To(BeTrue())
|
|
|
|
|
Expect(queueInfo.IsAutoDelete()).To(BeFalse())
|
2024-09-18 00:59:33 +08:00
|
|
|
Expect(queueInfo.IsExclusive()).To(BeFalse())
|
2025-01-30 18:29:44 +08:00
|
|
|
Expect(queueInfo.Type()).To(Equal(Classic))
|
2024-10-02 06:25:12 +08:00
|
|
|
// validate GET (query queue info)
|
|
|
|
|
queueInfoReceived, err := management.QueueInfo(context.TODO(), queueName)
|
|
|
|
|
Expect(queueInfoReceived).To(Equal(queueInfo))
|
|
|
|
|
|
2024-11-15 15:37:28 +08:00
|
|
|
err = management.DeleteQueue(context.TODO(), queueName)
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
2024-11-15 15:37:28 +08:00
|
|
|
|
2024-09-10 17:26:46 +08:00
|
|
|
})
|
|
|
|
|
|
2024-09-18 00:59:33 +08:00
|
|
|
It("AMQP Declare Queue should fail with Precondition fail", func() {
|
2024-11-15 15:37:28 +08:00
|
|
|
// The first queue is declared as Classic, and it should succeed
|
|
|
|
|
// The second queue is declared as Quorum, and it should fail since it is already declared as Classic
|
2025-01-30 18:29:44 +08:00
|
|
|
//queueName := generateName("AMQP Declare Queue should fail with Precondition fail")
|
|
|
|
|
queueName := "ab"
|
|
|
|
|
_, err := management.DeclareQueue(context.TODO(), &ClassicQueueSpecification{
|
|
|
|
|
Name: queueName,
|
2024-11-15 15:37:28 +08:00
|
|
|
})
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
2024-11-15 15:37:28 +08:00
|
|
|
|
2025-01-30 18:29:44 +08:00
|
|
|
_, err = management.DeclareQueue(context.TODO(), &QuorumQueueSpecification{
|
|
|
|
|
Name: queueName,
|
2024-11-15 15:37:28 +08:00
|
|
|
})
|
|
|
|
|
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).NotTo(BeNil())
|
2024-09-18 00:59:33 +08:00
|
|
|
Expect(err).To(Equal(ErrPreconditionFailed))
|
2024-11-15 15:37:28 +08:00
|
|
|
err = management.DeleteQueue(context.TODO(), queueName)
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
It("AMQP Declare Queue should fail during validation", func() {
|
2025-01-16 22:26:12 +08:00
|
|
|
queueName := generateName("AMQP Declare Queue should fail during validation")
|
2025-01-30 18:29:44 +08:00
|
|
|
_, err := management.DeclareQueue(context.TODO(), &QuorumQueueSpecification{
|
2024-11-15 15:37:28 +08:00
|
|
|
Name: queueName,
|
|
|
|
|
MaxLengthBytes: -1,
|
|
|
|
|
})
|
|
|
|
|
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).NotTo(BeNil())
|
|
|
|
|
Expect(err).To(HaveOccurred())
|
|
|
|
|
})
|
|
|
|
|
|
2025-01-30 18:29:44 +08:00
|
|
|
It("AMQP Declare Queue should fail if queue specification is nil", func() {
|
|
|
|
|
_, err := management.DeclareQueue(context.TODO(), nil)
|
|
|
|
|
Expect(err).NotTo(BeNil())
|
|
|
|
|
Expect(err).To(HaveOccurred())
|
|
|
|
|
Expect(err.Error()).Should(ContainSubstring("queue specification cannot be nil"))
|
|
|
|
|
})
|
|
|
|
|
|
2024-09-10 17:26:46 +08:00
|
|
|
It("AMQP Declare Queue should create client name queue", func() {
|
2025-01-30 18:29:44 +08:00
|
|
|
queueInfo, err := management.DeclareQueue(context.TODO(), &AutoGeneratedQueueSpecification{
|
|
|
|
|
IsAutoDelete: true,
|
|
|
|
|
IsExclusive: false,
|
|
|
|
|
})
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
Expect(queueInfo).NotTo(BeNil())
|
2024-11-15 15:37:28 +08:00
|
|
|
Expect(queueInfo.Name()).To(ContainSubstring("client.gen-"))
|
|
|
|
|
err = management.DeleteQueue(context.TODO(), queueInfo.Name())
|
2024-09-10 17:26:46 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
})
|
2024-10-02 05:39:33 +08:00
|
|
|
|
|
|
|
|
It("AMQP Purge Queue should succeed and return the number of messages purged", func() {
|
2025-01-16 22:26:12 +08:00
|
|
|
queueName := generateName("AMQP Purge Queue should succeed and return the number of messages purged")
|
2025-01-30 18:29:44 +08:00
|
|
|
queueInfo, err := management.DeclareQueue(context.TODO(), &QuorumQueueSpecification{
|
2024-11-15 15:37:28 +08:00
|
|
|
Name: queueName,
|
|
|
|
|
})
|
2024-10-02 05:39:33 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
publishMessages(queueName, 10)
|
2024-11-15 15:37:28 +08:00
|
|
|
purged, err := management.PurgeQueue(context.TODO(), queueInfo.Name())
|
2024-10-02 05:39:33 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
Expect(purged).To(Equal(10))
|
2025-01-16 22:26:12 +08:00
|
|
|
err = management.DeleteQueue(context.TODO(), queueName)
|
|
|
|
|
Expect(err).To(BeNil())
|
2024-10-02 05:39:33 +08:00
|
|
|
})
|
2024-10-02 06:25:12 +08:00
|
|
|
|
|
|
|
|
It("AMQP GET on non-existing queue should return ErrDoesNotExist", func() {
|
|
|
|
|
const queueName = "This queue does not exist"
|
|
|
|
|
result, err := management.QueueInfo(context.TODO(), queueName)
|
|
|
|
|
Expect(err).To(Equal(ErrDoesNotExist))
|
|
|
|
|
Expect(result).To(BeNil())
|
|
|
|
|
})
|
2024-09-10 17:26:46 +08:00
|
|
|
})
|
2024-10-02 05:39:33 +08:00
|
|
|
|
|
|
|
|
func publishMessages(queueName string, count int) {
|
2025-01-16 22:26:12 +08:00
|
|
|
conn, err := Dial(context.TODO(), []string{"amqp://guest:guest@localhost"}, nil)
|
|
|
|
|
Expect(err).To(BeNil())
|
2024-11-15 15:37:28 +08:00
|
|
|
|
2025-01-30 18:29:44 +08:00
|
|
|
publisher, err := conn.NewPublisher(context.TODO(), &QueueAddress{Queue: queueName}, "test")
|
2025-01-16 22:26:12 +08:00
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
Expect(publisher).NotTo(BeNil())
|
2024-10-02 05:39:33 +08:00
|
|
|
|
|
|
|
|
for i := 0; i < count; i++ {
|
2025-01-16 22:26:12 +08:00
|
|
|
publishResult, err := publisher.Publish(context.TODO(), amqp.NewMessage([]byte("Message #"+strconv.Itoa(i))))
|
|
|
|
|
Expect(err).To(BeNil())
|
|
|
|
|
Expect(publishResult).NotTo(BeNil())
|
|
|
|
|
Expect(publishResult.Outcome).To(Equal(&amqp.StateAccepted{}))
|
2024-10-02 05:39:33 +08:00
|
|
|
}
|
2025-01-16 22:26:12 +08:00
|
|
|
err = conn.Close(context.TODO())
|
|
|
|
|
Expect(err).To(BeNil())
|
2024-10-02 05:39:33 +08:00
|
|
|
|
|
|
|
|
}
|