public async Task ConsumePublish_WithNoError_Test() { var deliveryTag = (ulong)new Random().Next(); var consumeAbortedCalled = false; var consumer = new RabbitConsumer(_connection, _serviceName, _topicName, MessageHandler, () => { consumeAbortedCalled = true; }, false, 100, _options, _logger); await consumer.StartConsumeAsync(_cancellationTokenSource.Token); await _basicConsumer.HandleBasicDeliver(_consumerTag, deliveryTag, false, "exchange", "routingKey", null, null); A.CallTo(() => _rabbitChannel.BasicCancel(_consumerTag)) .MustNotHaveHappened(); A.CallTo(() => _rabbitChannel.BasicNack(deliveryTag, false, true)) .MustNotHaveHappened(); A.CallTo(() => _rabbitChannel.BasicAck(deliveryTag, false)) .MustHaveHappenedOnceExactly(); A.CallTo(() => _rabbitChannel.BasicPublish("", A <string> .Ignored, A <bool> .Ignored, A <IBasicProperties> .Ignored, A <ReadOnlyMemory <byte> > .Ignored)) .MustNotHaveHappened(); Assert.IsFalse(consumeAbortedCalled); }
public async Task ShouldProperlyStopConsumingMessages(int numberOfMessages) { var channelMock = new Mock <IModel>(); var connectionMock = new Mock <IConnection>(); connectionMock.Setup(x => x.CreateModel()) .Returns(channelMock.Object); var connectionFactoryMock = new Mock <IRabbitMqConnectionFactory>(); connectionFactoryMock.Setup(x => x.CreateRabbitMqConnection(It.IsAny <RabbitMqClientOptions>())) .Returns(connectionMock.Object); var consumer = new AsyncEventingBasicConsumer(channelMock.Object); connectionFactoryMock.Setup(x => x.CreateConsumer(It.IsAny <IModel>())) .Returns(consumer); var messageHandlingPipelineExecutingServiceMock = new Mock <IMessageHandlingPipelineExecutingService>(); var queueService = CreateService(connectionFactoryMock.Object, messageHandlingPipelineExecutingServiceMock.Object); queueService.StartConsuming(); for (var i = 1; i <= numberOfMessages; i++) { await consumer.HandleBasicDeliver( "1", (ulong)numberOfMessages, false, "exchange", "routing,key", null, new ReadOnlyMemory <byte>()); } messageHandlingPipelineExecutingServiceMock.Verify(x => x.Execute(It.IsAny <BasicDeliverEventArgs>(), It.IsAny <IQueueService>()), Times.Exactly(numberOfMessages)); queueService.StopConsuming(); await consumer.HandleBasicDeliver( "1", 0, false, "exchange", "routing,key", null, new ReadOnlyMemory <byte>()); messageHandlingPipelineExecutingServiceMock.Verify(x => x.Execute(It.IsAny <BasicDeliverEventArgs>(), It.IsAny <IQueueService>()), Times.Exactly(numberOfMessages)); }
public void StartReceivingMessages_InvokesCallbackWithCorrectEventMessage() { // Arrange var channelMock = new Mock <IModel>(); AsyncEventingBasicConsumer basicConsumer = null; channelMock.Setup(c => c.BasicConsume("TestQueue", true, "", false, false, null, It.IsAny <AsyncEventingBasicConsumer>())) .Callback((string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive, IDictionary <string, object> arguments, IBasicConsumer consumer) => { basicConsumer = consumer as AsyncEventingBasicConsumer; }); var connectionMock = new Mock <IConnection>(); connectionMock.Setup(c => c.CreateModel()) .Returns(channelMock.Object); var context = new RabbitMQBusContext(connectionMock.Object, "TestExchange"); var receiver = new RabbitMQMessageReceiver(context, "TestQueue", new List <string> { "TestTopic2" }); // Act bool callbackWasInvoked = false; IEventMessage eventMessage = null; receiver.StartReceivingMessages((e) => { callbackWasInvoked = true; eventMessage = e; }); var properties = new BasicProperties { Type = "Test type", Timestamp = new AmqpTimestamp(1542183431), CorrelationId = "test id" }; basicConsumer.HandleBasicDeliver("", 0, false, "", "routing.key", properties, Encoding.UTF8.GetBytes("test message")).Wait(); // Assert Assert.IsTrue(callbackWasInvoked); Assert.AreEqual("routing.key", eventMessage.RoutingKey); Assert.AreEqual("test message", eventMessage.Message); Assert.AreEqual("Test type", eventMessage.EventType); Assert.AreEqual(1542183431, eventMessage.Timestamp); Assert.AreEqual("test id", eventMessage.CorrelationId); }
public async Task ConsumerTriggersMessageReceiver() { var channelMock = new Mock <IModel>(); var properties = new Mock <IBasicProperties>(); var simulatedPayload = new ReadOnlyMemory <byte>(new byte[] { 1, 1, 1 }); AsyncEventingBasicConsumer?basicConsumer = null; // Once the channelMock registers a consumer, we'll fill it in here. using var hosted = new HostedRabbitMqService(_options.Object, _logger.Object, _connectionService.Object, _messageReceiver.Object); using var cancellation = new CancellationTokenSource(); _connectionService.Setup(c => c.GetChannel()).Returns(channelMock.Object); // in reality an extension method with a simpler signature is called, but Moq won't allow us to simulate that directly. So we expand the called extension method here. channelMock.Setup(c => c.BasicConsume(QueueName, It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <AsyncEventingBasicConsumer>())) .Callback <string, bool, string, bool, bool, IDictionary <string, object>, IBasicConsumer>((name, autoAck, consumerTag, noLocal, exclusive, arguments, consumer) => { // Consumer here is an actual RabbitMQ consumer waiting for our model to fire stuff. basicConsumer = consumer as AsyncEventingBasicConsumer; }); _messageReceiver.Setup(m => m.HandleIncoming(typeof(DummyEvent), simulatedPayload)).Returns(Task.CompletedTask).Verifiable("Message receiver was not called!"); await hosted.StartAsync(cancellation.Token); basicConsumer?.HandleBasicDeliver(string.Empty, 420, false, string.Empty, QueueName, properties.Object, simulatedPayload); channelMock.Verify(); _messageReceiver.Verify(); await hosted.StopAsync(cancellation.Token); }
public async Task ShouldProperlyConsumeMessagesButWithoutAutoAck(int numberOfMessages) { var channelMock = new Mock <IModel>(); var connectionMock = new Mock <IConnection>(); var consumer = new AsyncEventingBasicConsumer(channelMock.Object); var messageHandlingPipelineExecutingServiceMock = new Mock <IMessageHandlingPipelineExecutingService>(); const string exchangeName = "exchange"; var exchange = new RabbitMqExchange(exchangeName, ClientExchangeType.Consumption, new RabbitMqExchangeOptions { DisableAutoAck = true }); var consumingService = CreateConsumingService(messageHandlingPipelineExecutingServiceMock.Object, new[] { exchange }); consumingService.UseConnection(connectionMock.Object); consumingService.UseChannel(channelMock.Object); consumingService.UseConsumer(consumer); await consumer.HandleBasicDeliver( "1", 0, false, exchangeName, "routing,key", null, new ReadOnlyMemory <byte>()); messageHandlingPipelineExecutingServiceMock.Verify(x => x.Execute(It.IsAny <MessageHandlingContext>()), Times.Never); consumingService.StartConsuming(); for (var i = 1; i <= numberOfMessages; i++) { await consumer.HandleBasicDeliver( "1", (ulong)numberOfMessages, false, "exchange", "routing,key", null, new ReadOnlyMemory <byte>()); } messageHandlingPipelineExecutingServiceMock.Verify(x => x.Execute(It.IsAny <MessageHandlingContext>()), Times.Exactly(numberOfMessages)); }
public async Task ShouldProperlyHandlerMessagesByBatches(ushort prefetchCount, int numberOfMessages) { const string queueName = "queue.name"; var channelMock = new Mock <IModel>(); var connectionMock = new Mock <IConnection>(); connectionMock.Setup(x => x.CreateModel()) .Returns(channelMock.Object); var connectionFactoryMock = new Mock <IRabbitMqConnectionFactory>(); connectionFactoryMock.Setup(x => x.CreateRabbitMqConnection(It.IsAny <RabbitMqServiceOptions>())) .Returns(connectionMock.Object); var consumer = new AsyncEventingBasicConsumer(channelMock.Object); connectionFactoryMock.Setup(x => x.CreateConsumer(It.IsAny <IModel>())) .Returns(consumer); var callerMock = new Mock <IStubCaller>(); using var messageHandler = CreateBatchMessageHandler( queueName, prefetchCount, null, connectionFactoryMock.Object, callerMock.Object, Enumerable.Empty <IBatchMessageHandlingMiddleware>()); await messageHandler.StartAsync(CancellationToken.None); for (var i = 0; i < numberOfMessages; i++) { await consumer.HandleBasicDeliver( "1", (ulong)i, false, "exchange", "routing,key", null, new ReadOnlyMemory <byte>()); } var numberOfBatches = numberOfMessages / prefetchCount; callerMock.Verify(x => x.EmptyCall(), Times.Exactly(numberOfBatches)); var processedMessages = numberOfBatches * prefetchCount; callerMock.Verify(x => x.Call(It.IsAny <ReadOnlyMemory <byte> >()), Times.Exactly(processedMessages)); await messageHandler.StopAsync(CancellationToken.None); }
public async Task ShouldProperlyConsumeMessages(int numberOfMessages) { var channelMock = new Mock <IModel>(); var connectionMock = new Mock <IConnection>(); var consumer = new AsyncEventingBasicConsumer(channelMock.Object); var messageHandlingPipelineExecutingServiceMock = new Mock <IMessageHandlingPipelineExecutingService>(); var consumingService = CreateConsumingService(messageHandlingPipelineExecutingServiceMock.Object); consumingService.UseConnection(connectionMock.Object); consumingService.UseChannel(channelMock.Object); consumingService.UseConsumer(consumer); await consumer.HandleBasicDeliver( "1", 0, false, "exchange", "routing,key", null, new ReadOnlyMemory <byte>()); messageHandlingPipelineExecutingServiceMock.Verify(x => x.Execute(It.IsAny <BasicDeliverEventArgs>(), It.IsAny <IConsumingService>()), Times.Never); consumingService.StartConsuming(); for (var i = 1; i <= numberOfMessages; i++) { await consumer.HandleBasicDeliver( "1", (ulong)numberOfMessages, false, "exchange", "routing,key", null, new ReadOnlyMemory <byte>()); } messageHandlingPipelineExecutingServiceMock.Verify(x => x.Execute(It.IsAny <BasicDeliverEventArgs>(), It.IsAny <IConsumingService>()), Times.Exactly(numberOfMessages)); }
public async Task ShouldProperlyHandlerMessagesByTimer(int numberOfMessages) { const string queueName = "queue.name"; const ushort prefetchCount = 10; var handlingPeriod = TimeSpan.FromMilliseconds(100); var channelMock = new Mock <IModel>(); var connectionMock = new Mock <IConnection>(); connectionMock.Setup(x => x.CreateModel()) .Returns(channelMock.Object); var connectionFactoryMock = new Mock <IRabbitMqConnectionFactory>(); connectionFactoryMock.Setup(x => x.CreateRabbitMqConnection(It.IsAny <RabbitMqServiceOptions>())) .Returns(connectionMock.Object); var consumer = new AsyncEventingBasicConsumer(channelMock.Object); connectionFactoryMock.Setup(x => x.CreateConsumer(It.IsAny <IModel>())) .Returns(consumer); using var waitHandle = new AutoResetEvent(false); var callerMock = new Mock <IStubCaller>(); var caller = new StubCallerDecorator(callerMock.Object) { WaitHandle = waitHandle }; using var messageHandler = CreateBatchMessageHandler( queueName, prefetchCount, handlingPeriod, connectionFactoryMock.Object, caller, Enumerable.Empty <IBatchMessageHandlingMiddleware>()); await messageHandler.StartAsync(CancellationToken.None); const int smallBatchSize = prefetchCount - 1; var numberOfSmallBatches = (int)Math.Ceiling((double)numberOfMessages / smallBatchSize); for (var b = 0; b < numberOfSmallBatches; b++) { var lowerBound = b * smallBatchSize; var upperBound = (b + 1) * smallBatchSize > numberOfMessages ? numberOfMessages : (b + 1) * smallBatchSize; for (var i = lowerBound; i < upperBound; i++) { await consumer.HandleBasicDeliver( "1", (ulong)i, false, "exchange", "routing,key", null, new ReadOnlyMemory <byte>()); } waitHandle.WaitOne(_globalTestsTimeout); } callerMock.Verify(x => x.EmptyCall(), Times.Exactly(numberOfSmallBatches)); callerMock.Verify(x => x.Call(It.IsAny <ReadOnlyMemory <byte> >()), Times.Exactly(numberOfMessages)); await messageHandler.StopAsync(CancellationToken.None); }
public async Task ShouldProperlyExecutePipeline() { const ushort prefetchCount = 5; const string queueName = "queue.name"; var channelMock = new Mock <IModel>(); var connectionMock = new Mock <IConnection>(); connectionMock.Setup(x => x.CreateModel()) .Returns(channelMock.Object); var connectionFactoryMock = new Mock <IRabbitMqConnectionFactory>(); connectionFactoryMock.Setup(x => x.CreateRabbitMqConnection(It.IsAny <RabbitMqServiceOptions>())) .Returns(connectionMock.Object); var consumer = new AsyncEventingBasicConsumer(channelMock.Object); connectionFactoryMock.Setup(x => x.CreateConsumer(It.IsAny <IModel>())) .Returns(consumer); var callerMock = new Mock <IStubCaller>(); var orderingMap = new Dictionary <int, int>(); var firstMiddleware = new StubBatchMessageHandlingMiddleware(1, orderingMap); var secondMiddleware = new StubBatchMessageHandlingMiddleware(2, orderingMap); var thirdMiddleware = new StubBatchMessageHandlingMiddleware(3, orderingMap); var middlewares = new List <IBatchMessageHandlingMiddleware> { firstMiddleware, secondMiddleware, thirdMiddleware }; using var messageHandler = CreateBatchMessageHandler( queueName, prefetchCount, null, connectionFactoryMock.Object, callerMock.Object, middlewares); await messageHandler.StartAsync(CancellationToken.None); for (var i = 0; i < prefetchCount; i++) { await consumer.HandleBasicDeliver( "1", (ulong)i, false, "exchange", "routing,key", null, new ReadOnlyMemory <byte>()); } callerMock.Verify(x => x.EmptyCall(), Times.Once); Assert.Equal(1, orderingMap[thirdMiddleware.Number]); Assert.Equal(2, orderingMap[secondMiddleware.Number]); Assert.Equal(3, orderingMap[firstMiddleware.Number]); await messageHandler.StopAsync(CancellationToken.None); }