Add --show-io, improve I/O commands, and add test case for empty CAP LS.

This commit is contained in:
Valentin Lorentz
2015-12-19 09:30:50 +01:00
parent 097b28b8e7
commit 6d68a497ac
4 changed files with 52 additions and 17 deletions

View File

@ -26,6 +26,7 @@ def main(args):
file=sys.stderr) file=sys.stderr)
exit(1) exit(1)
_IrcTestCase.controllerClass = controller_class _IrcTestCase.controllerClass = controller_class
_IrcTestCase.show_io = args.show_io
unittest.main(module=module, argv=[sys.argv[0], 'discover']) unittest.main(module=module, argv=[sys.argv[0], 'discover'])
@ -33,6 +34,8 @@ parser = argparse.ArgumentParser(
description='A script to test interoperability of IRC software.') description='A script to test interoperability of IRC software.')
parser.add_argument('module', type=str, parser.add_argument('module', type=str,
help='The module used to run the tested program.') help='The module used to run the tested program.')
parser.add_argument('--show-io', action='store_true',
help='Show input/outputs with the tested program.')
args = parser.parse_args() args = parser.parse_args()
main(args) main(args)

View File

@ -6,6 +6,17 @@ from .irc_utils import message_parser
class _IrcTestCase(unittest.TestCase): class _IrcTestCase(unittest.TestCase):
controllerClass = None # Will be set by __main__.py controllerClass = None # Will be set by __main__.py
def getLine(self):
raise NotImplementedError()
def getMessage(self, filter_pred=None):
"""Gets a message and returns it. If a filter predicate is given,
fetches messages until the predicate returns a False on a message,
and returns this message."""
while True:
msg = message_parser.parse_message(self.getLine())
if not filter_pred or filter_pred(msg):
return msg
class BaseClientTestCase(_IrcTestCase): class BaseClientTestCase(_IrcTestCase):
"""Basic class for client tests. Handles spawning a client and getting """Basic class for client tests. Handles spawning a client and getting
messages from it.""" messages from it."""
@ -26,14 +37,21 @@ class BaseClientTestCase(_IrcTestCase):
def acceptClient(self): def acceptClient(self):
"""Make the server accept a client connection. Blocking.""" """Make the server accept a client connection. Blocking."""
(self.conn, addr) = self.server.accept() (self.conn, addr) = self.server.accept()
self.conn_file = self.conn.makefile(newline='\r\n') self.conn_file = self.conn.makefile(newline='\r\n',
encoding='utf8')
def getLine(self): def getLine(self):
return self.conn_file.readline().strip() line = self.conn_file.readline()
def getMessage(self): if self.show_io:
return message_parser.parse_message(self.conn_file.readline()) print('C: {}'.format(line.strip()))
return line
def sendLine(self, line):
assert self.conn.sendall(line.encode()) is None
if not line.endswith('\r\n'):
assert self.conn.sendall(b'\r\n') is None
print('S: {}'.format(line.strip()))
class NegociationHelper: class ClientNegociationHelper:
"""Helper class for tests handling capabilities negociation.""" """Helper class for tests handling capabilities negociation."""
def readCapLs(self): def readCapLs(self):
(hostname, port) = self.server.getsockname() (hostname, port) = self.server.getsockname()
@ -46,12 +64,25 @@ class NegociationHelper:
m = self.getMessage() m = self.getMessage()
self.assertEqual(m.command, 'CAP', self.assertEqual(m.command, 'CAP',
'First message is not CAP LS.') 'First message is not CAP LS.')
self.assertEqual(m.subcommand, 'LS', if m.params == ['LS']:
'First message is not CAP LS.')
if m.params == []:
self.protocol_version = 301 self.protocol_version = 301
elif m.params == ['302']: elif m.params == ['LS', '302']:
self.protocol_version = 302 self.protocol_version = 302
else: else:
raise AssertionError('Unknown protocol version {}' raise AssertionError('Unknown CAP params: {}'
.format(m.params)) .format(m.params))
def userNickPredicate(self, msg):
"""Predicate to be used with getMessage to handle NICK/USER
transparently."""
if msg.command == 'NICK':
self.assertEqual(len(msg.params), 1, msg)
self.nick = msg.params[0]
return False
elif msg.command == 'USER':
self.assertEqual(len(msg.params), 4, msg)
self.nick = msg.params
return False
else:
return True

View File

@ -1,6 +1,12 @@
from irctest import cases from irctest import cases
from irctest.irc_utils.message_parser import Message from irctest.irc_utils.message_parser import Message
class CapTestCase(cases.BaseClientTestCase, cases.NegociationHelper): class CapTestCase(cases.BaseClientTestCase, cases.ClientNegociationHelper):
def testSendCap(self): def testSendCap(self):
self.readCapLs() self.readCapLs()
def testEmptyCapLs(self):
self.readCapLs()
self.sendLine('CAP * LS :')
m = self.getMessage(filter_pred=self.userNickPredicate)
self.assertEqual(m, Message([], None, 'CAP', ['END']))

View File

@ -29,7 +29,7 @@ def parse_tags(s):
return tags return tags
Message = collections.namedtuple('Message', Message = collections.namedtuple('Message',
'tags prefix command subcommand params') 'tags prefix command params')
def parse_message(s): def parse_message(s):
"""Parse a message according to """Parse a message according to
@ -52,15 +52,10 @@ def parse_message(s):
else: else:
prefix = None prefix = None
command = tokens.pop(0) command = tokens.pop(0)
if command == 'CAP':
subcommand = tokens.pop(0)
else:
subcommand = None
params = tokens params = tokens
return Message( return Message(
tags=tags, tags=tags,
prefix=prefix, prefix=prefix,
command=command, command=command,
subcommand=subcommand,
params=params, params=params,
) )