mirror of
https://github.com/avatao-content/baseimage-tutorial-framework
synced 2024-11-22 13:31:32 +00:00
Implement robust unit test cases for message queue timing
This commit is contained in:
parent
641709c04e
commit
628485cff1
@ -6,6 +6,7 @@ from threading import Thread
|
|||||||
class MessageQueueHandler:
|
class MessageQueueHandler:
|
||||||
keys = ['message.queue']
|
keys = ['message.queue']
|
||||||
type_id = 'ControlEventHandler'
|
type_id = 'ControlEventHandler'
|
||||||
|
avg_word_len = 5
|
||||||
|
|
||||||
def __init__(self, wpm):
|
def __init__(self, wpm):
|
||||||
self.connector = None
|
self.connector = None
|
||||||
@ -15,11 +16,17 @@ class MessageQueueHandler:
|
|||||||
|
|
||||||
def _dispatch_messages(self):
|
def _dispatch_messages(self):
|
||||||
for message in iter(self._queue.get, None):
|
for message in iter(self._queue.get, None):
|
||||||
wpm = message['wpm'] if 'wpm' in message else self.wpm
|
|
||||||
cps = 5 * wpm / 60
|
|
||||||
message['typing'] = not self._queue.empty()
|
message['typing'] = not self._queue.empty()
|
||||||
self.connector.send_message(message)
|
self.connector.send_message(message)
|
||||||
sleep(len(message['message']) / cps)
|
self._sleep(self._get_sleep_time(message))
|
||||||
|
|
||||||
|
def _get_sleep_time(self, message):
|
||||||
|
words_per_min = message['wpm'] if 'wpm' in message else self.wpm
|
||||||
|
chars_per_min = self.avg_word_len * words_per_min / 60
|
||||||
|
return len(message['message']) / chars_per_min
|
||||||
|
|
||||||
|
def _sleep(self, seconds): # pylint: disable=no-self-use
|
||||||
|
sleep(seconds)
|
||||||
|
|
||||||
def handle_event(self, message, _):
|
def handle_event(self, message, _):
|
||||||
for unpacked in self._generate_messages_from_queue(message):
|
for unpacked in self._generate_messages_from_queue(message):
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
# pylint: disable=redefined-outer-name
|
# pylint: disable=redefined-outer-name
|
||||||
from math import inf
|
from time import time
|
||||||
from time import sleep
|
|
||||||
from os import urandom
|
from os import urandom
|
||||||
from random import randint
|
from random import randint
|
||||||
|
from queue import Queue
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -12,56 +12,97 @@ from .message_queue_handler import MessageQueueHandler
|
|||||||
class MockConnector:
|
class MockConnector:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.callback = None
|
self.callback = None
|
||||||
self.messages = []
|
self.messages = Queue()
|
||||||
|
self.send_times = Queue()
|
||||||
|
|
||||||
def raise_event(self, message):
|
def raise_event(self, message):
|
||||||
self.callback(message, self)
|
self.callback(message, self)
|
||||||
sleep(0.01)
|
|
||||||
|
|
||||||
def send_message(self, message):
|
def send_message(self, message):
|
||||||
self.messages.append(message)
|
self.messages.put(message)
|
||||||
|
self.send_times.put(time())
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def handler():
|
def handler():
|
||||||
connector = MockConnector()
|
class NoSleepMessageQueueHandler(MessageQueueHandler):
|
||||||
handler = MessageQueueHandler(inf)
|
sleep_start_times = Queue()
|
||||||
handler.connector = connector
|
sleep_seconds = Queue()
|
||||||
connector.callback = handler.handle_event
|
sleep_end_times = Queue()
|
||||||
|
|
||||||
|
def _sleep(self, seconds):
|
||||||
|
self.sleep_start_times.put(time())
|
||||||
|
self.sleep_seconds.put(seconds)
|
||||||
|
super()._sleep(seconds)
|
||||||
|
self.sleep_end_times.put(time())
|
||||||
|
|
||||||
|
handler = NoSleepMessageQueueHandler(100000)
|
||||||
|
handler.connector = MockConnector()
|
||||||
|
handler.connector.callback = handler.handle_event
|
||||||
|
|
||||||
handler.start()
|
handler.start()
|
||||||
yield handler
|
yield handler
|
||||||
handler.cleanup()
|
handler.cleanup()
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
def get_message_queue(*, size=None):
|
||||||
def queue():
|
size = randint(5, 10) if not size else size
|
||||||
yield {
|
return {
|
||||||
'key': 'message.queue',
|
'key': 'message.queue',
|
||||||
'messages': [
|
'messages': [
|
||||||
{'originator': urandom(4).hex(), 'message': urandom(16).hex()}
|
{'originator': urandom(4).hex(), 'message': urandom(randint(10, 20)).hex()}
|
||||||
for _ in range(randint(5, 10))
|
for _ in range(size)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_message_order(handler, queue):
|
def test_order(handler):
|
||||||
|
queue = get_message_queue()
|
||||||
handler.connector.raise_event(queue)
|
handler.connector.raise_event(queue)
|
||||||
old_list = queue['messages']
|
expected_messages = queue['messages']
|
||||||
new_list = handler.connector.messages
|
|
||||||
length = len(old_list)
|
actual_messages = []
|
||||||
assert len(new_list) == length
|
for _ in expected_messages:
|
||||||
for i in range(length):
|
actual_messages.append(handler.connector.messages.get())
|
||||||
unpacked = new_list[i]
|
|
||||||
assert unpacked['key'] == 'message.send'
|
assert len(actual_messages) == len(expected_messages)
|
||||||
assert unpacked['originator'] == old_list[i]['originator']
|
for i in range(len(expected_messages)): # pylint: disable=consider-using-enumerate
|
||||||
assert unpacked['typing'] == (i < length-1)
|
message = actual_messages[i]
|
||||||
|
assert message['key'] == 'message.send'
|
||||||
|
assert message['originator'] == expected_messages[i]['originator']
|
||||||
|
assert message['typing'] == (i < len(expected_messages)-1)
|
||||||
|
|
||||||
|
|
||||||
def test_wpm(handler, queue):
|
def test_timing(handler):
|
||||||
handler.wpm = 10000
|
q1 = get_message_queue(size=2)
|
||||||
handler.connector.raise_event(queue)
|
q2 = get_message_queue(size=2)
|
||||||
assert len(handler.connector.messages) == 1
|
handler.connector.raise_event(q1)
|
||||||
handler.wpm = 100000000
|
handler.connector.raise_event(q2)
|
||||||
handler.connector.raise_event(queue)
|
|
||||||
sleep(0.25)
|
messages = []
|
||||||
assert len(handler.connector.messages) == 2*len(queue['messages'])
|
send_times = []
|
||||||
|
sleep_start_times = []
|
||||||
|
sleep_seconds = []
|
||||||
|
sleep_end_times = []
|
||||||
|
for _ in range(len(q1['messages']) + len(q2['messages'])):
|
||||||
|
messages.append(handler.connector.messages.get())
|
||||||
|
send_times.append(handler.connector.send_times.get())
|
||||||
|
sleep_start_times.append(handler.sleep_start_times.get())
|
||||||
|
sleep_seconds.append(handler.sleep_seconds.get())
|
||||||
|
sleep_end_times.append(handler.sleep_end_times.get())
|
||||||
|
|
||||||
|
# no sleep before first message
|
||||||
|
assert sleep_start_times[0] > send_times[0]
|
||||||
|
assert messages[0]['typing']
|
||||||
|
|
||||||
|
# at least 'seconds' sleep before sending next messages
|
||||||
|
assert (send_times[0] + sleep_seconds[0]) < sleep_end_times[0]
|
||||||
|
assert (send_times[0] + sleep_seconds[0]) < send_times[1]
|
||||||
|
assert messages[1]['typing']
|
||||||
|
assert (send_times[1] + sleep_seconds[1]) < sleep_end_times[1]
|
||||||
|
assert (send_times[1] + sleep_seconds[1]) < send_times[2]
|
||||||
|
assert messages[2]['typing']
|
||||||
|
|
||||||
|
# at least 'seconds' sleep after last message
|
||||||
|
assert (send_times[2] + sleep_seconds[2]) < sleep_end_times[3]
|
||||||
|
assert not messages[3]['typing']
|
||||||
|
Loading…
Reference in New Issue
Block a user