public async Task CorrectlyRetriesMessageWithExplicitDelayAsync( string subscriberName, int retryNum, bool requeueRequested, bool shouldRetry, bool shouldAckManually = true, string?expectedExchange = null, string?expectedRoutingKey = null, string?expectedQueueDeclaredName = null ) { #region Arrage const ulong deliveryTag = 100500; const string publishedFromExchange = "to-exchange"; const string publishedRoutingKey = "to-routing-key"; var retryDelay = TimeSpan.FromSeconds(10); var propertiesMock = new FakeOptions { Headers = new Dictionary <string, object>() }; propertiesMock.IncrementRetryCount(retryNum); var channelMock = new Mock <IModel>(); var messageContext = CreateTestMessageContext( deliveryTag, propertiesMock, publishedFromExchange, publishedRoutingKey ); var subscriberSettings = _configurationManager.GetSubscriberSettings(subscriberName); #endregion Arrage #region Act await _acknowledgementBehaviour.HandleAsync <TestMessage>( Retry.In(retryDelay), channelMock.Object, messageContext, subscriberSettings ); #endregion Act #region Assert if (requeueRequested && shouldRetry) { channelMock.Verify( c => c.QueueDeclare( expectedQueueDeclaredName, true, false, false, It.Is <Dictionary <string, object> >(d => string.IsNullOrEmpty(d[QueueArgument.DEAD_LETTER_EXCHANGE] as string) && // возвращается в осн. очередь через стандартный обменник (string)d[QueueArgument.DEAD_LETTER_ROUTING_KEY] == subscriberSettings.QueueName && // по названию оригинальной очереди d.ContainsKey(QueueArgument.EXPIRES) && // TTL самой очереди тоже (чтобы не мусорить) d.ContainsKey(QueueArgument.MESSAGE_TTL) // TTL должен быть указан ) ), "Очередь не отложенного ретрая не объявлена с ожидаемыми параметрами." ); channelMock.Verify( c => c.BasicPublish( expectedExchange, expectedRoutingKey, false, It.Is <IBasicProperties>(p => (int)p.Headers[RetryExtensions.RETRY_NUMBER_KEY] == retryNum + 1 && // счетчик ретраев +1 // проверка на прокидывание оригинальных (с тем, которыми был опубликован) ключ роутинга и обменник (string)p.Headers[RetryExtensions.ORIGINAL_EXCHANGE_HEADER] == publishedFromExchange && (string)p.Headers[RetryExtensions.ORIGINAL_ROUTING_KEY_HEADER] == publishedRoutingKey ), It.IsAny <ReadOnlyMemory <byte> >() ), "Ретрай не произведен с ожидаемыми параметрами. Сообщение не отправлено в конец очереди через стандартный обменник." ); if (shouldAckManually) { channelMock.Verify(c => c.BasicAck(deliveryTag, false), "Обработанное сообщение не подтверждено."); } } else { if (shouldAckManually) { channelMock.Verify(c => c.BasicReject(deliveryTag, false)); } } channelMock.VerifyNoOtherCalls(); #endregion Assert }
public async Task CorrectlyRetriesMessageToTheEndOfQueueAsync( string subscriberName, int retryNum, bool requeueRequested, bool shouldRetry, bool shouldAckManually = true, string?expectedExchange = null, string?expectedRoutingKey = null ) { #region Arrage const ulong deliveryTag = 100500; var propertiesMock = new FakeOptions { Headers = new Dictionary <string, object>() }; propertiesMock.IncrementRetryCount(retryNum); var channelMock = new Mock <IModel>(); var messageContext = CreateTestMessageContext(deliveryTag, propertiesMock); var subscriberSettings = _configurationManager.GetSubscriberSettings(subscriberName); #endregion Arrage #region Act await _acknowledgementBehaviour.HandleAsync <TestMessage>( new Reject("Ошибка", requeue : requeueRequested), channelMock.Object, messageContext, subscriberSettings ); #endregion Act #region Assert if (requeueRequested && shouldRetry) { channelMock.Verify( c => c.BasicPublish( expectedExchange, expectedRoutingKey, false, It.Is <IBasicProperties>(p => (int)p.Headers["x-retry-number"] == retryNum + 1), // счетчик ретраев +1 It.IsAny <ReadOnlyMemory <byte> >() ), "Ретрай не произведен. Сообщение не отправлено в конец очереди через стандартный обменник." ); if (shouldAckManually) { channelMock.Verify(c => c.BasicAck(deliveryTag, false), "Обработанное сообщение не подтверждено."); } } else { if (shouldAckManually) { channelMock.Verify(c => c.BasicReject(deliveryTag, false)); } } channelMock.VerifyNoOtherCalls(); #endregion Assert }