Add Python 3 support.

This commit is contained in:
Valentin Lorentz 2017-05-25 09:55:13 +02:00
parent 0d14a005fe
commit 21e34db417
3 changed files with 51 additions and 24 deletions

View File

@ -34,6 +34,8 @@ Listen for data on a TCP port and forward to designated channel(s).
# pylint: disable=C0103 # pylint: disable=C0103
from imp import reload
import supybot import supybot
import supybot.world as world import supybot.world as world

View File

@ -49,6 +49,7 @@ import crypt
import multiprocessing import multiprocessing
import pickle import pickle
import random import random
import sys
import time import time
from twisted.internet import reactor, protocol from twisted.internet import reactor, protocol
@ -62,7 +63,7 @@ from supybot.commands import commalist
from supybot.commands import threading from supybot.commands import threading
from supybot.commands import wrap from supybot.commands import wrap
import config from . import config
_HELP_URL = "https://github.com/leamas/supybot-irccat" _HELP_URL = "https://github.com/leamas/supybot-irccat"
@ -150,7 +151,7 @@ class _Config(object):
def _dump(self): def _dump(self):
''' Update persistent data.''' ''' Update persistent data.'''
pickle.dump(self._data, open(self._path, 'w')) pickle.dump(self._data, open(self._path, 'wb'))
def get(self, section_name): def get(self, section_name):
''' Return (password, channels) tuple or raise KeyError. ''' ''' Return (password, channels) tuple or raise KeyError. '''
@ -175,7 +176,7 @@ class _Config(object):
class IrccatProtocol(basic.LineOnlyReceiver): class IrccatProtocol(basic.LineOnlyReceiver):
''' Line protocol: parse line, forward to channel(s). ''' ''' Line protocol: parse line, forward to channel(s). '''
delimiter = '\n' delimiter = b'\n'
def __init__(self, config_, blacklist, msg_conn): def __init__(self, config_, blacklist, msg_conn):
self.config = config_ self.config = config_
@ -204,6 +205,13 @@ class IrccatProtocol(basic.LineOnlyReceiver):
self.msg_conn.send((what, ['#test'])) self.msg_conn.send((what, ['#test']))
self.blacklist.register(self.peer.host, False) self.blacklist.register(self.peer.host, False)
try:
if sys.version_info[0] >= 3:
text = text.decode()
except UnicodeDecodeError:
warning('Invalid encoding: ' + repr(text))
return
try: try:
section, cleartext_pw, data = text.split(';', 2) section, cleartext_pw, data = text.split(';', 2)
except ValueError: except ValueError:

59
test.py
View File

@ -39,13 +39,15 @@
import os import os
import os.path import os.path
import socket
import subprocess import subprocess
from supybot.test import * from supybot.test import *
import config from . import config
import plugin as irccat from . import plugin as irccat
CLIENT = os.path.join(os.path.dirname(__file__), 'irccat')
def clear_sections(testcase): def clear_sections(testcase):
if os.path.exists('test-sections.pickle'): if os.path.exists('test-sections.pickle'):
@ -53,6 +55,24 @@ def clear_sections(testcase):
config.global_option('sectionspath').setValue('test-sections.pickle') config.global_option('sectionspath').setValue('test-sections.pickle')
config.global_option('port').setValue(23456) config.global_option('port').setValue(23456)
def communicate(msg, sendonly):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
s.connect(('localhost', 23456))
s.sendall(msg)
if not sendonly:
data = []
try:
data.append([s.recv(1024)])
while data[-1]:
data.append(s.recv(1024))
except socket.timeout:
pass
return b''.join(data)
finally:
s.close()
class IrccatTestList(PluginTestCase): class IrccatTestList(PluginTestCase):
plugins = ('Irccat', 'User') plugins = ('Irccat', 'User')
@ -71,7 +91,6 @@ class IrccatTestList(PluginTestCase):
class IrccatTestCopy(ChannelPluginTestCase): class IrccatTestCopy(ChannelPluginTestCase):
plugins = ('Irccat', 'User') plugins = ('Irccat', 'User')
channel = '#test' channel = '#test'
cmd_tmpl = "echo '%s' | nc --send-only localhost 23456"
def setUp(self, nick='test'): # pylint: disable=W0221 def setUp(self, nick='test'): # pylint: disable=W0221
clear_sections(self) clear_sections(self)
@ -81,24 +100,21 @@ class IrccatTestCopy(ChannelPluginTestCase):
self.assertNotError('sectiondata ivar ivarpw #test', private = True) self.assertNotError('sectiondata ivar ivarpw #test', private = True)
def testCopy(self): def testCopy(self):
cmd = self.cmd_tmpl % 'ivar;ivarpw;ivar data' communicate(b'ivar;ivarpw;ivar data\n', sendonly=True)
subprocess.check_call(cmd, shell = True)
result = self.getMsg(' ') result = self.getMsg(' ')
self.assertIsNot(result, None)
self.assertEqual(result.args[1], 'ivar data') self.assertEqual(result.args[1], 'ivar data')
def testBadFormat(self): def testBadFormat(self):
cmd = self.cmd_tmpl % 'ivar;ivarpw data' communicate(b'ivar;ivarpw data\n', sendonly=True)
subprocess.check_call(cmd, shell = True)
self.assertRegexp(' ', 'Illegal format.*') self.assertRegexp(' ', 'Illegal format.*')
def testBadPw(self): def testBadPw(self):
cmd = self.cmd_tmpl % 'ivar;ivarpw22;ivar data' communicate(b'ivar;ivarpw22;ivar data\n', sendonly=True)
subprocess.check_call(cmd, shell = True)
self.assertRegexp(' ', 'Bad password.*') self.assertRegexp(' ', 'Bad password.*')
def testBadSection(self): def testBadSection(self):
cmd = self.cmd_tmpl % 'ivaru22;ivarpw22;ivar data' communicate(b'ivaru22;ivarpw22;ivar data\n', sendonly=True)
subprocess.check_call(cmd, shell = True)
self.assertRegexp(' ', 'No such section.*') self.assertRegexp(' ', 'No such section.*')
@ -115,28 +131,28 @@ class IrccatTestIrccat(ChannelPluginTestCase):
self.assertNotError('sectiondata ivar ivarpw #test', private = True) self.assertNotError('sectiondata ivar ivarpw #test', private = True)
def testIrccatEnvPw(self): def testIrccatEnvPw(self):
cmd = 'IRCCAT_PASSWORD=ivarpw plugins/Irccat/irccat' \ cmd = 'IRCCAT_PASSWORD=ivarpw %s' \
' localhost 23456 ivar ivar data' ' localhost 23456 ivar ivar data'
subprocess.check_call(cmd, shell = True) subprocess.check_call(cmd % CLIENT, shell = True)
self.assertResponse(' ', 'ivar data') self.assertResponse(' ', 'ivar data')
def testIrccatStdinPw(self): def testIrccatStdinPw(self):
cmd = 'plugins/Irccat/irccat -s localhost 23456 ivar ivar data' cmd = '%s -s localhost 23456 ivar ivar data'
p = subprocess.Popen(cmd, shell = True, stdin = subprocess.PIPE) p = subprocess.Popen(cmd % CLIENT, shell = True, stdin = subprocess.PIPE)
p.communicate('ivarpw\n') p.communicate(b'ivarpw\n')
self.assertResponse(' ', 'ivar data') self.assertResponse(' ', 'ivar data')
def testIrccatBadCmdline(self): def testIrccatBadCmdline(self):
cmd = 'IRCCAT_PASSWORD=ivarpw plugins/Irccat/irccat' \ cmd = 'IRCCAT_PASSWORD=ivarpw %s' \
' localhost 23456' ' localhost 23456'
with self.assertRaises(subprocess.CalledProcessError): with self.assertRaises(subprocess.CalledProcessError):
subprocess.check_output(cmd, shell = True) subprocess.check_output(cmd % CLIENT, shell = True)
def testIrccatBadPort(self): def testIrccatBadPort(self):
cmd = 'IRCCAT_PASSWORD=ivarpw plugins/Irccat/irccat' \ cmd = 'IRCCAT_PASSWORD=ivarpw %s' \
' localhost 23456xx ivar ivar data' ' localhost 23456xx ivar ivar data'
with self.assertRaises(subprocess.CalledProcessError): with self.assertRaises(subprocess.CalledProcessError):
subprocess.check_output(cmd, shell = True) subprocess.check_output(cmd % CLIENT, shell = True)
class IrccatTestData(PluginTestCase): class IrccatTestData(PluginTestCase):
@ -150,7 +166,8 @@ class IrccatTestData(PluginTestCase):
self.assertNotError('sectiondata yngve yngve #al-bot-test') self.assertNotError('sectiondata yngve yngve #al-bot-test')
def testList(self): def testList(self):
self.assertResponse('sectionlist', 'yngve ivar') m = self._feedMsg('sectionlist')
self.assertIn(m.args[1], ('yngve ivar', 'ivar yngve'))
def testReload(self): def testReload(self):
self.assertResponse('reload Irccat', 'The operation succeeded.') self.assertResponse('reload Irccat', 'The operation succeeded.')