Initial commit.
This commit is contained in:
32
mail/spamassassin/pyzor-0.7.0/tests/unit/__init__.py
Normal file
32
mail/spamassassin/pyzor-0.7.0/tests/unit/__init__.py
Normal file
@@ -0,0 +1,32 @@
|
||||
"""A suite of unit tests that verifies the correct behaviour of various
|
||||
functions/methods in the pyzord code.
|
||||
|
||||
Note these tests the source of pyzor, not the version currently installed.
|
||||
"""
|
||||
|
||||
import unittest
|
||||
|
||||
import test_gdbm
|
||||
import test_mysql
|
||||
import test_redis
|
||||
import test_client
|
||||
import test_digest
|
||||
import test_server
|
||||
import test_account
|
||||
|
||||
def suite():
|
||||
"""Gather all the tests from this package in a test suite."""
|
||||
test_suite = unittest.TestSuite()
|
||||
|
||||
test_suite.addTest(test_gdbm.suite())
|
||||
test_suite.addTest(test_mysql.suite())
|
||||
test_suite.addTest(test_redis.suite())
|
||||
test_suite.addTest(test_client.suite())
|
||||
test_suite.addTest(test_digest.suite())
|
||||
test_suite.addTest(test_server.suite())
|
||||
test_suite.addTest(test_account.suite())
|
||||
return test_suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
139
mail/spamassassin/pyzor-0.7.0/tests/unit/test_account.py
Normal file
139
mail/spamassassin/pyzor-0.7.0/tests/unit/test_account.py
Normal file
@@ -0,0 +1,139 @@
|
||||
"""Test the pyzor.account module
|
||||
"""
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import email
|
||||
import hashlib
|
||||
import unittest
|
||||
import StringIO
|
||||
|
||||
import pyzor
|
||||
import pyzor.config
|
||||
import pyzor.account
|
||||
|
||||
class AccountTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
self.timestamp = 1381219396
|
||||
self.msg = email.message_from_string("")
|
||||
self.msg["Op"] = "ping"
|
||||
self.msg["Thread"] = "14941"
|
||||
self.msg["PV"] = "2.1"
|
||||
self.msg["User"] = "anonymous"
|
||||
self.msg["Time"] = str(self.timestamp)
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
|
||||
def test_sign_msg(self):
|
||||
"""Test the sign message function"""
|
||||
hashed_key = hashlib.sha1(b"test_key").hexdigest()
|
||||
expected = "2ab1bad2aae6fd80c656a896c82eef0ec1ec38a0"
|
||||
result = pyzor.account.sign_msg(hashed_key, self.timestamp, self.msg)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_hash_key(self):
|
||||
"""Test the hash key function"""
|
||||
user = "testuser"
|
||||
key = "testkey"
|
||||
expected = "0957bd79b58263657127a39762879098286d8477"
|
||||
result = pyzor.account.hash_key(key, user)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_verify_signature(self):
|
||||
"""Test the verify signature function"""
|
||||
def mock_sm(h, t, m):
|
||||
return "testsig"
|
||||
real_sm = pyzor.account.sign_msg
|
||||
pyzor.account.sign_msg = mock_sm
|
||||
try:
|
||||
self.msg["Sig"] = "testsig"
|
||||
del self.msg["Time"]
|
||||
self.msg["Time"] = str(int(time.time()))
|
||||
pyzor.account.verify_signature(self.msg, "testkey")
|
||||
finally:
|
||||
pyzor.account.sign_msg = real_sm
|
||||
|
||||
def test_verify_signature_old_timestamp(self):
|
||||
"""Test the verify signature with old timestamp"""
|
||||
def mock_sm(h, t, m):
|
||||
return "testsig"
|
||||
real_sm = pyzor.account.sign_msg
|
||||
pyzor.account.sign_msg = mock_sm
|
||||
try:
|
||||
self.msg["Sig"] = "testsig"
|
||||
self.assertRaises(pyzor.SignatureError, pyzor.account.verify_signature, self.msg, "testkey")
|
||||
finally:
|
||||
pyzor.account.sign_msg = real_sm
|
||||
|
||||
def test_verify_signature_bad_signature(self):
|
||||
"""Test the verify signature with invalid signature"""
|
||||
def mock_sm(h, t, m):
|
||||
return "testsig"
|
||||
real_sm = pyzor.account.sign_msg
|
||||
pyzor.account.sign_msg = mock_sm
|
||||
try:
|
||||
self.msg["Sig"] = "testsig-bad"
|
||||
del self.msg["Time"]
|
||||
self.msg["Time"] = str(int(time.time()))
|
||||
self.assertRaises(pyzor.SignatureError, pyzor.account.verify_signature, self.msg, "testkey")
|
||||
finally:
|
||||
pyzor.account.sign_msg = real_sm
|
||||
|
||||
class LoadAccountTest(unittest.TestCase):
|
||||
"""Tests for the load_accounts function"""
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
|
||||
self.real_exists = os.path.exists
|
||||
os.path.exists = lambda p: True
|
||||
self.mock_file = StringIO.StringIO()
|
||||
self.real_open = pyzor.account.__builtins__["open"]
|
||||
def mock_open(path, mode="r", buffering=-1):
|
||||
if path == "test_file":
|
||||
self.mock_file.seek(0)
|
||||
return self.mock_file
|
||||
else:
|
||||
return self.real_open(path, mode, buffering)
|
||||
pyzor.account.__builtins__["open"] = mock_open
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
os.path.exists = self.real_exists
|
||||
pyzor.account.__builtins__["open"] = self.real_open
|
||||
|
||||
def test_load_accounts(self):
|
||||
"""Test loading the account file"""
|
||||
self.mock_file.write("public.pyzor.org : 24441 : test : 123abc,cba321\n"
|
||||
"public2.pyzor.org : 24441 : test2 : 123abc,cba321")
|
||||
result = pyzor.config.load_accounts("test_file")
|
||||
self.assertIn(("public.pyzor.org", 24441), result)
|
||||
self.assertIn(("public2.pyzor.org", 24441), result)
|
||||
account = result[("public.pyzor.org", 24441)]
|
||||
self.assertEqual((account.username, account.salt, account.key),
|
||||
("test", "123abc", "cba321"))
|
||||
account = result[("public2.pyzor.org", 24441)]
|
||||
self.assertEqual((account.username, account.salt, account.key),
|
||||
("test2", "123abc", "cba321"))
|
||||
|
||||
def test_load_accounts_comment(self):
|
||||
"""Test skipping commented lines"""
|
||||
self.mock_file.write("#public1.pyzor.org : 24441 : test : 123abc,cba321")
|
||||
result = pyzor.config.load_accounts("test_file")
|
||||
self.assertNotIn(("public.pyzor.org", 24441), result)
|
||||
self.assertFalse(result)
|
||||
|
||||
def suite():
|
||||
"""Gather all the tests from this module in a test suite."""
|
||||
test_suite = unittest.TestSuite()
|
||||
test_suite.addTest(unittest.makeSuite(AccountTest))
|
||||
test_suite.addTest(unittest.makeSuite(LoadAccountTest))
|
||||
return test_suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
|
||||
|
||||
168
mail/spamassassin/pyzor-0.7.0/tests/unit/test_client.py
Normal file
168
mail/spamassassin/pyzor-0.7.0/tests/unit/test_client.py
Normal file
@@ -0,0 +1,168 @@
|
||||
import sys
|
||||
import time
|
||||
import socket
|
||||
import unittest
|
||||
|
||||
import pyzor
|
||||
import pyzor.client
|
||||
import pyzor.account
|
||||
import pyzor.message
|
||||
|
||||
def make_MockSocket(response, request):
|
||||
"""Create a MockSocket class that will append requests to
|
||||
the specified `request` list and return the specified `response`
|
||||
"""
|
||||
class MockSocket():
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
def settimeout(self, timeout):
|
||||
pass
|
||||
def recvfrom(self, packetsize):
|
||||
return response, ("127.0.0.1", 24441)
|
||||
def sendto(self, data, flag, address):
|
||||
request.append(data)
|
||||
return MockSocket
|
||||
|
||||
def make_MockThreadId(thread):
|
||||
"""Creates a MockThreadId class that will generate
|
||||
the specified thread number.
|
||||
"""
|
||||
class MockThreadId(int):
|
||||
def __new__(cls, i):
|
||||
return int.__new__(cls, i)
|
||||
@classmethod
|
||||
def generate(cls):
|
||||
return thread
|
||||
|
||||
def in_ok_range(self):
|
||||
return True
|
||||
return MockThreadId
|
||||
|
||||
def mock_sign_msg(hash_key, timestamp, msg):
|
||||
return "TestSig"
|
||||
|
||||
def mock_hash_key(user_key, user):
|
||||
return None
|
||||
|
||||
class ClientTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
self.real_sg = pyzor.account.sign_msg
|
||||
pyzor.account.sign_msg = mock_sign_msg
|
||||
self.real_hk = pyzor.account.hash_key
|
||||
pyzor.account.hash_key = mock_hash_key
|
||||
self.thread = 33715
|
||||
|
||||
# the response the mock socket will send
|
||||
self.response = "Code: 200\nDiag: OK\nPV: 2.1\nThread: 33715\n\n"
|
||||
# the requests send by the client will be stored here
|
||||
self.request = []
|
||||
# the expected request that the client should send
|
||||
self.expected = {"Thread": str(self.thread),
|
||||
"PV": str(pyzor.proto_version),
|
||||
"User": "anonymous",
|
||||
"Time": str(int(time.time())),
|
||||
"Sig": "TestSig"}
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
pyzor.account.sign_msg = self.real_sg
|
||||
pyzor.account.hash_key = self.real_hk
|
||||
|
||||
def check_request(self, request):
|
||||
"""Check if the request sent by the client is equal
|
||||
to the expected one.
|
||||
"""
|
||||
req = {}
|
||||
request = request.decode("utf8").replace("\n\n", "\n")
|
||||
for line in request.splitlines():
|
||||
key = line.split(":")[0].strip()
|
||||
value = line.split(":")[1].strip()
|
||||
req[key] = value
|
||||
self.assertEqual(req, self.expected)
|
||||
|
||||
def check_client(self, accounts, method, *args, **kwargs):
|
||||
"""Tests if the request and response are sent
|
||||
and read correctly by the client.
|
||||
"""
|
||||
real_socket = socket.socket
|
||||
socket.socket = make_MockSocket(self.response.encode("utf8"),
|
||||
self.request)
|
||||
|
||||
real_ThreadId = pyzor.message.ThreadId
|
||||
pyzor.message.ThreadId = make_MockThreadId(self.thread)
|
||||
client = pyzor.client.Client(accounts)
|
||||
try:
|
||||
response = getattr(client, method)(*args, **kwargs)
|
||||
self.assertEqual(str(response), self.response)
|
||||
self.check_request(self.request[0])
|
||||
finally:
|
||||
socket.socket = real_socket
|
||||
pyzor.message.ThreadId = real_ThreadId
|
||||
return client
|
||||
|
||||
def test_ping(self):
|
||||
"""Test the client ping request"""
|
||||
self.expected["Op"] = "ping"
|
||||
self.check_client(None, "ping")
|
||||
|
||||
def test_pong(self):
|
||||
"""Test the client pong request"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
self.expected["Op"] = "pong"
|
||||
self.expected["Op-Digest"] = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
self.check_client(None, "pong", digest)
|
||||
|
||||
def test_check(self):
|
||||
"""Test the client check request"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
self.expected["Op"] = "check"
|
||||
self.expected["Op-Digest"] = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
self.check_client(None, "check", digest)
|
||||
|
||||
def test_info(self):
|
||||
"""Test the client info request"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
self.expected["Op"] = "info"
|
||||
self.expected["Op-Digest"] = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
self.check_client(None, "info", digest)
|
||||
|
||||
def test_report(self):
|
||||
"""Test the client report request"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
self.expected["Op"] = "report"
|
||||
self.expected["Op-Digest"] = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
self.expected["Op-Spec"] = "20,3,60,3"
|
||||
self.check_client(None, "report", digest)
|
||||
|
||||
def test_whitelist(self):
|
||||
"""Test the client whitelist request"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
self.expected["Op"] = "whitelist"
|
||||
self.expected["Op-Digest"] = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
self.expected["Op-Spec"] = "20,3,60,3"
|
||||
self.check_client(None, "whitelist", digest)
|
||||
|
||||
def test_handle_account(self):
|
||||
"""Test client handling accounts"""
|
||||
test_account = pyzor.account.Account("TestUser", "TestKey", "TestSalt")
|
||||
self.expected["Op"] = "ping"
|
||||
self.expected["User"] = "TestUser"
|
||||
self.check_client({("public.pyzor.org", 24441): test_account}, "ping")
|
||||
|
||||
def test_handle_invalid_thread(self):
|
||||
"""Test invalid thread id"""
|
||||
self.thread += 20
|
||||
self.expected["Op"] = "ping"
|
||||
self.assertRaises(pyzor.ProtocolError, self.check_client, None, "ping")
|
||||
|
||||
def suite():
|
||||
"""Gather all the tests from this module in a test suite."""
|
||||
test_suite = unittest.TestSuite()
|
||||
test_suite.addTest(unittest.makeSuite(ClientTest))
|
||||
return test_suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
200
mail/spamassassin/pyzor-0.7.0/tests/unit/test_digest.py
Normal file
200
mail/spamassassin/pyzor-0.7.0/tests/unit/test_digest.py
Normal file
@@ -0,0 +1,200 @@
|
||||
"""The the pyzor.digest module
|
||||
"""
|
||||
|
||||
import sys
|
||||
import hashlib
|
||||
import unittest
|
||||
|
||||
from pyzor.digest import *
|
||||
|
||||
HTML_TEXT = """<html><head><title>Email spam</title></head><body>
|
||||
<p><b>Email spam</b>, also known as <b>junk email</b>
|
||||
or <b>unsolicited bulk email</b> (<i>UBE</i>), is a subset of
|
||||
<a href="/wiki/Spam_(electronic)" title="Spam (electronic)">electronic spam</a>
|
||||
involving nearly identical messages sent to numerous recipients by <a href="/wiki/Email" title="Email">
|
||||
email</a>. Clicking on <a href="/wiki/Html_email#Security_vulnerabilities" title="Html email" class="mw-redirect">
|
||||
links in spam email</a> may send users to <a href="/wiki/Phishing" title="Phishing">phishing</a>
|
||||
web sites or sites that are hosting <a href="/wiki/Malware" title="Malware">malware</a>.</body></html>"""
|
||||
|
||||
HTML_TEXT_STRIPED = 'Email spam Email spam , also known as junk email or unsolicited bulk email ( UBE ),'\
|
||||
' is a subset of electronic spam involving nearly identical messages sent to numerous recipients by email'\
|
||||
' . Clicking on links in spam email may send users to phishing web sites or sites that are hosting malware .'
|
||||
|
||||
class HTMLStripperTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
self.data = []
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
|
||||
def test_HTMLStripper(self):
|
||||
stripper = HTMLStripper(self.data)
|
||||
stripper.feed(HTML_TEXT)
|
||||
res = " ".join(self.data)
|
||||
self.assertEqual(res, HTML_TEXT_STRIPED)
|
||||
|
||||
|
||||
class PreDigestTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
self.lines = []
|
||||
|
||||
def mock_digest_paylods(c, message):
|
||||
yield message.decode("utf8")
|
||||
|
||||
def mock_handle_line(s, line):
|
||||
self.lines.append(line.decode("utf8"))
|
||||
|
||||
self.real_digest_payloads = DataDigester.digest_payloads
|
||||
self.real_handle_line = DataDigester.handle_line
|
||||
DataDigester.digest_payloads = mock_digest_paylods
|
||||
DataDigester.handle_line = mock_handle_line
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
DataDigester.digest_payloads = self.real_digest_payloads
|
||||
DataDigester.handle_line = self.real_handle_line
|
||||
|
||||
|
||||
def test_predigest_emails(self):
|
||||
"""Test email removal in the predigest process"""
|
||||
real_longstr = DataDigester.longstr_ptrn
|
||||
DataDigester.longstr_ptrn = re.compile(r'\S{100,}')
|
||||
emails = ["test@example.com",
|
||||
"test123@example.com",
|
||||
"test+abc@example.com",
|
||||
"test.test2@example.com",
|
||||
"test.test2+abc@example.com", ]
|
||||
message = "Test %s Test2"
|
||||
expected = "TestTest2"
|
||||
try:
|
||||
for email in emails:
|
||||
self.lines = []
|
||||
DataDigester((message % email).encode("utf8"))
|
||||
self.assertEqual(self.lines[0], expected)
|
||||
finally:
|
||||
DataDigester.longstr_ptrn = real_longstr
|
||||
|
||||
# XXX This fails
|
||||
# def test_predigest_emails_whitespace(self):
|
||||
# real_longstr = DataDigester.longstr_ptrn
|
||||
# DataDigester.longstr_ptrn = re.compile(r'\S{100,}')
|
||||
# emails = ["chirila@example. com",
|
||||
# "chirila@example . com",
|
||||
# "chirila @example. com",
|
||||
# "chirila@ example. com",
|
||||
# "chirila @example . com",
|
||||
# "chirila @ example. com",
|
||||
# "chirila @ example . com",]
|
||||
# message = "Test %s Test2"
|
||||
# expected = "TestTest2"
|
||||
# try:
|
||||
# for email in emails:
|
||||
# self.lines = []
|
||||
# DataDigester(message % email)
|
||||
# self.assertEqual(self.lines[0], expected)
|
||||
# finally:
|
||||
# DataDigester.longstr_ptrn = real_longstr
|
||||
|
||||
|
||||
def test_predigest_urls(self):
|
||||
"""Test url removal in the predigest process"""
|
||||
real_longstr = DataDigester.longstr_ptrn
|
||||
DataDigester.longstr_ptrn = re.compile(r'\S{100,}')
|
||||
urls = ["http://www.example.com",
|
||||
# "www.example.com", # XXX This also fail
|
||||
"http://example.com",
|
||||
# "example.com", # XXX This also fails
|
||||
"http://www.example.com/test/"
|
||||
"http://www.example.com/test/test2", ]
|
||||
message = "Test %s Test2"
|
||||
expected = "TestTest2"
|
||||
try:
|
||||
for url in urls:
|
||||
self.lines = []
|
||||
DataDigester((message % url).encode("utf8"))
|
||||
self.assertEqual(self.lines[0], expected)
|
||||
finally:
|
||||
DataDigester.longstr_ptrn = real_longstr
|
||||
|
||||
def test_predigest_long(self):
|
||||
"""Test long "words" removal in the predigest process"""
|
||||
strings = ["0A2D3f%a#S",
|
||||
"3sddkf9jdkd9",
|
||||
"@@#@@@@@@@@@"]
|
||||
message = "Test %s Test2"
|
||||
expected = "TestTest2"
|
||||
for string in strings:
|
||||
self.lines = []
|
||||
DataDigester((message % string).encode("utf8"))
|
||||
self.assertEqual(self.lines[0], expected)
|
||||
|
||||
def test_predigest_min_line_lenght(self):
|
||||
"""Test small lines removal in the predigest process"""
|
||||
message = "This line is included\n"\
|
||||
"not this\n"\
|
||||
"This also"
|
||||
expected = ["Thislineisincluded", "Thisalso"]
|
||||
DataDigester(message.encode("utf8"))
|
||||
self.assertEqual(self.lines, expected)
|
||||
|
||||
def test_predigest_atomic(self):
|
||||
"""Test atomic messages (lines <= 4) in the predigest process"""
|
||||
message = "All this message\nShould be included\nIn the predigest"
|
||||
expected = ["Allthismessage", "Shouldbeincluded", "Inthepredigest"]
|
||||
DataDigester(message.encode("utf8"))
|
||||
self.assertEqual(self.lines, expected)
|
||||
|
||||
def test_predigest_pieced(self):
|
||||
"""Test pieced messages (lines > 4) in the predigest process"""
|
||||
message = ""
|
||||
for i in range(100):
|
||||
message += "Line%d test test test\n" % i
|
||||
expected = []
|
||||
for i in [20, 21, 22, 60, 61, 62]:
|
||||
expected.append("Line%dtesttesttest" % i)
|
||||
DataDigester(message.encode("utf8"))
|
||||
self.assertEqual(self.lines, expected)
|
||||
|
||||
class DigestTests(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
self.lines = []
|
||||
|
||||
def mock_digest_paylods(c, message):
|
||||
yield message.decode("utf8")
|
||||
|
||||
self.real_digest_payloads = DataDigester.digest_payloads
|
||||
DataDigester.digest_payloads = mock_digest_paylods
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
DataDigester.digest_payloads = self.real_digest_payloads
|
||||
|
||||
def test_digest(self):
|
||||
message = b"That's some good ham right there"
|
||||
predigested = b"That'ssomegoodhamrightthere"
|
||||
|
||||
digest = hashlib.sha1()
|
||||
digest.update(predigested)
|
||||
|
||||
expected = digest.hexdigest()
|
||||
result = DataDigester(message).value
|
||||
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def suite():
|
||||
"""Gather all the tests from this module in a test suite."""
|
||||
test_suite = unittest.TestSuite()
|
||||
test_suite.addTest(unittest.makeSuite(HTMLStripperTests))
|
||||
test_suite.addTest(unittest.makeSuite(PreDigestTests))
|
||||
test_suite.addTest(unittest.makeSuite(DigestTests))
|
||||
return test_suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
153
mail/spamassassin/pyzor-0.7.0/tests/unit/test_gdbm.py
Normal file
153
mail/spamassassin/pyzor-0.7.0/tests/unit/test_gdbm.py
Normal file
@@ -0,0 +1,153 @@
|
||||
"""Test the pyzor.engines.gdbm_ module."""
|
||||
|
||||
import gdbm
|
||||
import unittest
|
||||
import threading
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pyzor.engines
|
||||
import pyzor.engines.gdbm_
|
||||
import pyzor.engines.common
|
||||
|
||||
class MockTimer():
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
def start(self):
|
||||
pass
|
||||
def setDaemon(self, daemon):
|
||||
pass
|
||||
|
||||
class MockGdbm(dict):
|
||||
"""Mock a gdbm database"""
|
||||
|
||||
def firstkey(self):
|
||||
if not self.keys():
|
||||
return None
|
||||
self.key_index = 1
|
||||
return self.keys()[0]
|
||||
|
||||
def nextkey(self, key):
|
||||
if len(self.keys()) <= self.key_index:
|
||||
return None
|
||||
else:
|
||||
self.key_index += 1
|
||||
return self.keys()[self.key_index]
|
||||
|
||||
def sync(self):
|
||||
pass
|
||||
def reorganize(self):
|
||||
pass
|
||||
|
||||
class GdbmTest(unittest.TestCase):
|
||||
"""Test the GdbmDBHandle class"""
|
||||
|
||||
max_age = 60 * 60 * 24 * 30 * 4
|
||||
r_count = 24
|
||||
wl_count = 42
|
||||
entered = datetime.now() - timedelta(days=10)
|
||||
updated = datetime.now() - timedelta(days=2)
|
||||
wl_entered = datetime.now() - timedelta(days=20)
|
||||
wl_updated = datetime.now() - timedelta(days=3)
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
self.real_timer = threading.Timer
|
||||
threading.Timer = MockTimer
|
||||
|
||||
self.db = MockGdbm()
|
||||
def mock_open(fn, mode):
|
||||
return self.db
|
||||
self.real_open = gdbm.open
|
||||
gdbm.open = mock_open
|
||||
|
||||
self.record = pyzor.engines.common.Record(self.r_count, self.wl_count,
|
||||
self.entered, self.updated,
|
||||
self.wl_entered, self.wl_updated)
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
threading.Timer = self.real_timer
|
||||
gdbm.open = self.real_open
|
||||
|
||||
def record_as_str(self, record=None):
|
||||
if not record:
|
||||
record = self.record
|
||||
return ("1,%s,%s,%s,%s,%s,%s" % (record.r_count, record.r_entered,
|
||||
record.r_updated, record.wl_count,
|
||||
record.wl_entered, record.wl_updated)).encode("utf8")
|
||||
|
||||
def test_set_item(self):
|
||||
"""Test GdbmDBHandle.__setitem__"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
|
||||
handle = pyzor.engines.gdbm_.GdbmDBHandle(None, None,
|
||||
max_age=self.max_age)
|
||||
handle[digest] = self.record
|
||||
|
||||
self.assertEqual(self.db[digest], self.record_as_str().decode("utf8"))
|
||||
|
||||
def test_get_item(self):
|
||||
"""Test GdbmDBHandle.__getitem__"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
|
||||
handle = pyzor.engines.gdbm_.GdbmDBHandle(None, None,
|
||||
max_age=self.max_age)
|
||||
self.db[digest] = self.record_as_str()
|
||||
|
||||
result = handle[digest]
|
||||
|
||||
self.assertEqual(self.record_as_str(result), self.record_as_str())
|
||||
|
||||
def test_del_item(self):
|
||||
"""Test GdbmDBHandle.__delitem__"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
handle = pyzor.engines.gdbm_.GdbmDBHandle(None, None,
|
||||
max_age=self.max_age)
|
||||
self.db[digest] = self.record_as_str()
|
||||
|
||||
del handle[digest]
|
||||
|
||||
self.assertFalse(self.db.get(digest))
|
||||
|
||||
def test_reorganize_older(self):
|
||||
"""Test GdbmDBHandle.start_reorganizing with older records"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
|
||||
self.db[digest] = self.record_as_str()
|
||||
handle = pyzor.engines.gdbm_.GdbmDBHandle(None, None,
|
||||
max_age=3600 * 24)
|
||||
|
||||
self.assertFalse(self.db.get(digest))
|
||||
|
||||
def test_reorganize_older_no_max_age(self):
|
||||
"""Test GdbmDBHandle.start_reorganizing with older records, but no
|
||||
max_age set.
|
||||
"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
|
||||
self.db[digest] = self.record_as_str()
|
||||
handle = pyzor.engines.gdbm_.GdbmDBHandle(None, None,
|
||||
max_age=None)
|
||||
|
||||
self.assertEqual(self.db[digest], self.record_as_str())
|
||||
|
||||
def test_reorganize_fresh(self):
|
||||
"""Test GdbmDBHandle.start_reorganizing with newer records"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
|
||||
self.db[digest] = self.record_as_str()
|
||||
handle = pyzor.engines.gdbm_.GdbmDBHandle(None, None,
|
||||
max_age=3600 * 24 * 3)
|
||||
|
||||
self.assertEqual(self.db[digest], self.record_as_str())
|
||||
|
||||
|
||||
def suite():
|
||||
"""Gather all the tests from this module in a test suite."""
|
||||
test_suite = unittest.TestSuite()
|
||||
test_suite.addTest(unittest.makeSuite(GdbmTest))
|
||||
return test_suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
156
mail/spamassassin/pyzor-0.7.0/tests/unit/test_mysql.py
Normal file
156
mail/spamassassin/pyzor-0.7.0/tests/unit/test_mysql.py
Normal file
@@ -0,0 +1,156 @@
|
||||
"""Test the pyzor.engines.mysql module."""
|
||||
|
||||
import unittest
|
||||
import threading
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pyzor.engines
|
||||
import pyzor.engines.mysql
|
||||
import pyzor.engines.common
|
||||
|
||||
class MockTimer():
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
def start(self):
|
||||
pass
|
||||
def setDaemon(self, daemon):
|
||||
pass
|
||||
|
||||
def make_MockMySQL(result, queries):
|
||||
class MockCursor():
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def fetchone(self):
|
||||
return result
|
||||
def fetchall(self):
|
||||
return [result]
|
||||
def execute(self, query, args=None):
|
||||
queries.append((query, args))
|
||||
def close(self):
|
||||
pass
|
||||
class MockDB():
|
||||
def cursor(self):
|
||||
return MockCursor()
|
||||
def close(self):
|
||||
pass
|
||||
def commit(self):
|
||||
pass
|
||||
def autocommit(self, value):
|
||||
pass
|
||||
class MockMysql():
|
||||
@staticmethod
|
||||
def connect(*args, **kwargs):
|
||||
return MockDB()
|
||||
class Error(Exception):
|
||||
pass
|
||||
return MockMysql
|
||||
|
||||
|
||||
class MySQLTest(unittest.TestCase):
|
||||
"""Test the GdbmDBHandle class"""
|
||||
|
||||
max_age = 60 * 60 * 24 * 30 * 4
|
||||
r_count = 24
|
||||
wl_count = 42
|
||||
entered = datetime.now() - timedelta(days=10)
|
||||
updated = datetime.now() - timedelta(days=2)
|
||||
wl_entered = datetime.now() - timedelta(days=20)
|
||||
wl_updated = datetime.now() - timedelta(days=3)
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
self.real_timer = threading.Timer
|
||||
threading.Timer = MockTimer
|
||||
|
||||
self.record = pyzor.engines.common.Record(self.r_count, self.wl_count,
|
||||
self.entered, self.updated,
|
||||
self.wl_entered, self.wl_updated)
|
||||
|
||||
self.response = self.record_unpack()
|
||||
self.queries = []
|
||||
|
||||
mock_MySQL = make_MockMySQL(self.response, self.queries)
|
||||
self.real_mysql = pyzor.engines.mysql.MySQLdb
|
||||
pyzor.engines.mysql.MySQLdb = mock_MySQL
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
threading.Timer = self.real_timer
|
||||
pyzor.engines.mysql.MySQLdb = self.real_mysql
|
||||
|
||||
def record_unpack(self, record=None):
|
||||
if not record:
|
||||
record = self.record
|
||||
return (record.r_count, record.wl_count,
|
||||
record.r_entered, record.r_updated,
|
||||
record.wl_entered, record.wl_updated)
|
||||
|
||||
def test_reconnect(self):
|
||||
"""Test MySQLDBHandle.__init__"""
|
||||
expected = "DELETE FROM testtable WHERE r_updated<%s"
|
||||
|
||||
pyzor.engines.mysql.MySQLDBHandle("testhost,testuser,testpass,testdb,testtable",
|
||||
None, max_age=self.max_age)
|
||||
|
||||
self.assertEqual(self.queries[0][0], expected)
|
||||
|
||||
def test_no_reorganize(self):
|
||||
pyzor.engines.mysql.MySQLDBHandle("testhost,testuser,testpass,testdb,testtable",
|
||||
None, max_age=None)
|
||||
self.assertFalse(self.queries)
|
||||
|
||||
def test_set_item(self):
|
||||
"""Test MySQLDBHandle.__setitem__"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
expected = ("INSERT INTO testtable (digest, r_count, wl_count, "
|
||||
"r_entered, r_updated, wl_entered, wl_updated) "
|
||||
"VALUES (%s, %s, %s, %s, %s, %s, %s) ON "
|
||||
"DUPLICATE KEY UPDATE r_count=%s, wl_count=%s, "
|
||||
"r_entered=%s, r_updated=%s, wl_entered=%s, "
|
||||
"wl_updated=%s",
|
||||
(digest, self.r_count, self.wl_count, self.entered,
|
||||
self.updated, self.wl_entered, self.wl_updated,
|
||||
self.r_count, self.wl_count, self.entered,
|
||||
self.updated, self.wl_entered, self.wl_updated))
|
||||
handle = pyzor.engines.mysql.MySQLDBHandle("testhost,testuser,testpass,testdb,testtable",
|
||||
None, max_age=self.max_age)
|
||||
|
||||
handle[digest] = self.record
|
||||
self.assertEqual(self.queries[1], expected)
|
||||
|
||||
def test_get_item(self):
|
||||
"""Test MySQLDBHandle.__getitem__"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
expected = ("SELECT r_count, wl_count, r_entered, r_updated, "
|
||||
"wl_entered, wl_updated FROM testtable WHERE digest=%s",
|
||||
(digest,))
|
||||
handle = pyzor.engines.mysql.MySQLDBHandle("testhost,testuser,testpass,testdb,testtable",
|
||||
None, max_age=self.max_age)
|
||||
|
||||
result = handle[digest]
|
||||
self.assertEqual(self.queries[1], expected)
|
||||
self.assertEqual(self.record_unpack(result), self.record_unpack())
|
||||
|
||||
def test_del_item(self):
|
||||
"""Test MySQLDBHandle.__detitem__"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
expected = ("DELETE FROM testtable WHERE digest=%s", (digest,))
|
||||
|
||||
handle = pyzor.engines.mysql.MySQLDBHandle("testhost,testuser,testpass,testdb,testtable",
|
||||
None, max_age=self.max_age)
|
||||
del handle[digest]
|
||||
self.assertEqual(self.queries[1], expected)
|
||||
|
||||
|
||||
def suite():
|
||||
"""Gather all the tests from this module in a test suite."""
|
||||
test_suite = unittest.TestSuite()
|
||||
test_suite.addTest(unittest.makeSuite(MySQLTest))
|
||||
return test_suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
188
mail/spamassassin/pyzor-0.7.0/tests/unit/test_redis.py
Normal file
188
mail/spamassassin/pyzor-0.7.0/tests/unit/test_redis.py
Normal file
@@ -0,0 +1,188 @@
|
||||
"""Test the pyzor.engines.gdbm_ module."""
|
||||
|
||||
import unittest
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pyzor.engines
|
||||
import pyzor.engines.redis_
|
||||
import pyzor.engines.common
|
||||
|
||||
|
||||
class EncodingRedisTest(unittest.TestCase):
|
||||
"""Test the RedisDBHandle class"""
|
||||
|
||||
r_count = 24
|
||||
wl_count = 42
|
||||
entered = datetime(2014, 4, 23, 15, 41, 30)
|
||||
updated = datetime(2014, 4, 25, 17, 22, 25)
|
||||
wl_entered = datetime(2014, 2, 12, 11, 10, 55)
|
||||
wl_updated = datetime(2014, 3, 25, 5, 1, 50)
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
|
||||
self.record = pyzor.engines.common.Record(self.r_count, self.wl_count,
|
||||
self.entered, self.updated,
|
||||
self.wl_entered, self.wl_updated)
|
||||
|
||||
def compare_records(self, r1, r2):
|
||||
attrs = ("r_count", "r_entered", "r_updated",
|
||||
"wl_count", "wl_entered", "wl_updated")
|
||||
self.assertTrue(all(getattr(r1, attr) == getattr(r2, attr)
|
||||
for attr in attrs))
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
|
||||
def test_encode_record(self):
|
||||
expected = ("24,2014-04-23 15:41:30,2014-04-25 17:22:25,"
|
||||
"42,2014-02-12 11:10:55,2014-03-25 05:01:50").encode()
|
||||
result = pyzor.engines.redis_.RedisDBHandle._encode_record(self.record)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_encode_record_no_date(self):
|
||||
expected = ("24,2014-04-23 15:41:30,,"
|
||||
"42,2014-02-12 11:10:55,2014-03-25 05:01:50").encode()
|
||||
self.record.r_updated = None
|
||||
result = pyzor.engines.redis_.RedisDBHandle._encode_record(self.record)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_encode_record_no_white(self):
|
||||
expected = ("24,2014-04-23 15:41:30,2014-04-25 17:22:25,"
|
||||
"0,,").encode()
|
||||
self.record.wl_count = 0
|
||||
self.record.wl_entered = None
|
||||
self.record.wl_updated = None
|
||||
result = pyzor.engines.redis_.RedisDBHandle._encode_record(self.record)
|
||||
self.assertEqual(result, expected)
|
||||
|
||||
def test_decode_record(self):
|
||||
encoded = ("24,2014-04-23 15:41:30,2014-04-25 17:22:25,"
|
||||
"42,2014-02-12 11:10:55,2014-03-25 05:01:50").encode()
|
||||
result = pyzor.engines.redis_.RedisDBHandle._decode_record(encoded)
|
||||
self.compare_records(result, self.record)
|
||||
|
||||
def test_decode_record_no_date(self):
|
||||
encoded = ("24,2014-04-23 15:41:30,,"
|
||||
"42,2014-02-12 11:10:55,2014-03-25 05:01:50").encode()
|
||||
result = pyzor.engines.redis_.RedisDBHandle._decode_record(encoded)
|
||||
self.record.r_updated = None
|
||||
self.compare_records(result, self.record)
|
||||
|
||||
def test_decode_record_no_white(self):
|
||||
encoded = ("24,2014-04-23 15:41:30,2014-04-25 17:22:25,"
|
||||
"0,,").encode()
|
||||
result = pyzor.engines.redis_.RedisDBHandle._decode_record(encoded)
|
||||
self.record.wl_count = 0
|
||||
self.record.wl_entered = None
|
||||
self.record.wl_updated = None
|
||||
self.compare_records(result, self.record)
|
||||
|
||||
def make_MockRedis(commands):
|
||||
class MockRedis():
|
||||
def __init__(self, *args, **kwargs):
|
||||
commands.append(("init", args, kwargs))
|
||||
def set(self, *args, **kwargs):
|
||||
commands.append(("set", args, kwargs))
|
||||
def setex(self, *args, **kwargs):
|
||||
commands.append(("setex", args, kwargs))
|
||||
def get(self, *args, **kwargs):
|
||||
commands.append(("get", args, kwargs))
|
||||
def delete(self, *args, **kwargs):
|
||||
commands.append(("delete", args, kwargs))
|
||||
return MockRedis
|
||||
|
||||
mock_encode_record = lambda s, x: x
|
||||
mock_decode_record = lambda s, x: x
|
||||
|
||||
class RedisTest(unittest.TestCase):
|
||||
|
||||
max_age = 60 * 60
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
|
||||
self.commands = []
|
||||
|
||||
self.real_redis = pyzor.engines.redis_.redis.StrictRedis
|
||||
self.real_encode = pyzor.engines.redis_.RedisDBHandle._encode_record
|
||||
self.real_decode = pyzor.engines.redis_.RedisDBHandle._decode_record
|
||||
|
||||
pyzor.engines.redis_.redis.StrictRedis = make_MockRedis(self.commands)
|
||||
pyzor.engines.redis_.RedisDBHandle._encode_record = mock_encode_record
|
||||
pyzor.engines.redis_.RedisDBHandle._decode_record = mock_decode_record
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
pyzor.engines.redis_.redis.StrictRedis = self.real_redis
|
||||
pyzor.engines.redis_.RedisDBHandle._encode_record = self.real_encode
|
||||
pyzor.engines.redis_.RedisDBHandle._decode_record = self.real_decode
|
||||
|
||||
def test_init(self):
|
||||
expected = {"host": "example.com",
|
||||
"port": 6387,
|
||||
"password": "passwd",
|
||||
"db": 5,
|
||||
}
|
||||
db = pyzor.engines.redis_.RedisDBHandle("example.com,6387,passwd,5",
|
||||
None)
|
||||
self.assertEqual(self.commands[0], ("init", (), expected))
|
||||
|
||||
def test_init_defaults(self):
|
||||
expected = {"host": "localhost",
|
||||
"port": 6379,
|
||||
"password": None,
|
||||
"db": 0,
|
||||
}
|
||||
db = pyzor.engines.redis_.RedisDBHandle(",,,", None)
|
||||
self.assertEqual(self.commands[0], ("init", (), expected))
|
||||
|
||||
def test_set(self):
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
value = "record test"
|
||||
|
||||
db = pyzor.engines.redis_.RedisDBHandle(",,,", None)
|
||||
db[digest] = value
|
||||
|
||||
expected = ("pyzord.digest.%s" % digest, value)
|
||||
self.assertEqual(self.commands[1], ("set", expected, {}))
|
||||
|
||||
def test_set_max_age(self):
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
value = "record test"
|
||||
|
||||
db = pyzor.engines.redis_.RedisDBHandle(",,,", None,
|
||||
max_age=self.max_age)
|
||||
db[digest] = value
|
||||
|
||||
expected = ("pyzord.digest.%s" % digest, self.max_age, value)
|
||||
self.assertEqual(self.commands[1], ("setex", expected, {}))
|
||||
|
||||
def test_get(self):
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
|
||||
db = pyzor.engines.redis_.RedisDBHandle(",,,", None)
|
||||
result = db[digest]
|
||||
|
||||
expected = ("pyzord.digest.%s" % digest,)
|
||||
self.assertEqual(self.commands[1], ("get", expected, {}))
|
||||
|
||||
def test_delete(self):
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
|
||||
db = pyzor.engines.redis_.RedisDBHandle(",,,", None)
|
||||
del db[digest]
|
||||
|
||||
expected = ("pyzord.digest.%s" % digest,)
|
||||
self.assertEqual(self.commands[1], ("delete", expected, {}))
|
||||
|
||||
def suite():
|
||||
"""Gather all the tests from this module in a test suite."""
|
||||
test_suite = unittest.TestSuite()
|
||||
test_suite.addTest(unittest.makeSuite(EncodingRedisTest))
|
||||
test_suite.addTest(unittest.makeSuite(RedisTest))
|
||||
return test_suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
341
mail/spamassassin/pyzor-0.7.0/tests/unit/test_server.py
Normal file
341
mail/spamassassin/pyzor-0.7.0/tests/unit/test_server.py
Normal file
@@ -0,0 +1,341 @@
|
||||
"""Test the pyzor.server module
|
||||
"""
|
||||
import io
|
||||
import sys
|
||||
import time
|
||||
import logging
|
||||
import hashlib
|
||||
import unittest
|
||||
import SocketServer
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import pyzor
|
||||
import pyzor.server
|
||||
import pyzor.engines.common
|
||||
|
||||
class MockServer():
|
||||
"""Mocks the pyzor.server.Server class"""
|
||||
|
||||
def __init__(self):
|
||||
self.log = logging.getLogger("pyzord")
|
||||
self.usage_log = logging.getLogger("pyzord-usage")
|
||||
self.log.addHandler(logging.NullHandler())
|
||||
self.usage_log.addHandler(logging.NullHandler())
|
||||
|
||||
|
||||
class MockDatagramRequestHandler():
|
||||
""" Mock the SocketServer.DatagramRequestHand."""
|
||||
|
||||
def __init__(self, headers, database=None, acl=None, accounts=None):
|
||||
"""Initiates an request handler and set's the data in `headers` as
|
||||
the request. Also set's the database, acl and accounts for the
|
||||
MockServer.
|
||||
|
||||
This will be set as base class for RequestHandler.
|
||||
"""
|
||||
self.rfile = io.BytesIO()
|
||||
self.wfile = io.BytesIO()
|
||||
for i, j in headers.iteritems():
|
||||
self.rfile.write(("%s: %s\n" % (i, j)).encode("utf8"))
|
||||
self.rfile.seek(0)
|
||||
self.packet = None
|
||||
self.client_address = ["127.0.0.1"]
|
||||
|
||||
# Setup MockServer data
|
||||
self.server = MockServer()
|
||||
self.server.database = database
|
||||
if acl:
|
||||
self.server.acl = acl
|
||||
else:
|
||||
self.server.acl = {pyzor.anonymous_user: ("check", "report", "ping", "info", "whitelist",)}
|
||||
self.server.accounts = accounts
|
||||
|
||||
self.handle()
|
||||
|
||||
def handle(self):
|
||||
pass
|
||||
|
||||
|
||||
class RequestHandlerTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
unittest.TestCase.setUp(self)
|
||||
self.real_drh = SocketServer.DatagramRequestHandler
|
||||
SocketServer.DatagramRequestHandler = MockDatagramRequestHandler
|
||||
pyzor.server.RequestHandler.__bases__ = (MockDatagramRequestHandler,)
|
||||
|
||||
# setup the basic values for request and response
|
||||
self.request = {"User": pyzor.anonymous_user,
|
||||
"Time": str(int(time.time())),
|
||||
"PV": str(pyzor.proto_version),
|
||||
"Thread": "3597"}
|
||||
self.expected_response = {"Code": "200",
|
||||
"Diag": "OK",
|
||||
"PV": str(pyzor.proto_version),
|
||||
"Thread": "3597"}
|
||||
|
||||
def tearDown(self):
|
||||
unittest.TestCase.tearDown(self)
|
||||
SocketServer.DatagramRequestHandler = self.real_drh
|
||||
pyzor.server.RequestHandler.__bases__ = (self.real_drh,)
|
||||
|
||||
def check_response(self, handler):
|
||||
"""Checks if the response from the handler is equal to
|
||||
the expected response.
|
||||
"""
|
||||
handler.wfile.seek(0)
|
||||
response = handler.wfile.read()
|
||||
response = response.decode("utf8").replace("\n\n", "\n")
|
||||
|
||||
result = {}
|
||||
for line in response.splitlines():
|
||||
key = line.split(":", 1)[0].strip()
|
||||
value = line.split(":")[1].strip()
|
||||
result[key] = value
|
||||
|
||||
self.assertEqual(result, self.expected_response)
|
||||
|
||||
def timestamp(self, time_obj):
|
||||
if not time_obj:
|
||||
return 0
|
||||
else:
|
||||
return str(int(time.mktime(time_obj.timetuple())))
|
||||
|
||||
def test_ping(self):
|
||||
"""Tests the ping command handler"""
|
||||
self.request["Op"] = "ping"
|
||||
handler = pyzor.server.RequestHandler(self.request)
|
||||
|
||||
self.check_response(handler)
|
||||
|
||||
def test_pong(self):
|
||||
"""Tests the pong command handler"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
database = {digest: pyzor.engines.common.Record(24, 42)}
|
||||
|
||||
self.request["Op"] = "pong"
|
||||
self.request["Op-Digest"] = digest
|
||||
handler = pyzor.server.RequestHandler(self.request, database)
|
||||
self.expected_response["Count"] = str(sys.maxint)
|
||||
self.expected_response["WL-Count"] = "0"
|
||||
|
||||
def test_check(self):
|
||||
"""Tests the check command handler"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
database = {digest: pyzor.engines.common.Record(24, 42)}
|
||||
|
||||
self.request["Op"] = "check"
|
||||
self.request["Op-Digest"] = digest
|
||||
handler = pyzor.server.RequestHandler(self.request, database)
|
||||
self.expected_response["Count"] = "24"
|
||||
self.expected_response["WL-Count"] = "42"
|
||||
|
||||
self.check_response(handler)
|
||||
|
||||
def test_check_new(self):
|
||||
"""Tests the check command handler with a new record"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
database = {}
|
||||
|
||||
self.request["Op"] = "check"
|
||||
self.request["Op-Digest"] = digest
|
||||
handler = pyzor.server.RequestHandler(self.request, database)
|
||||
self.expected_response["Count"] = "0"
|
||||
self.expected_response["WL-Count"] = "0"
|
||||
|
||||
self.check_response(handler)
|
||||
|
||||
def test_info(self):
|
||||
"""Tests the info command handler"""
|
||||
entered = datetime.now() - timedelta(days=10)
|
||||
updated = datetime.now()
|
||||
wl_entered = datetime.now() - timedelta(days=20)
|
||||
wl_updated = datetime.now() - timedelta(days=2)
|
||||
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
database = {digest: pyzor.engines.common.Record(24, 42, entered, updated,
|
||||
wl_entered, wl_updated)}
|
||||
self.request["Op"] = "info"
|
||||
self.request["Op-Digest"] = digest
|
||||
handler = pyzor.server.RequestHandler(self.request, database)
|
||||
self.expected_response["Count"] = "24"
|
||||
self.expected_response["WL-Count"] = "42"
|
||||
self.expected_response["Entered"] = self.timestamp(entered)
|
||||
self.expected_response["Updated"] = self.timestamp(updated)
|
||||
self.expected_response["WL-Entered"] = self.timestamp(wl_entered)
|
||||
self.expected_response["WL-Updated"] = self.timestamp(wl_updated)
|
||||
|
||||
self.check_response(handler)
|
||||
|
||||
def test_info_new(self):
|
||||
"""Tests the info command handler with a new record"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
database = {}
|
||||
self.request["Op"] = "info"
|
||||
self.request["Op-Digest"] = digest
|
||||
handler = pyzor.server.RequestHandler(self.request, database)
|
||||
self.expected_response["Count"] = "0"
|
||||
self.expected_response["WL-Count"] = "0"
|
||||
self.expected_response["Entered"] = "0"
|
||||
self.expected_response["Updated"] = "0"
|
||||
self.expected_response["WL-Entered"] = "0"
|
||||
self.expected_response["WL-Updated"] = "0"
|
||||
|
||||
self.check_response(handler)
|
||||
|
||||
def test_report(self):
|
||||
"""Tests the report command handler"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
database = {digest: pyzor.engines.common.Record(24, 42)}
|
||||
|
||||
self.request["Op"] = "report"
|
||||
self.request["Op-Digest"] = digest
|
||||
handler = pyzor.server.RequestHandler(self.request, database)
|
||||
|
||||
self.check_response(handler)
|
||||
self.assertEqual(database[digest].r_count, 25)
|
||||
|
||||
def test_report_new(self):
|
||||
"""Tests the report command handler with a new record"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
database = {}
|
||||
|
||||
self.request["Op"] = "report"
|
||||
self.request["Op-Digest"] = digest
|
||||
handler = pyzor.server.RequestHandler(self.request, database)
|
||||
|
||||
self.check_response(handler)
|
||||
self.assertEqual(database[digest].r_count, 1)
|
||||
|
||||
def test_whitelist(self):
|
||||
"""Tests the whitelist command handler"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
database = {digest: pyzor.engines.common.Record(24, 42)}
|
||||
|
||||
self.request["Op"] = "whitelist"
|
||||
self.request["Op-Digest"] = digest
|
||||
handler = pyzor.server.RequestHandler(self.request, database)
|
||||
|
||||
self.check_response(handler)
|
||||
self.assertEqual(database[digest].wl_count, 43)
|
||||
|
||||
def test_whitelist_new(self):
|
||||
"""Tests the whitelist command handler with a new record"""
|
||||
digest = "2aedaac999d71421c9ee49b9d81f627a7bc570aa"
|
||||
database = {}
|
||||
|
||||
self.request["Op"] = "whitelist"
|
||||
self.request["Op-Digest"] = digest
|
||||
handler = pyzor.server.RequestHandler(self.request, database)
|
||||
|
||||
self.check_response(handler)
|
||||
self.assertEqual(database[digest].wl_count, 1)
|
||||
|
||||
def test_handle_no_version(self):
|
||||
"""Tests handling an request with no version specified"""
|
||||
self.request["Op"] = "ping"
|
||||
del self.request["PV"]
|
||||
handler = pyzor.server.RequestHandler(self.request)
|
||||
|
||||
self.expected_response["Code"] = "400"
|
||||
self.expected_response["Diag"] = "Bad request"
|
||||
self.check_response(handler)
|
||||
|
||||
def test_handle_unsupported_version(self):
|
||||
"""Tests handling an request with an unsupported version specified"""
|
||||
self.request["Op"] = "ping"
|
||||
self.request["PV"] = str(pyzor.proto_version + 2)
|
||||
handler = pyzor.server.RequestHandler(self.request)
|
||||
|
||||
self.expected_response["Code"] = "505"
|
||||
self.expected_response["Diag"] = "Version Not Supported"
|
||||
self.check_response(handler)
|
||||
|
||||
def test_handle_not_implemented(self):
|
||||
"""Tests handling an request with an unimplemented command"""
|
||||
self.request["Op"] = "notimplemented"
|
||||
acl = {pyzor.anonymous_user: "notimplemented"}
|
||||
handler = pyzor.server.RequestHandler(self.request, acl=acl)
|
||||
|
||||
self.expected_response["Code"] = "501"
|
||||
self.expected_response["Diag"] = "Not implemented"
|
||||
self.check_response(handler)
|
||||
|
||||
def test_handle_unauthorized(self):
|
||||
"""Tests handling an request with an unauthorized command"""
|
||||
self.request["Op"] = "report"
|
||||
acl = {pyzor.anonymous_user: ("ping", "check")}
|
||||
handler = pyzor.server.RequestHandler(self.request, acl=acl)
|
||||
|
||||
self.expected_response["Code"] = "403"
|
||||
self.expected_response["Diag"] = "Forbidden"
|
||||
self.check_response(handler)
|
||||
|
||||
def test_handle_account(self):
|
||||
"""Tests handling an request where user is not anonymous"""
|
||||
self.request["Op"] = "ping"
|
||||
self.request["User"] = "testuser"
|
||||
acl = {"testuser": ("ping", "check")}
|
||||
accounts = {"testuser": "testkey"}
|
||||
|
||||
mock_vs = lambda x, y: None
|
||||
real_vs = pyzor.account.verify_signature
|
||||
pyzor.account.verify_signature = mock_vs
|
||||
try:
|
||||
handler = pyzor.server.RequestHandler(self.request, acl=acl,
|
||||
accounts=accounts)
|
||||
self.check_response(handler)
|
||||
finally:
|
||||
pyzor.account.verify_signature = real_vs
|
||||
|
||||
def test_handle_unknown_account(self):
|
||||
"""Tests handling an request where user is unkwown"""
|
||||
self.request["Op"] = "ping"
|
||||
self.request["User"] = "testuser"
|
||||
acl = {"testuser": ("ping", "check")}
|
||||
accounts = {}
|
||||
|
||||
self.expected_response["Code"] = "401"
|
||||
self.expected_response["Diag"] = "Unauthorized"
|
||||
|
||||
def mock_vs(x, y):
|
||||
pass
|
||||
real_vs = pyzor.account.verify_signature
|
||||
pyzor.account.verify_signature = mock_vs
|
||||
try:
|
||||
handler = pyzor.server.RequestHandler(self.request, acl=acl,
|
||||
accounts=accounts)
|
||||
self.check_response(handler)
|
||||
finally:
|
||||
pyzor.account.verify_signature = real_vs
|
||||
|
||||
def test_handle_invalid_signature(self):
|
||||
"""Tests handling an request where user key is invalid"""
|
||||
self.request["Op"] = "ping"
|
||||
self.request["User"] = "testuser"
|
||||
acl = {"testuser": ("ping", "check")}
|
||||
accounts = {"testuser": ("ping", "check")}
|
||||
|
||||
self.expected_response["Code"] = "401"
|
||||
self.expected_response["Diag"] = "Unauthorized"
|
||||
|
||||
def mock_vs(x, y):
|
||||
raise pyzor.SignatureError("Invalid signature.")
|
||||
real_vs = pyzor.account.verify_signature
|
||||
pyzor.account.verify_signature = mock_vs
|
||||
try:
|
||||
handler = pyzor.server.RequestHandler(self.request, acl=acl,
|
||||
accounts=accounts)
|
||||
self.check_response(handler)
|
||||
finally:
|
||||
pyzor.account.verify_signature = real_vs
|
||||
|
||||
def suite():
|
||||
"""Gather all the tests from this module in a test suite."""
|
||||
test_suite = unittest.TestSuite()
|
||||
test_suite.addTest(unittest.makeSuite(RequestHandlerTest))
|
||||
return test_suite
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user