def _test_nack(self, version): if version not in commands.versions(VERSION): print 'Skipping test case (version %s is not configured)' % VERSION defer.returnValue(None) config = self.getConfig(version) client = async.Stomp(config) try: client = yield client.connect(host=VIRTUALHOST, versions=[version]) except StompProtocolError as e: print 'Broker does not support STOMP protocol %s. Skipping this test case. [%s]' % (version, e) defer.returnValue(None) client.subscribe(self.queue, {StompSpec.ACK_HEADER: StompSpec.ACK_CLIENT_INDIVIDUAL, StompSpec.ID_HEADER: '4711'}, listener=SubscriptionListener(self._nackFrame, ack=False)) client.send(self.queue, self.frame) while not self.framesHandled: yield task.deferLater(reactor, 0.01, lambda: None) client.disconnect() yield client.disconnected if BROKER == 'activemq': print 'Broker %s by default does not redeliver messages. Will not try and harvest the NACKed message.' % BROKER return self.framesHandled = 0 client = yield client.connect(host=VIRTUALHOST) client.subscribe(self.queue, {StompSpec.ACK_HEADER: StompSpec.ACK_CLIENT_INDIVIDUAL, StompSpec.ID_HEADER: '4711'}, listener=SubscriptionListener(self._eatFrame, ack=True)) while self.framesHandled != 1: yield task.deferLater(reactor, 0.01, lambda: None) client.disconnect() yield client.disconnected
def test_4_integration_stomp_1_1(self): if StompSpec.VERSION_1_1 not in commands.versions(VERSION): print 'This broker does not support STOMP protocol version 1.1' return client = Stomp(self.getConfig(StompSpec.VERSION_1_1)) client.connect(host=VIRTUALHOST) client.send(self.DESTINATION, 'test message 1') client.send(self.DESTINATION, 'test message 2') self.assertFalse(client.canRead(self.TIMEOUT)) token = client.subscribe(self.DESTINATION, {StompSpec.ID_HEADER: 4711, StompSpec.ACK_HEADER: 'client-individual'}) self.assertTrue(client.canRead(self.TIMEOUT)) client.ack(client.receiveFrame()) self.assertTrue(client.canRead(self.TIMEOUT)) client.ack(client.receiveFrame()) self.assertFalse(client.canRead(self.TIMEOUT)) client.unsubscribe(token) client.send(self.DESTINATION, 'test message 3', receipt='4711') self.assertTrue(client.canRead(self.TIMEOUT)) self.assertEquals(client.receiveFrame(), StompFrame(StompSpec.RECEIPT, {'receipt-id': '4711'})) self.assertFalse(client.canRead(self.TIMEOUT)) client.subscribe(self.DESTINATION, {StompSpec.ID_HEADER: 4711, StompSpec.ACK_HEADER: 'client-individual'}) self.assertTrue(client.canRead(self.TIMEOUT)) client.ack(client.receiveFrame()) self.assertFalse(client.canRead(self.TIMEOUT)) client.disconnect(receipt='4712') self.assertEquals(client.receiveFrame(), StompFrame(StompSpec.RECEIPT, {'receipt-id': '4712'})) self.assertRaises(StompConnectionError, client.receiveFrame) client.connect(host=VIRTUALHOST) client.disconnect(receipt='4711') self.assertEquals(client.receiveFrame(), StompFrame(StompSpec.RECEIPT, {'receipt-id': '4711'})) client.close() self.assertRaises(StompConnectionError, client.canRead, 0)
def test_5_integration_stomp_1_1_heartbeat(self): if BROKER == 'apollo': print "Broker %s doesn't properly support heart-beating. Skipping test." % BROKER return if StompSpec.VERSION_1_1 not in commands.versions(VERSION): print 'This broker does not support STOMP protocol version 1.1' return port = 61612 if (BROKER == 'activemq') else PORT # stomp+nio on 61613 does not work properly, so use stomp on 61612 client = Stomp(self.getConfig(StompSpec.VERSION_1_1, port)) self.assertEquals(client.lastReceived, None) self.assertEquals(client.lastSent, None) heartBeatPeriod = 100 client.connect(host=VIRTUALHOST, heartBeats=(heartBeatPeriod, heartBeatPeriod)) self.assertTrue((time.time() - client.lastReceived) < 0.1) if not (client.serverHeartBeat and client.clientHeartBeat): print 'broker does not support heart-beating. disconnecting ...' client.disconnect() client.close() return serverHeartBeatInSeconds = client.serverHeartBeat / 1000.0 clientHeartBeatInSeconds = client.clientHeartBeat / 1000.0 start = time.time() while (time.time() - start) < (2.5 * max(serverHeartBeatInSeconds, clientHeartBeatInSeconds)): time.sleep(0.5 * min(serverHeartBeatInSeconds, clientHeartBeatInSeconds)) client.canRead(0) self.assertTrue((time.time() - client.lastReceived) < (1.5 * serverHeartBeatInSeconds)) if (time.time() - client.lastSent) > (0.5 * clientHeartBeatInSeconds): client.beat() self.assertTrue((time.time() - client.lastSent) < 0.1) start = time.time() try: while not client.canRead(0.5 * clientHeartBeatInSeconds): pass except StompConnectionError: self.assertTrue((time.time() - start) < (3.0 * clientHeartBeatInSeconds)) self.assertTrue((time.time() - client.lastReceived) < (1.5 * serverHeartBeatInSeconds)) self.assertTrue((time.time() - client.lastSent) > clientHeartBeatInSeconds) else: raise client.close()
def _test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_disconnect(self, version): if version not in commands.versions(VERSION): print 'This broker does not support STOMP protocol version 1.1' return config = self.getConfig(StompSpec.VERSION_1_1) client = async.Stomp(config) try: client = yield client.connect(host=VIRTUALHOST) if client.session.version == '1.0': yield client.disconnect() raise StompProtocolError('Broker chose STOMP protocol 1.0') except StompProtocolError as e: print 'Broker does not support STOMP protocol 1.1. Skipping this test case. [%s]' % e defer.returnValue(None) if client.session.version != version: print 'Broker does not support STOMP protocol %s. Skipping this test case.' % version yield client.disconnect() defer.returnValue(None) # enqueue two messages client.send(self.queue, self.frame1, self.msg1Hdrs) client.send(self.queue, self.frame2) defaultHeaders = {StompSpec.ACK_HEADER: 'client-individual'} if version != '1.0': defaultHeaders.update(self.headers) # barf on first message so it will get put in error queue # use selector to guarantee message order. AMQ doesn't guarantee order by default headers = {'selector': "food = 'barf'"} headers.update(defaultHeaders) client.subscribe(self.queue, self._saveFrameAndBarf, headers, errorDestination=self.errorQueue, onMessageFailed=self._onMessageFailedSendToErrorDestinationAndRaise) # client disconnected and returned error try: yield client.disconnected except StompestTestError: pass else: raise client = async.Stomp(config) # take a fresh client to prevent replay (we were disconnected by an error) # reconnect and subscribe again - consuming second message then disconnecting client = yield client.connect(host=VIRTUALHOST) headers.pop('selector') client.subscribe(self.queue, self._eatOneFrameAndDisconnect, headers, errorDestination=self.errorQueue) # client disconnects without error yield client.disconnected # reconnect and subscribe to error queue client = yield client.connect(host=VIRTUALHOST) client.subscribe(self.errorQueue, self._saveErrorFrameAndDisconnect, defaultHeaders) # wait for disconnect yield client.disconnected # verify that first message was in error queue self.assertEquals(self.frame1, self.errorQueueFrame.body) self.assertEquals(self.msg1Hdrs['food'], self.errorQueueFrame.headers['food']) self.assertNotEquals(self.unhandledFrame.headers['message-id'], self.errorQueueFrame.headers['message-id']) # verify that second message was consumed self.assertEquals(self.frame2, self.consumedFrame.body)
def _test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_disconnect(self, version): if version not in commands.versions(VERSION): print("Skipping test case (version %s is not configured)" % VERSION) defer.returnValue(None) if BROKER == "rabbitmq": print("RabbitMQ does not support selector header") defer.returnValue(None) config = self.getConfig(version) client = async.Stomp(config) try: yield client.connect(host=VIRTUALHOST, versions=[version]) except StompProtocolError as e: print("Broker does not support STOMP protocol %s. Skipping this test case. [%s]" % (e, version)) defer.returnValue(None) # enqueue two messages messageHeaders = dict(self.msg1Hdrs) defaultHeaders = {StompSpec.ACK_HEADER: StompSpec.ACK_CLIENT_INDIVIDUAL} specialCharactersHeader = b"fen\xc3\xaatre".decode("utf-8") if version != StompSpec.VERSION_1_0: defaultHeaders.update(self.headers) messageHeaders[specialCharactersHeader] = b"\xc2\xbfqu\xc3\xa9 tal?".decode("utf-8") client.send(self.queue, self.frame1, messageHeaders) client.send(self.queue, self.frame2) client.disconnect() yield client.disconnected # barf on first message so it will get put in error queue # use selector to guarantee message order (order not necessarily guaranteed) headers = {StompSpec.SELECTOR_HEADER: "food='barf'"} headers.update(defaultHeaders) yield client.connect(host=VIRTUALHOST, versions=[version]) client.subscribe( self.queue, headers, listener=SubscriptionListener( self._saveFrameAndBarf, errorDestination=self.errorQueue, onMessageFailed=self._onMessageFailedSendToErrorDestinationAndRaise, ), ) # client disconnected and returned error try: yield client.disconnected except StompestTestError: pass else: raise client = async.Stomp(config) # take a fresh client to prevent replay (we were disconnected by an error) # reconnect and subscribe again - consuming second message then disconnecting yield client.connect(host=VIRTUALHOST) headers.pop("selector") client.subscribe( self.queue, headers, listener=SubscriptionListener(self._eatOneFrameAndDisconnect, errorDestination=self.errorQueue), ) # client disconnects without error yield client.disconnected # reconnect and subscribe to error queue yield client.connect(host=VIRTUALHOST) client.subscribe( self.errorQueue, defaultHeaders, listener=SubscriptionListener(self._saveErrorFrameAndDisconnect) ) # wait for disconnect yield client.disconnected # verify that first message was in error queue self.assertEquals(self.frame1, self.errorQueueFrame.body) self.assertEquals(messageHeaders["food"], self.errorQueueFrame.headers["food"]) if version != StompSpec.VERSION_1_0: self.assertEquals( messageHeaders[specialCharactersHeader], self.errorQueueFrame.headers[specialCharactersHeader] ) self.assertNotEquals( self.unhandledFrame.headers[StompSpec.MESSAGE_ID_HEADER], self.errorQueueFrame.headers[StompSpec.MESSAGE_ID_HEADER], ) # verify that second message was consumed self.assertEquals(self.frame2, self.consumedFrame.body)
def _test_onhandlerException_ackMessage_filterReservedHdrs_send2ErrorQ_and_disconnect(self, version): if version not in commands.versions(VERSION): print 'Skipping test case (version %s is not configured)' % VERSION defer.returnValue(None) if BROKER == 'rabbitmq': print 'RabbitMQ does not support selector header' defer.returnValue(None) config = self.getConfig(version) client = async.Stomp(config) try: yield client.connect(host=VIRTUALHOST, versions=[version]) except StompProtocolError as e: print 'Broker does not support STOMP protocol %s. Skipping this test case. [%s]' % (e, version) defer.returnValue(None) # enqueue two messages messageHeaders = dict(self.msg1Hdrs) defaultHeaders = {StompSpec.ACK_HEADER: StompSpec.ACK_CLIENT_INDIVIDUAL} specialCharactersHeader = u'fen\xeatre:\r\n' if version != StompSpec.VERSION_1_0: defaultHeaders.update(self.headers) messageHeaders[specialCharactersHeader] = u'\xbfqu\xe9 tal?, s\xfc\xdf' client.send(self.queue, self.frame1, messageHeaders) client.send(self.queue, self.frame2) client.disconnect() yield client.disconnected # barf on first message so it will get put in error queue # use selector to guarantee message order (order not necessarily guaranteed) headers = {StompSpec.SELECTOR_HEADER: u"food='barf'"} headers.update(defaultHeaders) yield client.connect(host=VIRTUALHOST, versions=[version]) client.subscribe(self.queue, headers, listener=SubscriptionListener(self._saveFrameAndBarf, errorDestination=self.errorQueue, onMessageFailed=self._onMessageFailedSendToErrorDestinationAndRaise)) # client disconnected and returned error try: yield client.disconnected except StompestTestError: pass else: raise client = async.Stomp(config) # take a fresh client to prevent replay (we were disconnected by an error) # reconnect and subscribe again - consuming second message then disconnecting client = yield client.connect(host=VIRTUALHOST) headers.pop('selector') client.subscribe(self.queue, headers, listener=SubscriptionListener(self._eatOneFrameAndDisconnect, errorDestination=self.errorQueue)) # client disconnects without error yield client.disconnected # reconnect and subscribe to error queue client = yield client.connect(host=VIRTUALHOST) client.subscribe(self.errorQueue, defaultHeaders, listener=SubscriptionListener(self._saveErrorFrameAndDisconnect)) # wait for disconnect yield client.disconnected # verify that first message was in error queue self.assertEquals(self.frame1, self.errorQueueFrame.body) self.assertEquals(messageHeaders[u'food'], self.errorQueueFrame.headers['food']) if version != StompSpec.VERSION_1_0: self.assertEquals(messageHeaders[specialCharactersHeader], self.errorQueueFrame.headers[specialCharactersHeader]) self.assertNotEquals(self.unhandledFrame.headers[StompSpec.MESSAGE_ID_HEADER], self.errorQueueFrame.headers[StompSpec.MESSAGE_ID_HEADER]) # verify that second message was consumed self.assertEquals(self.frame2, self.consumedFrame.body)