3
0
mirror of https://github.com/jlu5/PyLink.git synced 2024-11-24 03:29:28 +01:00

Modularize tests using common classes, add our custom test runner (#56)

This commit is contained in:
James Lu 2015-08-29 14:06:07 -07:00
parent 549a1d1ba4
commit a58bee7355
5 changed files with 250 additions and 201 deletions

17
conf.py
View File

@ -23,7 +23,8 @@ testconf = {'bot':
'nick': 'PyLink', 'nick': 'PyLink',
'user': 'pylink', 'user': 'pylink',
'realname': 'PyLink Service Client', 'realname': 'PyLink Service Client',
'loglevel': 'INFO', # Suppress logging in the test output for the most part.
'loglevel': 'CRITICAL',
'serverdesc': 'PyLink unit tests' 'serverdesc': 'PyLink unit tests'
}, },
'servers': 'servers':
@ -45,12 +46,12 @@ testconf = {'bot':
with open(fname, 'r') as f: with open(fname, 'r') as f:
global conf global conf
try: if world.testing:
conf = yaml.load(f) conf = testconf
except Exception as e: confname = 'testconf'
if world.testing: else:
conf = testconf try:
confname = 'testconf' conf = yaml.load(f)
else: except Exception as e:
print('ERROR: Failed to load config from %r: %s: %s' % (fname, type(e).__name__, e)) print('ERROR: Failed to load config from %r: %s: %s' % (fname, type(e).__name__, e))
sys.exit(4) sys.exit(4)

22
runtests.py Executable file
View File

@ -0,0 +1,22 @@
#!/usr/bin/env python3
import unittest
import glob
import imp
import os
import sys
runner = unittest.TextTestRunner(verbosity=2)
fails = []
suites = []
# Yay, import hacks!
sys.path.append(os.path.join(os.getcwd(), 'tests'))
for testfile in glob.glob('tests/test_*.py'):
# Strip the tests/ and .py extension: tests/test_whatever.py => test_whatever
module = testfile.replace('.py', '').replace('tests/', '')
module = __import__(module)
suites.append(unittest.defaultTestLoader.loadTestsFromModule(module))
testsuite = unittest.TestSuite(suites)
runner.run(testsuite)

35
tests/test_coreplugin.py Normal file
View File

@ -0,0 +1,35 @@
#!/usr/bin/env python
import inspircd
import unittest
import world
import coreplugin
import tests_common
world.testing = inspircd
class CorePluginTestCase(tests_common.PluginTestCase):
@unittest.skip("Test doesn't work yet.")
def testKillRespawn(self):
self.irc.run(':9PY KILL {u} :test'.format(u=self.u))
hooks = self.irc.takeHooks()
# Make sure we're respawning our PseudoClient when its killed
print(hooks)
spmain = [h for h in hooks if h[1] == 'PYLINK_SPAWNMAIN']
self.assertTrue(spmain, 'PYLINK_SPAWNMAIN hook was never sent!')
msgs = self.irc.takeMsgs()
commands = self.irc.takeCommands(msgs)
self.assertIn('UID', commands)
self.assertIn('FJOIN', commands)
# Also make sure that we're updating the irc.pseudoclient field
self.assertNotEqual(self.irc.pseudoclient.uid, spmain[0]['olduser'])
def testKickrejoin(self):
self.proto.kickClient(self.irc, self.u, '#pylink', self.u, 'test')
msgs = self.irc.takeMsgs()
commands = self.irc.takeCommands(msgs)
self.assertIn('FJOIN', commands)

View File

@ -6,116 +6,40 @@ from collections import defaultdict
import inspircd import inspircd
import classes import classes
import utils import world
import coreplugin
class TestProtoInspIRCd(unittest.TestCase): import tests_common
def setUp(self):
self.irc = classes.FakeIRC('unittest', inspircd)
self.proto = self.irc.proto
self.sdata = self.irc.serverdata
# This is to initialize ourself as an internal PseudoServer, so we can spawn clients
self.irc.connect()
self.u = self.irc.pseudoclient.uid
self.maxDiff = None
self.initial_messages = self.irc.takeMsgs()
# Clear the hooks called at startup (spawnmain and possibly others)
self.irc.takeHooks()
def testConnect(self): world.testing = inspircd
commands = self.irc.takeCommands(self.initial_messages)
# SERVER pylink.unittest abcd 0 9PY :PyLink Service
serverline = 'SERVER %s %s 0 %s :PyLink Service' % (
self.sdata['hostname'], self.sdata['sendpass'], self.sdata['sid'])
self.assertIn(serverline, self.initial_messages)
self.assertIn('BURST', commands)
self.assertIn('ENDBURST', commands)
# Is it creating our lovely PyLink PseudoClient?
self.assertIn('UID', commands)
self.assertIn('FJOIN', commands)
class InspIRCdTestCase(tests_common.CommonProtoTestCase):
def testCheckRecvpass(self): def testCheckRecvpass(self):
# Correct recvpass here. # Correct recvpass here.
self.irc.run('SERVER somehow.someday abcd 0 0AL :Somehow Server - McMurdo Station, Antarctica') self.irc.run('SERVER somehow.someday abcd 0 0AL :Somehow Server - McMurdo Station, Antarctica')
# Incorrect recvpass here; should raise ProtocolError. # Incorrect recvpass here; should raise ProtocolError.
self.assertRaises(classes.ProtocolError, self.irc.run, 'SERVER somehow.someday BADPASS 0 0AL :Somehow Server - McMurdo Station, Antarctica') self.assertRaises(classes.ProtocolError, self.irc.run, 'SERVER somehow.someday BADPASS 0 0AL :Somehow Server - McMurdo Station, Antarctica')
def testSpawnClient(self): def testConnect(self):
u = self.proto.spawnClient(self.irc, 'testuser3', 'moo', 'hello.world').uid self.proto.connect(self.irc)
# Check the server index and the user index initial_messages = self.irc.takeMsgs()
self.assertIn(u, self.irc.servers[self.irc.sid].users) commands = self.irc.takeCommands(initial_messages)
self.assertIn(u, self.irc.users) # SERVER pylink.unittest abcd 0 9PY :PyLink Service
# Raise ValueError when trying to spawn a client on a server that's not ours serverline = 'SERVER %s %s 0 %s :%s' % (
self.assertRaises(ValueError, self.proto.spawnClient, self.irc, 'abcd', 'user', 'dummy.user.net', server='44A') self.sdata['hostname'], self.sdata['sendpass'], self.sdata['sid'],
# Unfilled args should get placeholder fields and not error. self.irc.botdata['serverdesc'])
self.proto.spawnClient(self.irc, 'testuser4') self.assertIn(serverline, initial_messages)
self.assertIn('BURST', commands)
def testJoinClient(self): self.assertIn('ENDBURST', commands)
u = self.u # Is it creating our lovely PyLink PseudoClient?
self.proto.joinClient(self.irc, u, '#Channel') self.assertIn('UID', commands)
self.assertIn(u, self.irc.channels['#channel'].users) self.assertIn('FJOIN', commands)
# Non-existant user.
self.assertRaises(LookupError, self.proto.joinClient, self.irc, '9PYZZZZZZ', '#test')
def testPartClient(self):
u = self.u
self.proto.joinClient(self.irc, u, '#channel')
self.proto.partClient(self.irc, u, '#channel')
self.assertNotIn(u, self.irc.channels['#channel'].users)
def testQuitClient(self):
u = self.proto.spawnClient(self.irc, 'testuser3', 'moo', 'hello.world').uid
self.proto.joinClient(self.irc, u, '#channel')
self.assertRaises(LookupError, self.proto.quitClient, self.irc, '9PYZZZZZZ', 'quit reason')
self.proto.quitClient(self.irc, u, 'quit reason')
self.assertNotIn(u, self.irc.channels['#channel'].users)
self.assertNotIn(u, self.irc.users)
self.assertNotIn(u, self.irc.servers[self.irc.sid].users)
def testKickClient(self):
target = self.proto.spawnClient(self.irc, 'soccerball', 'soccerball', 'abcd').uid
self.proto.joinClient(self.irc, target, '#pylink')
self.assertIn(self.u, self.irc.channels['#pylink'].users)
self.assertIn(target, self.irc.channels['#pylink'].users)
self.proto.kickClient(self.irc, self.u, '#pylink', target, 'Pow!')
self.assertNotIn(target, self.irc.channels['#pylink'].users)
def testNickClient(self):
self.proto.nickClient(self.irc, self.u, 'NotPyLink')
self.assertEqual('NotPyLink', self.irc.users[self.u].nick)
def testModeClient(self):
testuser = self.proto.spawnClient(self.irc, 'testcakes')
self.irc.takeMsgs()
self.proto.modeClient(self.irc, self.u, testuser.uid, [('+i', None), ('+w', None)])
self.assertEqual({('i', None), ('w', None)}, testuser.modes)
self.proto.modeClient(self.irc, self.u, '#pylink', [('+s', None), ('+l', '30')])
self.assertEqual({('s', None), ('l', '30')}, self.irc.channels['#pylink'].modes)
cmds = self.irc.takeCommands(self.irc.takeMsgs())
self.assertEqual(cmds, ['MODE', 'FMODE'])
def testSpawnServer(self): def testSpawnServer(self):
# Incorrect SID length super(InspIRCdTestCase, self).testSpawnServer()
self.assertRaises(Exception, self.proto.spawnServer, self.irc, 'subserver.pylink', '34Q0')
self.proto.spawnServer(self.irc, 'subserver.pylink', '34Q')
# Duplicate server name
self.assertRaises(Exception, self.proto.spawnServer, self.irc, 'Subserver.PyLink', '34Z')
# Duplicate SID
self.assertRaises(Exception, self.proto.spawnServer, self.irc, 'another.Subserver.PyLink', '34Q')
self.assertIn('34Q', self.irc.servers)
# Are we bursting properly? # Are we bursting properly?
self.assertIn(':34Q ENDBURST', self.irc.takeMsgs()) self.assertIn(':34Q ENDBURST', self.irc.takeMsgs())
def testSpawnClientOnServer(self): def testHandleSQuit(self):
self.proto.spawnServer(self.irc, 'subserver.pylink', '34Q')
u = self.proto.spawnClient(self.irc, 'person1', 'person', 'users.overdrive.pw', server='34Q')
# We're spawning clients on the right server, hopefully...
self.assertIn(u.uid, self.irc.servers['34Q'].users)
self.assertNotIn(u.uid, self.irc.servers[self.irc.sid].users)
def testSquit(self):
# Spawn a messy network map, just because! # Spawn a messy network map, just because!
self.proto.spawnServer(self.irc, 'level1.pylink', '34P') self.proto.spawnServer(self.irc, 'level1.pylink', '34P')
self.proto.spawnServer(self.irc, 'level2.pylink', '34Q', uplink='34P') self.proto.spawnServer(self.irc, 'level2.pylink', '34Q', uplink='34P')
@ -145,124 +69,122 @@ class TestProtoInspIRCd(unittest.TestCase):
self.assertEqual('test.server', self.irc.servers['0AL'].name) self.assertEqual('test.server', self.irc.servers['0AL'].name)
def testHandleUID(self): def testHandleUID(self):
self.irc.run('SERVER whatever.net abcd 0 10X :something')
self.irc.run(':10X UID 10XAAAAAB 1429934638 GL 0::1 hidden-7j810p.9mdf.lrek.0000.0000.IP gl 0::1 1429934638 +Wioswx +ACGKNOQXacfgklnoqvx :realname') self.irc.run(':10X UID 10XAAAAAB 1429934638 GL 0::1 hidden-7j810p.9mdf.lrek.0000.0000.IP gl 0::1 1429934638 +Wioswx +ACGKNOQXacfgklnoqvx :realname')
self.assertIn('10XAAAAAB', self.irc.servers['10X'].users) self.assertIn('10XAAAAAB', self.irc.servers['10X'].users)
self.assertIn('10XAAAAAB', self.irc.users)
u = self.irc.users['10XAAAAAB'] u = self.irc.users['10XAAAAAB']
self.assertEqual('GL', u.nick) self.assertEqual('GL', u.nick)
expected = {'uid': '10XAAAAAB', 'ts': '1429934638', 'nick': 'GL',
'realhost': '0::1', 'ident': 'gl', 'ip': '0::1',
'host': 'hidden-7j810p.9mdf.lrek.0000.0000.IP'}
hookdata = self.irc.takeHooks()[0][-1]
self.assertEqual(hookdata, expected)
def testHandleKill(self): def testHandleKill(self):
self.irc.takeMsgs() # Ignore the initial connect messages self.irc.takeMsgs() # Ignore the initial connect messages
utils.add_hook(self.irc.dummyhook, 'KILL') self.u = self.irc.pseudoclient.uid
olduid = self.irc.pseudoclient.uid self.irc.run(':{u} KILL {u} :killed'.format(u=self.u))
self.irc.run(':{u} KILL {u} :killed'.format(u=olduid))
msgs = self.irc.takeMsgs() msgs = self.irc.takeMsgs()
commands = self.irc.takeCommands(msgs) commands = self.irc.takeCommands(msgs)
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[0][-1]
del hookdata['ts'] self.assertEqual(hookdata['target'], self.u)
self.assertEqual({'target': olduid, 'text': 'killed'}, hookdata) self.assertEqual(hookdata['text'], 'killed')
# Make sure we're respawning our PseudoClient when its killed self.assertNotIn(self.u, self.irc.users)
self.assertIn('UID', commands)
self.assertIn('FJOIN', commands)
# Also make sure that we're updating the irc.pseudoclient field
self.assertNotEqual(self.irc.pseudoclient.uid, olduid)
def testHandleKick(self): def testHandleKick(self):
self.irc.takeMsgs() # Ignore the initial connect messages self.irc.takeMsgs() # Ignore the initial connect messages
utils.add_hook(self.irc.dummyhook, 'KICK')
self.irc.run(':{u} KICK #pylink {u} :kicked'.format(u=self.irc.pseudoclient.uid)) self.irc.run(':{u} KICK #pylink {u} :kicked'.format(u=self.irc.pseudoclient.uid))
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[0][-1]
del hookdata['ts'] self.assertEqual(hookdata['target'], self.u)
self.assertEqual({'target': self.u, 'text': 'kicked', 'channel': '#pylink'}, hookdata) self.assertEqual(hookdata['text'], 'kicked')
self.assertEqual(hookdata['channel'], '#pylink')
# Ditto above def testHandleFJoinUsers(self):
msgs = self.irc.takeMsgs()
commands = self.irc.takeCommands(msgs)
self.assertIn('FJOIN', commands)
def testHandleFjoinUsers(self):
self.irc.run(':10X FJOIN #Chat 1423790411 + :,10XAAAAAA ,10XAAAAAB') self.irc.run(':10X FJOIN #Chat 1423790411 + :,10XAAAAAA ,10XAAAAAB')
self.assertEqual({'10XAAAAAA', '10XAAAAAB'}, self.irc.channels['#chat'].users) self.assertEqual({'10XAAAAAA', '10XAAAAAB'}, self.irc.channels['#chat'].users)
# self.assertIn('10XAAAAAB', self.irc.channels['#chat'].users) self.assertIn('#chat', self.irc.users['10XAAAAAA'].channels)
# Sequential FJOINs must NOT remove existing users # Sequential FJOINs must NOT remove existing users
self.irc.run(':10X FJOIN #Chat 1423790412 + :,10XAAAAAC') self.irc.run(':10X FJOIN #Chat 1423790412 + :,10XAAAAAC')
# Join list can be empty too, in the case of permanent channels with 0 users. # Join list can be empty too, in the case of permanent channels with 0 users.
self.irc.run(':10X FJOIN #Chat 1423790413 +nt :') self.irc.run(':10X FJOIN #Chat 1423790413 +nt :')
def testHandleFjoinModes(self): def testHandleFJoinModes(self):
self.irc.run(':10X FJOIN #Chat 1423790411 +nt :,10XAAAAAA ,10XAAAAAB') self.irc.run(':10X FJOIN #Chat 1423790411 +nt :,10XAAAAAA ,10XAAAAAB')
self.assertEqual({('n', None), ('t', None)}, self.irc.channels['#chat'].modes) self.assertEqual({('n', None), ('t', None)}, self.irc.channels['#chat'].modes)
# Sequential FJOINs must NOT remove existing modes # Sequential FJOINs must NOT remove existing modes
self.irc.run(':10X FJOIN #Chat 1423790412 + :,10XAAAAAC') self.irc.run(':10X FJOIN #Chat 1423790412 + :,10XAAAAAC')
self.assertEqual({('n', None), ('t', None)}, self.irc.channels['#chat'].modes) self.assertEqual({('n', None), ('t', None)}, self.irc.channels['#chat'].modes)
def testHandleFjoinModesWithArgs(self): def testHandleFJoinModesWithArgs(self):
self.irc.run(':10X FJOIN #Chat 1423790414 +nlks 10 t0psekrit :,10XAAAAAA ,10XAAAAAB') self.irc.run(':10X FJOIN #Chat 1423790414 +nlks 10 t0psekrit :,10XAAAAAA ,10XAAAAAB')
self.assertEqual({('n', None), ('s', None), ('l', '10'), ('k', 't0psekrit')}, self.assertEqual({('n', None), ('s', None), ('l', '10'), ('k', 't0psekrit')},
self.irc.channels['#chat'].modes) self.irc.channels['#chat'].modes)
def testHandleFjoinPrefixes(self): def testHandleFJoinPrefixes(self):
self.irc.run(':10X FJOIN #Chat 1423790418 +nt :ov,10XAAAAAA v,10XAAAAAB ,10XAAAAAC') self.irc.run(':10X FJOIN #Chat 1423790418 +nt :ov,10XAAAAAA v,10XAAAAAB ,10XAAAAAC')
self.assertEqual({('n', None), ('t', None)}, self.irc.channels['#chat'].modes) self.assertEqual({('n', None), ('t', None)}, self.irc.channels['#chat'].modes)
self.assertEqual({'10XAAAAAA', '10XAAAAAB', '10XAAAAAC'}, self.irc.channels['#chat'].users) self.assertEqual({'10XAAAAAA', '10XAAAAAB', '10XAAAAAC'}, self.irc.channels['#chat'].users)
self.assertIn('10XAAAAAA', self.irc.channels['#chat'].prefixmodes['ops']) self.assertIn('10XAAAAAA', self.irc.channels['#chat'].prefixmodes['ops'])
self.assertEqual({'10XAAAAAA', '10XAAAAAB'}, self.irc.channels['#chat'].prefixmodes['voices']) self.assertEqual({'10XAAAAAA', '10XAAAAAB'}, self.irc.channels['#chat'].prefixmodes['voices'])
def testHandleFjoinHook(self): def testHandleFJoinHook(self):
utils.add_hook(self.irc.dummyhook, 'JOIN')
self.irc.run(':10X FJOIN #PyLink 1423790418 +ls 10 :ov,10XAAAAAA v,10XAAAAAB ,10XAAAAAC') self.irc.run(':10X FJOIN #PyLink 1423790418 +ls 10 :ov,10XAAAAAA v,10XAAAAAB ,10XAAAAAC')
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[0][-1]
expected = {'modes': [('+l', '10'), ('+s', None)], expected = {'modes': [('+l', '10'), ('+s', None)],
'channel': '#pylink', 'channel': '#pylink',
'users': ['10XAAAAAA', '10XAAAAAB', '10XAAAAAC'], 'users': ['10XAAAAAA', '10XAAAAAB', '10XAAAAAC'],
'ts': 1423790418} 'ts': 1423790418}
self.assertEqual(expected, hookdata) self.assertEqual(expected, hookdata)
def testHandleFmode(self): def testHandleFMode(self):
self.irc.run(':10X FJOIN #pylink 1423790411 +n :o,10XAAAAAA ,10XAAAAAB')
utils.add_hook(self.irc.dummyhook, 'MODE')
self.irc.run(':70M FMODE #pylink 1423790412 +ikl herebedragons 100') self.irc.run(':70M FMODE #pylink 1423790412 +ikl herebedragons 100')
self.assertEqual({('i', None), ('k', 'herebedragons'), ('l', '100'), ('n', None)}, self.irc.channels['#pylink'].modes) self.assertEqual({('i', None), ('k', 'herebedragons'), ('l', '100')}, self.irc.channels['#pylink'].modes)
self.irc.run(':70M FMODE #pylink 1423790413 -ilk+m herebedragons') self.irc.run(':70M FMODE #pylink 1423790413 -ilk+m herebedragons')
self.assertEqual({('m', None), ('n', None)}, self.irc.channels['#pylink'].modes) self.assertEqual({('m', None)}, self.irc.channels['#pylink'].modes)
hookdata = self.irc.takeHooks() hookdata = self.irc.takeHooks()
expected = [{'target': '#pylink', 'modes': [('+i', None), ('+k', 'herebedragons'), ('+l', '100')], 'ts': 1423790412}, expected = [['70M', 'FMODE', {'target': '#pylink', 'modes':
{'target': '#pylink', 'modes': [('-i', None), ('-l', None), ('-k', 'herebedragons'), ('+m', None)], 'ts': 1423790413}] [('+i', None), ('+k', 'herebedragons'),
('+l', '100')], 'ts': 1423790412}
],
['70M', 'FMODE', {'target': '#pylink', 'modes':
[('-i', None), ('-l', None),
('-k', 'herebedragons'), ('+m', None)],
'ts': 1423790413}]
]
self.assertEqual(expected, hookdata) self.assertEqual(expected, hookdata)
def testHandleFmodeWithPrefixes(self): def testHandleFModeWithPrefixes(self):
self.irc.run(':70M FJOIN #pylink 1423790411 +n :o,10XAAAAAA ,10XAAAAAB') self.irc.run(':70M FJOIN #pylink 123 +n :o,10XAAAAAA ,10XAAAAAB')
utils.add_hook(self.irc.dummyhook, 'MODE')
# Prefix modes are stored separately, so they should never show up in .modes # Prefix modes are stored separately, so they should never show up in .modes
self.assertNotIn(('o', '10XAAAAAA'), self.irc.channels['#pylink'].modes) self.assertNotIn(('o', '10XAAAAAA'), self.irc.channels['#pylink'].modes)
self.assertEqual({'10XAAAAAA'}, self.irc.channels['#pylink'].prefixmodes['ops']) self.assertEqual({'10XAAAAAA'}, self.irc.channels['#pylink'].prefixmodes['ops'])
self.irc.run(':70M FMODE #pylink 1423790412 +lot 50 %s' % self.u) self.irc.run(':70M FMODE #pylink 123 +lot 50 %s' % self.u)
self.assertIn(self.u, self.irc.channels['#pylink'].prefixmodes['ops']) self.assertIn(self.u, self.irc.channels['#pylink'].prefixmodes['ops'])
modes = {('l', '50'), ('n', None), ('t', None)} modes = {('l', '50'), ('n', None), ('t', None)}
self.assertEqual(modes, self.irc.channels['#pylink'].modes) self.assertEqual(modes, self.irc.channels['#pylink'].modes)
self.irc.run(':70M FMODE #pylink 1423790413 -o %s' % self.u) self.irc.run(':70M FMODE #pylink 123 -o %s' % self.u)
self.assertEqual(modes, self.irc.channels['#pylink'].modes) self.assertEqual(modes, self.irc.channels['#pylink'].modes)
self.assertNotIn(self.u, self.irc.channels['#pylink'].prefixmodes['ops']) self.assertNotIn(self.u, self.irc.channels['#pylink'].prefixmodes['ops'])
# Test hooks # Test hooks
hookdata = self.irc.takeHooks() hookdata = self.irc.takeHooks()
expected = [{'target': '#pylink', 'modes': [('+l', '50'), ('+o', '9PYAAAAAA'), ('+t', None)], 'ts': 1423790412}, expected = [['70M', 'FJOIN', {'channel': '#pylink', 'ts': 123, 'modes': [('+n', None)],
{'target': '#pylink', 'modes': [('-o', '9PYAAAAAA')], 'ts': 1423790413}] 'users': ['10XAAAAAA', '10XAAAAAB']}],
['70M', 'FMODE', {'target': '#pylink', 'modes': [('+l', '50'), ('+o', '9PYAAAAAA'), ('+t', None)], 'ts': 123}],
['70M', 'FMODE', {'target': '#pylink', 'modes': [('-o', '9PYAAAAAA')], 'ts': 123}]]
self.assertEqual(expected, hookdata) self.assertEqual(expected, hookdata)
def testFmodeRemovesOldParams(self): def testHandleFModeRemovesOldParams(self):
utils.add_hook(self.irc.dummyhook, 'MODE')
self.irc.run(':70M FMODE #pylink 1423790412 +l 50') self.irc.run(':70M FMODE #pylink 1423790412 +l 50')
self.assertEqual({('l', '50')}, self.irc.channels['#pylink'].modes) self.assertEqual({('l', '50')}, self.irc.channels['#pylink'].modes)
self.irc.run(':70M FMODE #pylink 1423790412 +l 30') self.irc.run(':70M FMODE #pylink 1423790412 +l 30')
self.assertEqual({('l', '30')}, self.irc.channels['#pylink'].modes) self.assertEqual({('l', '30')}, self.irc.channels['#pylink'].modes)
hookdata = self.irc.takeHooks() hookdata = self.irc.takeHooks()
expected = [{'target': '#pylink', 'modes': [('+l', '50')], 'ts': 1423790412}, expected = [['70M', 'FMODE', {'target': '#pylink', 'modes': [('+l', '50')], 'ts': 1423790412}],
{'target': '#pylink', 'modes': [('+l', '30')], 'ts': 1423790412}] ['70M', 'FMODE', {'target': '#pylink', 'modes': [('+l', '30')], 'ts': 1423790412}]]
self.assertEqual(expected, hookdata) self.assertEqual(expected, hookdata)
def testFjoinResetsTS(self): def testHandleFJoinResetsTS(self):
curr_ts = self.irc.channels['#pylink'].ts curr_ts = self.irc.channels['#pylink'].ts
self.irc.run(':70M FJOIN #pylink 5 + :') self.irc.run(':70M FJOIN #pylink 5 + :')
self.assertEqual(self.irc.channels['#pylink'].ts, 5) self.assertEqual(self.irc.channels['#pylink'].ts, 5)
@ -273,87 +195,60 @@ class TestProtoInspIRCd(unittest.TestCase):
def testHandleTopic(self): def testHandleTopic(self):
self.irc.connect() self.irc.connect()
utils.add_hook(self.irc.dummyhook, 'TOPIC')
self.irc.run(':9PYAAAAAA TOPIC #PyLink :test') self.irc.run(':9PYAAAAAA TOPIC #PyLink :test')
self.assertEqual(self.irc.channels['#pylink'].topic, 'test') self.assertEqual(self.irc.channels['#pylink'].topic, 'test')
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[0][-1]
# Setter is a nick here, not an UID - this is to be consistent
# with FTOPIC above, which sends the nick/prefix of the topic setter.
self.assertTrue(utils.isNick(hookdata.get('setter')))
self.assertEqual(type(hookdata['ts']), int) self.assertEqual(type(hookdata['ts']), int)
self.assertEqual(hookdata['topic'], 'test') self.assertEqual(hookdata['topic'], 'test')
self.assertEqual(hookdata['channel'], '#pylink') self.assertEqual(hookdata['channel'], '#pylink')
def testMsgHooks(self): def testHandleMessages(self):
for m in ('NOTICE', 'PRIVMSG'): for m in ('NOTICE', 'PRIVMSG'):
utils.add_hook(self.irc.dummyhook, m)
self.irc.run(':70MAAAAAA %s #dev :afasfsa' % m) self.irc.run(':70MAAAAAA %s #dev :afasfsa' % m)
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[0][-1]
del hookdata['ts'] self.assertEqual(hookdata['target'], '#dev')
self.assertEqual({'target': '#dev', 'text': 'afasfsa'}, hookdata) self.assertEqual(hookdata['text'], 'afasfsa')
def testHandlePart(self): def testHandlePart(self):
utils.add_hook(self.irc.dummyhook, 'PART') hookdata = self.irc.takeHooks()
self.irc.run(':9PYAAAAAA PART #pylink') self.irc.run(':9PYAAAAAA PART #pylink')
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[0][-1]
del hookdata['ts'] self.assertEqual(hookdata['channels'], ['#pylink'])
self.assertEqual({'channel': '#pylink', 'text': ''}, hookdata) self.assertEqual(hookdata['text'], '')
def testUIDHook(self):
utils.add_hook(self.irc.dummyhook, 'UID')
# Create the server so we won't KeyError on processing UID
self.irc.run('SERVER whatever. abcd 0 10X :Whatever Server - Hellas Planitia, Mars')
self.irc.run(':10X UID 10XAAAAAB 1429934638 GL 0::1 '
'hidden-7j810p.9mdf.lrek.0000.0000.IP gl 0::1 1429934638 '
'+Wioswx +ACGKNOQXacfgklnoqvx :realname')
expected = {'uid': '10XAAAAAB', 'ts': '1429934638', 'nick': 'GL',
'realhost': '0::1', 'ident': 'gl', 'ip': '0::1',
'host': 'hidden-7j810p.9mdf.lrek.0000.0000.IP'}
hookdata = self.irc.takeHooks()[0]
self.assertEqual(hookdata, expected)
def testHandleQuit(self): def testHandleQuit(self):
utils.add_hook(self.irc.dummyhook, 'QUIT') self.irc.takeHooks()
self.irc.run('SERVER whatever. abcd 0 10X :Whatever Server - Hellas Planitia, Mars')
self.irc.run(':10X UID 10XAAAAAB 1429934638 GL 0::1 '
'hidden-7j810p.9mdf.lrek.0000.0000.IP gl 0::1 1429934638 '
'+Wioswx +ACGKNOQXacfgklnoqvx :realname')
self.irc.run(':10XAAAAAB QUIT :Quit: quit message goes here') self.irc.run(':10XAAAAAB QUIT :Quit: quit message goes here')
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[0][-1]
del hookdata['ts'] self.assertEqual(hookdata['text'], 'Quit: quit message goes here')
self.assertEqual(hookdata, {'text': 'Quit: quit message goes here'})
self.assertNotIn('10XAAAAAB', self.irc.users) self.assertNotIn('10XAAAAAB', self.irc.users)
self.assertNotIn('10XAAAAAB', self.irc.servers['10X'].users) self.assertNotIn('10XAAAAAB', self.irc.servers['10X'].users)
def testHandleServer(self): def testHandleServer(self):
utils.add_hook(self.irc.dummyhook, 'SERVER')
self.irc.run(':00A SERVER test.server * 1 00C :testing raw message syntax') self.irc.run(':00A SERVER test.server * 1 00C :testing raw message syntax')
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[-1][-1]
del hookdata['ts'] self.assertEqual(hookdata['name'], 'test.server')
self.assertEqual(hookdata, {'name': 'test.server', 'sid': '00C', self.assertEqual(hookdata['sid'], '00C')
'text': 'testing raw message syntax'}) self.assertEqual(hookdata['text'], 'testing raw message syntax')
self.assertIn('00C', self.irc.servers) self.assertIn('00C', self.irc.servers)
def testHandleNick(self): def testHandleNick(self):
utils.add_hook(self.irc.dummyhook, 'NICK')
self.irc.run(':9PYAAAAAA NICK PyLink-devel 1434744242') self.irc.run(':9PYAAAAAA NICK PyLink-devel 1434744242')
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[0][-1]
expected = {'newnick': 'PyLink-devel', 'oldnick': 'PyLink', 'ts': 1434744242} expected = {'newnick': 'PyLink-devel', 'oldnick': 'PyLink', 'ts': 1434744242}
self.assertEqual(hookdata, expected) self.assertEqual(hookdata, expected)
self.assertEqual('PyLink-devel', self.irc.users['9PYAAAAAA'].nick) self.assertEqual('PyLink-devel', self.irc.users['9PYAAAAAA'].nick)
def testHandleSave(self): def testHandleSave(self):
utils.add_hook(self.irc.dummyhook, 'SAVE')
self.irc.run(':9PYAAAAAA NICK Derp_ 1433728673') self.irc.run(':9PYAAAAAA NICK Derp_ 1433728673')
self.irc.run(':70M SAVE 9PYAAAAAA 1433728673') self.irc.run(':70M SAVE 9PYAAAAAA 1433728673')
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[-1][-1]
self.assertEqual(hookdata, {'target': '9PYAAAAAA', 'ts': 1433728673}) self.assertEqual(hookdata, {'target': '9PYAAAAAA', 'ts': 1433728673, 'oldnick': 'Derp_'})
self.assertEqual('9PYAAAAAA', self.irc.users['9PYAAAAAA'].nick) self.assertEqual('9PYAAAAAA', self.irc.users['9PYAAAAAA'].nick)
def testInviteHook(self): def testHandleInvite(self):
utils.add_hook(self.irc.dummyhook, 'INVITE')
self.irc.run(':10XAAAAAA INVITE 9PYAAAAAA #blah 0') self.irc.run(':10XAAAAAA INVITE 9PYAAAAAA #blah 0')
hookdata = self.irc.takeHooks()[0] hookdata = self.irc.takeHooks()[-1][-1]
del hookdata['ts'] del hookdata['ts']
self.assertEqual(hookdata, {'target': '9PYAAAAAA', 'channel': '#blah'}) self.assertEqual(hookdata, {'target': '9PYAAAAAA', 'channel': '#blah'})

96
tests/tests_common.py Normal file
View File

@ -0,0 +1,96 @@
import sys
import os
sys.path += [os.getcwd(), os.path.join(os.getcwd(), 'protocols')]
import unittest
import world
import classes
world.started.set()
class PluginTestCase(unittest.TestCase):
def setUp(self):
self.irc = classes.FakeIRC('unittest', world.testing)
self.proto = self.irc.proto
self.irc.connect()
self.sdata = self.irc.serverdata
self.u = self.irc.pseudoclient.uid
self.maxDiff = None
# Dummy servers/users used in tests below.
self.proto.spawnServer(self.irc, 'whatever.', sid='10X')
for x in range(3):
self.proto.spawnClient(self.irc, 'user%s' % x, server='10X')
class CommonProtoTestCase(PluginTestCase):
def testJoinClient(self):
u = self.u
self.proto.joinClient(self.irc, u, '#Channel')
self.assertIn(u, self.irc.channels['#channel'].users)
# Non-existant user.
self.assertRaises(LookupError, self.proto.joinClient, self.irc, '9PYZZZZZZ', '#test')
def testKickClient(self):
target = self.proto.spawnClient(self.irc, 'soccerball', 'soccerball', 'abcd').uid
self.proto.joinClient(self.irc, target, '#pylink')
self.assertIn(self.u, self.irc.channels['#pylink'].users)
self.assertIn(target, self.irc.channels['#pylink'].users)
self.proto.kickClient(self.irc, self.u, '#pylink', target, 'Pow!')
self.assertNotIn(target, self.irc.channels['#pylink'].users)
def testModeClient(self):
testuser = self.proto.spawnClient(self.irc, 'testcakes')
self.irc.takeMsgs()
self.proto.modeClient(self.irc, self.u, testuser.uid, [('+i', None), ('+w', None)])
self.assertEqual({('i', None), ('w', None)}, testuser.modes)
self.proto.modeClient(self.irc, self.u, '#pylink', [('+s', None), ('+l', '30')])
self.assertEqual({('s', None), ('l', '30')}, self.irc.channels['#pylink'].modes)
cmds = self.irc.takeCommands(self.irc.takeMsgs())
self.assertEqual(cmds, ['MODE', 'FMODE'])
def testNickClient(self):
self.proto.nickClient(self.irc, self.u, 'NotPyLink')
self.assertEqual('NotPyLink', self.irc.users[self.u].nick)
def testPartClient(self):
u = self.u
self.proto.joinClient(self.irc, u, '#channel')
self.proto.partClient(self.irc, u, '#channel')
self.assertNotIn(u, self.irc.channels['#channel'].users)
def testQuitClient(self):
u = self.proto.spawnClient(self.irc, 'testuser3', 'moo', 'hello.world').uid
self.proto.joinClient(self.irc, u, '#channel')
self.assertRaises(LookupError, self.proto.quitClient, self.irc, '9PYZZZZZZ', 'quit reason')
self.proto.quitClient(self.irc, u, 'quit reason')
self.assertNotIn(u, self.irc.channels['#channel'].users)
self.assertNotIn(u, self.irc.users)
self.assertNotIn(u, self.irc.servers[self.irc.sid].users)
def testSpawnClient(self):
u = self.proto.spawnClient(self.irc, 'testuser3', 'moo', 'hello.world').uid
# Check the server index and the user index
self.assertIn(u, self.irc.servers[self.irc.sid].users)
self.assertIn(u, self.irc.users)
# Raise ValueError when trying to spawn a client on a server that's not ours
self.assertRaises(ValueError, self.proto.spawnClient, self.irc, 'abcd', 'user', 'dummy.user.net', server='44A')
# Unfilled args should get placeholder fields and not error.
self.proto.spawnClient(self.irc, 'testuser4')
def testSpawnClientOnServer(self):
self.proto.spawnServer(self.irc, 'subserver.pylink', '34Q')
u = self.proto.spawnClient(self.irc, 'person1', 'person', 'users.overdrive.pw', server='34Q')
# We're spawning clients on the right server, hopefully...
self.assertIn(u.uid, self.irc.servers['34Q'].users)
self.assertNotIn(u.uid, self.irc.servers[self.irc.sid].users)
def testSpawnServer(self):
# Incorrect SID length
self.assertRaises(Exception, self.proto.spawnServer, self.irc, 'subserver.pylink', '34Q0')
self.proto.spawnServer(self.irc, 'subserver.pylink', '34Q')
# Duplicate server name
self.assertRaises(Exception, self.proto.spawnServer, self.irc, 'Subserver.PyLink', '34Z')
# Duplicate SID
self.assertRaises(Exception, self.proto.spawnServer, self.irc, 'another.Subserver.PyLink', '34Q')
self.assertIn('34Q', self.irc.servers)