public void StartConsumerWithoutQueueTest() { var consumer = new AmqpConsumer(channelMock.Object, publisherMock.Object, builderMock.Object, managerMock.Object); Assert.Throws <ArgumentNullException>(() => consumer.Start(processorMock.Object, string.Empty)); }
public void ReceiveAsyncDetectsAnEmbeddedAmqpErrorForOperationCanceled() { var eventHub = "eventHubName"; var consumerGroup = "$DEFAULT"; var partition = "3"; var identifier = "cusTOM-1D"; var eventPosition = EventPosition.FromOffset(123); var trackLastEnqueued = false; var invalidateOnSteal = true; var ownerLevel = 123L; var tokenValue = "123ABC"; var retryPolicy = new BasicRetryPolicy(new EventHubsRetryOptions()); var embeddedException = new OperationCanceledException("", new AmqpException(new Error { Condition = AmqpError.ArgumentError })); var mockConverter = new Mock <AmqpMessageConverter>(); var mockCredential = new Mock <TokenCredential>(); var mockScope = new Mock <AmqpConnectionScope>(); using var cancellationSource = new CancellationTokenSource(); mockCredential .Setup(credential => credential.GetTokenAsync(It.IsAny <TokenRequestContext>(), It.Is <CancellationToken>(value => value == cancellationSource.Token))) .Returns(new ValueTask <AccessToken>(new AccessToken(tokenValue, DateTimeOffset.MaxValue))); mockScope .Setup(scope => scope.OpenConsumerLinkAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <EventPosition>(), It.IsAny <TimeSpan>(), It.IsAny <TimeSpan>(), It.IsAny <uint>(), It.IsAny <long?>(), It.IsAny <long?>(), It.IsAny <bool>(), It.IsAny <string>(), It.IsAny <CancellationToken>())) .Throws(embeddedException); var consumer = new AmqpConsumer(eventHub, consumerGroup, partition, identifier, eventPosition, trackLastEnqueued, invalidateOnSteal, ownerLevel, null, null, mockScope.Object, Mock.Of <AmqpMessageConverter>(), retryPolicy); Assert.That(async() => await consumer.ReceiveAsync(100, null, cancellationSource.Token), Throws.InstanceOf <OperationCanceledException>()); mockScope .Verify(scope => scope.OpenConsumerLinkAsync( It.Is <string>(value => value == consumerGroup), It.Is <string>(value => value == partition), It.Is <EventPosition>(value => value == eventPosition), It.IsAny <TimeSpan>(), It.IsAny <TimeSpan>(), It.IsAny <uint>(), It.IsAny <long?>(), It.Is <long?>(value => value == ownerLevel), It.Is <bool>(value => value == trackLastEnqueued), It.Is <string>(value => value == identifier), It.IsAny <CancellationToken>()), Times.Once()); }
public void StartConsumerAlreadyStartedTest() { var consumer = new AmqpConsumer(channelMock.Object, publisherMock.Object, builderMock.Object, managerMock.Object); consumer.Start(processorMock.Object, queueName); Assert.Throws <InvalidOperationException>(() => consumer.Start(processorMock.Object, queueName)); }
public void CloseRespectsTheCancellationToken() { var consumer = new AmqpConsumer("aHub", "$DEFAULT", "0", EventPosition.Earliest, true, null, null, Mock.Of <AmqpConnectionScope>(), Mock.Of <AmqpMessageConverter>(), Mock.Of <EventHubsRetryPolicy>()); using var cancellationSource = new CancellationTokenSource(); cancellationSource.Cancel(); Assert.That(async() => await consumer.CloseAsync(cancellationSource.Token), Throws.InstanceOf <TaskCanceledException>(), "Cancellation should trigger the appropriate exception."); Assert.That(consumer.IsClosed, Is.False, "Cancellation should have interrupted closing and left the consumer in an open state."); }
public async Task CloseMarksTheConsumerAsClosed() { var consumer = new AmqpConsumer("aHub", "$DEFAULT", "0", EventPosition.Earliest, true, null, null, Mock.Of <AmqpConnectionScope>(), Mock.Of <AmqpMessageConverter>(), Mock.Of <EventHubsRetryPolicy>()); Assert.That(consumer.IsClosed, Is.False, "The consumer should not be closed on creation"); await consumer.CloseAsync(CancellationToken.None); Assert.That(consumer.IsClosed, Is.True, "The consumer should be marked as closed after closing"); }
public void ReceiveAsyncAppliesTheRetryPolicyForAmqpErrors(EventHubsRetryOptions retryOptions) { var eventHub = "eventHubName"; var consumerGroup = "$DEFAULT"; var partition = "3"; var eventPosition = EventPosition.FromOffset(123); var trackLastEnqueued = false; var invalidateOnSteal = true; var ownerLevel = 123L; var tokenValue = "123ABC"; var retryPolicy = new BasicRetryPolicy(retryOptions); var retriableException = AmqpError.CreateExceptionForError(new Error { Condition = AmqpError.ServerBusyError }, "dummy"); var mockConverter = new Mock <AmqpMessageConverter>(); var mockCredential = new Mock <TokenCredential>(); var mockScope = new Mock <AmqpConnectionScope>(); using var cancellationSource = new CancellationTokenSource(); mockCredential .Setup(credential => credential.GetTokenAsync(It.IsAny <TokenRequestContext>(), It.Is <CancellationToken>(value => value == cancellationSource.Token))) .Returns(new ValueTask <AccessToken>(new AccessToken(tokenValue, DateTimeOffset.MaxValue))); mockScope .Setup(scope => scope.OpenConsumerLinkAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <EventPosition>(), It.IsAny <TimeSpan>(), It.IsAny <uint>(), It.IsAny <long?>(), It.IsAny <long?>(), It.IsAny <bool>(), It.IsAny <CancellationToken>())) .Throws(retriableException); var consumer = new AmqpConsumer(eventHub, consumerGroup, partition, eventPosition, trackLastEnqueued, invalidateOnSteal, ownerLevel, null, null, mockScope.Object, Mock.Of <AmqpMessageConverter>(), retryPolicy); Assert.That(async() => await consumer.ReceiveAsync(100, null, cancellationSource.Token), Throws.InstanceOf(retriableException.GetType())); mockScope .Verify(scope => scope.OpenConsumerLinkAsync( It.Is <string>(value => value == consumerGroup), It.Is <string>(value => value == partition), It.Is <EventPosition>(value => value == eventPosition), It.IsAny <TimeSpan>(), It.IsAny <uint>(), It.IsAny <long?>(), It.Is <long?>(value => value == ownerLevel), It.Is <bool>(value => value == trackLastEnqueued), It.IsAny <CancellationToken>()), Times.Exactly(1 + retryOptions.MaximumRetries)); }
public void StartConsumerTest() { var consumer = new AmqpConsumer(channelMock.Object, publisherMock.Object, builderMock.Object, managerMock.Object); Assert.True(String.IsNullOrEmpty(consumer.ConsumerTag)); consumer.Start(processorMock.Object, queueName); Assert.False(String.IsNullOrEmpty(consumer.ConsumerTag)); consumer.Stop(); Assert.True(String.IsNullOrEmpty(consumer.ConsumerTag)); channelMock.Verify(c => c.BasicConsume(queueName, false, It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IDictionary <string, object> >(), It.IsAny <IBasicConsumer>())); managerMock.Verify(m => m.EnsureQueue(queueName)); }
public void ReceiveAsyncRespectsTheRetryPolicy(RetryOptions retryOptions) { var eventHub = "eventHubName"; var consumerGroup = "$DEFAULT"; var partition = "3"; var eventPosition = EventPosition.FromOffset(123); var options = new EventHubConsumerClientOptions { Identifier = "OMG!" }; var tokenValue = "123ABC"; var retryPolicy = new BasicRetryPolicy(retryOptions); var retriableException = new EventHubsException(true, "Test"); var mockConverter = new Mock <AmqpMessageConverter>(); var mockCredential = new Mock <TokenCredential>(); var mockScope = new Mock <AmqpConnectionScope>(); using var cancellationSource = new CancellationTokenSource(); mockCredential .Setup(credential => credential.GetTokenAsync(It.IsAny <TokenRequestContext>(), It.Is <CancellationToken>(value => value == cancellationSource.Token))) .Returns(new ValueTask <AccessToken>(new AccessToken(tokenValue, DateTimeOffset.MaxValue))); mockScope .Setup(scope => scope.OpenConsumerLinkAsync( It.IsAny <string>(), It.IsAny <string>(), It.IsAny <EventPosition>(), It.IsAny <EventHubConsumerClientOptions>(), It.IsAny <TimeSpan>(), It.IsAny <CancellationToken>())) .Throws(retriableException); var consumer = new AmqpConsumer(eventHub, consumerGroup, partition, eventPosition, options, mockScope.Object, Mock.Of <AmqpMessageConverter>(), retryPolicy); Assert.That(async() => await consumer.ReceiveAsync(100, null, cancellationSource.Token), Throws.InstanceOf(retriableException.GetType())); mockScope .Verify(scope => scope.OpenConsumerLinkAsync( It.Is <string>(value => value == consumerGroup), It.Is <string>(value => value == partition), It.Is <EventPosition>(value => value == eventPosition), It.Is <EventHubConsumerClientOptions>(value => value == options), It.IsAny <TimeSpan>(), It.IsAny <CancellationToken>()), Times.Exactly(1 + retryOptions.MaximumRetries)); }
public void ReceiveAsyncValidatesTheMaximumMessageCount(int count) { var eventHub = "eventHubName"; var consumerGroup = "$DEFAULT"; var partition = "3"; var eventPosition = EventPosition.FromOffset(123); var retryPolicy = new BasicRetryPolicy(new EventHubsRetryOptions()); var retriableException = new EventHubsException(true, "Test"); var mockConverter = new Mock <AmqpMessageConverter>(); var mockCredential = new Mock <TokenCredential>(); var mockScope = new Mock <AmqpConnectionScope>(); using var cancellationSource = new CancellationTokenSource(); var consumer = new AmqpConsumer(eventHub, consumerGroup, partition, eventPosition, true, null, null, mockScope.Object, Mock.Of <AmqpMessageConverter>(), retryPolicy); Assert.That(async() => await consumer.ReceiveAsync(count, null, cancellationSource.Token), Throws.InstanceOf <ArgumentException>()); }
public void ReceiveAsyncValidatesConnectionClosed() { var endpoint = new Uri("amqps://not.real.com"); var eventHub = "eventHubName"; var consumerGroup = "$DEFAULT"; var partition = "3"; var eventPosition = EventPosition.FromOffset(123); var options = new EventHubConsumerClientOptions(); var retryPolicy = new BasicRetryPolicy(new EventHubsRetryOptions()); var mockCredential = new EventHubTokenCredential(Mock.Of <TokenCredential>()); var scope = new AmqpConnectionScope(endpoint, endpoint, eventHub, mockCredential, EventHubsTransportType.AmqpTcp, null); var consumer = new AmqpConsumer(eventHub, consumerGroup, partition, eventPosition, true, false, null, null, null, scope, Mock.Of <AmqpMessageConverter>(), retryPolicy); scope.Dispose(); Assert.That(async() => await consumer.ReceiveAsync(100, null, CancellationToken.None), Throws.InstanceOf <EventHubsException>().And.Property(nameof(EventHubsException.Reason)).EqualTo(EventHubsException.FailureReason.ClientClosed)); }
public async Task ReceiveAsyncValidatesClosed() { var eventHub = "eventHubName"; var consumerGroup = "$DEFAULT"; var partition = "3"; var eventPosition = EventPosition.FromOffset(123); var options = new EventHubConsumerClientOptions(); var retryPolicy = new BasicRetryPolicy(new EventHubsRetryOptions()); var retriableException = new EventHubsException(true, "Test"); var mockConverter = new Mock <AmqpMessageConverter>(); var mockCredential = new Mock <TokenCredential>(); var mockScope = new Mock <AmqpConnectionScope>(); using var cancellationSource = new CancellationTokenSource(); var consumer = new AmqpConsumer(eventHub, consumerGroup, partition, eventPosition, true, false, null, null, null, mockScope.Object, Mock.Of <AmqpMessageConverter>(), retryPolicy); await consumer.CloseAsync(cancellationSource.Token); Assert.That(async() => await consumer.ReceiveAsync(100, null, cancellationSource.Token), Throws.InstanceOf <EventHubsException>().And.Property(nameof(EventHubsException.Reason)).EqualTo(EventHubsException.FailureReason.ClientClosed)); }
public void ReceiveAsyncRespectsTheCancellationTokenIfSetWhenCalled() { var eventHub = "eventHubName"; var consumerGroup = "$DEFAULT"; var partition = "3"; var identifier = "cusTOM-1D"; var eventPosition = EventPosition.FromOffset(123); var retryPolicy = new BasicRetryPolicy(new EventHubsRetryOptions()); var retriableException = new EventHubsException(true, "Test"); var mockConverter = new Mock <AmqpMessageConverter>(); var mockCredential = new Mock <TokenCredential>(); var mockScope = new Mock <AmqpConnectionScope>(); using var cancellationSource = new CancellationTokenSource(); cancellationSource.Cancel(); var consumer = new AmqpConsumer(eventHub, consumerGroup, partition, identifier, eventPosition, true, true, null, null, null, mockScope.Object, Mock.Of <AmqpMessageConverter>(), retryPolicy); Assert.That(async() => await consumer.ReceiveAsync(100, null, cancellationSource.Token), Throws.InstanceOf <TaskCanceledException>()); }
public void Initialize(AmqpConsumer consumer) { }
/// <summary> /// Sets the active partition stolen exception for a consumer, using its /// private field. /// </summary> /// /// <param name="consumer">The consumer to retrieve the exception from.</param> /// <param name="exception">The exception to set.</param> /// private void SetActivePartitionStolenException(AmqpConsumer consumer, Exception exception) => typeof(AmqpConsumer) .GetField("_activePartitionStolenException", BindingFlags.Instance | BindingFlags.NonPublic) .SetValue(consumer, exception);
/// <summary> /// Gets the active partition stolen exception for a consumer, using its /// private field. /// </summary> /// /// <param name="consumer">The consumer to retrieve the exception from.</param> /// /// <returns>The active partition stolen exception of the <paramref name="consumer"/>, if present; otherwise, <c>null</c>.</returns> /// private Exception GetActivePartitionStolenException(AmqpConsumer consumer) => (Exception) typeof(AmqpConsumer) .GetField("_activePartitionStolenException", BindingFlags.Instance | BindingFlags.NonPublic) .GetValue(consumer);