Fixes test_two_pools_three_listener
The Notification Listener Tracker class is not threadsafe, so when a test stop an already stopped listener this one can be restarted, due to concurrency access of the threads list and concurrency execution of the start/stop/wait method of the notification listener. This result of a lockup of the test or a listener can continue to got unepxected message. This change fixes that by never stop the tread with the tracker callback but only manually with the test. This test also rename some 'Listener' to 'Server', to not mismatch the driver listener from the notification listener. Closes-bug: #1410902 Change-Id: I4777c7dd0ba71c61850d36641e85f33f9461e9c1
This commit is contained in:
parent
408d0da9be
commit
b888ee3ebf
@ -14,6 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
import testscenarios
|
import testscenarios
|
||||||
@ -26,53 +27,55 @@ from oslo_messaging.tests import utils as test_utils
|
|||||||
load_tests = testscenarios.load_tests_apply_scenarios
|
load_tests = testscenarios.load_tests_apply_scenarios
|
||||||
|
|
||||||
|
|
||||||
class RestartableListenerThread(object):
|
class RestartableServerThread(object):
|
||||||
def __init__(self, listener):
|
def __init__(self, server):
|
||||||
self.listener = listener
|
self.server = server
|
||||||
self.thread = None
|
self.thread = None
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
if self.thread is None:
|
if self.thread is None:
|
||||||
self.thread = threading.Thread(target=self.listener.start)
|
self.thread = threading.Thread(target=self.server.start)
|
||||||
self.thread.daemon = True
|
self.thread.daemon = True
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
if self.thread is not None:
|
if self.thread is not None:
|
||||||
self.listener.stop()
|
# Check start() does nothing with a running listener
|
||||||
self.listener.wait()
|
self.server.start()
|
||||||
self.thread.join()
|
self.server.stop()
|
||||||
|
self.server.wait()
|
||||||
|
self.thread.join(timeout=15)
|
||||||
|
ret = self.thread.isAlive()
|
||||||
self.thread = None
|
self.thread = None
|
||||||
|
return ret
|
||||||
def wait_end(self):
|
return True
|
||||||
self.thread.join(timeout=15)
|
|
||||||
return self.thread.isAlive()
|
|
||||||
|
|
||||||
|
|
||||||
class ListenerSetupMixin(object):
|
class ListenerSetupMixin(object):
|
||||||
|
|
||||||
class ListenerTracker(object):
|
class ThreadTracker(object):
|
||||||
def __init__(self, expect_messages):
|
def __init__(self):
|
||||||
self._expect_messages = expect_messages
|
|
||||||
self._received_msgs = 0
|
self._received_msgs = 0
|
||||||
self.listeners = []
|
self.threads = []
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
|
||||||
def info(self, ctxt, publisher_id, event_type, payload, metadata):
|
def info(self, ctxt, publisher_id, event_type, payload, metadata):
|
||||||
self._received_msgs += 1
|
# NOTE(sileht): this run into an other thread
|
||||||
if self._expect_messages == self._received_msgs:
|
with self.lock:
|
||||||
self.stop()
|
self._received_msgs += 1
|
||||||
|
|
||||||
def wait_for(self, expect_messages):
|
def wait_for_messages(self, expect_messages):
|
||||||
while expect_messages != self._received_msgs:
|
while self._received_msgs < expect_messages:
|
||||||
yield
|
time.sleep(0.01)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
for listener in self.listeners:
|
for thread in self.threads:
|
||||||
# Check start() does nothing with a running listener
|
thread.stop()
|
||||||
listener.start()
|
self.threads = []
|
||||||
listener.stop()
|
|
||||||
listener.wait()
|
def start(self, thread):
|
||||||
self.listeners = []
|
self.threads.append(thread)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.trackers = {}
|
self.trackers = {}
|
||||||
@ -83,7 +86,7 @@ class ListenerSetupMixin(object):
|
|||||||
self.trackers[pool].stop()
|
self.trackers[pool].stop()
|
||||||
self.trackers = {}
|
self.trackers = {}
|
||||||
|
|
||||||
def _setup_listener(self, transport, endpoints, expect_messages,
|
def _setup_listener(self, transport, endpoints,
|
||||||
targets=None, pool=None):
|
targets=None, pool=None):
|
||||||
|
|
||||||
if pool is None:
|
if pool is None:
|
||||||
@ -95,16 +98,18 @@ class ListenerSetupMixin(object):
|
|||||||
targets = [oslo_messaging.Target(topic='testtopic')]
|
targets = [oslo_messaging.Target(topic='testtopic')]
|
||||||
|
|
||||||
tracker = self.trackers.setdefault(
|
tracker = self.trackers.setdefault(
|
||||||
tracker_name, self.ListenerTracker(expect_messages))
|
tracker_name, self.ThreadTracker())
|
||||||
listener = oslo_messaging.get_notification_listener(
|
listener = oslo_messaging.get_notification_listener(
|
||||||
transport, targets=targets, endpoints=[tracker] + endpoints,
|
transport, targets=targets, endpoints=[tracker] + endpoints,
|
||||||
allow_requeue=True, pool=pool)
|
allow_requeue=True, pool=pool)
|
||||||
tracker.listeners.append(listener)
|
|
||||||
|
|
||||||
thread = RestartableListenerThread(listener)
|
thread = RestartableServerThread(listener)
|
||||||
thread.start()
|
tracker.start(thread)
|
||||||
return thread
|
return thread
|
||||||
|
|
||||||
|
def wait_for_messages(self, expect_messages, tracker_name='__default__'):
|
||||||
|
self.trackers[tracker_name].wait_for_messages(expect_messages)
|
||||||
|
|
||||||
def _setup_notifier(self, transport, topic='testtopic',
|
def _setup_notifier(self, transport, topic='testtopic',
|
||||||
publisher_id='testpublisher'):
|
publisher_id='testpublisher'):
|
||||||
return oslo_messaging.Notifier(transport, topic=topic,
|
return oslo_messaging.Notifier(transport, topic=topic,
|
||||||
@ -168,12 +173,13 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
|
|
||||||
endpoint = mock.Mock()
|
endpoint = mock.Mock()
|
||||||
endpoint.info.return_value = None
|
endpoint.info.return_value = None
|
||||||
listener_thread = self._setup_listener(transport, [endpoint], 1)
|
listener_thread = self._setup_listener(transport, [endpoint])
|
||||||
|
|
||||||
notifier = self._setup_notifier(transport)
|
notifier = self._setup_notifier(transport)
|
||||||
notifier.info({}, 'an_event.start', 'test message')
|
notifier.info({}, 'an_event.start', 'test message')
|
||||||
|
|
||||||
self.assertFalse(listener_thread.wait_end())
|
self.wait_for_messages(1)
|
||||||
|
self.assertFalse(listener_thread.stop())
|
||||||
|
|
||||||
endpoint.info.assert_called_once_with(
|
endpoint.info.assert_called_once_with(
|
||||||
{}, 'testpublisher', 'an_event.start', 'test message',
|
{}, 'testpublisher', 'an_event.start', 'test message',
|
||||||
@ -186,14 +192,15 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
endpoint.info.return_value = None
|
endpoint.info.return_value = None
|
||||||
targets = [oslo_messaging.Target(topic="topic1"),
|
targets = [oslo_messaging.Target(topic="topic1"),
|
||||||
oslo_messaging.Target(topic="topic2")]
|
oslo_messaging.Target(topic="topic2")]
|
||||||
listener_thread = self._setup_listener(transport, [endpoint], 2,
|
listener_thread = self._setup_listener(transport, [endpoint],
|
||||||
targets=targets)
|
targets=targets)
|
||||||
notifier = self._setup_notifier(transport, topic='topic1')
|
notifier = self._setup_notifier(transport, topic='topic1')
|
||||||
notifier.info({'ctxt': '1'}, 'an_event.start1', 'test')
|
notifier.info({'ctxt': '1'}, 'an_event.start1', 'test')
|
||||||
notifier = self._setup_notifier(transport, topic='topic2')
|
notifier = self._setup_notifier(transport, topic='topic2')
|
||||||
notifier.info({'ctxt': '2'}, 'an_event.start2', 'test')
|
notifier.info({'ctxt': '2'}, 'an_event.start2', 'test')
|
||||||
|
|
||||||
self.assertFalse(listener_thread.wait_end())
|
self.wait_for_messages(2)
|
||||||
|
self.assertFalse(listener_thread.stop())
|
||||||
|
|
||||||
endpoint.info.assert_has_calls([
|
endpoint.info.assert_has_calls([
|
||||||
mock.call({'ctxt': '1'}, 'testpublisher',
|
mock.call({'ctxt': '1'}, 'testpublisher',
|
||||||
@ -213,7 +220,7 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
exchange="exchange1"),
|
exchange="exchange1"),
|
||||||
oslo_messaging.Target(topic="topic",
|
oslo_messaging.Target(topic="topic",
|
||||||
exchange="exchange2")]
|
exchange="exchange2")]
|
||||||
listener_thread = self._setup_listener(transport, [endpoint], 2,
|
listener_thread = self._setup_listener(transport, [endpoint],
|
||||||
targets=targets)
|
targets=targets)
|
||||||
|
|
||||||
notifier = self._setup_notifier(transport, topic="topic")
|
notifier = self._setup_notifier(transport, topic="topic")
|
||||||
@ -236,7 +243,8 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
notifier.info({'ctxt': '2'},
|
notifier.info({'ctxt': '2'},
|
||||||
'an_event.start', 'test message exchange2')
|
'an_event.start', 'test message exchange2')
|
||||||
|
|
||||||
self.assertFalse(listener_thread.wait_end())
|
self.wait_for_messages(2)
|
||||||
|
self.assertFalse(listener_thread.stop())
|
||||||
|
|
||||||
endpoint.info.assert_has_calls([
|
endpoint.info.assert_has_calls([
|
||||||
mock.call({'ctxt': '1'}, 'testpublisher', 'an_event.start',
|
mock.call({'ctxt': '1'}, 'testpublisher', 'an_event.start',
|
||||||
@ -255,11 +263,12 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
endpoint2 = mock.Mock()
|
endpoint2 = mock.Mock()
|
||||||
endpoint2.info.return_value = oslo_messaging.NotificationResult.HANDLED
|
endpoint2.info.return_value = oslo_messaging.NotificationResult.HANDLED
|
||||||
listener_thread = self._setup_listener(transport,
|
listener_thread = self._setup_listener(transport,
|
||||||
[endpoint1, endpoint2], 1)
|
[endpoint1, endpoint2])
|
||||||
notifier = self._setup_notifier(transport)
|
notifier = self._setup_notifier(transport)
|
||||||
notifier.info({}, 'an_event.start', 'test')
|
notifier.info({}, 'an_event.start', 'test')
|
||||||
|
|
||||||
self.assertFalse(listener_thread.wait_end())
|
self.wait_for_messages(1)
|
||||||
|
self.assertFalse(listener_thread.stop())
|
||||||
|
|
||||||
endpoint1.info.assert_called_once_with(
|
endpoint1.info.assert_called_once_with(
|
||||||
{}, 'testpublisher', 'an_event.start', 'test', {
|
{}, 'testpublisher', 'an_event.start', 'test', {
|
||||||
@ -282,12 +291,12 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
return oslo_messaging.NotificationResult.HANDLED
|
return oslo_messaging.NotificationResult.HANDLED
|
||||||
|
|
||||||
endpoint.info.side_effect = side_effect_requeue
|
endpoint.info.side_effect = side_effect_requeue
|
||||||
listener_thread = self._setup_listener(transport,
|
listener_thread = self._setup_listener(transport, [endpoint])
|
||||||
[endpoint], 2)
|
|
||||||
notifier = self._setup_notifier(transport)
|
notifier = self._setup_notifier(transport)
|
||||||
notifier.info({}, 'an_event.start', 'test')
|
notifier.info({}, 'an_event.start', 'test')
|
||||||
|
|
||||||
self.assertFalse(listener_thread.wait_end())
|
self.wait_for_messages(2)
|
||||||
|
self.assertFalse(listener_thread.stop())
|
||||||
|
|
||||||
endpoint.info.assert_has_calls([
|
endpoint.info.assert_has_calls([
|
||||||
mock.call({}, 'testpublisher', 'an_event.start', 'test',
|
mock.call({}, 'testpublisher', 'an_event.start', 'test',
|
||||||
@ -304,17 +313,19 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
endpoint2.info.return_value = None
|
endpoint2.info.return_value = None
|
||||||
|
|
||||||
targets = [oslo_messaging.Target(topic="topic")]
|
targets = [oslo_messaging.Target(topic="topic")]
|
||||||
listener1_thread = self._setup_listener(transport, [endpoint1], 2,
|
listener1_thread = self._setup_listener(transport, [endpoint1],
|
||||||
targets=targets, pool="pool1")
|
targets=targets, pool="pool1")
|
||||||
listener2_thread = self._setup_listener(transport, [endpoint2], 2,
|
listener2_thread = self._setup_listener(transport, [endpoint2],
|
||||||
targets=targets, pool="pool2")
|
targets=targets, pool="pool2")
|
||||||
|
|
||||||
notifier = self._setup_notifier(transport, topic="topic")
|
notifier = self._setup_notifier(transport, topic="topic")
|
||||||
notifier.info({'ctxt': '0'}, 'an_event.start', 'test message0')
|
notifier.info({'ctxt': '0'}, 'an_event.start', 'test message0')
|
||||||
notifier.info({'ctxt': '1'}, 'an_event.start', 'test message1')
|
notifier.info({'ctxt': '1'}, 'an_event.start', 'test message1')
|
||||||
|
|
||||||
self.assertFalse(listener2_thread.wait_end())
|
self.wait_for_messages(2, "pool1")
|
||||||
self.assertFalse(listener1_thread.wait_end())
|
self.wait_for_messages(2, "pool2")
|
||||||
|
self.assertFalse(listener2_thread.stop())
|
||||||
|
self.assertFalse(listener1_thread.stop())
|
||||||
|
|
||||||
def mocked_endpoint_call(i):
|
def mocked_endpoint_call(i):
|
||||||
return mock.call({'ctxt': '%d' % i}, 'testpublisher',
|
return mock.call({'ctxt': '%d' % i}, 'testpublisher',
|
||||||
@ -337,11 +348,11 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
endpoint3.info.return_value = None
|
endpoint3.info.return_value = None
|
||||||
|
|
||||||
targets = [oslo_messaging.Target(topic="topic")]
|
targets = [oslo_messaging.Target(topic="topic")]
|
||||||
listener1_thread = self._setup_listener(transport, [endpoint1], 100,
|
listener1_thread = self._setup_listener(transport, [endpoint1],
|
||||||
targets=targets, pool="pool1")
|
targets=targets, pool="pool1")
|
||||||
listener2_thread = self._setup_listener(transport, [endpoint2], 100,
|
listener2_thread = self._setup_listener(transport, [endpoint2],
|
||||||
targets=targets, pool="pool2")
|
targets=targets, pool="pool2")
|
||||||
listener3_thread = self._setup_listener(transport, [endpoint3], 100,
|
listener3_thread = self._setup_listener(transport, [endpoint3],
|
||||||
targets=targets, pool="pool2")
|
targets=targets, pool="pool2")
|
||||||
|
|
||||||
def mocked_endpoint_call(i):
|
def mocked_endpoint_call(i):
|
||||||
@ -356,7 +367,7 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
'test message%d' % i)
|
'test message%d' % i)
|
||||||
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
||||||
|
|
||||||
self.trackers['pool2'].wait_for(25)
|
self.wait_for_messages(25, 'pool2')
|
||||||
listener2_thread.stop()
|
listener2_thread.stop()
|
||||||
|
|
||||||
for i in range(0, 25):
|
for i in range(0, 25):
|
||||||
@ -364,7 +375,7 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
'test message%d' % i)
|
'test message%d' % i)
|
||||||
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
||||||
|
|
||||||
self.trackers['pool2'].wait_for(50)
|
self.wait_for_messages(50, 'pool2')
|
||||||
listener2_thread.start()
|
listener2_thread.start()
|
||||||
listener3_thread.stop()
|
listener3_thread.stop()
|
||||||
|
|
||||||
@ -373,7 +384,7 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
'test message%d' % i)
|
'test message%d' % i)
|
||||||
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
||||||
|
|
||||||
self.trackers['pool2'].wait_for(75)
|
self.wait_for_messages(75, 'pool2')
|
||||||
listener3_thread.start()
|
listener3_thread.start()
|
||||||
|
|
||||||
for i in range(0, 25):
|
for i in range(0, 25):
|
||||||
@ -381,9 +392,12 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
'test message%d' % i)
|
'test message%d' % i)
|
||||||
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
||||||
|
|
||||||
self.assertFalse(listener3_thread.wait_end())
|
self.wait_for_messages(100, 'pool1')
|
||||||
self.assertFalse(listener2_thread.wait_end())
|
self.wait_for_messages(100, 'pool2')
|
||||||
self.assertFalse(listener1_thread.wait_end())
|
|
||||||
|
self.assertFalse(listener3_thread.stop())
|
||||||
|
self.assertFalse(listener2_thread.stop())
|
||||||
|
self.assertFalse(listener1_thread.stop())
|
||||||
|
|
||||||
self.assertEqual(100, endpoint1.info.call_count)
|
self.assertEqual(100, endpoint1.info.call_count)
|
||||||
endpoint1.info.assert_has_calls(mocked_endpoint1_calls)
|
endpoint1.info.assert_has_calls(mocked_endpoint1_calls)
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
import testscenarios
|
import testscenarios
|
||||||
@ -26,55 +27,55 @@ from oslo_messaging.tests import utils as test_utils
|
|||||||
load_tests = testscenarios.load_tests_apply_scenarios
|
load_tests = testscenarios.load_tests_apply_scenarios
|
||||||
|
|
||||||
|
|
||||||
class RestartableListenerThread(object):
|
class RestartableServerThread(object):
|
||||||
def __init__(self, listener):
|
def __init__(self, server):
|
||||||
self.listener = listener
|
self.server = server
|
||||||
self.thread = None
|
self.thread = None
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
if self.thread is None:
|
if self.thread is None:
|
||||||
self.thread = threading.Thread(target=self.listener.start)
|
self.thread = threading.Thread(target=self.server.start)
|
||||||
self.thread.daemon = True
|
self.thread.daemon = True
|
||||||
self.thread.start()
|
self.thread.start()
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
if self.thread is not None:
|
if self.thread is not None:
|
||||||
self.listener.stop()
|
# Check start() does nothing with a running listener
|
||||||
self.listener.wait()
|
self.server.start()
|
||||||
self.thread.join()
|
self.server.stop()
|
||||||
|
self.server.wait()
|
||||||
|
self.thread.join(timeout=15)
|
||||||
|
ret = self.thread.isAlive()
|
||||||
self.thread = None
|
self.thread = None
|
||||||
|
return ret
|
||||||
def wait_end(self):
|
return True
|
||||||
self.thread.join(timeout=15)
|
|
||||||
return self.thread.isAlive()
|
|
||||||
|
|
||||||
|
|
||||||
class ListenerSetupMixin(object):
|
class ListenerSetupMixin(object):
|
||||||
|
|
||||||
class ListenerTracker(object):
|
class ThreadTracker(object):
|
||||||
def __init__(self, expect_messages):
|
def __init__(self):
|
||||||
self._expect_messages = expect_messages
|
|
||||||
self._received_msgs = 0
|
self._received_msgs = 0
|
||||||
self.listeners = []
|
self.threads = []
|
||||||
|
self.lock = threading.Lock()
|
||||||
|
|
||||||
def info(self, ctxt, publisher_id, event_type, payload, metadata):
|
def info(self, ctxt, publisher_id, event_type, payload, metadata):
|
||||||
self._received_msgs += 1
|
# NOTE(sileht): this run into an other thread
|
||||||
if self._expect_messages == self._received_msgs:
|
with self.lock:
|
||||||
self.stop()
|
self._received_msgs += 1
|
||||||
|
|
||||||
def wait_for(self, expect_messages):
|
def wait_for_messages(self, expect_messages):
|
||||||
print('expecting %d messages have %d' %
|
while self._received_msgs < expect_messages:
|
||||||
(expect_messages, self._received_msgs))
|
time.sleep(0.01)
|
||||||
while expect_messages != self._received_msgs:
|
|
||||||
yield
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
for listener in self.listeners:
|
for thread in self.threads:
|
||||||
# Check start() does nothing with a running listener
|
thread.stop()
|
||||||
listener.start()
|
self.threads = []
|
||||||
listener.stop()
|
|
||||||
listener.wait()
|
def start(self, thread):
|
||||||
self.listeners = []
|
self.threads.append(thread)
|
||||||
|
thread.start()
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.trackers = {}
|
self.trackers = {}
|
||||||
@ -85,7 +86,7 @@ class ListenerSetupMixin(object):
|
|||||||
self.trackers[pool].stop()
|
self.trackers[pool].stop()
|
||||||
self.trackers = {}
|
self.trackers = {}
|
||||||
|
|
||||||
def _setup_listener(self, transport, endpoints, expect_messages,
|
def _setup_listener(self, transport, endpoints,
|
||||||
targets=None, pool=None):
|
targets=None, pool=None):
|
||||||
|
|
||||||
if pool is None:
|
if pool is None:
|
||||||
@ -97,16 +98,18 @@ class ListenerSetupMixin(object):
|
|||||||
targets = [messaging.Target(topic='testtopic')]
|
targets = [messaging.Target(topic='testtopic')]
|
||||||
|
|
||||||
tracker = self.trackers.setdefault(
|
tracker = self.trackers.setdefault(
|
||||||
tracker_name, self.ListenerTracker(expect_messages))
|
tracker_name, self.ThreadTracker())
|
||||||
listener = messaging.get_notification_listener(
|
listener = messaging.get_notification_listener(
|
||||||
transport, targets=targets, endpoints=[tracker] + endpoints,
|
transport, targets=targets, endpoints=[tracker] + endpoints,
|
||||||
allow_requeue=True, pool=pool)
|
allow_requeue=True, pool=pool)
|
||||||
tracker.listeners.append(listener)
|
|
||||||
|
|
||||||
thread = RestartableListenerThread(listener)
|
thread = RestartableServerThread(listener)
|
||||||
thread.start()
|
tracker.start(thread)
|
||||||
return thread
|
return thread
|
||||||
|
|
||||||
|
def wait_for_messages(self, expect_messages, tracker_name='__default__'):
|
||||||
|
self.trackers[tracker_name].wait_for_messages(expect_messages)
|
||||||
|
|
||||||
def _setup_notifier(self, transport, topic='testtopic',
|
def _setup_notifier(self, transport, topic='testtopic',
|
||||||
publisher_id='testpublisher'):
|
publisher_id='testpublisher'):
|
||||||
return messaging.Notifier(transport, topic=topic,
|
return messaging.Notifier(transport, topic=topic,
|
||||||
@ -169,12 +172,13 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
|
|
||||||
endpoint = mock.Mock()
|
endpoint = mock.Mock()
|
||||||
endpoint.info.return_value = None
|
endpoint.info.return_value = None
|
||||||
listener_thread = self._setup_listener(transport, [endpoint], 1)
|
listener_thread = self._setup_listener(transport, [endpoint])
|
||||||
|
|
||||||
notifier = self._setup_notifier(transport)
|
notifier = self._setup_notifier(transport)
|
||||||
notifier.info({}, 'an_event.start', 'test message')
|
notifier.info({}, 'an_event.start', 'test message')
|
||||||
|
|
||||||
self.assertFalse(listener_thread.wait_end())
|
self.wait_for_messages(1)
|
||||||
|
self.assertFalse(listener_thread.stop())
|
||||||
|
|
||||||
endpoint.info.assert_called_once_with(
|
endpoint.info.assert_called_once_with(
|
||||||
{}, 'testpublisher', 'an_event.start', 'test message',
|
{}, 'testpublisher', 'an_event.start', 'test message',
|
||||||
@ -187,14 +191,15 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
endpoint.info.return_value = None
|
endpoint.info.return_value = None
|
||||||
targets = [messaging.Target(topic="topic1"),
|
targets = [messaging.Target(topic="topic1"),
|
||||||
messaging.Target(topic="topic2")]
|
messaging.Target(topic="topic2")]
|
||||||
listener_thread = self._setup_listener(transport, [endpoint], 2,
|
listener_thread = self._setup_listener(transport, [endpoint],
|
||||||
targets=targets)
|
targets=targets)
|
||||||
notifier = self._setup_notifier(transport, topic='topic1')
|
notifier = self._setup_notifier(transport, topic='topic1')
|
||||||
notifier.info({'ctxt': '1'}, 'an_event.start1', 'test')
|
notifier.info({'ctxt': '1'}, 'an_event.start1', 'test')
|
||||||
notifier = self._setup_notifier(transport, topic='topic2')
|
notifier = self._setup_notifier(transport, topic='topic2')
|
||||||
notifier.info({'ctxt': '2'}, 'an_event.start2', 'test')
|
notifier.info({'ctxt': '2'}, 'an_event.start2', 'test')
|
||||||
|
|
||||||
self.assertFalse(listener_thread.wait_end())
|
self.wait_for_messages(2)
|
||||||
|
self.assertFalse(listener_thread.stop())
|
||||||
|
|
||||||
endpoint.info.assert_has_calls([
|
endpoint.info.assert_has_calls([
|
||||||
mock.call({'ctxt': '1'}, 'testpublisher',
|
mock.call({'ctxt': '1'}, 'testpublisher',
|
||||||
@ -214,7 +219,7 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
exchange="exchange1"),
|
exchange="exchange1"),
|
||||||
messaging.Target(topic="topic",
|
messaging.Target(topic="topic",
|
||||||
exchange="exchange2")]
|
exchange="exchange2")]
|
||||||
listener_thread = self._setup_listener(transport, [endpoint], 2,
|
listener_thread = self._setup_listener(transport, [endpoint],
|
||||||
targets=targets)
|
targets=targets)
|
||||||
|
|
||||||
notifier = self._setup_notifier(transport, topic="topic")
|
notifier = self._setup_notifier(transport, topic="topic")
|
||||||
@ -237,7 +242,8 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
notifier.info({'ctxt': '2'},
|
notifier.info({'ctxt': '2'},
|
||||||
'an_event.start', 'test message exchange2')
|
'an_event.start', 'test message exchange2')
|
||||||
|
|
||||||
self.assertFalse(listener_thread.wait_end())
|
self.wait_for_messages(2)
|
||||||
|
self.assertFalse(listener_thread.stop())
|
||||||
|
|
||||||
endpoint.info.assert_has_calls([
|
endpoint.info.assert_has_calls([
|
||||||
mock.call({'ctxt': '1'}, 'testpublisher', 'an_event.start',
|
mock.call({'ctxt': '1'}, 'testpublisher', 'an_event.start',
|
||||||
@ -256,11 +262,12 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
endpoint2 = mock.Mock()
|
endpoint2 = mock.Mock()
|
||||||
endpoint2.info.return_value = messaging.NotificationResult.HANDLED
|
endpoint2.info.return_value = messaging.NotificationResult.HANDLED
|
||||||
listener_thread = self._setup_listener(transport,
|
listener_thread = self._setup_listener(transport,
|
||||||
[endpoint1, endpoint2], 1)
|
[endpoint1, endpoint2])
|
||||||
notifier = self._setup_notifier(transport)
|
notifier = self._setup_notifier(transport)
|
||||||
notifier.info({}, 'an_event.start', 'test')
|
notifier.info({}, 'an_event.start', 'test')
|
||||||
|
|
||||||
self.assertFalse(listener_thread.wait_end())
|
self.wait_for_messages(1)
|
||||||
|
self.assertFalse(listener_thread.stop())
|
||||||
|
|
||||||
endpoint1.info.assert_called_once_with(
|
endpoint1.info.assert_called_once_with(
|
||||||
{}, 'testpublisher', 'an_event.start', 'test', {
|
{}, 'testpublisher', 'an_event.start', 'test', {
|
||||||
@ -283,12 +290,12 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
return messaging.NotificationResult.HANDLED
|
return messaging.NotificationResult.HANDLED
|
||||||
|
|
||||||
endpoint.info.side_effect = side_effect_requeue
|
endpoint.info.side_effect = side_effect_requeue
|
||||||
listener_thread = self._setup_listener(transport,
|
listener_thread = self._setup_listener(transport, [endpoint])
|
||||||
[endpoint], 2)
|
|
||||||
notifier = self._setup_notifier(transport)
|
notifier = self._setup_notifier(transport)
|
||||||
notifier.info({}, 'an_event.start', 'test')
|
notifier.info({}, 'an_event.start', 'test')
|
||||||
|
|
||||||
self.assertFalse(listener_thread.wait_end())
|
self.wait_for_messages(2)
|
||||||
|
self.assertFalse(listener_thread.stop())
|
||||||
|
|
||||||
endpoint.info.assert_has_calls([
|
endpoint.info.assert_has_calls([
|
||||||
mock.call({}, 'testpublisher', 'an_event.start', 'test',
|
mock.call({}, 'testpublisher', 'an_event.start', 'test',
|
||||||
@ -305,17 +312,19 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
endpoint2.info.return_value = None
|
endpoint2.info.return_value = None
|
||||||
|
|
||||||
targets = [messaging.Target(topic="topic")]
|
targets = [messaging.Target(topic="topic")]
|
||||||
listener1_thread = self._setup_listener(transport, [endpoint1], 2,
|
listener1_thread = self._setup_listener(transport, [endpoint1],
|
||||||
targets=targets, pool="pool1")
|
targets=targets, pool="pool1")
|
||||||
listener2_thread = self._setup_listener(transport, [endpoint2], 2,
|
listener2_thread = self._setup_listener(transport, [endpoint2],
|
||||||
targets=targets, pool="pool2")
|
targets=targets, pool="pool2")
|
||||||
|
|
||||||
notifier = self._setup_notifier(transport, topic="topic")
|
notifier = self._setup_notifier(transport, topic="topic")
|
||||||
notifier.info({'ctxt': '0'}, 'an_event.start', 'test message0')
|
notifier.info({'ctxt': '0'}, 'an_event.start', 'test message0')
|
||||||
notifier.info({'ctxt': '1'}, 'an_event.start', 'test message1')
|
notifier.info({'ctxt': '1'}, 'an_event.start', 'test message1')
|
||||||
|
|
||||||
self.assertFalse(listener2_thread.wait_end())
|
self.wait_for_messages(2, "pool1")
|
||||||
self.assertFalse(listener1_thread.wait_end())
|
self.wait_for_messages(2, "pool2")
|
||||||
|
self.assertFalse(listener2_thread.stop())
|
||||||
|
self.assertFalse(listener1_thread.stop())
|
||||||
|
|
||||||
def mocked_endpoint_call(i):
|
def mocked_endpoint_call(i):
|
||||||
return mock.call({'ctxt': '%d' % i}, 'testpublisher',
|
return mock.call({'ctxt': '%d' % i}, 'testpublisher',
|
||||||
@ -338,11 +347,11 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
endpoint3.info.return_value = None
|
endpoint3.info.return_value = None
|
||||||
|
|
||||||
targets = [messaging.Target(topic="topic")]
|
targets = [messaging.Target(topic="topic")]
|
||||||
listener1_thread = self._setup_listener(transport, [endpoint1], 100,
|
listener1_thread = self._setup_listener(transport, [endpoint1],
|
||||||
targets=targets, pool="pool1")
|
targets=targets, pool="pool1")
|
||||||
listener2_thread = self._setup_listener(transport, [endpoint2], 100,
|
listener2_thread = self._setup_listener(transport, [endpoint2],
|
||||||
targets=targets, pool="pool2")
|
targets=targets, pool="pool2")
|
||||||
listener3_thread = self._setup_listener(transport, [endpoint3], 100,
|
listener3_thread = self._setup_listener(transport, [endpoint3],
|
||||||
targets=targets, pool="pool2")
|
targets=targets, pool="pool2")
|
||||||
|
|
||||||
def mocked_endpoint_call(i):
|
def mocked_endpoint_call(i):
|
||||||
@ -357,7 +366,7 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
'test message%d' % i)
|
'test message%d' % i)
|
||||||
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
||||||
|
|
||||||
self.trackers['pool2'].wait_for(25)
|
self.wait_for_messages(25, 'pool2')
|
||||||
listener2_thread.stop()
|
listener2_thread.stop()
|
||||||
|
|
||||||
for i in range(0, 25):
|
for i in range(0, 25):
|
||||||
@ -365,7 +374,7 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
'test message%d' % i)
|
'test message%d' % i)
|
||||||
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
||||||
|
|
||||||
self.trackers['pool2'].wait_for(50)
|
self.wait_for_messages(50, 'pool2')
|
||||||
listener2_thread.start()
|
listener2_thread.start()
|
||||||
listener3_thread.stop()
|
listener3_thread.stop()
|
||||||
|
|
||||||
@ -374,7 +383,7 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
'test message%d' % i)
|
'test message%d' % i)
|
||||||
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
||||||
|
|
||||||
self.trackers['pool2'].wait_for(75)
|
self.wait_for_messages(75, 'pool2')
|
||||||
listener3_thread.start()
|
listener3_thread.start()
|
||||||
|
|
||||||
for i in range(0, 25):
|
for i in range(0, 25):
|
||||||
@ -382,9 +391,12 @@ class TestNotifyListener(test_utils.BaseTestCase, ListenerSetupMixin):
|
|||||||
'test message%d' % i)
|
'test message%d' % i)
|
||||||
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
mocked_endpoint1_calls.append(mocked_endpoint_call(i))
|
||||||
|
|
||||||
self.assertFalse(listener3_thread.wait_end())
|
self.wait_for_messages(100, 'pool1')
|
||||||
self.assertFalse(listener2_thread.wait_end())
|
self.wait_for_messages(100, 'pool2')
|
||||||
self.assertFalse(listener1_thread.wait_end())
|
|
||||||
|
self.assertFalse(listener3_thread.stop())
|
||||||
|
self.assertFalse(listener2_thread.stop())
|
||||||
|
self.assertFalse(listener1_thread.stop())
|
||||||
|
|
||||||
self.assertEqual(100, endpoint1.info.call_count)
|
self.assertEqual(100, endpoint1.info.call_count)
|
||||||
endpoint1.info.assert_has_calls(mocked_endpoint1_calls)
|
endpoint1.info.assert_has_calls(mocked_endpoint1_calls)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user