def test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_no_disconnect(self): config = StompConfig(HOST, PORT) creator = StompCreator(config) # Connect stomp = yield creator.getConnection() # Enqueue two messages stomp.send(self.queue, self.msg1, self.msg1Hdrs) stomp.send(self.queue, self.msg2) # Barf on first msg, disconnect on second msg stomp.subscribe( self.queue, self._barfOneEatOneAndDisonnect, {"ack": "client-individual", "activemq.prefetchSize": 1}, errorDestination=self.errorQueue, ) # Client disconnects without error yield stomp.getDisconnectedDeferred() # Reconnect and subscribe to error queue stomp = yield creator.getConnection() stomp.subscribe( self.errorQueue, self._saveErrMsgAndDisconnect, {"ack": "client-individual", "activemq.prefetchSize": 1} ) # Wait for disconnect yield stomp.getDisconnectedDeferred() # Verify that one message was in error queue (can't guarantee order) self.assertNotEquals(None, self.errQMsg) self.assertTrue(self.errQMsg["body"] in (self.msg1, self.msg2))
def test_onDisconnect_waitForOutstandingMessagesToFinish(self): self.config = StompConfig(HOST, PORT) self.creator = StompCreator(self.config) config = StompConfig(HOST, PORT) creator = StompCreator(config) # Connect stomp = yield creator.getConnection() for i in range(self.numMsgs): stomp.send(self.queue, self.msg) stomp.subscribe( self.queue, self._msgHandler, {"ack": "client-individual", "activemq.prefetchSize": self.numMsgs} ) # Wait for disconnect yield stomp.getDisconnectedDeferred() # Reconnect and subscribe again to make sure that all messages in the queue were ack'ed stomp = yield creator.getConnection() self.timeExpired = False self.timeoutDelayedCall = reactor.callLater(1, self._timesUp, stomp) stomp.subscribe( self.queue, self._eatOneMsgAndDisconnect, {"ack": "client-individual", "activemq.prefetchSize": self.numMsgs}, ) # Wait for disconnect yield stomp.getDisconnectedDeferred() # Time should have expired if there were no messages left in the queue self.assertTrue(self.timeExpired)
class GracefulDisconnectTestCase(unittest.TestCase): numMsgs = 5 msgCount = 0 msg = 'test' queue = '/queue/aysncStompestGracefulDisconnectUnitTest' disconnected = defer.Deferred() disconnectedAgain = defer.Deferred() ackMode = getClientAckMode() def test_onDisconnect_waitForOutstandingMessagesToFinish(self): self.config = StompConfig('localhost', 61613) self.creator = StompCreator(self.config) deferConnected = self.creator.getConnection().addCallback(self._onConnected) self.disconnected.addCallback(self._reconnect) self.disconnectedAgain.addCallback(self._verifyAllMsgsAcked) return defer.DeferredList([ self.disconnected, self.disconnectedAgain, ] ) def _onConnected(self, stomp): stomp.getDisconnectedDeferred().addCallback(self.disconnected.callback).addErrback(self.disconnected.errback) for i in range(self.numMsgs): stomp.send(self.queue, self.msg) stomp.subscribe(self.queue, self._msgHandler, {'ack': self.ackMode, 'activemq.prefetchSize': self.numMsgs}) def _msgHandler(self, stomp, msg): self.msgCount += 1 if self.msgCount < self.numMsgs: d = defer.Deferred() reactor.callLater(1, d.callback, None) return d else: stomp.disconnect() def _reconnect(self, result): self.creator.getConnection().addCallback(self._onReconnect) def _onReconnect(self, stomp): stomp.getDisconnectedDeferred().addCallback(self.disconnectedAgain.callback).addErrback(self.disconnectedAgain.errback) self.timeExpired = False self.timeoutDelayedCall = reactor.callLater(1, self._timesUp, stomp) stomp.subscribe(self.queue, self._eatOneMsgAndDisconnect, {'ack': self.ackMode, 'activemq.prefetchSize': self.numMsgs}) def _timesUp(self, stomp): print "Times up!!!" self.timeExpired = True stomp.disconnect() def _eatOneMsgAndDisconnect(self, stomp, msg): self.timeoutDelayedCall.cancel() stomp.disconnect() def _verifyAllMsgsAcked(self, result): print "VERIFY!" self.assertTrue(self.timeExpired) return result
def test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_disconnect(self): config = StompConfig(HOST, PORT) creator = StompCreator(config, alwaysDisconnectOnUnhandledMsg=True) # Connect stomp = yield creator.getConnection() # Enqueue two messages stomp.send(self.queue, self.msg1, self.msg1Hdrs) stomp.send(self.queue, self.msg2) # Barf on first message so it will get put in error queue # Use selector to guarantee message order. AMQ doesn't not guarantee order by default stomp.subscribe( self.queue, self._saveMsgAndBarf, {"ack": "client-individual", "activemq.prefetchSize": 1, "selector": "food = 'barf'"}, errorDestination=self.errorQueue, ) # Client disconnected and returned error try: yield stomp.getDisconnectedDeferred() except StompestTestError: pass else: self.assertTrue(False) # Reconnect and subscribe again - consuming second message then disconnecting stomp = yield creator.getConnection() stomp.subscribe( self.queue, self._eatOneMsgAndDisconnect, {"ack": "client-individual", "activemq.prefetchSize": 1}, errorDestination=self.errorQueue, ) # Client disconnects without error yield stomp.getDisconnectedDeferred() # Reconnect and subscribe to error queue stomp = yield creator.getConnection() stomp.subscribe( self.errorQueue, self._saveErrMsgAndDisconnect, {"ack": "client-individual", "activemq.prefetchSize": 1} ) # Wait for disconnect yield stomp.getDisconnectedDeferred() # Verify that first message was in error queue self.assertEquals(self.msg1, self.errQMsg["body"]) self.assertEquals(self.msg1Hdrs["food"], self.errQMsg["headers"]["food"]) self.assertNotEquals(self.unhandledMsg["headers"]["message-id"], self.errQMsg["headers"]["message-id"]) # Verify that second message was consumed self.assertEquals(self.msg2, self.consumedMsg["body"])
def test_onhandlerException_disconnect(self): config = StompConfig(HOST, PORT) creator = StompCreator(config) # Connect stomp = yield creator.getConnection() # Enqueue a message stomp.send(self.queue, self.msg1, self.msg1Hdrs) # Barf on first msg (implicit disconnect) stomp.subscribe(self.queue, self._saveMsgAndBarf, {"ack": "client-individual", "activemq.prefetchSize": 1}) # Client disconnected and returned error try: yield stomp.getDisconnectedDeferred() except StompestTestError, e: pass
def test_onDisconnect_waitForOutstandingMessagesToFinish(self): self.config = StompConfig('localhost', 61613) self.creator = StompCreator(self.config) deferConnected = self.creator.getConnection().addCallback(self._onConnected) self.disconnected.addCallback(self._reconnect) self.disconnectedAgain.addCallback(self._verifyAllMsgsAcked) return defer.DeferredList([ self.disconnected, self.disconnectedAgain, ] )
def test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_errback(self): self.cleanQueues() self.config = StompConfig('localhost', 61613) self.creator = StompCreator(self.config) deferConnected = self.creator.getConnection().addCallback(self._onConnected) deferredTestErr = self.assertFailure(self.disconnected, StompestTestError).addCallback(self._reconnectAfterErr) self.disconnectedAgain.addCallback(self._reconnectForErrQ) self.disconnectedFromErrQ.addCallback(self._verifyErrMsg) #asserts err message content is correct return defer.DeferredList([ deferredTestErr, #asserts that handler exception triggered disconnect and was propagated to disconnect deferred self.disconnectedAgain, #asserts that message causing the exception was ack'ed to broker (otherwise, this message would not get delivered) self.disconnectedFromErrQ, #asserts that we were able to read a message from the error queue ] )
def test_bad_port_tcp_error(self): config = StompConfig('localhost', 65535) creator = StompCreator(config) return self.assertFailure(creator.getConnection(), error.ConnectionRefusedError)
def test_bad_host_tcp_error(self): config = StompConfig('nosuchhost', 61613) creator = StompCreator(config) return self.assertFailure(creator.getConnection(), error.DNSLookupError)
def test_stomp_error_after_connected(self): config = StompConfig('localhost', self.testPort) creator = StompCreator(config) creator.getConnection().addCallback(self.onConnected) return self.assertFailure(self.disconnected, StompProtocolError)
def test_stomp_error_before_connected(self): config = StompConfig('localhost', self.testPort) creator = StompCreator(config) return self.assertFailure(creator.getConnection(), StompProtocolError)
def test_connection_timeout(self): config = StompConfig('localhost', self.testPort) creator = StompCreator(config, connectTimeout=1) return self.assertFailure(creator.getConnection(), StompConnectTimeout)
class HandlerExceptionWithErrorQueueIntegrationTestCase(unittest.TestCase): msg1 = 'choke on this' msg1Hdrs = {'food': 'barf', 'persistent': 'true'} msg2 = 'follow up message' queue = '/queue/asyncStompestHandlerExceptionWithErrorQueueUnitTest' errorQueue = '/queue/zzz.error.asyncStompestHandlerExceptionWithErrorQueueUnitTest' disconnected = defer.Deferred() disconnectedAgain = defer.Deferred() disconnectedFromErrQ = defer.Deferred() ackMode = getClientAckMode() def cleanQueues(self): self.cleanQueue(self.queue) self.cleanQueue(self.errorQueue) def cleanQueue(self, queue): stomp = Stomp('localhost', 61613) stomp.connect() stomp.subscribe(queue, {'ack': 'client'}) while stomp.canRead(1): frame = stomp.receiveFrame() stomp.ack(frame) print "Dequeued old message: %s" % frame stomp.disconnect() def test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_errback(self): self.cleanQueues() self.config = StompConfig('localhost', 61613) self.creator = StompCreator(self.config) deferConnected = self.creator.getConnection().addCallback(self._onConnected) deferredTestErr = self.assertFailure(self.disconnected, StompestTestError).addCallback(self._reconnectAfterErr) self.disconnectedAgain.addCallback(self._reconnectForErrQ) self.disconnectedFromErrQ.addCallback(self._verifyErrMsg) #asserts err message content is correct return defer.DeferredList([ deferredTestErr, #asserts that handler exception triggered disconnect and was propagated to disconnect deferred self.disconnectedAgain, #asserts that message causing the exception was ack'ed to broker (otherwise, this message would not get delivered) self.disconnectedFromErrQ, #asserts that we were able to read a message from the error queue ] ) def _onConnected(self, stomp): stomp.getDisconnectedDeferred().addCallback(self.disconnected.callback).addErrback(self.disconnected.errback) stomp.send(self.queue, self.msg1, self.msg1Hdrs) stomp.send(self.queue, self.msg2) #Use selector to guarantee message order. AMQ doesn't not guarantee order by default stomp.subscribe(self.queue, self._saveMsgAndBarf, {'ack': self.ackMode, 'activemq.prefetchSize': 1, 'selector': "food = 'barf'"}, errorDestination=self.errorQueue) def _saveMsgAndBarf(self, stomp, msg): print 'Save message and barf' self.assertEquals(self.msg1, msg['body']) self.unhandledMsg = msg raise StompestTestError('this is a test') def _reconnectAfterErr(self, result): self.creator.getConnection().addCallback(self._onConnectedAgain) def _onConnectedAgain(self, stomp): stomp.getDisconnectedDeferred().addCallback(self.disconnectedAgain.callback).addErrback(self.disconnectedAgain.errback) stomp.subscribe(self.queue, self._eatOneMsgAndDisconnect, {'ack': self.ackMode, 'activemq.prefetchSize': 1}, errorDestination=self.errorQueue) def _eatOneMsgAndDisconnect(self, stomp, msg): print 'Eat message and disconnect' self.assertEquals(self.msg2, msg['body']) stomp.disconnect() def _reconnectForErrQ(self, result): self.creator.getConnection().addCallback(self._onConnectedForErrQ) def _onConnectedForErrQ(self, stomp): stomp.getDisconnectedDeferred().addCallback(self.disconnectedFromErrQ.callback).addErrback(self.disconnectedFromErrQ.errback) stomp.subscribe(self.errorQueue, self._saveErrMsgAndDisconnect, {'ack': self.ackMode, 'activemq.prefetchSize': 1}) def _saveErrMsgAndDisconnect(self, stomp, msg): print 'Save error message and disconnect' self.errQMsg = msg stomp.disconnect() def _verifyErrMsg(self, result): self.assertEquals(self.msg1, self.errQMsg['body']) self.assertEquals(self.msg1Hdrs['food'], self.errQMsg['headers']['food']) self.assertNotEquals(self.unhandledMsg['headers']['message-id'], self.errQMsg['headers']['message-id'])