Fix race conditions in networking test suite

This commit is contained in:
Kristóf Tóth 2019-10-10 15:05:04 +02:00
parent 628485cff1
commit 88bc42c7f2

View File

@ -39,9 +39,12 @@ def zmq_connector(_listener_and_connector):
def run_ioloop_once(): def run_ioloop_once():
# hack: we have to wait for the messages to get through # Hack: we have to wait for the messages to get through
# the network stack of the OS while the IOLoop is waiting # the network stack of the OS while the IOLoop is waiting
# for them via select/epoll/kqueue # for them via select/epoll/kqueue.
# This is an inherent race condition, but solving this
# problem properly would make the test code difficult
# to understand, so we use this half measure.
IOLoop.current().call_later(0.1, IOLoop.current().stop) IOLoop.current().call_later(0.1, IOLoop.current().stop)
IOLoop.current().start() IOLoop.current().start()
@ -67,7 +70,7 @@ def test_messages():
def wait_until_subscriber_connects(listener, connector): def wait_until_subscriber_connects(listener, connector):
# Warning: you are better off without comprehending how this works # Warning: you are better off without comprehending how this works
# Reference: ZMQ PUB-SUB slow joiner problem # Reference: ZMQ PUB-SUB slow joiner problem
connector.subscribe('-', '_')
# Wait until something can go through the connection # Wait until something can go through the connection
dummy = {'key': '-'} dummy = {'key': '-'}
while True: while True:
@ -82,6 +85,7 @@ def wait_until_subscriber_connects(listener, connector):
with suppress(IOError): with suppress(IOError):
if connector.recv_message(block=False) == sentinel: if connector.recv_message(block=False) == sentinel:
break break
connector.unsubscribe('-', '_')
def test_server_downlink(zmq_listener, zmq_connector, test_messages): def test_server_downlink(zmq_listener, zmq_connector, test_messages):
@ -158,8 +162,10 @@ def test_connector_preserves_intent(zmq_listener, zmq_connector):
def test_server_uplink(zmq_listener, zmq_connector, test_messages): def test_server_uplink(zmq_listener, zmq_connector, test_messages):
messages = []
zmq_connector.subscribe('') zmq_connector.subscribe('')
wait_until_subscriber_connects(zmq_listener, zmq_connector)
messages = []
zmq_connector.register_callback(messages.append) zmq_connector.register_callback(messages.append)
for message in test_messages: for message in test_messages:
@ -175,8 +181,10 @@ def test_connector_downlink_subscribe(zmq_listener, zmq_connector):
key2_messages = [{'key': '2', 'data': i} for i in range(randint(128, 256))] key2_messages = [{'key': '2', 'data': i} for i in range(randint(128, 256))]
all_messages = key1_messages + key2_messages all_messages = key1_messages + key2_messages
messages = []
zmq_connector.subscribe('1') zmq_connector.subscribe('1')
wait_until_subscriber_connects(zmq_listener, zmq_connector)
messages = []
zmq_connector.register_callback(messages.append) zmq_connector.register_callback(messages.append)
for message in all_messages: for message in all_messages:
@ -197,6 +205,7 @@ def test_listener_sync_recv(zmq_listener, zmq_connector, test_messages):
def test_connector_sync_recv(zmq_listener, zmq_connector, test_messages): def test_connector_sync_recv(zmq_listener, zmq_connector, test_messages):
zmq_connector.subscribe('') zmq_connector.subscribe('')
wait_until_subscriber_connects(zmq_listener, zmq_connector) wait_until_subscriber_connects(zmq_listener, zmq_connector)
for message in test_messages: for message in test_messages:
zmq_listener.send_message(message) zmq_listener.send_message(message)
assert zmq_connector.recv_message() == message assert zmq_connector.recv_message() == message