def test_ack_basic(self): """ Test reliable client (ACK) behavior. """ dest = '/queue/ack-basic' conn1 = MockConnection() conn1.reliable_subscriber = True self.qm.subscribe(conn1, dest) m1 = Frame(frames.MESSAGE, headers={ 'destination': dest}, body='Message body (1)') self.qm.send(m1) self.assertEqual(conn1.frames[0], m1) m2 = Frame(frames.MESSAGE, headers={ 'destination': dest}, body='Message body (2)') self.qm.send(m2) self.assertEqual(len(conn1.frames), 1) self.assertEqual(conn1.frames[0], m1) ack = Frame(frames.ACK, headers={'destination': dest, 'message-id': m1.headers['message-id']}) self.qm.ack(conn1, ack) self.assertEqual(len(conn1.frames), 2, "Expected 2 frames now, after ACK.") self.assertEqual(conn1.frames[1], m2)
def test_ack_basic(self): """ Test reliable client (ACK) behavior. """ dest = '/queue/ack-basic' conn1 = MockConnection() conn1.reliable_subscriber = True self.qm.subscribe(conn1, dest) m1 = Frame(frames.MESSAGE, headers={'destination': dest}, body='Message body (1)') self.qm.send(m1) self.assertEqual(conn1.frames[0], m1) m2 = Frame(frames.MESSAGE, headers={'destination': dest}, body='Message body (2)') self.qm.send(m2) self.assertEqual(len(conn1.frames), 1) self.assertEqual(conn1.frames[0], m1) ack = Frame(frames.ACK, headers={ 'destination': dest, 'message-id': m1.headers['message-id'] }) self.qm.ack(conn1, ack) self.assertEqual(len(conn1.frames), 2, "Expected 2 frames now, after ACK.") self.assertEqual(conn1.frames[1], m2)
def setUp(self): self.qm = MockQueueManager() self.tm = MockTopicManager() self.conn = MockConnection() self.auth = MockAuthenticator() self.engine = StompEngine(connection=self.conn, queue_manager=self.qm, topic_manager=self.tm, authenticator=None)
def test_ack_transaction(self): """ Test the reliable client (ACK) behavior with transactions. """ dest = '/queue/ack-transaction' conn1 = MockConnection() conn1.reliable_subscriber = True self.qm.subscribe(conn1, dest) m1 = Frame(frames.MESSAGE, headers={ 'destination': dest, }, body='Message body (1)') self.qm.send(m1) assert conn1.frames[0] == m1 m2 = Frame(frames.MESSAGE, headers={'destination': dest}, body='Message body (2)') self.qm.send(m2) assert len(conn1.frames ) == 1, "Expected connection to still only have 1 frame." assert conn1.frames[0] == m1 ack = Frame(frames.ACK, headers={ 'destination': dest, 'transaction': 'abc', 'message-id': m1.headers.get('message-id') }) self.qm.ack(conn1, ack, transaction='abc') ack = Frame(frames.ACK, headers={ 'destination': dest, 'transaction': 'abc', 'message-id': m2.headers.get('message-id') }) self.qm.ack(conn1, ack, transaction='abc') self.assertEqual(len(conn1.frames), 2, "Expected 2 frames now, after ACK.") self.assertEqual(conn1.frames[1], m2) self.qm.resend_transaction_frames(conn1, transaction='abc') self.assertEqual(len(conn1.frames), 3, "Expected 3 frames after re-transmit.") self.assertTrue(self.qm._pending[conn1], "Expected 1 pending (waiting on ACK) frame." "")
def test_favorReliable(self): """ Test the favor reliable delivery scheduler. """ sched = FavorReliableSubscriberScheduler() conn1 = MockConnection() conn1.reliable_subscriber = True conn2 = MockConnection() conn2.reliable_subscriber = False choice = sched.choice((conn1, conn2), None) self.assertIs( choice, conn1, "Expected reliable connection to be selected.")
def test_clear_transaction_frames(self): """ Test the clearing of transaction ACK frames. """ dest = '/queue/tx' f = Frame(frames.SEND, headers={'destination': dest, 'transaction': '1'}, body='Body-A') self.qm.send(f) self.assertIn(dest, self.store.destinations()) conn1 = MockConnection() conn1.reliable_subscriber = True self.qm.subscribe(conn1, dest) self.assertEqual(len(conn1.frames), 1) self.qm.clear_transaction_frames(conn1, '1')
def test_disconnect_pending_frames(self): """ Test a queue disconnect when there are pending frames. """ dest = '/queue/disconnect-pending-frames' conn1 = MockConnection() conn1.reliable_subscriber = True self.qm.subscribe(conn1, dest) m1 = Frame(frames.MESSAGE, headers={ 'destination': dest}, body='Message body (1)') self.qm.send(m1) self.assertEqual(conn1.frames[0], m1) self.qm.disconnect(conn1) # Now we need to ensure that the frame we sent is re-queued. self.assertEqual(len(self.store.frames(dest)), 1)
def test_disconnect_pending_frames(self): """ Test a queue disconnect when there are pending frames. """ dest = '/queue/disconnect-pending-frames' conn1 = MockConnection() conn1.reliable_subscriber = True self.qm.subscribe(conn1, dest) m1 = Frame(frames.MESSAGE, headers={'destination': dest}, body='Message body (1)') self.qm.send(m1) self.assertEqual(conn1.frames[0], m1) self.qm.disconnect(conn1) # Now we need to ensure that the frame we sent is re-queued. self.assertEqual(len(self.store.frames(dest)), 1)
class ProtocolBaseTestCase(unittest.TestCase): def get_protocol(self): return STOMP12 def setUp(self): self.qm = MockQueueManager() self.tm = MockTopicManager() self.conn = MockConnection() self.auth = MockAuthenticator() self.engine = StompEngine(connection=self.conn, queue_manager=self.qm, topic_manager=self.tm, authenticator=None, protocol=self.get_protocol()) def feed_frame(self, cmd, headers=None, body=''): self.engine.process_frame(Frame(cmd, headers or {}, body)) return self.conn.frames[-1] def tearDown(self): self.conn.reset()
def test_clear_transaction_frames(self): """ Test the clearing of transaction ACK frames. """ dest = '/queue/tx' f = Frame(frames.SEND, headers={ 'destination': dest, 'transaction': '1' }, body='Body-A') self.qm.send(f) self.assertIn(dest, self.store.destinations()) conn1 = MockConnection() conn1.reliable_subscriber = True self.qm.subscribe(conn1, dest) self.assertEqual(len(conn1.frames), 1) self.qm.clear_transaction_frames(conn1, '1')
def test_send_reliableFirst(self): """ Test that messages are prioritized to reliable subscribers. This is actually a test of the underlying scheduler more than it is a test of the send message, per se. """ dest = '/queue/dest' conn1 = MockConnection() conn1.reliable_subscriber = True self.qm.subscribe(conn1, dest) conn2 = MockConnection() conn2.reliable_subscriber = False self.qm.subscribe(conn2, dest) f = Frame(frames.MESSAGE, headers={ 'destination': dest, 'message-id': uuid.uuid4() }, body='Empty') self.qm.send(f) self.assertEqual(len(conn1.frames), 1) self.assertEqual(len(conn2.frames), 0)
def test_ack_transaction(self): """ Test the reliable client (ACK) behavior with transactions. """ dest = '/queue/ack-transaction' conn1 = MockConnection() conn1.reliable_subscriber = True self.qm.subscribe(conn1, dest) m1 = Frame(frames.MESSAGE, headers={ 'destination': dest, }, body='Message body (1)') self.qm.send(m1) assert conn1.frames[0] == m1 m2 = Frame(frames.MESSAGE, headers={ 'destination': dest}, body='Message body (2)') self.qm.send(m2) assert len( conn1.frames) == 1, "Expected connection to still only have 1 frame." assert conn1.frames[0] == m1 ack = Frame(frames.ACK, headers={ 'destination': dest, 'transaction': 'abc', 'message-id': m1.headers.get('message-id')}) self.qm.ack(conn1, ack, transaction='abc') ack = Frame(frames.ACK, headers={ 'destination': dest, 'transaction': 'abc', 'message-id': m2.headers.get('message-id')}) self.qm.ack(conn1, ack, transaction='abc') self.assertEqual(len(conn1.frames), 2, "Expected 2 frames now, after ACK.") self.assertEqual(conn1.frames[1], m2) self.qm.resend_transaction_frames(conn1, transaction='abc') self.assertEqual(len(conn1.frames), 3, "Expected 3 frames after re-transmit.") self.assertTrue(self.qm._pending[conn1], "Expected 1 pending (waiting on ACK) frame.""")
def test_send_reliableFirst(self): """ Test that messages are prioritized to reliable subscribers. This is actually a test of the underlying scheduler more than it is a test of the send message, per se. """ dest = '/queue/dest' conn1 = MockConnection() conn1.reliable_subscriber = True self.qm.subscribe(conn1, dest) conn2 = MockConnection() conn2.reliable_subscriber = False self.qm.subscribe(conn2, dest) f = Frame(frames.MESSAGE, headers={ 'destination': dest, 'message-id': uuid.uuid4()}, body='Empty') self.qm.send(f) self.assertEqual(len(conn1.frames), 1) self.assertEqual(len(conn2.frames), 0)
def test_favorReliable(self): """ Test the favor reliable delivery scheduler. """ sched = FavorReliableSubscriberScheduler() conn1 = MockConnection() conn1.reliable_subscriber = True conn2 = MockConnection() conn2.reliable_subscriber = False choice = sched.choice((conn1, conn2), None) self.assertIs(choice, conn1, "Expected reliable connection to be selected.")
class EngineTest(unittest.TestCase): def setUp(self): self.qm = MockQueueManager() self.tm = MockTopicManager() self.conn = MockConnection() self.auth = MockAuthenticator() self.engine = StompEngine(connection=self.conn, queue_manager=self.qm, topic_manager=self.tm, authenticator=None) def tearDown(self): self.conn.reset() def _connect(self): """ Call the engine connect() method so that we have a valid 'session'. """ self.engine.process_frame(Frame('CONNECT')) def assertErrorFrame(self, frame, msgsub): """ Assert that the passed in frame is an error frame and that message contains specified string. """ assert frame.cmd.lower() == 'error' assert msgsub.lower() in frame.headers['message'].lower() def test_connect_no_auth(self): """ Test the CONNECT command with no auth required. """ assert self.engine.connected == False self.engine.process_frame(Frame('CONNECT')) assert self.engine.connected == True def test_connect_auth(self): """ Test the CONNECT command when auth is required. """ self.engine.authenticator = self.auth assert self.engine.connected == False self.engine.process_frame(Frame('CONNECT')) self.assertErrorFrame(self.conn.frames[-1], 'Auth') assert self.engine.connected == False self.engine.process_frame( Frame('CONNECT', headers={ 'login': MockAuthenticator.LOGIN, 'passcode': MockAuthenticator.PASSCODE })) assert self.engine.connected == True def test_subscribe_noack(self): """ Test subscribing to topics and queues w/ no ACK. """ self._connect() self.engine.process_frame( Frame('SUBSCRIBE', headers={'destination': '/queue/bar'})) assert self.conn in self.qm.queues['/queue/bar'] self.engine.process_frame( Frame('SUBSCRIBE', headers={'destination': '/foo/bar'})) assert self.conn in self.tm.topics['/foo/bar'] def test_send(self): """ Test sending to a topic and queue. """ self._connect() msg = Frame('SEND', headers={'destination': '/queue/foo'}, body='QUEUEMSG-BODY') self.engine.process_frame(msg) self.assertEqual(msg, self.qm.messages[-1]) msg = Frame('SEND', headers={'destination': '/topic/foo'}, body='TOPICMSG-BODY') self.engine.process_frame(msg) self.assertEqual(msg, self.tm.messages[-1]) msg = Frame('SEND', headers={}, body='TOPICMSG-BODY') self.engine.process_frame(msg) self.assertErrorFrame(self.conn.frames[-1], 'Missing destination') def test_receipt(self): """ Test pushing frames with a receipt specified. """ self._connect() receipt_id = 'FOOBAR' msg = Frame('SEND', headers={ 'destination': '/queue/foo', 'receipt': receipt_id }, body='QUEUEMSG-BODY') self.engine.process_frame(msg) rframe = self.conn.frames[-1] self.assertIsInstance(rframe, ReceiptFrame) self.assertEqual(receipt_id, rframe.headers.get('receipt-id')) receipt_id = 'FOOBAR2' self.engine.process_frame( Frame('SUBSCRIBE', headers={ 'destination': '/queue/bar', 'receipt': receipt_id })) rframe = self.conn.frames[-1] self.assertIsInstance(rframe, ReceiptFrame) self.assertEqual(receipt_id, rframe.headers.get('receipt-id')) def test_subscribe_ack(self): """ Test subscribing to a queue with ack=true """ self._connect() self.engine.process_frame( Frame('SUBSCRIBE', headers={ 'destination': '/queue/bar', 'ack': 'client' })) assert self.conn.reliable_subscriber == True assert self.conn in self.qm.queues['/queue/bar'] def test_unsubscribe(self): """ Test the UNSUBSCRIBE command. """ self._connect() self.engine.process_frame( Frame('SUBSCRIBE', headers={'destination': '/queue/bar'})) assert self.conn in self.qm.queues['/queue/bar'] self.engine.process_frame( Frame('UNSUBSCRIBE', headers={'destination': '/queue/bar'})) assert self.conn not in self.qm.queues['/queue/bar'] self.engine.process_frame( Frame('UNSUBSCRIBE', headers={'destination': '/invalid'})) def test_begin(self): """ Test transaction BEGIN. """ self._connect() self.engine.process_frame( Frame('BEGIN', headers={'transaction': 'abc'})) assert 'abc' in self.engine.transactions assert len(self.engine.transactions['abc']) == 0 def test_commit(self): """ Test transaction COMMIT. """ self._connect() self.engine.process_frame( Frame('BEGIN', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('BEGIN', headers={'transaction': '123'})) self.engine.process_frame( Frame('SEND', headers={ 'destination': '/dest', 'transaction': 'abc' }, body='ASDF')) self.engine.process_frame( Frame('SEND', headers={ 'destination': '/dest', 'transaction': 'abc' }, body='ASDF')) self.engine.process_frame( Frame('SEND', headers={ 'destination': '/dest', 'transaction': '123' }, body='ASDF')) assert len(self.tm.messages) == 0 self.engine.process_frame( Frame('COMMIT', headers={'transaction': 'abc'})) assert len(self.tm.messages) == 2 assert len(self.engine.transactions) == 1 self.engine.process_frame( Frame('COMMIT', headers={'transaction': '123'})) assert len(self.tm.messages) == 3 assert len(self.engine.transactions) == 0 def test_commit_invalid(self): """ Test invalid states for transaction COMMIT. """ self._connect() # Send a message with invalid transaction f = Frame('SEND', headers={ 'destination': '/dest', 'transaction': '123' }, body='ASDF') self.engine.process_frame(f) self.assertErrorFrame(self.conn.frames[-1], 'invalid transaction') # Attempt to commit invalid transaction self.engine.process_frame( Frame('COMMIT', headers={'transaction': 'abc'})) # Attempt to commit already-committed transaction self.engine.process_frame( Frame('BEGIN', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('SEND', headers={ 'destination': '/dest', 'transaction': 'abc' }, body='FOO')) self.engine.process_frame( Frame('COMMIT', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('COMMIT', headers={'transaction': 'abc'})) self.assertErrorFrame(self.conn.frames[-1], 'invalid transaction') def test_abort(self): """ Test transaction ABORT. """ self._connect() self.engine.process_frame( Frame('BEGIN', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('BEGIN', headers={'transaction': '123'})) f1 = Frame('SEND', headers={ 'destination': '/dest', 'transaction': 'abc' }, body='ASDF') self.engine.process_frame(f1) f2 = Frame('SEND', headers={ 'destination': '/dest', 'transaction': 'abc' }, body='ASDF') self.engine.process_frame(f2) f3 = Frame('SEND', headers={ 'destination': '/dest', 'transaction': '123' }, body='ASDF') self.engine.process_frame(f3) assert len(self.tm.messages) == 0 self.engine.process_frame( Frame('ABORT', headers={'transaction': 'abc'})) assert len(self.tm.messages) == 0 assert len(self.engine.transactions) == 1 def test_abort_invalid(self): """ Test invalid states for transaction ABORT. """ self._connect() self.engine.process_frame( Frame('ABORT', headers={'transaction': 'abc'})) self.assertErrorFrame(self.conn.frames[-1], 'invalid transaction') self.engine.process_frame( Frame('BEGIN', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('ABORT', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('ABORT', headers={'transaction': 'abc2'})) self.assertErrorFrame(self.conn.frames[-1], 'invalid transaction')
def setUp(self): self.store = self._queuestore() self.qm = QueueManager(self.store) self.conn = MockConnection()
class EngineTest(unittest.TestCase): def setUp(self): self.qm = MockQueueManager() self.tm = MockTopicManager() self.conn = MockConnection() self.auth = MockAuthenticator() self.engine = StompEngine(connection=self.conn, queue_manager=self.qm, topic_manager=self.tm, authenticator=None) def tearDown(self): self.conn.reset() def _connect(self): """ Call the engine connect() method so that we have a valid 'session'. """ self.engine.process_frame(Frame('CONNECT')) def assertErrorFrame(self, frame, msgsub): """ Assert that the passed in frame is an error frame and that message contains specified string. """ assert frame.cmd.lower() == 'error' assert msgsub.lower() in frame.headers['message'].lower() def test_connect_no_auth(self): """ Test the CONNECT command with no auth required. """ assert self.engine.connected == False self.engine.process_frame(Frame('CONNECT')) assert self.engine.connected == True def test_connect_auth(self): """ Test the CONNECT command when auth is required. """ self.engine.authenticator = self.auth assert self.engine.connected == False self.engine.process_frame(Frame('CONNECT')) self.assertErrorFrame(self.conn.frames[-1], 'Auth') assert self.engine.connected == False self.engine.process_frame(Frame('CONNECT', headers={'login': MockAuthenticator.LOGIN, 'passcode': MockAuthenticator.PASSCODE})) assert self.engine.connected == True def test_subscribe_noack(self): """ Test subscribing to topics and queues w/ no ACK. """ self._connect() self.engine.process_frame( Frame('SUBSCRIBE', headers={'destination': '/queue/bar'})) assert self.conn in self.qm.queues['/queue/bar'] self.engine.process_frame( Frame('SUBSCRIBE', headers={'destination': '/foo/bar'})) assert self.conn in self.tm.topics['/foo/bar'] def test_send(self): """ Test sending to a topic and queue. """ self._connect() msg = Frame('SEND', headers={ 'destination': '/queue/foo'}, body='QUEUEMSG-BODY') self.engine.process_frame(msg) self.assertEqual(msg, self.qm.messages[-1]) msg = Frame('SEND', headers={ 'destination': '/topic/foo'}, body='TOPICMSG-BODY') self.engine.process_frame(msg) self.assertEqual(msg, self.tm.messages[-1]) msg = Frame('SEND', headers={}, body='TOPICMSG-BODY') self.engine.process_frame(msg) self.assertErrorFrame(self.conn.frames[-1], 'Missing destination') def test_receipt(self): """ Test pushing frames with a receipt specified. """ self._connect() receipt_id = 'FOOBAR' msg = Frame('SEND', headers={ 'destination': '/queue/foo', 'receipt': receipt_id}, body='QUEUEMSG-BODY') self.engine.process_frame(msg) rframe = self.conn.frames[-1] self.assertIsInstance(rframe, ReceiptFrame) self.assertEqual(receipt_id, rframe.headers.get('receipt-id')) receipt_id = 'FOOBAR2' self.engine.process_frame(Frame('SUBSCRIBE', headers={ 'destination': '/queue/bar', 'receipt': receipt_id})) rframe = self.conn.frames[-1] self.assertIsInstance(rframe, ReceiptFrame) self.assertEqual(receipt_id, rframe.headers.get('receipt-id')) def test_subscribe_ack(self): """ Test subscribing to a queue with ack=true """ self._connect() self.engine.process_frame(Frame('SUBSCRIBE', headers={'destination': '/queue/bar', 'ack': 'client'})) assert self.conn.reliable_subscriber == True assert self.conn in self.qm.queues['/queue/bar'] def test_unsubscribe(self): """ Test the UNSUBSCRIBE command. """ self._connect() self.engine.process_frame( Frame('SUBSCRIBE', headers={'destination': '/queue/bar'})) assert self.conn in self.qm.queues['/queue/bar'] self.engine.process_frame( Frame('UNSUBSCRIBE', headers={'destination': '/queue/bar'})) assert self.conn not in self.qm.queues['/queue/bar'] self.engine.process_frame( Frame('UNSUBSCRIBE', headers={'destination': '/invalid'})) def test_begin(self): """ Test transaction BEGIN. """ self._connect() self.engine.process_frame( Frame('BEGIN', headers={'transaction': 'abc'})) assert 'abc' in self.engine.transactions assert len(self.engine.transactions['abc']) == 0 def test_commit(self): """ Test transaction COMMIT. """ self._connect() self.engine.process_frame( Frame('BEGIN', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('BEGIN', headers={'transaction': '123'})) self.engine.process_frame(Frame( 'SEND', headers={'destination': '/dest', 'transaction': 'abc'}, body='ASDF')) self.engine.process_frame(Frame( 'SEND', headers={'destination': '/dest', 'transaction': 'abc'}, body='ASDF')) self.engine.process_frame(Frame( 'SEND', headers={'destination': '/dest', 'transaction': '123'}, body='ASDF')) assert len(self.tm.messages) == 0 self.engine.process_frame( Frame('COMMIT', headers={'transaction': 'abc'})) assert len(self.tm.messages) == 2 assert len(self.engine.transactions) == 1 self.engine.process_frame( Frame('COMMIT', headers={'transaction': '123'})) assert len(self.tm.messages) == 3 assert len(self.engine.transactions) == 0 def test_commit_invalid(self): """ Test invalid states for transaction COMMIT. """ self._connect() # Send a message with invalid transaction f = Frame('SEND', headers={ 'destination': '/dest', 'transaction': '123'}, body='ASDF') self.engine.process_frame(f) self.assertErrorFrame(self.conn.frames[-1], 'invalid transaction') # Attempt to commit invalid transaction self.engine.process_frame( Frame('COMMIT', headers={'transaction': 'abc'})) # Attempt to commit already-committed transaction self.engine.process_frame( Frame('BEGIN', headers={'transaction': 'abc'})) self.engine.process_frame(Frame( 'SEND', headers={'destination': '/dest', 'transaction': 'abc'}, body='FOO')) self.engine.process_frame( Frame('COMMIT', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('COMMIT', headers={'transaction': 'abc'})) self.assertErrorFrame(self.conn.frames[-1], 'invalid transaction') def test_abort(self): """ Test transaction ABORT. """ self._connect() self.engine.process_frame( Frame('BEGIN', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('BEGIN', headers={'transaction': '123'})) f1 = Frame('SEND', headers={ 'destination': '/dest', 'transaction': 'abc'}, body='ASDF') self.engine.process_frame(f1) f2 = Frame('SEND', headers={ 'destination': '/dest', 'transaction': 'abc'}, body='ASDF') self.engine.process_frame(f2) f3 = Frame('SEND', headers={ 'destination': '/dest', 'transaction': '123'}, body='ASDF') self.engine.process_frame(f3) assert len(self.tm.messages) == 0 self.engine.process_frame( Frame('ABORT', headers={'transaction': 'abc'})) assert len(self.tm.messages) == 0 assert len(self.engine.transactions) == 1 def test_abort_invalid(self): """ Test invalid states for transaction ABORT. """ self._connect() self.engine.process_frame( Frame('ABORT', headers={'transaction': 'abc'})) self.assertErrorFrame(self.conn.frames[-1], 'invalid transaction') self.engine.process_frame( Frame('BEGIN', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('ABORT', headers={'transaction': 'abc'})) self.engine.process_frame( Frame('ABORT', headers={'transaction': 'abc2'})) self.assertErrorFrame(self.conn.frames[-1], 'invalid transaction')
def setUp(self): self.tm = TopicManager() self.conn = MockConnection()