Exemple #1
0
    def test_nack_invalid_frame(self):
        self.engine.connected = True

        self.engine.process_frame(Frame(frames.NACK, headers={'subscription': 'foo'}))
        self.assertIsInstance(self.conn.frames[-1], ErrorFrame)
        self.engine.process_frame(Frame(frames.NACK, headers={'message-id': 1}))
        self.assertIsInstance(self.conn.frames[-1], ErrorFrame)
Exemple #2
0
    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)
Exemple #3
0
    def test_send_backlog_err_unreliable(self):
        """ Test errors when sending backlog to reliable subscriber. """
        class ExcThrowingConn(object):
            reliable_subscriber = False

            def send_frame(self, frame):
                raise RuntimeError("Error sending data.")

        dest = '/queue/dest'

        f = Frame(frames.SEND, headers={'destination': dest}, body='123')
        self.qm.send(f)

        f2 = Frame(frames.SEND, headers={'destination': dest}, body='12345')
        self.qm.send(f2)

        conn = ExcThrowingConn()
        try:
            self.qm.subscribe(conn, dest)
            self.fail("Expected error when sending backlog.")
        except RuntimeError:
            pass

        # The message will have been requeued at this point, so add a valid
        # subscriber

        self.qm.subscribe(self.conn, dest)

        self.assertEqual(len(self.conn.frames), 2,
                         "Expected frame to be delivered")
        self.assertListEqual(list(self.conn.frames), [f2, f])
Exemple #4
0
    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'))
Exemple #5
0
    def test_dequeue_specific(self):
        """ Test that we only dequeue from the correct queue. """
        dest = '/queue/foo'
        notdest = '/queue/other'

        frame1 = Frame('MESSAGE', headers={
                       'message-id': str(uuid.uuid4())}, body='message-1')
        self.store.enqueue(dest, frame1)

        frame2 = Frame('MESSAGE', headers={
                       'message-id': str(uuid.uuid4())}, body='message-2')
        self.store.enqueue(notdest, frame2)

        frame3 = Frame('MESSAGE', headers={
                       'message-id': str(uuid.uuid4())}, body='message-3')
        self.store.enqueue(dest, frame3)

        self.assertTrue(self.store.has_frames(dest))
        self.assertEqual(self.store.size(dest), 2)

        rframe1 = self.store.dequeue(dest)
        self.assertEqual(frame1, rframe1)

        rframe2 = self.store.dequeue(dest)
        self.assertEqual(frame3, rframe2)

        self.assertFalse(self.store.has_frames(dest))
        self.assertEqual(self.store.size(dest), 0)
Exemple #6
0
    def test_dequeue_order(self):
        """ Test the order that frames are returned by dequeue() method. """
        dest = '/queue/foo'

        frame1 = Frame('MESSAGE', headers={
                       'message-id': str(uuid.uuid4())}, body='message-1')
        self.store.enqueue(dest, frame1)

        frame2 = Frame('MESSAGE', headers={
                       'message-id': str(uuid.uuid4())}, body='message-2')
        self.store.enqueue(dest, frame2)

        frame3 = Frame('MESSAGE', headers={
                       'message-id': str(uuid.uuid4())}, body='message-3')
        self.store.enqueue(dest, frame3)

        self.assertTrue(self.store.has_frames(dest))
        self.assertEqual(self.store.size(dest), 3)

        rframe1 = self.store.dequeue(dest)
        self.assertEqual(frame1, rframe1)

        rframe2 = self.store.dequeue(dest)
        self.assertEqual(frame2, rframe2)

        rframe3 = self.store.dequeue(dest)
        self.assertEqual(frame3, rframe3)

        self.assertFalse(self.store.has_frames(dest))
        self.assertEqual(self.store.size(dest), 0)
Exemple #7
0
    def test_sync_checkpoint_timeout(self):
        """ Test a expected sync behavior with checkpoint_timeout param. """

        data_dir = tempfile.mkdtemp(prefix='coilmq-dbm-test')
        try:
            store = DbmQueue(data_dir, checkpoint_timeout=0.5)
            dest = '/queue/foo'

            frame = Frame('MESSAGE',
                          headers={'message-id': str(uuid.uuid4())},
                          body='some data -1')
            store.enqueue(dest, frame)

            time.sleep(0.5)

            frame = Frame('MESSAGE',
                          headers={'message-id': str(uuid.uuid4())},
                          body='some data -2')
            store.enqueue(dest, frame)

            self.assertEqual(store.size(dest), 2)

            # No close()!

            store2 = DbmQueue(data_dir)
            self.assertEqual(store2.size(dest), 2)

        except:
            shutil.rmtree(data_dir, ignore_errors=True)
            raise
Exemple #8
0
    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']
Exemple #9
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."
                        "")
Exemple #10
0
    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'}))
Exemple #11
0
    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)
Exemple #12
0
 def test_no_heartbeat_from_client(self):
     with self.with_heartbeat(STOMP11(self.engine, receive_heartbeat_interval=50)):
         self.engine.process_frame(Frame(frames.CONNECT, headers={'heart-beat': '50,50', 'accept-version': '1.1'}))
         self.assertTrue(self.engine.connected)
         self.assertTrue(self.engine.protocol.timer._running)
         time.sleep(0.53)
         self.assertFalse(self.engine.connected)
Exemple #13
0
    def test_send_subscriber_timeout(self):
        """ Test a send command when one subscriber errs out. """
        class TimeoutConnection(object):
            reliable_subscriber = False

            def send_frame(self, frame):
                raise socket.timeout("timed out")

            def reset(self):
                pass

        dest = '/topic/dest'

        bad_client = TimeoutConnection()

        # Subscribe both a good client and a bad client.
        self.tm.subscribe(bad_client, dest)
        self.tm.subscribe(self.conn, dest)

        f = Frame('message', headers={'destination': dest}, body='Empty')
        self.tm.send(f)

        # Make sure out good client got the message.
        self.assertEqual(len(self.conn.frames), 1)
        self.assertEqual(self.conn.frames[0], f)

        # Make sure our bad client got disconnected
        # (This might be a bit too intimate.)
        self.assertNotIn(bad_client, self.tm._topics[dest])
Exemple #14
0
    def test_unsubscribe(self):
        """ Test unsubscribing a connection from the queue. """
        dest = '/topic/dest'

        self.tm.subscribe(self.conn, dest)
        f = Frame(frames.MESSAGE, headers={'destination': dest}, body='Empty')
        self.tm.send(f)

        self.assertEqual(len(self.conn.frames), 1)
        self.assertEqual(self.conn.frames[0], f)

        self.tm.unsubscribe(self.conn, dest)
        f = Frame(frames.MESSAGE, headers={'destination': dest}, body='Empty')
        self.tm.send(f)

        self.assertEqual(len(self.conn.frames), 1)
Exemple #15
0
    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
Exemple #16
0
    def test_sync_checkpoint_ops(self):
        """ Test a expected sync behavior with checkpoint_operations param. """

        data_dir = tempfile.mkdtemp(prefix='coilmq-dbm-test')
        max_ops = 5
        try:
            store = DbmQueue(data_dir, checkpoint_operations=max_ops)
            dest = '/queue/foo'

            for i in range(max_ops + 1):
                frame = Frame('MESSAGE',
                              headers={'message-id': str(uuid.uuid4())},
                              body='some data - %d' % i)
                store.enqueue(dest, frame)

            self.assertEqual(store.size(dest), max_ops + 1)

            # No close()!

            store2 = DbmQueue(data_dir)
            self.assertEqual(store2.size(dest), max_ops + 1)

        except:
            shutil.rmtree(data_dir, ignore_errors=True)
            raise
Exemple #17
0
    def test_dequeue_order(self):
        """ Test the order that frames are returned by dequeue() method. """
        dest = '/queue/foo'

        frame1 = Frame('MESSAGE',
                       headers={'message-id': 'id-1'},
                       body='message-1')
        self.store.enqueue(dest, frame1)

        frame2 = Frame('MESSAGE',
                       headers={'message-id': 'id-2'},
                       body='message-2')
        self.store.enqueue(dest, frame2)

        frame3 = Frame('MESSAGE',
                       headers={'message-id': 'id-3'},
                       body='message-3')
        self.store.enqueue(dest, frame3)

        self.assertTrue(self.store.has_frames(dest))
        self.assertEqual(self.store.size(dest), 3)

        # Perform some updates to change the expected order.

        sess = meta.Session()
        sess.execute(model.frames_table.update().where(
            model.frames_table.c.message_id == 'id-1').values(
                queued=datetime.datetime(2010, 1, 1)))
        sess.execute(model.frames_table.update().where(
            model.frames_table.c.message_id == 'id-2').values(
                queued=datetime.datetime(2009, 1, 1)))
        sess.execute(model.frames_table.update().where(
            model.frames_table.c.message_id == 'id-3').values(
                queued=datetime.datetime(2004, 1, 1)))
        sess.commit()

        rframe1 = self.store.dequeue(dest)
        assert frame3 == rframe1

        rframe2 = self.store.dequeue(dest)
        assert frame2 == rframe2

        rframe3 = self.store.dequeue(dest)
        assert frame1 == rframe3

        assert self.store.has_frames(dest) == False
        assert self.store.size(dest) == 0
Exemple #18
0
 def connect(self, frame, response=None):
     connected_frame = Frame(frames.CONNECTED)
     self._negotiate_protocol(frame, connected_frame)
     heart_beat = frame.headers.get('heart-beat', '0,0')
     if heart_beat:
         self.enable_heartbeat(*map(int, heart_beat.split(',')),
                               response=connected_frame)
     super(STOMP11, self).connect(frame, response=connected_frame)
Exemple #19
0
    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')
Exemple #20
0
    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
Exemple #21
0
    def test_enqueue(self):
        """ Test the enqueue() method. """
        dest = '/queue/foo'
        frame = Frame('MESSAGE', headers={
                      'message-id': str(uuid.uuid4())}, body='some data')
        self.store.enqueue(dest, frame)

        self.assertTrue(self.store.has_frames(dest))
        self.assertEqual(self.store.size(dest), 1)
Exemple #22
0
    def test_send_simple(self):
        """ Test a basic send command. """
        dest = '/topic/dest'

        f = Frame(frames.SEND, headers={'destination': dest}, body='Empty')
        self.tm.send(f)

        # Assert some side-effects
        self.assertIn('message-id', f.headers)
        self.assertEqual(f.cmd, 'message')
Exemple #23
0
    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 send(self,
          destination,
          message,
          set_content_length=True,
          extra_headers=None):
     headers = extra_headers or {}
     headers['destination'] = destination
     if set_content_length:
         headers['content-length'] = len(message)
     self.send_frame(Frame('send', headers=headers, body=message))
Exemple #25
0
 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']
Exemple #26
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')
Exemple #27
0
    def send_simple(self):
        """ Test a basic send command. """
        dest = '/queue/dest'

        f = Frame(frames.SEND, headers={'destination': dest}, body='Empty')
        self.qm.send(f)

        self.assertIn(dest, self.store.destinations())
        self.assertEqua(len(self.store.frames(dest)), 1)

        # Assert some side-effects
        self.assertIn('message-id', f.headers)
        self.assertEqual(f.command, frames.MESSAGE)
Exemple #28
0
    def test_dequeue_identity(self):
        """ Test the dequeue() method. """
        dest = '/queue/foo'
        frame = Frame('MESSAGE',
                      headers={'message-id': str(uuid.uuid4())},
                      body='some data')
        self.store.enqueue(dest, frame)

        self.assertTrue(self.store.has_frames(dest))
        self.assertEqual(self.store.size(dest), 1)

        rframe = self.store.dequeue(dest)
        self.assertEqual(frame, rframe)
        self.assertIsNot(frame, rframe)

        self.assertFalse(self.store.has_frames(dest))
        self.assertEqual(self.store.size(dest), 0)
Exemple #29
0
    def test_dequeue(self):
        """ Test the dequeue() method. """
        dest = '/queue/foo'
        frame = Frame('MESSAGE', headers={
                      'message-id': str(uuid.uuid4())}, body='some data')
        self.store.enqueue(dest, frame)

        self.assertTrue(self.store.has_frames(dest))
        self.assertEqual(self.store.size(dest), 1)

        rframe = self.store.dequeue(dest)
        self.assertEqual(frame, rframe)

        # We cannot generically assert whether or not frame and rframe are
        # the *same* object.

        self.assertFalse(self.store.has_frames(dest))
        self.assertEqual(self.store.size(dest), 0)
Exemple #30
0
    def test_sync_loss(self):
        """ Test metadata loss behavior. """

        data_dir = tempfile.mkdtemp(prefix='coilmq-dbm-test')
        try:
            store = DbmQueue(data_dir)
            dest = '/queue/foo'
            frame = Frame('MESSAGE',
                          headers={'message-id': str(uuid.uuid4())},
                          body='some data')
            store.enqueue(dest, frame)
            self.assertEqual(store.size(dest), 1)

            store2 = DbmQueue(data_dir)
            self.assertEqual(store2.size(dest), 0)

        except:
            shutil.rmtree(data_dir, ignore_errors=True)
            raise
Exemple #31
0
 def test_pack_binary(self):
     bin_body = "\x00\x00HELLO\x00\x00DONKEY\x00\x00"
     frame = Frame(frames.CONNECT, body=bin_body)
     self.assertEqual(frame.pack(
     ), b'CONNECT\ncontent-length:17\n\n\x00\x00HELLO\x00\x00DONKEY\x00\x00\x00')
Exemple #32
0
 def test_pack(self):
     frame = Frame(frames.CONNECT, OrderedDict(foo='bar'), 'body')
     self.assertEqual(
         frame.pack(), b'CONNECT\nfoo:bar\ncontent-length:4\n\nbody\x00')
Exemple #33
0
 def test_parse_frame_empty_body(self):
     buff = io.BytesIO(
         b'SUBSCRIBE\nack:auto\ndestination:/queue/test\n\n\x00fdffdfd')
     f = Frame.from_buffer(buff)
Exemple #34
0
 def test_parse_frame_body_not_terminated(self):
     buff = io.BytesIO(b'CONNECT\ncontent-length:10\n\n0123456789')
     self.assertRaises(BodyNotTerminated, lambda: Frame.from_buffer(buff))
Exemple #35
0
 def test_parse_frame_incomplete_body(self):
     buff = io.BytesIO(b'CONNECT\ncontent-length:1000\n\n0123456789\x00')
     self.assertRaises(IncompleteFrame, lambda: Frame.from_buffer(buff))