From 41d63ff3ccf3bc81e0c46a6758570056e2ee4ced Mon Sep 17 00:00:00 2001 From: Shivaram Lingamneni Date: Thu, 27 Feb 2020 23:00:37 -0500 Subject: [PATCH] add znc playback test --- irctest/irc_utils/junkdrawer.py | 13 ++++ irctest/server_tests/test_chathistory.py | 8 +-- irctest/server_tests/test_znc_playback.py | 74 +++++++++++++++++++++++ 3 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 irctest/irc_utils/junkdrawer.py create mode 100644 irctest/server_tests/test_znc_playback.py diff --git a/irctest/irc_utils/junkdrawer.py b/irctest/irc_utils/junkdrawer.py new file mode 100644 index 0000000..64b9908 --- /dev/null +++ b/irctest/irc_utils/junkdrawer.py @@ -0,0 +1,13 @@ +import datetime +from collections import namedtuple + +HistoryMessage = namedtuple('HistoryMessage', ['time', 'msgid', 'target', 'text']) + +def to_history_message(msg): + return HistoryMessage(time=msg.tags.get('time'), msgid=msg.tags.get('msgid'), target=msg.params[0], text=msg.params[1]) + +# thanks jess! +IRCV3_FORMAT_STRFTIME = "%Y-%m-%dT%H:%M:%S.%f%z" + +def ircv3_timestamp_to_unixtime(timestamp): + return datetime.datetime.strptime(timestamp, IRCV3_FORMAT_STRFTIME).timestamp() diff --git a/irctest/server_tests/test_chathistory.py b/irctest/server_tests/test_chathistory.py index 05b7978..6734321 100644 --- a/irctest/server_tests/test_chathistory.py +++ b/irctest/server_tests/test_chathistory.py @@ -1,22 +1,16 @@ import secrets import time -from collections import namedtuple from irctest import cases +from irctest.irc_utils.junkdrawer import to_history_message from irctest.irc_utils.random import random_name -#ANCIENT_TIMESTAMP = '2006-01-02T15:04:05.999Z' - CHATHISTORY_CAP = 'draft/chathistory' EVENT_PLAYBACK_CAP = 'draft/event-playback' -HistoryMessage = namedtuple('HistoryMessage', ['time', 'msgid', 'target', 'text']) MYSQL_PASSWORD = "" -def to_history_message(msg): - return HistoryMessage(time=msg.tags.get('time'), msgid=msg.tags.get('msgid'), target=msg.params[0], text=msg.params[1]) - def validate_chathistory_batch(msgs): batch_tag = None closed_batch_tag = None diff --git a/irctest/server_tests/test_znc_playback.py b/irctest/server_tests/test_znc_playback.py new file mode 100644 index 0000000..2591a62 --- /dev/null +++ b/irctest/server_tests/test_znc_playback.py @@ -0,0 +1,74 @@ +import time + +from irctest import cases +from irctest.irc_utils.junkdrawer import ircv3_timestamp_to_unixtime +from irctest.irc_utils.junkdrawer import to_history_message +from irctest.irc_utils.random import random_name + +class ZncPlaybackTestCase(cases.BaseServerTestCase): + + @cases.SpecificationSelector.requiredBySpecification('Oragono') + def testZncPlayback(self): + chname = random_name('#znc_channel') + bar = random_name('bar') + self.controller.registerUser(self, bar, bar) + self.connectClient(bar, name=bar, capabilities=['batch', 'labeled-response', 'message-tags', 'server-time', 'echo-message'], password=bar) + self.joinChannel(bar, chname) + + qux = random_name('qux') + self.connectClient(qux, name=qux, capabilities=['batch', 'labeled-response', 'message-tags', 'server-time', 'echo-message']) + self.joinChannel(qux, chname) + + self.sendLine(qux, 'PRIVMSG %s :hi there' % (bar,)) + dm = to_history_message([msg for msg in self.getMessages(qux) if msg.command == 'PRIVMSG'][0]) + self.assertEqual(dm.text, 'hi there') + + NUM_MESSAGES = 10 + echo_messages = [] + for i in range(NUM_MESSAGES): + self.sendLine(qux, 'PRIVMSG %s :this is message %d' % (chname, i)) + echo_messages.extend(to_history_message(msg) for msg in self.getMessages(qux) if msg.command == 'PRIVMSG') + time.sleep(0.003) + self.assertEqual(len(echo_messages), NUM_MESSAGES) + + self.getMessages(bar) + + # reattach to 'bar' + self.connectClient(bar, name='viewer', capabilities=['batch', 'labeled-response', 'message-tags', 'server-time', 'echo-message'], password=bar) + self.sendLine('viewer', 'PRIVMSG *playback :play * %d' % (int(time.time() - 60))) + messages = [to_history_message(msg) for msg in self.getMessages('viewer') if msg.command == 'PRIVMSG'] + self.assertEqual(set(messages), set([dm] + echo_messages)) + self.sendLine('viewer', 'QUIT') + self.assertDisconnected('viewer') + + # reattach to 'bar', play back selectively + self.connectClient(bar, name='viewer', capabilities=['batch', 'labeled-response', 'message-tags', 'server-time', 'echo-message'], password=bar) + mid_timestamp = ircv3_timestamp_to_unixtime(echo_messages[5].time) + # exclude message 5 itself (oragono's CHATHISTORY implementation corrects for this, but znc.in/playback does not because whatever) + mid_timestamp += .001 + self.sendLine('viewer', 'PRIVMSG *playback :play * %s' % (mid_timestamp,)) + messages = [to_history_message(msg) for msg in self.getMessages('viewer') if msg.command == 'PRIVMSG'] + self.assertEqual(messages, echo_messages[6:]) + self.sendLine('viewer', 'QUIT') + self.assertDisconnected('viewer') + + # reattach to 'bar', play back selectively (pass a parameter and 2 timestamps) + self.connectClient(bar, name='viewer', capabilities=['batch', 'labeled-response', 'message-tags', 'server-time', 'echo-message'], password=bar) + start_timestamp = ircv3_timestamp_to_unixtime(echo_messages[2].time) + start_timestamp += .001 + end_timestamp = ircv3_timestamp_to_unixtime(echo_messages[7].time) + self.sendLine('viewer', 'PRIVMSG *playback :play %s %s %s' % (chname, start_timestamp, end_timestamp,)) + messages = [to_history_message(msg) for msg in self.getMessages('viewer') if msg.command == 'PRIVMSG'] + self.assertEqual(messages, echo_messages[3:7]) + self.sendLine('viewer', 'QUIT') + self.assertDisconnected('viewer') + + # test limiting behavior + config = self.controller.getConfig() + config['history']['znc-maxmessages'] = 5 + self.controller.rehash(self, config) + self.connectClient(bar, name='viewer', capabilities=['batch', 'labeled-response', 'message-tags', 'server-time', 'echo-message'], password=bar) + self.sendLine('viewer', 'PRIVMSG *playback :play %s %d' % (chname, int(time.time() - 60))) + messages = [to_history_message(msg) for msg in self.getMessages('viewer') if msg.command == 'PRIVMSG'] + # should receive the latest 5 messages + self.assertEqual(messages, echo_messages[5:])