public void OpenConsumerLinkPreservesTheStolenExceptionWhenInvalidateIsSet()
        {
            var eventHub          = "fake-hub";
            var terminalException = new EventHubsException(eventHub, "Expected", EventHubsException.FailureReason.ConsumerDisconnected);
            var mockConsumer      = new MockAmqpConsumer(eventHub, true, terminalException);

            SetActivePartitionStolenException(mockConsumer, terminalException);
            Assert.That(async() => await mockConsumer.InvokeCreateConsumerLinkAsync("cg", "0", EventPosition.Earliest, 300, null, 34, true, TimeSpan.FromSeconds(30), CancellationToken.None), Throws.InstanceOf(terminalException.GetType()), "The exception should have been surfaced on the first call.");
            Assert.That(async() => await mockConsumer.InvokeCreateConsumerLinkAsync("cg", "0", EventPosition.Earliest, 300, null, 34, true, TimeSpan.FromSeconds(30), CancellationToken.None), Throws.InstanceOf(terminalException.GetType()), "The exception should have been surfaced on the second call.");
            Assert.That(async() => await mockConsumer.InvokeCreateConsumerLinkAsync("cg", "0", EventPosition.Earliest, 300, null, 34, true, TimeSpan.FromSeconds(30), CancellationToken.None), Throws.InstanceOf(terminalException.GetType()), "The exception should have been surfaced on the third call.");

            var capturedException = GetActivePartitionStolenException(mockConsumer);

            Assert.That(capturedException, Is.SameAs(terminalException), "The active exception should have been preserved after the calls were completed.");
        }
        public void CloseConsumerLinkIgnoresGeneralExceptions(Exception terminalException)
        {
            var eventHub     = "fake-hub";
            var link         = new ReceivingAmqpLink(new AmqpLinkSettings());
            var mockConsumer = new MockAmqpConsumer(eventHub, true, terminalException);

            try
            {
                mockConsumer.InvokeCloseConsumerLink(link);
                Assert.That(GetActivePartitionStolenException(mockConsumer), Is.Null);
            }
            finally
            {
                link?.SafeClose();
            }
        }
        public void OpenConsumerLinkClearsTheStolenExceptionWhenInvalidateIsNotSet()
        {
            var eventHub          = "fake-hub";
            var terminalException = new AmqpException(new Error {
                Condition = AmqpErrorCode.Stolen
            });
            var mockConsumer = new MockAmqpConsumer(eventHub, false, terminalException);

            SetActivePartitionStolenException(mockConsumer, terminalException);
            Assert.That(async() => await mockConsumer.InvokeCreateConsumerLinkAsync("cg", "0", EventPosition.Earliest, 300, null, 34, true, TimeSpan.FromSeconds(30), CancellationToken.None), Throws.InstanceOf(terminalException.GetType()), "The exception should have been surfaced on the first call.");
            Assert.That(async() => await mockConsumer.InvokeCreateConsumerLinkAsync("cg", "0", EventPosition.Earliest, 300, null, 34, true, TimeSpan.FromSeconds(30), CancellationToken.None), Throws.Nothing, "The second call should not throw.");
            Assert.That(async() => await mockConsumer.InvokeCreateConsumerLinkAsync("cg", "0", EventPosition.Earliest, 300, null, 34, true, TimeSpan.FromSeconds(30), CancellationToken.None), Throws.Nothing, "The third call should not throw.");

            var capturedException = GetActivePartitionStolenException(mockConsumer);

            Assert.That(capturedException, Is.Null, "The active exception should have been cleared after it was surfaced.");
        }
        public void CloseConsumerLinkDetectsAStolenPartition()
        {
            var eventHub          = "fake-hub";
            var terminalException = new AmqpException(new Error {
                Condition = AmqpErrorCode.Stolen
            });
            var link         = new ReceivingAmqpLink(new AmqpLinkSettings());
            var mockConsumer = new MockAmqpConsumer(eventHub, true, terminalException);

            try
            {
                mockConsumer.InvokeCloseConsumerLink(link);
                Assert.That(GetActivePartitionStolenException(mockConsumer), Is.SameAs(terminalException));
            }
            finally
            {
                link?.SafeClose();
            }
        }
        public async Task ReceiveAsyncDetectsAndCapturesAStolenPartition()
        {
            var eventHub          = "fake-hub";
            var terminalException = new AmqpException(AmqpErrorCode.Stolen, "This is a terminal exception message.");
            var expectedException = terminalException.TranslateServiceException(eventHub);
            var capturedException = default(Exception);
            var mockConsumer      = new MockAmqpConsumer(eventHub, true, terminalException);

            mockConsumer.MockConnectionScope
            .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(terminalException);

            try
            {
                await mockConsumer.ReceiveAsync(10, TimeSpan.FromSeconds(1), CancellationToken.None);
            }
            catch (Exception ex)
            {
                capturedException = ex;
            }

            Assert.That(capturedException, Is.Not.Null, "An exception should have been surfaced.");
            Assert.That(capturedException.GetType(), Is.EqualTo(expectedException.GetType()), "The captured exception was not of the expected type.");
            Assert.That(capturedException.Message, Is.EqualTo(expectedException.Message), "The mocked terminal exception should have been surfaced.");

            var preservedException = GetActivePartitionStolenException(mockConsumer);

            Assert.That(preservedException, Is.SameAs(terminalException), "The preserved exception should match the terminal exception.");
        }
        public async Task ReceiveAsyncSurfacesStolenPartitionWhenInvalidated()
        {
            var eventHub          = "fake-hub";
            var terminalException = new AmqpException(AmqpErrorCode.Stolen, "This is a terminal exception message.");
            var expectedException = terminalException.TranslateServiceException(eventHub);
            var capturedException = default(Exception);
            var mockConsumer      = new MockAmqpConsumer(eventHub, true, terminalException);

            SetActivePartitionStolenException(mockConsumer, terminalException);

            try
            {
                await mockConsumer.ReceiveAsync(10, TimeSpan.FromSeconds(1), CancellationToken.None);
            }
            catch (Exception ex)
            {
                capturedException = ex;
            }

            Assert.That(capturedException, Is.Not.Null, "An exception should have been surfaced.");
            Assert.That(capturedException.GetType(), Is.EqualTo(expectedException.GetType()), "The captured exception was not of the expected type.");
            Assert.That(capturedException.Message, Is.EqualTo(expectedException.Message), "The mocked terminal exception should have been surfaced.");

            // Because the terminal exception was injected, it should not attempt to open the actual link.

            mockConsumer.MockConnectionScope
            .Verify(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>()),
                    Times.Never);
        }
        public async Task OpenConsumerLinkSurfacesAStolenPartition()
        {
            var eventHub          = "fake-hub";
            var terminalException = new EventHubsException(eventHub, "Expected", EventHubsException.FailureReason.ConsumerDisconnected);
            var capturedException = default(Exception);
            var mockConsumer      = new MockAmqpConsumer(eventHub, true, terminalException);

            SetActivePartitionStolenException(mockConsumer, terminalException);

            try
            {
                await mockConsumer.InvokeCreateConsumerLinkAsync("cg", "0", EventPosition.Earliest, 300, null, 34, true, TimeSpan.FromSeconds(30), CancellationToken.None);
            }
            catch (Exception ex)
            {
                capturedException = ex;
            }

            Assert.That(capturedException, Is.Not.Null, "An exception should have been surfaced.");
            Assert.That(capturedException.GetType(), Is.EqualTo(terminalException.GetType()), "The captured exception was not of the expected type.");
            Assert.That(capturedException, Is.SameAs(terminalException), "The mocked terminal exception should have been surfaced.");
        }