Exemplo n.º 1
0
    def test_send_exchange_with_reply(self):
        driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)
        target1 = oslo_messaging.Target(topic="test-topic", exchange="e1")
        listener1 = _ListenerThread(driver.listen(target1), 1)
        target2 = oslo_messaging.Target(topic="test-topic", exchange="e2")
        listener2 = _ListenerThread(driver.listen(target2), 1)

        rc = driver.send(target1, {"context": "whatever"}, {
            "method": "echo",
            "id": "e1"
        },
                         wait_for_reply=True,
                         timeout=30)
        self.assertIsNotNone(rc)
        self.assertEqual(rc.get('correlation-id'), 'e1')

        rc = driver.send(target2, {"context": "whatever"}, {
            "method": "echo",
            "id": "e2"
        },
                         wait_for_reply=True,
                         timeout=30)
        self.assertIsNotNone(rc)
        self.assertEqual(rc.get('correlation-id'), 'e2')

        listener1.join(timeout=30)
        self.assertFalse(listener1.isAlive())
        listener2.join(timeout=30)
        self.assertFalse(listener2.isAlive())
        driver.cleanup()
Exemplo n.º 2
0
    def test_notification(self):
        driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)
        notifications = [(oslo_messaging.Target(topic="topic-1"), 'info'),
                         (oslo_messaging.Target(topic="topic-1"), 'error'),
                         (oslo_messaging.Target(topic="topic-2"), 'debug')]
        nl = driver.listen_for_notifications(notifications)

        listener = _ListenerThread(nl, 3)
        targets = [
            'topic-1.info',
            'topic-1.bad',  # should be dropped
            'bad-topic.debug',  # should be dropped
            'topic-1.error',
            'topic-2.debug'
        ]

        for t in targets:
            driver.send_notification(oslo_messaging.Target(topic=t), "context",
                                     {'target': t}, 1.0)
        listener.join(timeout=30)
        self.assertFalse(listener.isAlive())
        topics = [x.message.get('target') for x in listener.get_messages()]
        self.assertTrue('topic-1.info' in topics)
        self.assertTrue('topic-1.error' in topics)
        self.assertTrue('topic-2.debug' in topics)
        self.assertEqual(self._broker.dropped_count, 2)
        driver.cleanup()
Exemplo n.º 3
0
 def test_listener_cleanup(self):
     """Verify unused listener can cleanly shutdown."""
     driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)
     target = oslo_messaging.Target(topic="test-topic")
     listener = driver.listen(target)
     self.assertIsInstance(listener, amqp_driver.ProtonListener)
     driver.cleanup()
Exemplo n.º 4
0
    def test_notification(self):
        driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)
        notifications = [(oslo_messaging.Target(topic="topic-1"), 'info'),
                         (oslo_messaging.Target(topic="topic-1"), 'error'),
                         (oslo_messaging.Target(topic="topic-2"), 'debug')]
        nl = driver.listen_for_notifications(notifications, None)

        # send one for each support version:
        msg_count = len(notifications) * 2
        listener = _ListenerThread(nl, msg_count)
        targets = [
            'topic-1.info',
            'topic-1.bad',  # should be dropped
            'bad-topic.debug',  # should be dropped
            'topic-1.error',
            'topic-2.debug'
        ]

        for version in (1.0, 2.0):
            for t in targets:
                driver.send_notification(oslo_messaging.Target(topic=t),
                                         "context", {'target': t}, version)

        listener.join(timeout=30)
        self.assertFalse(listener.isAlive())
        topics = [x.message.get('target') for x in listener.get_messages()]

        self.assertEqual(len(topics), msg_count)
        self.assertEqual(topics.count('topic-1.info'), 2)
        self.assertEqual(topics.count('topic-1.error'), 2)
        self.assertEqual(topics.count('topic-2.debug'), 2)
        self.assertEqual(self._broker.dropped_count, 4)
        driver.cleanup()
Exemplo n.º 5
0
 def test_send_no_reply(self):
     driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)
     target = oslo_messaging.Target(topic="test-topic")
     listener = _ListenerThread(driver.listen(target), 1)
     rc = driver.send(target, {"context": True}, {"msg": "value"},
                      wait_for_reply=False)
     self.assertIsNone(rc)
     listener.join(timeout=30)
     self.assertFalse(listener.isAlive())
     self.assertEqual(listener.messages.get().message, {"msg": "value"})
     driver.cleanup()
    def _failover(self, fail_brokers):
        self._brokers[0].start()
        # self.config(trace=True, group="oslo_messaging_amqp")
        driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)

        target = oslo_messaging.Target(topic="my-topic")
        listener = _ListenerThread(
            driver.listen(target, None, None)._poll_style_listener, 2)

        # wait for listener links to come up
        # 4 == 3 links per listener + 1 for the global reply queue
        predicate = lambda: self._brokers[0].sender_link_count == 4
        _wait_until(predicate, 30)
        self.assertTrue(predicate())

        rc = driver.send(target, {"context": "whatever"},
                         {"method": "echo", "id": "echo-1"},
                         wait_for_reply=True,
                         timeout=30)
        self.assertIsNotNone(rc)
        self.assertEqual(rc.get('correlation-id'), 'echo-1')

        # 1 request msg, 1 response:
        self.assertEqual(self._brokers[0].topic_count, 1)
        self.assertEqual(self._brokers[0].direct_count, 1)

        # invoke failover method
        fail_brokers(self._brokers[0], self._brokers[1])

        # wait for listener links to re-establish on broker 1
        # 4 = 3 links per listener + 1 for the global reply queue
        predicate = lambda: self._brokers[1].sender_link_count == 4
        _wait_until(predicate, 30)
        self.assertTrue(predicate())

        rc = driver.send(target,
                         {"context": "whatever"},
                         {"method": "echo", "id": "echo-2"},
                         wait_for_reply=True,
                         timeout=2)
        self.assertIsNotNone(rc)
        self.assertEqual(rc.get('correlation-id'), 'echo-2')

        # 1 request msg, 1 response:
        self.assertEqual(self._brokers[1].topic_count, 1)
        self.assertEqual(self._brokers[1].direct_count, 1)

        listener.join(timeout=30)
        self.assertFalse(listener.isAlive())

        # note: stopping the broker first tests cleaning up driver without a
        # connection active
        self._brokers[1].stop()
        driver.cleanup()
Exemplo n.º 7
0
    def test_broker_failover(self):
        """Simulate failover of one broker to another."""
        self._brokers[0].start()
        driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)

        target = oslo_messaging.Target(topic="my-topic")
        listener = _ListenerThread(driver.listen(target), 2)

        rc = driver.send(target, {"context": "whatever"}, {
            "method": "echo",
            "id": "echo-1"
        },
                         wait_for_reply=True,
                         timeout=30)
        self.assertIsNotNone(rc)
        self.assertEqual(rc.get('correlation-id'), 'echo-1')
        # 1 request msg, 1 response:
        self.assertEqual(self._brokers[0].topic_count, 1)
        self.assertEqual(self._brokers[0].direct_count, 1)

        # fail broker 0 and start broker 1:
        self._brokers[0].stop()
        self._brokers[1].start()
        deadline = time.time() + 30
        responded = False
        sequence = 2
        while deadline > time.time() and not responded:
            if not listener.isAlive():
                # listener may have exited after replying to an old correlation
                # id: restart new listener
                listener = _ListenerThread(driver.listen(target), 1)
            try:
                rc = driver.send(target, {"context": "whatever"}, {
                    "method": "echo",
                    "id": "echo-%d" % sequence
                },
                                 wait_for_reply=True,
                                 timeout=2)
                self.assertIsNotNone(rc)
                self.assertEqual(rc.get('correlation-id'),
                                 'echo-%d' % sequence)
                responded = True
            except oslo_messaging.MessagingTimeout:
                sequence += 1

        self.assertTrue(responded)
        listener.join(timeout=30)
        self.assertFalse(listener.isAlive())

        # note: stopping the broker first tests cleaning up driver without a
        # connection active
        self._brokers[1].stop()
        driver.cleanup()
    def test_listener_failover(self):
        """Verify that Listeners sharing the same topic are re-established
        after failover.
        """
        self._brokers[0].start()
        # self.config(trace=True, group="oslo_messaging_amqp")
        driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)

        target = oslo_messaging.Target(topic="my-topic")
        bcast = oslo_messaging.Target(topic="my-topic", fanout=True)
        listener1 = _ListenerThread(
            driver.listen(target, None, None)._poll_style_listener, 2)
        listener2 = _ListenerThread(
            driver.listen(target, None, None)._poll_style_listener, 2)

        # wait for 7 sending links to become active on the broker.
        # 7 = 3 links per Listener + 1 global reply link
        predicate = lambda: self._brokers[0].sender_link_count == 7
        _wait_until(predicate, 30)
        self.assertTrue(predicate())

        driver.send(bcast, {"context": "whatever"},
                    {"method": "ignore", "id": "echo-1"})

        # 1 message per listener
        predicate = lambda: self._brokers[0].fanout_sent_count == 2
        _wait_until(predicate, 30)
        self.assertTrue(predicate())

        #  start broker 1 then shutdown broker 0:
        self._brokers[1].start()
        self._brokers[0].stop(clean=True)

        # wait again for 7 sending links to re-establish on broker 1
        predicate = lambda: self._brokers[1].sender_link_count == 7
        _wait_until(predicate, 30)
        self.assertTrue(predicate())

        driver.send(bcast, {"context": "whatever"},
                    {"method": "ignore", "id": "echo-2"})

        # 1 message per listener
        predicate = lambda: self._brokers[1].fanout_sent_count == 2
        _wait_until(predicate, 30)
        self.assertTrue(predicate())

        listener1.join(timeout=30)
        listener2.join(timeout=30)
        self.assertFalse(listener1.isAlive() or listener2.isAlive())

        driver.cleanup()
        self._brokers[1].stop()
Exemplo n.º 9
0
    def test_authentication_failure(self):
        """Verify that a bad password given in TransportHost is
        rejected by the broker.
        """

        addr = "amqp://*****:*****@%s:%d" % (self._broker.host,
                                             self._broker.port)
        url = oslo_messaging.TransportURL.parse(self.conf, addr)
        driver = amqp_driver.ProtonDriver(self.conf, url)
        target = oslo_messaging.Target(topic="test-topic")
        _ListenerThread(driver.listen(target), 1)
        self.assertRaises(oslo_messaging.MessagingTimeout,
                          driver.send,
                          target, {"context": True}, {"method": "echo"},
                          wait_for_reply=True,
                          timeout=2.0)
        driver.cleanup()
Exemplo n.º 10
0
    def test_authentication_ok(self):
        """Verify that username and password given in TransportHost are
        accepted by the broker.
        """

        addr = "amqp://*****:*****@%s:%d" % (self._broker.host,
                                            self._broker.port)
        url = oslo_messaging.TransportURL.parse(self.conf, addr)
        driver = amqp_driver.ProtonDriver(self.conf, url)
        target = oslo_messaging.Target(topic="test-topic")
        listener = _ListenerThread(driver.listen(target), 1)
        rc = driver.send(target, {"context": True}, {"method": "echo"},
                         wait_for_reply=True)
        self.assertIsNotNone(rc)
        listener.join(timeout=30)
        self.assertFalse(listener.isAlive())
        driver.cleanup()
Exemplo n.º 11
0
    def test_send_timeout(self):
        """Verify send timeout."""
        driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)
        target = oslo_messaging.Target(topic="test-topic")
        listener = _ListenerThread(driver.listen(target), 1)

        # the listener will drop this message:
        try:
            driver.send(target, {"context": "whatever"}, {"method": "drop"},
                        wait_for_reply=True,
                        timeout=1.0)
        except Exception as ex:
            self.assertIsInstance(ex, oslo_messaging.MessagingTimeout, ex)
        else:
            self.assertTrue(False, "No Exception raised!")
        listener.join(timeout=30)
        self.assertFalse(listener.isAlive())
        driver.cleanup()
Exemplo n.º 12
0
 def test_authentication_default_username(self):
     """Verify that a configured username/password is used if none appears
     in the URL.
     """
     addr = "amqp://%s:%d" % (self._broker.host, self._broker.port)
     self.config(username="******",
                 password="******",
                 group="oslo_messaging_amqp")
     url = oslo_messaging.TransportURL.parse(self.conf, addr)
     driver = amqp_driver.ProtonDriver(self.conf, url)
     target = oslo_messaging.Target(topic="test-topic")
     listener = _ListenerThread(driver.listen(target), 1)
     rc = driver.send(target, {"context": True},
                      {"method": "echo"}, wait_for_reply=True)
     self.assertIsNotNone(rc)
     listener.join(timeout=30)
     self.assertFalse(listener.isAlive())
     driver.cleanup()
Exemplo n.º 13
0
 def test_authentication_bad_mechs(self):
     """Verify that the connection fails if the client's SASL mechanisms do
     not match the broker's.
     """
     self.config(sasl_mechanisms="EXTERNAL ANONYMOUS",
                 group="oslo_messaging_amqp")
     addr = "amqp://*****:*****@%s:%d" % (self._broker.host,
                                         self._broker.port)
     url = oslo_messaging.TransportURL.parse(self.conf, addr)
     driver = amqp_driver.ProtonDriver(self.conf, url)
     target = oslo_messaging.Target(topic="test-topic")
     _ListenerThread(driver.listen(target), 1)
     self.assertRaises(oslo_messaging.MessagingTimeout,
                       driver.send,
                       target, {"context": True},
                       {"method": "echo"},
                       wait_for_reply=True,
                       timeout=2.0)
     driver.cleanup()
Exemplo n.º 14
0
    def test_notification(self):
        driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)
        notifications = [(messaging.Target(topic="topic-1"), 'info'),
                         (messaging.Target(topic="topic-1"), 'error'),
                         (messaging.Target(topic="topic-2"), 'debug')]
        nl = driver.listen_for_notifications(notifications, None)

        # send one for each support version:
        msg_count = len(notifications) * 2
        listener = _ListenerThread(nl, msg_count)
        targets = [
            'topic-1.info',
            'topic-1.bad',  # will raise MessagingDeliveryFailure
            'bad-topic.debug',  # will raise MessagingDeliveryFailure
            'topic-1.error',
            'topic-2.debug'
        ]

        excepted_targets = []
        exception_count = 0
        for version in (1.0, 2.0):
            for t in targets:
                try:
                    driver.send_notification(messaging.Target(topic=t),
                                             "context", {'target': t}, version)
                except messaging.MessageDeliveryFailure:
                    exception_count += 1
                    excepted_targets.append(t)

        listener.join(timeout=30)
        self.assertFalse(listener.isAlive())
        topics = [x.message.get('target') for x in listener.get_messages()]
        self.assertEqual(len(topics), msg_count)
        self.assertEqual(topics.count('topic-1.info'), 2)
        self.assertEqual(topics.count('topic-1.error'), 2)
        self.assertEqual(topics.count('topic-2.debug'), 2)
        self.assertEqual(self._broker.dropped_count, 4)
        self.assertEqual(exception_count, 4)
        self.assertEqual(excepted_targets.count('topic-1.bad'), 2)
        self.assertEqual(excepted_targets.count('bad-topic.debug'), 2)
        driver.cleanup()
Exemplo n.º 15
0
    def test_messaging_patterns(self):
        """Verify the direct, shared, and fanout message patterns work."""
        driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)
        target1 = oslo_messaging.Target(topic="test-topic", server="server1")
        listener1 = _ListenerThread(driver.listen(target1), 4)
        target2 = oslo_messaging.Target(topic="test-topic", server="server2")
        listener2 = _ListenerThread(driver.listen(target2), 3)

        shared_target = oslo_messaging.Target(topic="test-topic")
        fanout_target = oslo_messaging.Target(topic="test-topic", fanout=True)
        # this should go to only one server:
        driver.send(shared_target, {"context": "whatever"}, {
            "method": "echo",
            "id": "either-1"
        },
                    wait_for_reply=True)
        self.assertEqual(self._broker.topic_count, 1)
        self.assertEqual(self._broker.direct_count, 1)  # reply

        # this should go to the other server:
        driver.send(shared_target, {"context": "whatever"}, {
            "method": "echo",
            "id": "either-2"
        },
                    wait_for_reply=True)
        self.assertEqual(self._broker.topic_count, 2)
        self.assertEqual(self._broker.direct_count, 2)  # reply

        # these should only go to listener1:
        driver.send(target1, {"context": "whatever"}, {
            "method": "echo",
            "id": "server1-1"
        },
                    wait_for_reply=True)

        driver.send(target1, {"context": "whatever"}, {
            "method": "echo",
            "id": "server1-2"
        },
                    wait_for_reply=True)
        self.assertEqual(self._broker.direct_count, 6)  # 2X(send+reply)

        # this should only go to listener2:
        driver.send(target2, {"context": "whatever"}, {
            "method": "echo",
            "id": "server2"
        },
                    wait_for_reply=True)
        self.assertEqual(self._broker.direct_count, 8)

        # both listeners should get a copy:
        driver.send(fanout_target, {"context": "whatever"}, {
            "method": "echo",
            "id": "fanout"
        })

        listener1.join(timeout=30)
        self.assertFalse(listener1.isAlive())
        listener2.join(timeout=30)
        self.assertFalse(listener2.isAlive())
        self.assertEqual(self._broker.fanout_count, 1)

        listener1_ids = [x.message.get('id') for x in listener1.get_messages()]
        listener2_ids = [x.message.get('id') for x in listener2.get_messages()]

        self.assertTrue('fanout' in listener1_ids
                        and 'fanout' in listener2_ids)
        self.assertTrue('server1-1' in listener1_ids
                        and 'server1-1' not in listener2_ids)
        self.assertTrue('server1-2' in listener1_ids
                        and 'server1-2' not in listener2_ids)
        self.assertTrue('server2' in listener2_ids
                        and 'server2' not in listener1_ids)
        if 'either-1' in listener1_ids:
            self.assertTrue('either-2' in listener2_ids
                            and 'either-2' not in listener1_ids
                            and 'either-1' not in listener2_ids)
        else:
            self.assertTrue('either-2' in listener1_ids
                            and 'either-2' not in listener2_ids
                            and 'either-1' in listener2_ids)
        driver.cleanup()
Exemplo n.º 16
0
 def test_driver_unconnected_cleanup(self):
     """Verify the driver can cleanly shutdown even if never connected."""
     driver = amqp_driver.ProtonDriver(self.conf, self._broker_url)
     driver.cleanup()