public void TestRemotelyCloseConsumer() { Mock <INmsConnectionListener> mockConnectionListener = new Mock <INmsConnectionListener>(); bool exceptionFired = false; using (TestAmqpPeer testAmqpPeer = new TestAmqpPeer(Address, User, Password)) { TestLinkProcessor testLinkProcessor = new TestLinkProcessor(); testAmqpPeer.RegisterLinkProcessor(testLinkProcessor); testAmqpPeer.Open(); NmsConnection connection = (NmsConnection)EstablishConnection(); connection.Start(); connection.AddConnectionListener(mockConnectionListener.Object); connection.ExceptionListener += exception => { exceptionFired = true; }; ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); IQueue queue = session.GetQueue("myQueue"); // Create a consumer, then remotely end it afterwards. IMessageConsumer consumer = session.CreateConsumer(queue); testLinkProcessor.CloseConsumer(); Assert.That(() => exceptionFired, Is.False.After(200), "Exception listener shouldn't fire with no MessageListener"); // Verify the consumer gets marked closed mockConnectionListener.Verify(listener => listener.OnConsumerClosed(It.Is <IMessageConsumer>(x => x == consumer), It.IsAny <Exception>()), Times.Once, "consumer never closed."); session.Close(); connection.Close(); } }
public void TestFailoverHandlesDropAfterSessionCloseRequested() { using (TestAmqpPeer originalPeer = new TestAmqpPeer()) { ManualResetEvent originalConnected = new ManualResetEvent(false); // Create a peer to connect to var originalUri = CreatePeerUri(originalPeer); // Connect to the first peer originalPeer.ExpectSaslAnonymous(); originalPeer.ExpectOpen(); originalPeer.ExpectBegin(); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalUri == uri.ToString()))) .Callback(() => { originalConnected.Set(); }); NmsConnection connection = EstablishAnonymousConnection(originalPeer); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to peer"); originalPeer.ExpectBegin(); originalPeer.ExpectEnd(sendResponse: false); originalPeer.DropAfterLastMatcher(); ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); ManualResetEvent sessionCloseCompleted = new ManualResetEvent(false); Exception sessionClosedThrew = null; Task.Run(() => { try { session.Close(); } catch (Exception e) { sessionClosedThrew = e; } finally { sessionCloseCompleted.Set(); } }); originalPeer.WaitForAllMatchersToComplete(2000); Assert.IsTrue(sessionCloseCompleted.WaitOne(TimeSpan.FromSeconds(3)), "Session close should have completed by now"); Assert.IsNull(sessionClosedThrew, "Session close should have completed normally"); connection.Close(); } }
public void TestRemotelyCloseProducer() { ManualResetEvent producentClosed = new ManualResetEvent(false); Mock <INmsConnectionListener> mockConnectionListener = new Mock <INmsConnectionListener>(); mockConnectionListener .Setup(listener => listener.OnProducerClosed(It.IsAny <NmsMessageProducer>(), It.IsAny <Exception>())) .Callback(() => { producentClosed.Set(); }); using (TestAmqpPeer testAmqpPeer = new TestAmqpPeer(Address, User, Password)) { testAmqpPeer.Open(); TestLinkProcessor testLinkProcessor = new TestLinkProcessor(); testAmqpPeer.RegisterLinkProcessor(testLinkProcessor); NmsConnection connection = (NmsConnection)EstablishConnection(); connection.AddConnectionListener(mockConnectionListener.Object); ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); IQueue destination = session.GetQueue("myQueue"); IMessageProducer producer = session.CreateProducer(destination); testLinkProcessor.Producer.Link.Close(); Assert.True(producentClosed.WaitOne(TimeSpan.FromMilliseconds(1000))); Assert.That(() => producer.DisableMessageID, Throws.Exception.InstanceOf <IllegalStateException>()); producer.Close(); session.Close(); connection.Close(); } }
public void TestCreateProducerAfterConnectionDrops() { 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.ExpectSenderAttach(); finalPeer.ExpectDetach(expectClosed: true, sendResponse: true, replyClosed: true); finalPeer.ExpectClose(); ISession session = connection.CreateSession(); IQueue queue = session.GetQueue("myQueue"); IMessageProducer producer = session.CreateProducer(queue); Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer"); producer.Close(); connection.Close(); finalPeer.WaitForAllMatchersToComplete(1000); } }
private void DoRemotelyCloseConsumerWithMessageListenerFiresNMSExceptionListenerTestImpl(Symbol errorType, string errorMessage) { using (TestAmqpPeer testPeer = new TestAmqpPeer()) { ManualResetEvent consumerClosed = new ManualResetEvent(false); ManualResetEvent exceptionListenerFired = new ManualResetEvent(false); testPeer.ExpectSaslAnonymous(); testPeer.ExpectOpen(); testPeer.ExpectBegin(); NmsConnection connection = EstablishAnonymousConnection("failover.maxReconnectAttempts=1", testPeer); connection.ExceptionListener += exception => { exceptionListenerFired.Set(); }; Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConsumerClosed(It.IsAny <IMessageConsumer>(), It.IsAny <Exception>())) .Callback(() => { consumerClosed.Set(); }); connection.AddConnectionListener(connectionListener.Object); testPeer.ExpectBegin(); testPeer.ExpectBegin(nextOutgoingId: 2); ISession session1 = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); ISession session2 = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); IQueue queue = session2.GetQueue("myQueue"); // Create a consumer, then remotely end it afterwards. testPeer.ExpectReceiverAttach(); testPeer.ExpectLinkFlow(); testPeer.ExpectEnd(); testPeer.RemotelyDetachLastOpenedLinkOnLastOpenedSession(expectDetachResponse: true, closed: true, errorType: errorType, errorMessage: errorMessage, delayBeforeSend: 10); IMessageConsumer consumer = session2.CreateConsumer(queue); consumer.Listener += message => { }; // Close first session to allow the receiver remote close timing to be deterministic session1.Close(); // Verify the consumer gets marked closed testPeer.WaitForAllMatchersToComplete(1000); Assert.True(consumerClosed.WaitOne(TimeSpan.FromMilliseconds(2000)), "Consumer closed callback didn't trigger"); Assert.True(exceptionListenerFired.WaitOne(TimeSpan.FromMilliseconds(2000)), "NMS Exception listener should have fired with a MessageListener"); // Try closing it explicitly, should effectively no-op in client. // The test peer will throw during close if it sends anything. consumer.Close(); // Shut the connection down testPeer.ExpectClose(); connection.Close(); testPeer.WaitForAllMatchersToComplete(1000); } }
public void TestStartMaxReconnectAttemptsTriggeredWhenRemotesAreRejecting() { using (TestAmqpPeer firstPeer = new TestAmqpPeer()) using (TestAmqpPeer secondPeer = new TestAmqpPeer()) using (TestAmqpPeer thirdPeer = new TestAmqpPeer()) using (TestAmqpPeer fourthPeer = new TestAmqpPeer()) { ManualResetEvent failedConnection = new ManualResetEvent(false); firstPeer.RejectConnect(AmqpError.NOT_FOUND, "Resource could not be located"); secondPeer.RejectConnect(AmqpError.NOT_FOUND, "Resource could not be located"); thirdPeer.RejectConnect(AmqpError.NOT_FOUND, "Resource could not be located"); // This shouldn't get hit, but if it does accept the connect so we don't pass the failed // to connect assertion. fourthPeer.ExpectSaslAnonymous(); fourthPeer.ExpectOpen(); fourthPeer.ExpectBegin(); fourthPeer.ExpectClose(); NmsConnection connection = EstablishAnonymousConnection("failover.startupMaxReconnectAttempts=3&failover.reconnectDelay=15&failover.useReconnectBackOff=false", firstPeer, secondPeer, thirdPeer, fourthPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionFailure(It.IsAny <NMSException>())) .Callback(() => { failedConnection.Set(); }); connection.AddConnectionListener(connectionListener.Object); Assert.Catch <NMSException>(() => connection.Start(), "Should not be able to connect"); Assert.True(failedConnection.WaitOne(TimeSpan.FromSeconds(5))); try { connection.Close(); } catch (NMSException e) { } firstPeer.WaitForAllMatchersToComplete(2000); secondPeer.WaitForAllMatchersToComplete(2000); thirdPeer.WaitForAllMatchersToComplete(2000); // Shut down last peer and verify no connection made to it fourthPeer.PurgeExpectations(); fourthPeer.Close(); Assert.NotNull(firstPeer.ClientSocket, "Peer 1 should have accepted a TCP connection"); Assert.NotNull(secondPeer.ClientSocket, "Peer 2 should have accepted a TCP connection"); Assert.NotNull(thirdPeer.ClientSocket, "Peer 3 should have accepted a TCP connection"); Assert.IsNull(fourthPeer.ClientSocket, "Peer 4 should not have accepted any TCP connection"); } }
public void TestFailoverHandlesDropWithModifiedInitialReconnectDelay() { 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("failover.initialReconnectDelay=1&failover.reconnectDelay=600&failover.maxReconnectAttempts=10", 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(); connection.CreateSession(AcknowledgementMode.AutoAcknowledge); Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer"); // Shut it down finalPeer.ExpectClose(); connection.Close(); finalPeer.WaitForAllMatchersToComplete(1000); } }
private void DoRemotelyCloseConsumerWithMessageListenerFiresNMSExceptionListenerTestImpl(bool closeWithError) { using (TestAmqpPeer testPeer = new TestAmqpPeer(Address1, User, Password)) { ManualResetEvent consumerClosed = new ManualResetEvent(false); ManualResetEvent exceptionListenerFired = new ManualResetEvent(false); TestLinkProcessor linkProcessor = new TestLinkProcessor(); testPeer.RegisterLinkProcessor(linkProcessor); testPeer.Open(); NmsConnection connection = EstablishConnection("failover.maxReconnectAttempts=1", testPeer); connection.ExceptionListener += exception => { exceptionListenerFired.Set(); }; Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConsumerClosed(It.IsAny <IMessageConsumer>(), It.IsAny <Exception>())) .Callback(() => { consumerClosed.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); IQueue queue = session.GetQueue("myQueue"); // Create a consumer, then remotely end it afterwards. IMessageConsumer consumer = session.CreateConsumer(queue); consumer.Listener += message => { }; if (closeWithError) { linkProcessor.CloseConsumerWithError(); } else { linkProcessor.CloseConsumer(); } Assert.True(consumerClosed.WaitOne(TimeSpan.FromMilliseconds(2000)), "Consumer closed callback didn't trigger"); Assert.True(exceptionListenerFired.WaitOne(TimeSpan.FromMilliseconds(2000)), "JMS Exception listener should have fired with a MessageListener"); // Try closing it explicitly, should effectively no-op in client. // The test peer will throw during close if it sends anything. consumer.Close(); connection.Close(); } }
private void DoTestConsumerReceiveThrowsIfConnectionLost(bool useTimeout) { using (TestAmqpPeer testAmqpPeer = new TestAmqpPeer(Address, User, Password)) { string topicName = "myTopic"; testAmqpPeer.Open(); ManualResetEvent disconnected = new ManualResetEvent(false); NmsConnection connection = (NmsConnection)EstablishConnection(); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionFailure(It.IsAny <NMSException>())) .Callback(() => { disconnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); ISession session = connection.CreateSession(AcknowledgementMode.ClientAcknowledge); ITopic topic = session.GetTopic(topicName); testAmqpPeer.SendMessage(topicName, "test"); IMessageConsumer consumer = session.CreateConsumer(topic); testAmqpPeer.Close(); Assert.True(disconnected.WaitOne(), "Connection should be disconnected"); try { if (useTimeout) { consumer.Receive(TimeSpan.FromMilliseconds(1000)); } else { consumer.Receive(); } Assert.Fail("An exception should have been thrown"); } catch (NMSException) { // Expected } } }
public void TestFailoverEnforcesSendTimeout() { using (TestAmqpPeer testPeer = new TestAmqpPeer()) { ManualResetEvent connected = new ManualResetEvent(false); ManualResetEvent disconnected = new ManualResetEvent(false); // Connect to the test peer testPeer.ExpectSaslAnonymous(); testPeer.ExpectOpen(); testPeer.ExpectBegin(); testPeer.ExpectBegin(); testPeer.ExpectSenderAttach(); testPeer.DropAfterLastMatcher(); NmsConnection connection = EstablishAnonymousConnection("nms.sendTimeout=1000&failover.reconnectDelay=2000&failover.maxReconnectAttempts=60", testPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.IsAny <Uri>())) .Callback(() => { connected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionInterrupted(It.IsAny <Uri>())) .Callback(() => { disconnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(connected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to peer"); ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); IQueue queue = session.GetQueue("myQueue"); IMessageProducer producer = session.CreateProducer(queue); Assert.True(disconnected.WaitOne(TimeSpan.FromSeconds(5)), "Should lose connection to peer"); Assert.Catch <NMSException>(() => producer.Send(producer.CreateTextMessage("test"))); connection.Close(); testPeer.WaitForAllMatchersToComplete(1000); } }
public void TestCreateProducerAfterConnectionDrops() { using (TestAmqpPeer originalPeer = new TestAmqpPeer(Address1, User, Password)) using (TestAmqpPeer finalPeer = new TestAmqpPeer(Address2, User, Password)) { originalPeer.RegisterLinkProcessor(new TestLinkProcessor()); finalPeer.RegisterLinkProcessor(new TestLinkProcessor()); ManualResetEvent originalConnected = new ManualResetEvent(false); ManualResetEvent finalConnected = new ManualResetEvent(false); // Create a peer to connect to, then one to reconnect to originalPeer.Open(); finalPeer.Open(); NmsConnection connection = EstablishConnection(originalPeer, finalPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalPeer.Address == uri))) .Callback(() => { originalConnected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalPeer.Address == uri))) .Callback(() => { finalConnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer"); originalPeer.Close(); ISession session = connection.CreateSession(); IQueue queue = session.GetQueue("myQueue"); IMessageProducer producer = session.CreateProducer(queue); Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer"); producer.Close(); connection.Close(); } }
public void TestTempDestinationRecreatedAfterConnectionFailsOver() { using (TestAmqpPeer originalPeer = new TestAmqpPeer(Address1, User, Password)) using (TestAmqpPeer finalPeer = new TestAmqpPeer(Address2, User, Password)) { originalPeer.RegisterLinkProcessor(new TestLinkProcessor()); finalPeer.RegisterLinkProcessor(new TestLinkProcessor()); ManualResetEvent originalConnected = new ManualResetEvent(false); ManualResetEvent finalConnected = new ManualResetEvent(false); // Create a peer to connect to, then one to reconnect to originalPeer.Open(); finalPeer.Open(); NmsConnection connection = EstablishConnection(originalPeer, finalPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalPeer.Address == uri))) .Callback(() => { originalConnected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalPeer.Address == uri))) .Callback(() => { finalConnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer"); ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); ITemporaryTopic temporaryTopic = session.CreateTemporaryTopic(); originalPeer.Close(); Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer"); temporaryTopic.Delete(); connection.Close(); } }
public void TestFailoverHandlesDropThenRejectionCloseAfterConnect() { using (TestAmqpPeer originalPeer = new TestAmqpPeer(Address1, User, Password)) using (TestAmqpPeer rejectingPeer = new TestAmqpPeer(Address2, User, Password)) using (TestAmqpPeer finalPeer = new TestAmqpPeer(Address3, User, Password)) { 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 originalPeer.Open(); finalPeer.Open(); long ird = 0; long rd = 2000; NmsConnection connection = EstablishConnection("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 => originalPeer.Address == uri))) .Callback(() => { originalConnected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalPeer.Address == uri))) .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"); // Close the original peer and wait for things to shake out. originalPeer.Close(); Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer"); connection.Close(); } }
public async Task TestRemotelyCloseConsumerWithMessageListenerFiresExceptionListener() { Mock <INmsConnectionListener> mockConnectionListener = new Mock <INmsConnectionListener>(); string errorMessage = "buba"; using (TestAmqpPeer testPeer = new TestAmqpPeer()) { ManualResetEvent consumerClosed = new ManualResetEvent(false); ManualResetEvent exceptionFired = new ManualResetEvent(false); mockConnectionListener .Setup(listener => listener.OnConsumerClosed(It.IsAny <IMessageConsumer>(), It.IsAny <Exception>())) .Callback(() => consumerClosed.Set()); NmsConnection connection = (NmsConnection) await EstablishConnectionAsync(testPeer); connection.AddConnectionListener(mockConnectionListener.Object); connection.ExceptionListener += exception => { exceptionFired.Set(); }; testPeer.ExpectBegin(); ISession session = await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge); // Create a consumer, then remotely end it afterwards. testPeer.ExpectReceiverAttach(); testPeer.ExpectLinkFlow(); testPeer.RemotelyDetachLastOpenedLinkOnLastOpenedSession(expectDetachResponse: true, closed: true, errorType: AmqpError.RESOURCE_DELETED, errorMessage: errorMessage, 10); IQueue queue = await session.GetQueueAsync("myQueue"); IMessageConsumer consumer = await session.CreateConsumerAsync(queue); consumer.Listener += message => { }; // Verify the consumer gets marked closed testPeer.WaitForAllMatchersToComplete(1000); Assert.True(consumerClosed.WaitOne(2000), "Consumer closed callback didn't trigger"); Assert.True(exceptionFired.WaitOne(2000), "Exception listener should have fired with a MessageListener"); // Try closing it explicitly, should effectively no-op in client. // The test peer will throw during close if it sends anything. await consumer.CloseAsync(); } }
public async Task TestConsumerReceiveNoWaitThrowsIfConnectionLost() { ManualResetEvent disconnected = new ManualResetEvent(false); using (TestAmqpPeer testPeer = new TestAmqpPeer()) { NmsConnection connection = (NmsConnection) await EstablishConnectionAsync(testPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionFailure(It.IsAny <NMSException>())) .Callback(() => { disconnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); await connection.StartAsync(); testPeer.ExpectBegin(); ISession session = await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge); IQueue queue = await session.GetQueueAsync("queue"); testPeer.ExpectReceiverAttach(); testPeer.ExpectLinkFlow(); testPeer.RemotelyCloseConnection(expectCloseResponse: true, errorCondition: ConnectionError.CONNECTION_FORCED, errorMessage: "buba"); IMessageConsumer consumer = await session.CreateConsumerAsync(queue); Assert.True(disconnected.WaitOne(), "Connection should be disconnected"); try { consumer.ReceiveNoWait(); Assert.Fail("An exception should have been thrown"); } catch (NMSException) { // Expected } } }
public void TestFailoverHandlesDropAfterSessionCloseRequested() { using (TestAmqpPeer testPeer = new TestAmqpPeer(Address1, User, Password)) { ManualResetEvent connected = new ManualResetEvent(false); testPeer.RegisterLinkProcessor(new MockLinkProcessor(context => context.Complete(new Error(new Symbol("error"))))); testPeer.Open(); NmsConnection connection = EstablishConnection(testPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.IsAny <Uri>())) .Callback(() => { connected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(connected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to peer"); ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); testPeer.Close(); try { session.Close(); } catch (NMSException) { } catch (Exception) { Assert.Fail("Session close should have completed normally."); } connection.Close(); } }
public void TestFailoverEnforcesSendTimeout() { using (TestAmqpPeer testPeer = new TestAmqpPeer(Address1, User, Password)) { ManualResetEvent connected = new ManualResetEvent(false); ManualResetEvent disconnected = new ManualResetEvent(false); testPeer.RegisterLinkProcessor(new TestLinkProcessor()); testPeer.Open(); NmsConnection connection = EstablishConnection("nms.sendTimeout=1000&failover.reconnectDelay=2000&failover.maxReconnectAttempts=60", testPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.IsAny <Uri>())) .Callback(() => { connected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionInterrupted(It.IsAny <Uri>())) .Callback(() => { disconnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(connected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to peer"); ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); IQueue queue = session.GetQueue("myQueue"); IMessageProducer producer = session.CreateProducer(queue); testPeer.Close(); Assert.True(disconnected.WaitOne(TimeSpan.FromSeconds(5)), "Should lose connection to peer"); Assert.Catch <NMSException>(() => producer.Send(producer.CreateTextMessage("test"))); connection.Close(); } }
public void TestFailoverHandlesDropWithModifiedInitialReconnectDelay() { using (TestAmqpPeer originalPeer = new TestAmqpPeer(Address1, User, Password)) using (TestAmqpPeer finalPeer = new TestAmqpPeer(Address3, User, Password)) { ManualResetEvent originalConnected = new ManualResetEvent(false); ManualResetEvent finalConnected = new ManualResetEvent(false); // Create a peer to connect to, then one to reconnect to originalPeer.Open(); finalPeer.Open(); NmsConnection connection = EstablishConnection("failover.initialReconnectDelay=" + 1 + "&failover.reconnectDelay=" + 600 + "&failover.maxReconnectAttempts=10", originalPeer, finalPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionEstablished(It.Is <Uri>(uri => originalPeer.Address == uri))) .Callback(() => { originalConnected.Set(); }); connectionListener .Setup(listener => listener.OnConnectionRestored(It.Is <Uri>(uri => finalPeer.Address == uri))) .Callback(() => { finalConnected.Set(); }); connection.AddConnectionListener(connectionListener.Object); connection.Start(); Assert.True(originalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to original peer"); // Close the original peer originalPeer.Close(); connection.CreateSession(AcknowledgementMode.AutoAcknowledge); Assert.True(finalConnected.WaitOne(TimeSpan.FromSeconds(5)), "Should connect to final peer"); connection.Close(); } }
public async Task TestRemotelyCloseProducer() { string breadCrumb = "ErrorMessageBreadCrumb"; ManualResetEvent producerClosed = new ManualResetEvent(false); Mock <INmsConnectionListener> mockConnectionListener = new Mock <INmsConnectionListener>(); mockConnectionListener .Setup(listener => listener.OnProducerClosed(It.IsAny <NmsMessageProducer>(), It.IsAny <Exception>())) .Callback(() => { producerClosed.Set(); }); using (TestAmqpPeer testPeer = new TestAmqpPeer()) { NmsConnection connection = (NmsConnection) await EstablishConnectionAsync(testPeer); connection.AddConnectionListener(mockConnectionListener.Object); testPeer.ExpectBegin(); ISession session = await connection.CreateSessionAsync(AcknowledgementMode.AutoAcknowledge); // Create a producer, then remotely end it afterwards. testPeer.ExpectSenderAttach(); testPeer.RemotelyDetachLastOpenedLinkOnLastOpenedSession(expectDetachResponse: true, closed: true, errorType: AmqpError.RESOURCE_DELETED, breadCrumb, delayBeforeSend: 10); IQueue destination = await session.GetQueueAsync("myQueue"); IMessageProducer producer = await session.CreateProducerAsync(destination); // Verify the producer gets marked closed testPeer.WaitForAllMatchersToComplete(1000); Assert.True(producerClosed.WaitOne(TimeSpan.FromMilliseconds(1000)), "Producer closed callback didn't trigger"); Assert.That(() => producer.DisableMessageID, Throws.Exception.InstanceOf <IllegalStateException>(), "Producer never closed"); // Try closing it explicitly, should effectively no-op in client. // The test peer will throw during close if it sends anything. await producer.CloseAsync(); } }
public void TestStartMaxReconnectAttemptsTriggeredWhenRemotesAreRejecting() { using (TestAmqpPeer firstPeer = new TestAmqpPeer(Address1, User, Password)) using (TestAmqpPeer secondPeer = new TestAmqpPeer(Address2, User, Password)) using (TestAmqpPeer thirdPeer = new TestAmqpPeer(Address3, User, Password)) using (TestAmqpPeer fourthPeer = new TestAmqpPeer(Address4, User, Password)) { TestLinkProcessor linkProcessor = new TestLinkProcessor(); fourthPeer.RegisterLinkProcessor(linkProcessor); fourthPeer.Open(); ManualResetEvent failedConnection = new ManualResetEvent(false); NmsConnection connection = EstablishConnection( "failover.startupMaxReconnectAttempts=3&failover.reconnectDelay=15&failover.useReconnectBackOff=false", firstPeer, secondPeer, thirdPeer, fourthPeer); Mock <INmsConnectionListener> connectionListener = new Mock <INmsConnectionListener>(); connectionListener .Setup(listener => listener.OnConnectionFailure(It.IsAny <NMSException>())) .Callback(() => { failedConnection.Set(); }); connection.AddConnectionListener(connectionListener.Object); try { connection.Start(); Assert.Fail("Should not be able to connect"); } catch (Exception) { } Assert.True(failedConnection.WaitOne(TimeSpan.FromSeconds(5))); // Verify that no connection made to the last peer Assert.IsNull(linkProcessor.Consumer); } }
public void TestRemotelyCloseConsumerWithMessageListenerFiresExceptionListener() { Mock <INmsConnectionListener> mockConnectionListener = new Mock <INmsConnectionListener>(); bool exceptionFired = false; using (TestAmqpPeer testAmqpPeer = new TestAmqpPeer(Address, User, Password)) { var testLinkProcessor = new TestLinkProcessor(); testAmqpPeer.RegisterLinkProcessor(testLinkProcessor); testAmqpPeer.Open(); NmsConnection connection = (NmsConnection)EstablishConnection(); connection.Start(); connection.AddConnectionListener(mockConnectionListener.Object); connection.ExceptionListener += exception => { exceptionFired = true; }; ISession session = connection.CreateSession(AcknowledgementMode.AutoAcknowledge); IQueue queue = session.GetQueue("myQueue"); // Create a consumer, then remotely end it afterwards. IMessageConsumer consumer = session.CreateConsumer(queue); consumer.Listener += message => { }; testLinkProcessor.CloseConsumerWithError(); Assert.That(() => exceptionFired, Is.True.After(200)); // Verify the consumer gets marked closed mockConnectionListener.Verify(listener => listener.OnConsumerClosed(It.Is <IMessageConsumer>(x => x == consumer), It.IsAny <Exception>()), Times.Once, "consumer never closed."); // Try closing it explicitly, should effectively no-op in client. // The test peer will throw during close if it sends anything. consumer.Close(); session.Close(); connection.Close(); } }
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 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: true); rejectingPeer.WaitForAllMatchersToComplete(1000); 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 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 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); } }