public async Task TestIncomingExpiredMessageGetsFilteredAsync() { using (TestAmqpPeer testPeer = new TestAmqpPeer()) { IConnection connection = await EstablishConnectionAsync(testPeer); await connection.StartAsync(); testPeer.ExpectBegin(); ISession session = await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge); IQueue queue = await session.GetQueueAsync("myQueue"); // Expected the consumer to attach and send credit, then send it an // already-expired message followed by a live message. testPeer.ExpectReceiverAttach(); string expiredMsgContent = "already-expired"; Amqp.Message message = CreateExpiredMessage(expiredMsgContent); testPeer.ExpectLinkFlowRespondWithTransfer(message: message); string liveMsgContent = "valid"; testPeer.SendTransferToLastOpenedLinkOnLastOpenedSession(message: new Amqp.Message() { BodySection = new AmqpValue() { Value = liveMsgContent } }, nextIncomingId: 2); IMessageConsumer consumer = await session.CreateConsumerAsync(queue); // Add message listener, expect the first message to be filtered due to expiry, // and the second message to be given to the test app and accepted. Action <DeliveryState> modifiedMatcher = state => { var modified = state as Modified; Assert.IsNotNull(modified); Assert.IsTrue(modified.DeliveryFailed); Assert.IsTrue(modified.UndeliverableHere); }; testPeer.ExpectDisposition(settled: true, stateMatcher: modifiedMatcher, firstDeliveryId: 1, lastDeliveryId: 1); testPeer.ExpectDisposition(settled: true, stateMatcher: Assert.IsInstanceOf <Accepted>, firstDeliveryId: 2, lastDeliveryId: 2); ManualResetEvent success = new ManualResetEvent(false); ManualResetEvent listenerFailure = new ManualResetEvent(false); consumer.Listener += m => { if (liveMsgContent.Equals(((ITextMessage)m).Text)) { success.Set(); } else { listenerFailure.Set(); } }; Assert.True(success.WaitOne(TimeSpan.FromSeconds(5)), "didn't get expected message"); Assert.False(listenerFailure.WaitOne(TimeSpan.FromMilliseconds(100)), "Received message when message should not have been received"); testPeer.WaitForAllMatchersToComplete(3000); testPeer.ExpectClose(); await connection.CloseAsync(); testPeer.WaitForAllMatchersToComplete(3000); } }
public void TestFailoverHandlesDropThenRejectionCloseAfterConnect() { using (TestAmqpPeer originalPeer = new TestAmqpPeer()) using (TestAmqpPeer rejectingPeer = new TestAmqpPeer()) using (TestAmqpPeer finalPeer = new TestAmqpPeer()) { ManualResetEvent originalConnected = new ManualResetEvent(false); ManualResetEvent finalConnected = new ManualResetEvent(false); // Create a peer to connect to, one to fail to reconnect to, and a final one to reconnect to var originalUri = CreatePeerUri(originalPeer); var rejectingUri = CreatePeerUri(rejectingPeer); var finalUri = CreatePeerUri(finalPeer); // Connect to the first originalPeer.ExpectSaslAnonymous(); originalPeer.ExpectOpen(); originalPeer.ExpectBegin(); long ird = 0; long rd = 2000; DateTime start = DateTime.UtcNow; NmsConnection connection = EstablishAnonymousConnection("failover.initialReconnectDelay=" + ird + "&failover.reconnectDelay=" + rd + "&failover.maxReconnectAttempts=10", originalPeer, rejectingPeer, finalPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalUri == uri.ToString()))) .Callback(() => { originalConnected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalUri == uri.ToString()))) .Callback(() => { finalConnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer"); Assert.False(finalConnected.WaitOne(TimeSpan.FromMilliseconds(100)), "Should not yet have connected to final peer"); // Set expectations on rejecting and final peer rejectingPeer.RejectConnect(AmqpError.NOT_FOUND, "Resource could not be located"); finalPeer.ExpectSaslAnonymous(); finalPeer.ExpectOpen(); finalPeer.ExpectBegin(); // Close the original peer and wait for things to shake out. originalPeer.Close(sendClose: false); rejectingPeer.WaitForAllMatchersToComplete(2000); Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer"); DateTime end = DateTime.UtcNow; long margin = 2000; // TODO: It is failing because, we are not handling rejected connection properly, when socket connection is established // but broker replies with amqp:connection-establishment-failed. Initially connection is treated as successful, which resets // the attempts counter. As a result next connect attempt is being made without any delay. // Assert.That((end - start).TotalMilliseconds, Is.GreaterThanOrEqualTo(ird + rd).And.LessThanOrEqualTo(ird + rd + margin), "Elapsed time outwith expected range for reconnect"); finalPeer.ExpectClose(); connection.Close(); finalPeer.WaitForAllMatchersToComplete(1000); } }
public async Task TestAcknowledgeIndividualMessagesAsync() { using (TestAmqpPeer testPeer = new TestAmqpPeer()) { int msgCount = 6; IConnection connection = await EstablishConnectionAsync(testPeer); await connection.StartAsync(); testPeer.ExpectBegin(); ISession session = await connection.CreateSessionAsync(AcknowledgementMode.IndividualAcknowledge); IQueue queue = await session.GetQueueAsync("myQueue"); testPeer.ExpectReceiverAttach(); testPeer.ExpectLinkFlowRespondWithTransfer( message: CreateMessageWithNullContent(), count: msgCount, drain: false, nextIncomingId: 1, addMessageNumberProperty: true, sendDrainFlowResponse: false, sendSettled: false, creditMatcher: credit => Assert.Greater(credit, msgCount)); IMessageConsumer consumer = await session.CreateConsumerAsync(queue); CountdownEvent latch = new CountdownEvent(msgCount); List <ITextMessage> messages = new List <ITextMessage>(); consumer.Listener += message => { messages.Add((ITextMessage)message); latch.Signal(); }; Assert.True(latch.Wait(TimeSpan.FromMilliseconds(1000)), $"Should receive: {msgCount}, but received: {messages.Count}"); Action <DeliveryState> dispositionMatcher = state => { Assert.AreEqual(state.Descriptor.Code, MessageSupport.ACCEPTED_INSTANCE.Descriptor.Code); }; // Acknowledge the messages in a random order and verify the individual dispositions have expected delivery state. Random random = new Random(); for (int i = 0; i < msgCount; i++) { var message = messages[random.Next(msgCount - i)]; messages.Remove(message); uint deliveryNumber = (uint)message.Properties.GetInt(TestAmqpPeer.MESSAGE_NUMBER) + 1; testPeer.ExpectDisposition(settled: true, stateMatcher: dispositionMatcher, firstDeliveryId: deliveryNumber, lastDeliveryId: deliveryNumber); await message.AcknowledgeAsync(); testPeer.WaitForAllMatchersToComplete(3000); } testPeer.ExpectClose(); await connection.CloseAsync(); testPeer.WaitForAllMatchersToComplete(3000); } }
private async Task DoSendingMessageNonPersistentTestImpl(bool anonymousProducer, bool setPriority, bool setOnProducer) { using (TestAmqpPeer testPeer = new TestAmqpPeer()) { //Add capability to indicate support for ANONYMOUS-RELAY Symbol[] serverCapabilities = { SymbolUtil.OPEN_CAPABILITY_ANONYMOUS_RELAY }; IConnection connection = await EstablishConnectionAsync(testPeer, serverCapabilities : serverCapabilities); testPeer.ExpectBegin(); string queueName = "myQueue"; Action <object> targetMatcher = t => { var target = t as Target; Assert.IsNotNull(target); if (anonymousProducer) { Assert.IsNull(target.Address); } else { Assert.AreEqual(queueName, target.Address); } }; testPeer.ExpectSenderAttach(targetMatcher: targetMatcher, sourceMatcher: Assert.NotNull, senderSettled: false); ISession session = await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge); IQueue queue = await session.GetQueueAsync(queueName); IMessageProducer producer = null; if (anonymousProducer) { producer = await session.CreateProducerAsync(); } else { producer = await session.CreateProducerAsync(queue); } byte priority = 5; String text = "myMessage"; testPeer.ExpectTransfer(messageMatcher: message => { if (setPriority) { Assert.IsFalse(message.Header.Durable); Assert.AreEqual(5, message.Header.Priority); } Assert.AreEqual(text, (message.BodySection as AmqpValue).Value); }, stateMatcher: Assert.IsNull, settled: false, sendResponseDisposition: true, responseState: new Accepted(), responseSettled: true); ITextMessage textMessage = await session.CreateTextMessageAsync(text); if (setOnProducer) { producer.DeliveryMode = MsgDeliveryMode.NonPersistent; if (setPriority) { producer.Priority = (MsgPriority)5; } if (anonymousProducer) { await producer.SendAsync(queue, textMessage); } else { await producer.SendAsync(textMessage); } } else { if (anonymousProducer) { await producer.SendAsync(destination : queue, message : textMessage, deliveryMode : MsgDeliveryMode.NonPersistent, priority : setPriority?(MsgPriority)priority : NMSConstants.defaultPriority, timeToLive : NMSConstants.defaultTimeToLive); } else { await producer.SendAsync(message : textMessage, deliveryMode : MsgDeliveryMode.NonPersistent, priority : setPriority?(MsgPriority)priority : NMSConstants.defaultPriority, timeToLive : NMSConstants.defaultTimeToLive); } } Assert.AreEqual(MsgDeliveryMode.NonPersistent, textMessage.NMSDeliveryMode, "Should have NonPersistent delivery mode set"); testPeer.WaitForAllMatchersToComplete(1000); testPeer.ExpectClose(); await connection.CloseAsync(); testPeer.WaitForAllMatchersToComplete(1000); } }
private async Task DoSendingMessageNonPersistentTestImpl(bool setPriority) { using (TestAmqpPeer testPeer = new TestAmqpPeer()) { //Add capability to indicate support for ANONYMOUS-RELAY Symbol[] serverCapabilities = { SymbolUtil.OPEN_CAPABILITY_ANONYMOUS_RELAY }; var context = await EstablishNMSContextAsync(testPeer, serverCapabilities : serverCapabilities); testPeer.ExpectBegin(); string queueName = "myQueue"; Action <object> targetMatcher = t => { var target = t as Target; Assert.IsNotNull(target); }; testPeer.ExpectSenderAttach(targetMatcher: targetMatcher, sourceMatcher: Assert.NotNull, senderSettled: false); IQueue queue = await context.GetQueueAsync(queueName); INMSProducer producer = await context.CreateProducerAsync(); byte priority = 5; String text = "myMessage"; testPeer.ExpectTransfer(messageMatcher: message => { if (setPriority) { Assert.IsFalse(message.Header.Durable); Assert.AreEqual(priority, message.Header.Priority); } Assert.AreEqual(text, (message.BodySection as AmqpValue).Value); }, stateMatcher: Assert.IsNull, settled: false, sendResponseDisposition: true, responseState: new Accepted(), responseSettled: true); ITextMessage textMessage = await context.CreateTextMessageAsync(text); producer.DeliveryMode = MsgDeliveryMode.NonPersistent; if (setPriority) { producer.Priority = (MsgPriority)priority; } await producer.SendAsync(queue, textMessage); Assert.AreEqual(MsgDeliveryMode.NonPersistent, textMessage.NMSDeliveryMode, "Should have NonPersistent delivery mode set"); testPeer.WaitForAllMatchersToComplete(1000); testPeer.ExpectEnd(); testPeer.ExpectClose(); await context.CloseAsync(); testPeer.WaitForAllMatchersToComplete(1000); } }
public async Task TestRemotelyEndConnectionWithSessionWithConsumer() { string errorMessage = "buba"; using (TestAmqpPeer testPeer = new TestAmqpPeer()) { IConnection connection = await EstablishConnectionAsync(testPeer); testPeer.ExpectBegin(); ISession session = await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge); // Create a consumer, then remotely end the connection afterwards. testPeer.ExpectReceiverAttach(); testPeer.ExpectLinkFlow(); testPeer.RemotelyCloseConnection(expectCloseResponse: true, errorCondition: AmqpError.RESOURCE_LIMIT_EXCEEDED, errorMessage: errorMessage); IQueue queue = await session.GetQueueAsync("myQueue"); IMessageConsumer consumer = await session.CreateConsumerAsync(queue); Assert.That(() => ((NmsConnection)connection).IsConnected, Is.False.After(10_000, 100), "Connection never closes."); try { await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge); Assert.Fail("Expected ISE to be thrown due to being closed"); } catch (NMSConnectionException e) { Assert.True(e.ToString().Contains(AmqpError.RESOURCE_LIMIT_EXCEEDED)); Assert.True(e.ToString().Contains(errorMessage)); } // Verify the session is now marked closed try { var _ = session.AcknowledgementMode; Assert.Fail("Expected ISE to be thrown due to being closed"); } catch (IllegalStateException e) { Assert.True(e.ToString().Contains(AmqpError.RESOURCE_LIMIT_EXCEEDED)); Assert.True(e.ToString().Contains(errorMessage)); } // Verify the consumer is now marked closed try { consumer.Listener += message => { }; } catch (IllegalStateException e) { Assert.True(e.ToString().Contains(AmqpError.RESOURCE_LIMIT_EXCEEDED)); Assert.True(e.ToString().Contains(errorMessage)); } // Try closing them explicitly, should effectively no-op in client. // The test peer will throw during close if it sends anything. await consumer.CloseAsync(); await session.CloseAsync(); await connection.CloseAsync(); } }
public void TestRecoverOrderingWithAsyncConsumer() { ManualResetEvent latch = new ManualResetEvent(false); Exception asyncError = null; int recoverCount = 5; int messageCount = 8; int testPayloadLength = 255; string payload = Encoding.UTF8.GetString(new byte[testPayloadLength]); using (TestAmqpPeer testPeer = new TestAmqpPeer()) { IConnection connection = EstablishConnection(testPeer); connection.Start(); testPeer.ExpectBegin(); ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge); IQueue destination = session.GetQueue("myQueue"); connection.Start(); testPeer.ExpectReceiverAttach(); testPeer.ExpectLinkFlowRespondWithTransfer( message: new Amqp.Message() { BodySection = new AmqpValue() { Value = payload } }, count: messageCount, drain: false, nextIncomingId: 1, addMessageNumberProperty: true, sendDrainFlowResponse: false, sendSettled: false, creditMatcher: credit => Assert.Greater(credit, messageCount) ); IMessageConsumer consumer = session.CreateConsumer(destination); bool complete = false; int messageSeen = 0; int expectedIndex = 0; consumer.Listener += message => { if (complete) { return; } try { int actualIndex = message.Properties.GetInt(TestAmqpPeer.MESSAGE_NUMBER); Assert.AreEqual(expectedIndex, actualIndex, "Received Message Out Of Order"); // don't ack the message until we receive it X times if (messageSeen < recoverCount) { session.Recover(); messageSeen++; } else { messageSeen = 0; expectedIndex++; // Have the peer expect the accept the disposition (1-based, hence pre-incremented). testPeer.ExpectDisposition(settled: true, stateMatcher: state => Assert.AreEqual(state.Descriptor.Code, MessageSupport.ACCEPTED_INSTANCE.Descriptor.Code )); message.Acknowledge(); if (expectedIndex == messageCount) { complete = true; latch.Set(); } } } catch (Exception e) { complete = true; asyncError = e; latch.Set(); } }; Assert.True(latch.WaitOne(TimeSpan.FromSeconds(15)), "Messages not received within given timeout."); Assert.IsNull(asyncError, "Unexpected exception"); testPeer.WaitForAllMatchersToComplete(2000); testPeer.ExpectClose(); connection.Close(); testPeer.WaitForAllMatchersToComplete(2000); } }
public void TestConsumerCanReceivesMessagesWhenConnectionLostDuringAutoAck() { using (TestAmqpPeer originalPeer = new TestAmqpPeer()) using (TestAmqpPeer finalPeer = new TestAmqpPeer()) { ManualResetEvent consumerReady = new ManualResetEvent(false); ManualResetEvent originalConnected = new ManualResetEvent(false); ManualResetEvent finalConnected = new ManualResetEvent(false); // Connect to the first peer originalPeer.ExpectSaslAnonymous(); originalPeer.ExpectOpen(); originalPeer.ExpectBegin(); originalPeer.ExpectBegin(); NmsConnection connection = EstablishAnonymousConnection(originalPeer, finalPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.IsAny <Uri>())) .Callback(() => { originalConnected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionRestored(It.IsAny <Uri>())) .Callback(() => { finalConnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer"); originalPeer.ExpectReceiverAttach(); originalPeer.ExpectLinkFlowRespondWithTransfer(message: CreateMessageWithContent(), 1); originalPeer.RunAfterLastHandler(() => consumerReady.WaitOne(TimeSpan.FromSeconds(2))); originalPeer.DropAfterLastMatcher(); // Post Failover Expectations of FinalPeer finalPeer.ExpectSaslAnonymous(); finalPeer.ExpectOpen(); finalPeer.ExpectBegin(); finalPeer.ExpectBegin(); finalPeer.ExpectReceiverAttach(); finalPeer.ExpectLinkFlowRespondWithTransfer(message: CreateMessageWithContent(), 1); finalPeer.ExpectDispositionThatIsAcceptedAndSettled(); ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); IQueue queue = session.GetQueue("myQueue"); IMessageConsumer messageConsumer = session.CreateConsumer(queue); CountdownEvent msgReceivedLatch = new CountdownEvent(2); messageConsumer.Listener += message => { if (msgReceivedLatch.CurrentCount == 2) { consumerReady.Set(); finalConnected.WaitOne(2000); } msgReceivedLatch.Signal(); }; finalPeer.WaitForAllMatchersToComplete(5000); Assert.IsTrue(msgReceivedLatch.Wait(TimeSpan.FromSeconds(10)), $"Expected 2 messages, but got {2 - msgReceivedLatch.CurrentCount}"); } }
public void TestTempDestinationRecreatedAfterConnectionFailsOver() { using (TestAmqpPeer originalPeer = new TestAmqpPeer()) using (TestAmqpPeer finalPeer = new TestAmqpPeer()) { ManualResetEvent originalConnected = new ManualResetEvent(false); ManualResetEvent finalConnected = new ManualResetEvent(false); // Create a peer to connect to, then one to reconnect to var originalUri = CreatePeerUri(originalPeer); var finalUri = CreatePeerUri(finalPeer); originalPeer.ExpectSaslAnonymous(); originalPeer.ExpectOpen(); originalPeer.ExpectBegin(); originalPeer.ExpectBegin(); string dynamicAddress1 = "myTempTopicAddress"; originalPeer.ExpectTempTopicCreationAttach(dynamicAddress1); originalPeer.DropAfterLastMatcher(); NmsConnection connection = EstablishAnonymousConnection(originalPeer, finalPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalUri == uri.ToString()))) .Callback(() => { originalConnected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalUri == uri.ToString()))) .Callback(() => { finalConnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer"); // Post Failover Expectations of FinalPeer finalPeer.ExpectSaslAnonymous(); finalPeer.ExpectOpen(); finalPeer.ExpectBegin(); String dynamicAddress2 = "myTempTopicAddress2"; finalPeer.ExpectTempTopicCreationAttach(dynamicAddress2); // Session is recreated after previous temporary destinations are recreated on failover. finalPeer.ExpectBegin(); ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); ITemporaryTopic temporaryTopic = session.CreateTemporaryTopic(); Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer"); // Delete the temporary Topic and close the session. finalPeer.ExpectDetach(expectClosed: true, sendResponse: true, replyClosed: true); finalPeer.ExpectEnd(); temporaryTopic.Delete(); session.Close(); // Shut it down finalPeer.ExpectClose(); connection.Close(); originalPeer.WaitForAllMatchersToComplete(2000); finalPeer.WaitForAllMatchersToComplete(1000); } }
public void TestCreateConsumerAfterConnectionDrops() { using (TestAmqpPeer originalPeer = new TestAmqpPeer()) using (TestAmqpPeer finalPeer = new TestAmqpPeer()) { ManualResetEvent originalConnected = new ManualResetEvent(false); ManualResetEvent finalConnected = new ManualResetEvent(false); // Create a peer to connect to, then one to reconnect to var originalUri = CreatePeerUri(originalPeer); var finalUri = CreatePeerUri(finalPeer); // Connect to the first peer originalPeer.ExpectSaslAnonymous(); originalPeer.ExpectOpen(); originalPeer.ExpectBegin(); originalPeer.ExpectBegin(); originalPeer.DropAfterLastMatcher(); NmsConnection connection = EstablishAnonymousConnection(originalPeer, finalPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalUri == uri.ToString()))) .Callback(() => { originalConnected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalUri == uri.ToString()))) .Callback(() => { finalConnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer"); // Post Failover Expectations of FinalPeer finalPeer.ExpectSaslAnonymous(); finalPeer.ExpectOpen(); finalPeer.ExpectBegin(); finalPeer.ExpectBegin(); finalPeer.ExpectReceiverAttach(); finalPeer.ExpectLinkFlow(drain: false, sendDrainFlowResponse: false, creditMatcher: credit => Assert.AreEqual(credit, 200)); finalPeer.ExpectDetach(expectClosed: true, sendResponse: true, replyClosed: true); finalPeer.ExpectClose(); ISession session = connection.CreateSession(); IQueue queue = session.GetQueue("myQueue"); IMessageConsumer consumer = session.CreateConsumer(queue); Assert.IsNull(consumer.Receive(TimeSpan.FromMilliseconds(500))); Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer"); consumer.Close(); // Shut it down connection.Close(); finalPeer.WaitForAllMatchersToComplete(1000); } }
public void TestFailoverHandlesDropThenRejectionCloseAfterConnect() { using (TestAmqpPeer originalPeer = new TestAmqpPeer()) using (TestAmqpPeer rejectingPeer = new TestAmqpPeer()) using (TestAmqpPeer finalPeer = new TestAmqpPeer()) { ManualResetEvent originalConnected = new ManualResetEvent(false); ManualResetEvent finalConnected = new ManualResetEvent(false); // Create a peer to connect to, one to fail to reconnect to, and a final one to reconnect to var originalUri = CreatePeerUri(originalPeer); var rejectingUri = CreatePeerUri(rejectingPeer); var finalUri = CreatePeerUri(finalPeer); Logger.Info($"Original peer is at: {originalUri}"); Logger.Info($"Rejecting peer is at: {rejectingUri}"); Logger.Info($"Final peer is at: {finalUri}"); // Connect to the first originalPeer.ExpectSaslAnonymous(); originalPeer.ExpectOpen(); originalPeer.ExpectBegin(); long ird = 0; long rd = 2000; NmsConnection connection = EstablishAnonymousConnection("failover.initialReconnectDelay=" + ird + "&failover.reconnectDelay=" + rd + "&failover.maxReconnectAttempts=10", originalPeer, rejectingPeer, finalPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalUri == uri.ToString()))) .Callback(() => { originalConnected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalUri == uri.ToString()))) .Callback(() => { finalConnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer"); Assert.False(finalConnected.WaitOne(TimeSpan.FromMilliseconds(100)), "Should not yet have connected to final peer"); // Set expectations on rejecting and final peer rejectingPeer.RejectConnect(AmqpError.NOT_FOUND, "Resource could not be located"); finalPeer.ExpectSaslAnonymous(); finalPeer.ExpectOpen(); finalPeer.ExpectBegin(); // Close the original peer and wait for things to shake out. originalPeer.Close(sendClose: true); rejectingPeer.WaitForAllMatchersToComplete(2000); Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(10)), "Should connect to final peer"); finalPeer.ExpectClose(); connection.Close(); finalPeer.WaitForAllMatchersToComplete(1000); } }