diff options
| author | Barry Warsaw | 2016-03-25 18:03:12 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2016-03-25 18:03:12 -0400 |
| commit | 077a49a823af227c7038f9533eb8d9d55571bbe7 (patch) | |
| tree | dd0d2710a8bad8da08b085ffc611fdd8f9642813 /src | |
| parent | 142aca81121ec885d70ed74ea5a6b76ecf05221b (diff) | |
| download | mailman-077a49a823af227c7038f9533eb8d9d55571bbe7.tar.gz mailman-077a49a823af227c7038f9533eb8d9d55571bbe7.tar.zst mailman-077a49a823af227c7038f9533eb8d9d55571bbe7.zip | |
Diffstat (limited to 'src')
25 files changed, 162 insertions, 389 deletions
diff --git a/src/mailman/runners/archive.py b/src/mailman/runners/archive.py index 240d991f6..cfa0b1a12 100644 --- a/src/mailman/runners/archive.py +++ b/src/mailman/runners/archive.py @@ -17,17 +17,13 @@ """Archive runner.""" -__all__ = [ - 'ArchiveRunner', - ] - - import copy import logging from email.utils import parsedate_tz, mktime_tz from datetime import datetime from lazr.config import as_timedelta +from mailman import public from mailman.config import config from mailman.core.runner import Runner from mailman.interfaces.archiver import ClobberDate @@ -38,7 +34,6 @@ from mailman.interfaces.mailinglist import IListArchiverSet log = logging.getLogger('mailman.archiver') - def _should_clobber(msg, msgdata, archiver): """Should the Date header in the original message get clobbered?""" # Calculate the Date header of the message as a datetime. What if there @@ -49,12 +44,12 @@ def _should_clobber(msg, msgdata, archiver): return True section = getattr(config.archiver, archiver, None) if section is None: - log.error('No archiver config section found: {0}'.format(archiver)) + log.error('No archiver config section found: {}'.format(archiver)) return False try: clobber = ClobberDate[section.clobber_date] except ValueError: - log.error('Invalid clobber_date for "{0}": {1}'.format( + log.error('Invalid clobber_date for "{}": {}'.format( archiver, section.clobber_date)) return False if clobber is ClobberDate.always: @@ -81,7 +76,7 @@ def _should_clobber(msg, msgdata, archiver): return (abs(now() - claimed_date) > skew) - +@public class ArchiveRunner(Runner): """The archive runner.""" diff --git a/src/mailman/runners/bounce.py b/src/mailman/runners/bounce.py index ba05b400d..4150dc9b5 100644 --- a/src/mailman/runners/bounce.py +++ b/src/mailman/runners/bounce.py @@ -20,6 +20,7 @@ import logging from flufl.bounce import all_failures, scan_message +from mailman import public from mailman.app.bounces import ProbeVERP, StandardVERP, maybe_forward from mailman.core.runner import Runner from mailman.interfaces.bounce import BounceContext, IBounceProcessor @@ -32,7 +33,7 @@ log = logging.getLogger('mailman.bounce') elog = logging.getLogger('mailman.error') - +@public class BounceRunner(Runner): """The bounce runner.""" @@ -79,7 +80,7 @@ class BounceRunner(Runner): address = address.decode('utf-8') except UnicodeError: log.exception('Ignoring non-UTF-8 encoded ' - 'address: {0}'.format(address)) + 'address: {}'.format(address)) continue self._processor.register(mlist, address, msg, context) else: diff --git a/src/mailman/runners/command.py b/src/mailman/runners/command.py index 59d437469..15ccca438 100644 --- a/src/mailman/runners/command.py +++ b/src/mailman/runners/command.py @@ -17,11 +17,6 @@ """-request robot command runner.""" -__all__ = [ - 'CommandRunner', - 'Results', - ] - # See the delivery diagram in IncomingRunner.py. This module handles all # email destined for mylist-request, -join, and -leave. It no longer handles # bounce messages (i.e. -admin or -bounces), nor does it handle mail to @@ -34,6 +29,7 @@ from email.errors import HeaderParseError from email.header import decode_header, make_header from email.iterators import typed_subpart_iterator from io import StringIO +from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.core.runner import Runner @@ -48,7 +44,6 @@ NL = '\n' log = logging.getLogger('mailman.vette') - class CommandFinder: """Generate commands from the content of a message.""" @@ -120,7 +115,7 @@ class CommandFinder: yield parts - +@public @implementer(IEmailResults) class Results: """The email command results.""" @@ -143,7 +138,7 @@ The results of your email command are provided below. return value - +@public class CommandRunner(Runner): """The email command runner.""" @@ -173,9 +168,9 @@ class CommandRunner(Runner): # Include just a few key pieces of information from the original: the # sender, date, and message id. print(_('- Original message details:'), file=results) - subject = msg.get('subject', 'n/a') - date = msg.get('date', 'n/a') - from_ = msg.get('from', 'n/a') + subject = msg.get('subject', 'n/a') # flake8: noqa + date = msg.get('date', 'n/a') # flake8: noqa + from_ = msg.get('from', 'n/a') # flake8: noqa print(_(' From: $from_'), file=results) print(_(' Subject: $subject'), file=results) print(_(' Date: $date'), file=results) diff --git a/src/mailman/runners/digest.py b/src/mailman/runners/digest.py index 3d540d73f..f35b42b9a 100644 --- a/src/mailman/runners/digest.py +++ b/src/mailman/runners/digest.py @@ -17,11 +17,6 @@ """Digest runner.""" -__all__ = [ - 'DigestRunner', - ] - - import re import logging @@ -31,6 +26,7 @@ from email.mime.message import MIMEMessage from email.mime.text import MIMEText from email.utils import formatdate, getaddresses, make_msgid from io import StringIO +from mailman import public from mailman.config import config from mailman.core.i18n import _ from mailman.core.runner import Runner @@ -46,7 +42,6 @@ from urllib.error import URLError log = logging.getLogger('mailman.error') - class Digester: """Base digester class.""" @@ -85,7 +80,7 @@ class Digester: self._header = decorate(mlist, mlist.digest_header_uri) except URLError: log.exception( - 'Digest header decorator URI not found ({0}): {1}'.format( + 'Digest header decorator URI not found ({}): {}'.format( mlist.fqdn_listname, mlist.digest_header_uri)) self._header = '' self._toc = StringIO() @@ -110,8 +105,8 @@ class Digester: if not username: username = addresses[0][1] if username: - username = ' ({0})'.format(username) - lines = wrap('{0:2}. {1}'. format(count, subject), 65).split('\n') + username = ' ({})'.format(username) + lines = wrap('{:2}. {}'. format(count, subject), 65).split('\n') # See if the user's name can fit on the last line if len(lines[-1]) + len(username) > 70: lines.append(username) @@ -145,8 +140,6 @@ class Digester: msg['Message'] = count.decode('utf-8') - - class MIMEDigester(Digester): """A MIME digester.""" @@ -176,7 +169,8 @@ class MIMEDigester(Digester): _charset=self._charset) except UnicodeError: toc_part = MIMEText(toc_text.encode('utf-8'), _charset='utf-8') - toc_part['Content-Description']= _("Today's Topics ($count messages)") + toc_part['Content-Description'] = _( + "Today's Topics ($count messages)") self._message.attach(toc_part) def add_message(self, msg, count): @@ -210,7 +204,6 @@ class MIMEDigester(Digester): return self._message - class RFC1153Digester(Digester): """A digester of the format specified by RFC 1153.""" @@ -247,7 +240,7 @@ class RFC1153Digester(Digester): for header in config.digests.plain_digest_keep_headers.split(): if header in msg: value = oneline(msg[header], in_unicode=True) - value = wrap('{0}: {1}'.format(header, value)) + value = wrap('{}: {}'.format(header, value)) value = '\n\t'.join(value.split('\n')) print(value, file=self._text) print(file=self._text) @@ -277,7 +270,7 @@ class RFC1153Digester(Digester): self._mlist, self._mlist.digest_footer_uri) except URLError: log.exception( - 'Digest footer decorator URI not found ({0}): {1}'.format( + 'Digest footer decorator URI not found ({}): {}'.format( self._mlist.fqdn_listname, self._mlist.digest_footer_uri)) footer_text = '' @@ -307,7 +300,7 @@ class RFC1153Digester(Digester): return self._message - +@public class DigestRunner(Runner): """The digest runner.""" @@ -364,7 +357,7 @@ class DigestRunner(Runner): mime_recipients.add(email_address) else: raise AssertionError( - 'Digest member "{0}" unexpected delivery mode: {1}'.format( + 'Digest member "{}" unexpected delivery mode: {}'.format( email_address, member.delivery_mode)) # Add also the folks who are receiving one last digest. for address, delivery_mode in mlist.last_digest_recipients: @@ -376,7 +369,7 @@ class DigestRunner(Runner): mime_recipients.add(address.original_email) else: raise AssertionError( - 'OLD recipient "{0}" unexpected delivery mode: {1}'.format( + 'OLD recipient "{}" unexpected delivery mode: {}'.format( address, delivery_mode)) # Send the digests to the virgin queue for final delivery. queue = config.switchboards['virgin'] diff --git a/src/mailman/runners/incoming.py b/src/mailman/runners/incoming.py index 6d576cb50..dd9254194 100644 --- a/src/mailman/runners/incoming.py +++ b/src/mailman/runners/incoming.py @@ -26,11 +26,7 @@ prepared for delivery. Rejections, discards, and holds are processed immediately. """ -__all__ = [ - 'IncomingRunner', - ] - - +from mailman import public from mailman.core.chains import process from mailman.core.runner import Runner from mailman.database.transaction import transaction @@ -39,7 +35,7 @@ from mailman.interfaces.usermanager import IUserManager from zope.component import getUtility - +@public class IncomingRunner(Runner): """The incoming runner.""" diff --git a/src/mailman/runners/lmtp.py b/src/mailman/runners/lmtp.py index 3ec9e37c2..35cff4c94 100644 --- a/src/mailman/runners/lmtp.py +++ b/src/mailman/runners/lmtp.py @@ -34,17 +34,13 @@ so that the peer mail server can provide better diagnostics. http://www.faqs.org/rfcs/rfc2033.html """ -__all__ = [ - 'LMTPRunner', - ] - - import sys import email import logging import asyncore from email.utils import parseaddr +from mailman import public from mailman.config import config from mailman.core.runner import Runner from mailman.database.transaction import transactional @@ -94,8 +90,8 @@ SUBADDRESS_QUEUES = dict( request='command', ) -DASH = '-' -CRLF = '\r\n' +DASH = '-' +CRLF = '\r\n' ERR_451 = '451 Requested action aborted: error in processing' ERR_501 = '501 Message has defects' ERR_502 = '502 Error: command HELO not implemented' @@ -106,7 +102,6 @@ ERR_550_MID = '550 No Message-ID header provided' smtpd.__version__ = 'GNU Mailman LMTP runner 1.1' - def split_recipient(address): """Split an address into listname, subaddress and domain parts. @@ -134,7 +129,6 @@ def split_recipient(address): return listname, subaddress, domain - class Channel(smtpd.SMTPChannel): """An LMTP channel.""" @@ -151,13 +145,12 @@ class Channel(smtpd.SMTPChannel): """HELO is not a valid LMTP command.""" self.push(ERR_502) - ## def push(self, arg): - ## import pdb; pdb.set_trace() - ## return super().push(arg) - + # def push(self, arg): + # import pdb; pdb.set_trace() + # return super().push(arg) - +@public class LMTPRunner(Runner, smtpd.SMTPServer): # Only __init__ is called on startup. Asyncore is responsible for later # connections from the MTA. slice and numslices are ignored and are diff --git a/src/mailman/runners/nntp.py b/src/mailman/runners/nntp.py index 710f326b0..b125fe4f9 100644 --- a/src/mailman/runners/nntp.py +++ b/src/mailman/runners/nntp.py @@ -17,11 +17,6 @@ """NNTP runner.""" -__all__ = [ - 'NNTPRunner', - ] - - import re import email import socket @@ -29,6 +24,7 @@ import logging import nntplib from io import StringIO +from mailman import public from mailman.config import config from mailman.core.runner import Runner from mailman.interfaces.nntp import NewsgroupModeration @@ -53,7 +49,7 @@ mcre = re.compile(r""" """, re.VERBOSE) - +@public class NNTPRunner(Runner): def _dispose(self, mlist, msg, msgdata): # Get NNTP server connection information. @@ -65,7 +61,7 @@ class NNTPRunner(Runner): try: port = int(port) except (TypeError, ValueError): - log.exception('Bad [nntp]port value: {0}'.format(port)) + log.exception('Bad [nntp]port value: {}'.format(port)) port = 119 # Make sure we have the most up-to-date state if not msgdata.get('prepped'): @@ -80,15 +76,15 @@ class NNTPRunner(Runner): password=config.nntp.password) conn.post(fp) except nntplib.NNTPTemporaryError: - log.exception('{0} NNTP error for {1}'.format( + log.exception('{} NNTP error for {}'.format( msg.get('message-id', 'n/a'), mlist.fqdn_listname)) except socket.error: - log.exception('{0} NNTP socket error for {1}'.format( + log.exception('{} NNTP socket error for {}'.format( msg.get('message-id', 'n/a'), mlist.fqdn_listname)) except Exception: # Some other exception occurred, which we definitely did not # expect, so set this message up for requeuing. - log.exception('{0} NNTP unexpected exception for {1}'.format( + log.exception('{} NNTP unexpected exception for {}'.format( msg.get('message-id', 'n/a'), mlist.fqdn_listname)) return True finally: @@ -97,7 +93,6 @@ class NNTPRunner(Runner): return False - def prepare_message(mlist, msg, msgdata): # If the newsgroup is moderated, we need to add this header for the Usenet # software to accept the posting, and not forward it on to the n.g.'s @@ -170,7 +165,7 @@ def prepare_message(mlist, msg, msgdata): if len(dup_headers) % 2 != 0: # There are an odd number of headers; ignore the last one. bad_header = dup_headers.pop() - log.error('Ignoring odd [nntp]rewrite_duplicate_headers: {0}'.format( + log.error('Ignoring odd [nntp]rewrite_duplicate_headers: {}'.format( bad_header)) dup_headers.reverse() while dup_headers: diff --git a/src/mailman/runners/outgoing.py b/src/mailman/runners/outgoing.py index 98c484e3f..3f21e3813 100644 --- a/src/mailman/runners/outgoing.py +++ b/src/mailman/runners/outgoing.py @@ -17,16 +17,12 @@ """Outgoing runner.""" -__all__ = [ - 'OutgoingRunner', - ] - - import socket import logging from datetime import datetime from lazr.config import as_boolean, as_timedelta +from mailman import public from mailman.config import config from mailman.core.runner import Runner from mailman.interfaces.bounce import BounceContext, IBounceProcessor @@ -49,7 +45,7 @@ smtp_log = logging.getLogger('mailman.smtp') debug_log = logging.getLogger('mailman.debug') - +@public class OutgoingRunner(Runner): """The outgoing runner.""" @@ -92,7 +88,7 @@ class OutgoingRunner(Runner): # VERP every 'interval' number of times. msgdata['verp'] = (mlist.post_id % interval == 0) try: - debug_log.debug('[outgoing] {0}: {1}'.format( + debug_log.debug('[outgoing] {}: {}'.format( self._func, msg.get('message-id', 'n/a'))) self._func(mlist, msg, msgdata) self._logged = False @@ -154,7 +150,7 @@ class OutgoingRunner(Runner): if current_time > deliver_until: smtp_log.error('Discarding message with ' 'persistent temporary failures: ' - '{0}'.format(msg['message-id'])) + '{}'.format(msg['message-id'])) return False else: # We made some progress, so keep trying to delivery diff --git a/src/mailman/runners/pipeline.py b/src/mailman/runners/pipeline.py index b7ea7fa34..3ec7499f2 100644 --- a/src/mailman/runners/pipeline.py +++ b/src/mailman/runners/pipeline.py @@ -22,16 +22,12 @@ through the 'preparation pipeline'. This pipeline adds, deletes and modifies headers, calculates message recipients, and more. """ -__all__ = [ - 'PipelineRunner', - ] - - +from mailman import public from mailman.core.pipelines import process from mailman.core.runner import Runner - +@public class PipelineRunner(Runner): def _dispose(self, mlist, msg, msgdata): # Process the message through the mailing list's pipeline. diff --git a/src/mailman/runners/rest.py b/src/mailman/runners/rest.py index 831f99997..5a76d22c1 100644 --- a/src/mailman/runners/rest.py +++ b/src/mailman/runners/rest.py @@ -17,15 +17,11 @@ """Start the administrative HTTP server.""" -__all__ = [ - 'RESTRunner', - ] - - import signal import logging import threading +from mailman import public from mailman.core.runner import Runner from mailman.rest.wsgiapp import make_server @@ -33,7 +29,7 @@ from mailman.rest.wsgiapp import make_server log = logging.getLogger('mailman.http') - +@public class RESTRunner(Runner): # Don't install the standard signal handlers because as defined, they # won't actually stop the TCPServer started by .serve_forever(). @@ -54,7 +50,7 @@ class RESTRunner(Runner): # server. self._server = make_server() self._event = threading.Event() - def stopper(event, server): + def stopper(event, server): # flake8: noqa event.wait() server.shutdown() self._thread = threading.Thread( diff --git a/src/mailman/runners/retry.py b/src/mailman/runners/retry.py index 25743a5bd..f1af4f73c 100644 --- a/src/mailman/runners/retry.py +++ b/src/mailman/runners/retry.py @@ -17,18 +17,14 @@ """Retry delivery.""" -__all__ = [ - 'RetryRunner', - ] - - import time +from mailman import public from mailman.config import config from mailman.core.runner import Runner - +@public class RetryRunner(Runner): """Retry delivery.""" diff --git a/src/mailman/runners/tests/test_archiver.py b/src/mailman/runners/tests/test_archiver.py index 8aaaec86e..79f04c236 100644 --- a/src/mailman/runners/tests/test_archiver.py +++ b/src/mailman/runners/tests/test_archiver.py @@ -17,11 +17,6 @@ """Test the archive runner.""" -__all__ = [ - 'TestArchiveRunner', - ] - - import os import unittest @@ -39,7 +34,6 @@ from mailman.utilities.datetime import RFC822_DATE_FMT, factory, now from zope.interface import implementer - @implementer(IArchiver) class DummyArchiver: name = 'dummy' @@ -80,7 +74,6 @@ class BrokenArchiver: raise RuntimeError('Cannot archive message') - class TestArchiveRunner(unittest.TestCase): """Test the archive runner.""" @@ -282,4 +275,4 @@ First post! log_messages = mark.read() self.assertIn('Exception in "broken" archiver', log_messages) self.assertIn('RuntimeError: Cannot archive message', log_messages) - self.assertEqual(len(get_queue_messages('shunt')), 0) + get_queue_messages('shunt', expected_count=0) diff --git a/src/mailman/runners/tests/test_bounce.py b/src/mailman/runners/tests/test_bounce.py index 2fab646e4..e33ad9de2 100644 --- a/src/mailman/runners/tests/test_bounce.py +++ b/src/mailman/runners/tests/test_bounce.py @@ -17,13 +17,6 @@ """Test the bounce runner.""" -__all__ = [ - 'TestBounceRunner', - 'TestBounceRunnerBug876774', - 'TestStyle', - ] - - import unittest from mailman.app.bounces import send_probe @@ -43,7 +36,6 @@ from zope.component import getUtility from zope.interface import implementer - class TestBounceRunner(unittest.TestCase): """Test the bounce runner.""" @@ -69,9 +61,7 @@ Message-Id: <first> [mailman] site_owner: postmaster@example.com """) - - def tearDown(self): - config.pop('site owner') + self.addCleanup(config.pop, 'site owner') def test_does_no_processing(self): # If the mailing list does no bounce processing, the messages are @@ -79,7 +69,7 @@ Message-Id: <first> self._mlist.process_bounces = False self._bounceq.enqueue(self._msg, self._msgdata) self._runner.run() - self.assertEqual(len(get_queue_messages('bounces')), 0) + get_queue_messages('bounces', expected_count=0) self.assertEqual(len(list(self._processor.events)), 0) def test_verp_detection(self): @@ -87,7 +77,7 @@ Message-Id: <first> # event will be registered. self._bounceq.enqueue(self._msg, self._msgdata) self._runner.run() - self.assertEqual(len(get_queue_messages('bounces')), 0) + get_queue_messages('bounces', expected_count=0) events = list(self._processor.events) self.assertEqual(len(events), 1) self.assertEqual(events[0].email, 'anne@example.com') @@ -115,7 +105,7 @@ Original-Recipient: rfc822; somebody@example.com """) self._bounceq.enqueue(nonfatal, self._msgdata) self._runner.run() - self.assertEqual(len(get_queue_messages('bounces')), 0) + get_queue_messages('bounces', expected_count=0) events = list(self._processor.events) self.assertEqual(len(events), 0) @@ -127,7 +117,8 @@ Original-Recipient: rfc822; somebody@example.com # # Start be simulating a probe bounce. send_probe(self._member, self._msg) - message = get_queue_messages('virgin')[0].msg + items = get_queue_messages('virgin', expected_count=1) + message = items[0].msg bounce = message_from_string("""\ To: {0} From: mail-daemon@example.com @@ -136,7 +127,7 @@ Message-Id: <second> """.format(message['From'])) self._bounceq.enqueue(bounce, self._msgdata) self._runner.run() - self.assertEqual(len(get_queue_messages('bounces')), 0) + get_queue_messages('bounces', expected_count=0) events = list(self._processor.events) self.assertEqual(len(events), 1) self.assertEqual(events[0].email, 'anne@example.com') @@ -166,7 +157,7 @@ Original-Recipient: rfc822; bart@example.com """) self._bounceq.enqueue(dsn, self._msgdata) self._runner.run() - self.assertEqual(len(get_queue_messages('bounces')), 0) + get_queue_messages('bounces', expected_count=0) events = list(self._processor.events) self.assertEqual(len(events), 1) self.assertEqual(events[0].email, 'bart@example.com') @@ -196,7 +187,7 @@ Original-Recipient: rfc822; bart@example.com """) self._bounceq.enqueue(dsn, self._msgdata) self._runner.run() - self.assertEqual(len(get_queue_messages('bounces')), 0) + get_queue_messages('bounces', expected_count=0) events = list(self._processor.events) self.assertEqual(len(events), 0) @@ -215,7 +206,7 @@ Message-Id: <third> self._bounceq.enqueue(bogus, self._msgdata) mark = LogFileMark('mailman.bounce') self._runner.run() - self.assertEqual(len(get_queue_messages('bounces')), 0) + get_queue_messages('bounces', expected_count=0) events = list(self._processor.events) self.assertEqual(len(events), 0) line = mark.readline() @@ -223,12 +214,10 @@ Message-Id: <third> line[-51:-1], 'Bounce message w/no discernable addresses: <third>') # Here's the forwarded message to the site owners. - forwards = get_queue_messages('virgin') - self.assertEqual(len(forwards), 1) - self.assertEqual(forwards[0].msg['to'], 'postmaster@example.com') + items = get_queue_messages('virgin', expected_count=1) + self.assertEqual(items[0].msg['to'], 'postmaster@example.com') - # Create a style for the mailing list which sets the absolute minimum # attributes. In particular, this will not set the bogus `bounce_processing` # attribute which the default style set (before LP: #876774 was fixed). @@ -244,7 +233,6 @@ class TestStyle: mailing_list.preferred_language = 'en' - class TestBounceRunnerBug876774(unittest.TestCase): """Test LP: #876774. @@ -261,15 +249,13 @@ class TestBounceRunnerBug876774(unittest.TestCase): self._style = TestStyle() self._style_manager = getUtility(IStyleManager) self._style_manager.register(self._style) + self.addCleanup(self._style_manager.unregister, self._style) # Now we can create the mailing list. self._mlist = create_list('test@example.com', style_name='test') self._bounceq = config.switchboards['bounces'] self._processor = getUtility(IBounceProcessor) self._runner = make_testable_runner(BounceRunner, 'bounces') - def tearDown(self): - self._style_manager.unregister(self._style) - def test_bug876774(self): # LP: #876774, see above. bounce = message_from_string("""\ @@ -281,6 +267,6 @@ Message-Id: <first> self._bounceq.enqueue(bounce, dict(listid='test.example.com')) self.assertEqual(len(self._bounceq.files), 1) self._runner.run() - self.assertEqual(len(get_queue_messages('bounces')), 0) + get_queue_messages('bounces', expected_count=0) events = list(self._processor.events) self.assertEqual(len(events), 0) diff --git a/src/mailman/runners/tests/test_confirm.py b/src/mailman/runners/tests/test_confirm.py index 39cf85387..7dc2403fc 100644 --- a/src/mailman/runners/tests/test_confirm.py +++ b/src/mailman/runners/tests/test_confirm.py @@ -17,11 +17,6 @@ """Test the `confirm` command.""" -__all__ = [ - 'TestConfirm', - ] - - import unittest from datetime import datetime @@ -39,7 +34,6 @@ from mailman.testing.layers import ConfigLayer from zope.component import getUtility - class TestConfirm(unittest.TestCase): """Test confirmations.""" @@ -57,7 +51,7 @@ class TestConfirm(unittest.TestCase): self._token, token_owner, member = registrar.register(anne) def test_confirm_with_re_prefix(self): - subject = 'Re: confirm {0}'.format(self._token) + subject = 'Re: confirm {}'.format(self._token) msg = mfs("""\ From: anne@example.org To: test-confirm@example.com @@ -77,7 +71,7 @@ To: test-confirm@example.com self.assertEqual(address.email, 'anne@example.org') def test_confirm_with_random_ascii_prefix(self): - subject = '\x99AW: confirm {0}'.format(self._token) + subject = '\x99AW: confirm {}'.format(self._token) msg = mfs("""\ From: anne@example.org To: test-confirm@example.com @@ -100,8 +94,8 @@ To: test-confirm@example.com # Clear out the virgin queue so that the test below only sees the # reply to the confirmation message. get_queue_messages('virgin') - subject = 'Re: confirm {0}'.format(self._token) - to = 'test-confirm+{0}@example.com'.format(self._token) + subject = 'Re: confirm {}'.format(self._token) + to = 'test-confirm+{}@example.com'.format(self._token) msg = mfs("""\ From: Anne Person <anne@example.org> MIME-Version: 1.0 @@ -151,17 +145,16 @@ Franziskanerstra=C3=9Fe self.assertEqual(address.verified_on, datetime(2005, 8, 1, 7, 49, 23)) address = manager.get_address('anne@example.org') self.assertEqual(address.email, 'anne@example.org') - messages = get_queue_messages('virgin') - self.assertEqual(len(messages), 1) - self.assertEqual(messages[0].msgdata['recipients'], + items = get_queue_messages('virgin', expected_count=1) + self.assertEqual(items[0].msgdata['recipients'], set(['anne@example.org'])) def test_confirm_with_no_command_in_utf8_body(self): # Clear out the virgin queue so that the test below only sees the # reply to the confirmation message. get_queue_messages('virgin') - subject = 'Re: confirm {0}'.format(self._token) - to = 'test-confirm+{0}@example.com'.format(self._token) + subject = 'Re: confirm {}'.format(self._token) + to = 'test-confirm+{}@example.com'.format(self._token) msg = mfs("""\ From: Anne Person <anne@example.org> MIME-Version: 1.0 @@ -184,9 +177,8 @@ Franziskanerstra=C3=9Fe self.assertEqual(address.verified_on, datetime(2005, 8, 1, 7, 49, 23)) address = manager.get_address('anne@example.org') self.assertEqual(address.email, 'anne@example.org') - messages = get_queue_messages('virgin') - self.assertEqual(len(messages), 1) - self.assertEqual(messages[0].msgdata['recipients'], + items = get_queue_messages('virgin', expected_count=1) + self.assertEqual(items[0].msgdata['recipients'], set(['anne@example.org'])) def test_double_confirmation(self): @@ -196,8 +188,8 @@ Franziskanerstra=C3=9Fe # Clear out the virgin queue so that the test below only sees the # reply to the confirmation message. get_queue_messages('virgin') - subject = 'Re: confirm {0}'.format(self._token) - to = 'test-confirm+{0}@example.com'.format(self._token) + subject = 'Re: confirm {}'.format(self._token) + to = 'test-confirm+{}@example.com'.format(self._token) msg = mfs("""\ From: Anne Person <anne@example.org> @@ -213,13 +205,12 @@ From: Anne Person <anne@example.org> user = manager.get_user('anne@example.org') self.assertEqual(list(user.addresses)[0].email, 'anne@example.org') # Make sure that the confirmation was not attempted twice. - messages = get_queue_messages('virgin') - self.assertEqual(len(messages), 1) + items = get_queue_messages('virgin', expected_count=1) # Search the contents of the results message. There should be just # one 'Confirmation email' line. confirmation_lines = [] in_results = False - for line in body_line_iterator(messages[0].msg): + for line in body_line_iterator(items[0].msg): line = line.strip() if in_results: if line.startswith('- Done'): @@ -229,7 +220,7 @@ From: Anne Person <anne@example.org> if line.strip() == '- Results:': in_results = True self.assertEqual(len(confirmation_lines), 1) - self.assertFalse('did not match' in confirmation_lines[0]) + self.assertNotIn('did not match', confirmation_lines[0]) def test_welcome_message_after_confirmation(self): # Confirmations with a welcome message set. @@ -241,8 +232,8 @@ From: Anne Person <anne@example.org> # Clear out the virgin queue so that the test below only sees the # reply to the confirmation message. get_queue_messages('virgin') - subject = 'Re: confirm {0}'.format(self._token) - to = 'test-confirm+{0}@example.com'.format(self._token) + subject = 'Re: confirm {}'.format(self._token) + to = 'test-confirm+{}@example.com'.format(self._token) msg = mfs("""\ From: Anne Person <anne@example.org> @@ -254,8 +245,7 @@ From: Anne Person <anne@example.org> self._runner.run() # Now there's a email command notification and a welcome message. All # we care about for this test is the welcome message. - messages = get_queue_messages('virgin', sort_on='subject') - self.assertEqual(len(messages), 2) - message = messages[1].msg - self.assertEqual(str(message['subject']), + items = get_queue_messages('virgin', sort_on='subject', + expected_count=2) + self.assertEqual(str(items[1].msg['subject']), 'Welcome to the "Test" mailing list') diff --git a/src/mailman/runners/tests/test_digest.py b/src/mailman/runners/tests/test_digest.py index 279ae36d8..f767f78d4 100644 --- a/src/mailman/runners/tests/test_digest.py +++ b/src/mailman/runners/tests/test_digest.py @@ -17,12 +17,6 @@ """Test the digest runner.""" -__all__ = [ - 'TestDigest', - 'TestI18nDigest', - ] - - import unittest from email.iterators import _structure as structure @@ -42,7 +36,6 @@ from mailman.testing.layers import ConfigLayer from string import Template - class TestDigest(unittest.TestCase): """Test the digest runner.""" @@ -62,12 +55,11 @@ class TestDigest(unittest.TestCase): def _check_virgin_queue(self): # There should be two messages in the virgin queue: the digest as # plain-text and as multipart. - messages = get_queue_messages('virgin') - self.assertEqual(len(messages), 2) + items = get_queue_messages('virgin', expected_count=2) self.assertEqual( - sorted(item.msg.get_content_type() for item in messages), + sorted(item.msg.get_content_type() for item in items), ['multipart/mixed', 'text/plain']) - for item in messages: + for item in items: self.assertEqual(item.msg['subject'], 'Test Digest, Vol 1, Issue 1') @@ -132,8 +124,7 @@ Here is message $i # Run the digest runner to create the MIME and RFC 1153 digests. runner = make_testable_runner(DigestRunner) runner.run() - items = get_queue_messages('virgin') - self.assertEqual(len(items), 2) + items = get_queue_messages('virgin', expected_count=2) # Find the MIME one. mime_digest = None for item in items: @@ -166,8 +157,7 @@ multipart/mixed make_digest_messages(self._mlist) # There should be one message in the outgoing queue, destined for # Bart, formatted as a MIME digest. - items = get_queue_messages('virgin') - self.assertEqual(len(items), 1) + items = get_queue_messages('virgin', expected_count=1) # Bart is the only recipient. self.assertEqual(items[0].msgdata['recipients'], set(['bperson@example.com'])) @@ -192,8 +182,7 @@ multipart/mixed make_digest_messages(self._mlist) # There should be one message in the outgoing queue, destined for # Bart, formatted as a MIME digest. - items = get_queue_messages('virgin') - self.assertEqual(len(items), 1) + items = get_queue_messages('virgin', expected_count=1) # Bart is the only recipient. self.assertEqual(items[0].msgdata['recipients'], set(['bperson@example.com'])) @@ -210,7 +199,6 @@ multipart/mixed """) - class TestI18nDigest(unittest.TestCase): layer = ConfigLayer maxDiff = None @@ -252,12 +240,11 @@ Content-Transfer-Encoding: 7bit self._runner.run() # There are two digests in the virgin queue; one is the MIME digest # and the other is the RFC 1153 digest. - messages = get_queue_messages('virgin') - self.assertEqual(len(messages), 2) - if messages[0].msg.is_multipart(): - mime, rfc1153 = messages[0].msg, messages[1].msg + items = get_queue_messages('virgin', expected_count=2) + if items[0].msg.is_multipart(): + mime, rfc1153 = items[0].msg, items[1].msg else: - rfc1153, mime = messages[0].msg, messages[1].msg + rfc1153, mime = items[0].msg, items[1].msg # The MIME version contains a mix of French and Japanese. The digest # chrome added by Mailman is in French. self.assertEqual(mime['subject'].encode(), diff --git a/src/mailman/runners/tests/test_incoming.py b/src/mailman/runners/tests/test_incoming.py index d813cc34b..c8878c0c5 100644 --- a/src/mailman/runners/tests/test_incoming.py +++ b/src/mailman/runners/tests/test_incoming.py @@ -17,11 +17,6 @@ """Test the incoming queue runner.""" -__all__ = [ - 'TestIncoming', - ] - - import unittest from mailman.app.lifecycle import create_list @@ -34,7 +29,6 @@ from mailman.testing.helpers import ( from mailman.testing.layers import ConfigLayer - class Chain(TerminalChainBase): name = 'test' description = 'a test chain' @@ -47,7 +41,6 @@ class Chain(TerminalChainBase): config.switchboards['out'].enqueue(msg, msgdata) - class TestIncoming(unittest.TestCase): """Test the incoming queue runner.""" @@ -73,9 +66,8 @@ To: test@example.com msgdata = dict(listid='test.example.com') config.switchboards['in'].enqueue(self._msg, msgdata) self._in.run() - messages = get_queue_messages('out') - self.assertEqual(len(messages), 1) - self.assertEqual(messages[0].msgdata.get('marker'), 'posting') + items = get_queue_messages('out', expected_count=1) + self.assertEqual(items[0].msgdata.get('marker'), 'posting') def test_owner(self): # A message posted to the list goes through the posting chain. @@ -83,6 +75,5 @@ To: test@example.com to_owner=True) config.switchboards['in'].enqueue(self._msg, msgdata) self._in.run() - messages = get_queue_messages('out') - self.assertEqual(len(messages), 1) - self.assertEqual(messages[0].msgdata.get('marker'), 'owner') + items = get_queue_messages('out', expected_count=1) + self.assertEqual(items[0].msgdata.get('marker'), 'owner') diff --git a/src/mailman/runners/tests/test_join.py b/src/mailman/runners/tests/test_join.py index 239d8e2ef..0f24f3847 100644 --- a/src/mailman/runners/tests/test_join.py +++ b/src/mailman/runners/tests/test_join.py @@ -17,12 +17,6 @@ """Test mailing list joins.""" -__all__ = [ - 'TestJoin', - 'TestJoinWithDigests', - ] - - import unittest from email.iterators import body_line_iterator @@ -34,13 +28,12 @@ from mailman.interfaces.subscriptions import ISubscriptionService, TokenOwner from mailman.interfaces.usermanager import IUserManager from mailman.runners.command import CommandRunner from mailman.testing.helpers import ( - get_queue_messages, make_testable_runner, reset_the_world, + get_queue_messages, make_testable_runner, specialized_message_from_string as mfs) from mailman.testing.layers import ConfigLayer from zope.component import getUtility - class TestJoin(unittest.TestCase): """Test mailing list joins.""" @@ -52,9 +45,6 @@ class TestJoin(unittest.TestCase): self._commandq = config.switchboards['command'] self._runner = make_testable_runner(CommandRunner, 'command') - def tearDown(self): - reset_the_world() - def test_double_confirmation(self): # A join request comes in using both the -join address and the word # 'subscribe' in the first line of the body. This should produce just @@ -74,16 +64,16 @@ subscribe # There will be two messages in the queue. The first one is a reply # to Anne notifying her of the status of her command email. The # second one is the confirmation message of her join request. - messages = get_queue_messages('virgin', sort_on='subject') - self.assertEqual(len(messages), 2) - self.assertTrue(str(messages[1].msg['subject']).startswith('confirm')) - self.assertEqual(messages[0].msg['subject'], + items = get_queue_messages('virgin', sort_on='subject', + expected_count=2) + self.assertTrue(str(items[1].msg['subject']).startswith('confirm')) + self.assertEqual(items[0].msg['subject'], 'The results of your email commands') # Search the contents of the results message. There should be just # one 'Confirmation email' line. confirmation_lines = [] in_results = False - for line in body_line_iterator(messages[0].msg): + for line in body_line_iterator(items[0].msg): line = line.strip() if in_results: if line.startswith('- Done'): @@ -95,7 +85,7 @@ subscribe # There should be exactly one confirmation line. self.assertEqual(len(confirmation_lines), 1) # And the confirmation line should name Anne's email address. - self.assertTrue('anne@example.org' in confirmation_lines[0]) + self.assertIn('anne@example.org', confirmation_lines[0]) def test_join_when_already_a_member(self): anne = getUtility(IUserManager).create_user('anne@example.org') @@ -113,15 +103,14 @@ Subject: join # There will be one message in the queue - a reply to Anne notifying # her of the status of her command email. Because Anne is already # subscribed to the list, she gets and needs no confirmation. - messages = get_queue_messages('virgin') - self.assertEqual(len(messages), 1) - self.assertEqual(messages[0].msg['subject'], + items = get_queue_messages('virgin', expected_count=1) + self.assertEqual(items[0].msg['subject'], 'The results of your email commands') # Search the contents of the results message. There should be just # one 'Confirmation email' line. confirmation_lines = [] in_results = False - for line in body_line_iterator(messages[0].msg): + for line in body_line_iterator(items[0].msg): line = line.strip() if in_results: if line.startswith('- Done'): @@ -133,10 +122,9 @@ Subject: join # There should be exactly one confirmation line. self.assertEqual(len(confirmation_lines), 1) # And the confirmation line should name Anne's email address. - self.assertTrue('anne@example.org' in confirmation_lines[0]) + self.assertIn('anne@example.org', confirmation_lines[0]) - class TestJoinWithDigests(unittest.TestCase): """Test mailing list joins with the digests=<no|mime|plain> argument.""" @@ -147,17 +135,14 @@ class TestJoinWithDigests(unittest.TestCase): self._commandq = config.switchboards['command'] self._runner = make_testable_runner(CommandRunner, 'command') - def tearDown(self): - reset_the_world() - def _confirm(self): # There will be two messages in the queue - the confirmation messages, # and a reply to Anne notifying her of the status of her command # email. We need to dig the confirmation token out of the Subject # header of the latter so that we can confirm the subscription. - messages = get_queue_messages('virgin', sort_on='subject') - self.assertEqual(len(messages), 2) - subject_words = str(messages[1].msg['subject']).split() + items = get_queue_messages('virgin', sort_on='subject', + expected_count=2) + subject_words = str(items[1].msg['subject']).split() self.assertEqual(subject_words[0], 'confirm') token = subject_words[1] token, token_owner, rmember = IRegistrar(self._mlist).confirm(token) diff --git a/src/mailman/runners/tests/test_lmtp.py b/src/mailman/runners/tests/test_lmtp.py index 69343c857..9d86af2dc 100644 --- a/src/mailman/runners/tests/test_lmtp.py +++ b/src/mailman/runners/tests/test_lmtp.py @@ -17,11 +17,6 @@ """Tests for the LMTP server.""" -__all__ = [ - 'TestLMTP', - ] - - import os import smtplib import unittest @@ -34,7 +29,6 @@ from mailman.testing.helpers import get_lmtp_client, get_queue_messages from mailman.testing.layers import LMTPLayer - class TestLMTP(unittest.TestCase): """Test various aspects of the LMTP server.""" @@ -45,9 +39,7 @@ class TestLMTP(unittest.TestCase): self._mlist = create_list('test@example.com') self._lmtp = get_lmtp_client(quiet=True) self._lmtp.lhlo('remote.example.org') - - def tearDown(self): - self._lmtp.close() + self.addCleanup(self._lmtp.close) def test_message_id_required(self): # The message is rejected if it does not have a Message-ID header. @@ -73,9 +65,8 @@ Message-ID: <ant> Subject: This has a Message-ID but no Message-ID-Hash """) - messages = get_queue_messages('in') - self.assertEqual(len(messages), 1) - self.assertEqual(messages[0].msg['message-id-hash'], + items = get_queue_messages('in', expected_count=1) + self.assertEqual(items[0].msg['message-id-hash'], 'MS6QLWERIJLGCRF44J7USBFDELMNT2BW') def test_original_message_id_hash_is_overwritten(self): @@ -87,11 +78,10 @@ Message-ID-Hash: IGNOREME Subject: This has a Message-ID but no Message-ID-Hash """) - messages = get_queue_messages('in') - self.assertEqual(len(messages), 1) - all_headers = messages[0].msg.get_all('message-id-hash') + items = get_queue_messages('in', expected_count=1) + all_headers = items[0].msg.get_all('message-id-hash') self.assertEqual(len(all_headers), 1) - self.assertEqual(messages[0].msg['message-id-hash'], + self.assertEqual(items[0].msg['message-id-hash'], 'MS6QLWERIJLGCRF44J7USBFDELMNT2BW') def test_received_time(self): @@ -103,9 +93,8 @@ Subject: This has no Message-ID header Message-ID: <ant> """) - messages = get_queue_messages('in') - self.assertEqual(len(messages), 1) - self.assertEqual(messages[0].msgdata['received_time'], + items = get_queue_messages('in', expected_count=1) + self.assertEqual(items[0].msgdata['received_time'], datetime(2005, 8, 1, 7, 49, 23)) def test_queue_directory(self): @@ -157,8 +146,8 @@ Subject: This should not be recognized as a join command """) # The message is in the incoming queue but not the command queue. - self.assertEqual(len(get_queue_messages('in')), 1) - self.assertEqual(len(get_queue_messages('command')), 0) + get_queue_messages('in', expected_count=1) + get_queue_messages('command', expected_count=0) def test_mailing_list_with_subaddress_command(self): # Like above, but we can still send a command to the mailing list. @@ -173,11 +162,10 @@ Subject: This will be recognized as a join command. """) # The message is in the command queue but not the incoming queue. - self.assertEqual(len(get_queue_messages('in')), 0) - self.assertEqual(len(get_queue_messages('command')), 1) + get_queue_messages('in', expected_count=0) + get_queue_messages('command', expected_count=1) - class TestBugs(unittest.TestCase): """Test some LMTP related bugs.""" @@ -198,9 +186,8 @@ Subject: My subject Message-ID: <alpha> """) - messages = get_queue_messages('in') - self.assertEqual(len(messages), 1) - self.assertEqual(messages[0].msgdata['listid'], + items = get_queue_messages('in', expected_count=1) + self.assertEqual(items[0].msgdata['listid'], 'my-list.example.com') def test_issue140(self): @@ -215,6 +202,5 @@ Message-ID: <alpha> \xa0 """) - messages = get_queue_messages('in') - self.assertEqual(len(messages), 1) - self.assertEqual(messages[0].msg['message-id'], '<alpha>') + items = get_queue_messages('in', expected_count=1) + self.assertEqual(items[0].msg['message-id'], '<alpha>') diff --git a/src/mailman/runners/tests/test_nntp.py b/src/mailman/runners/tests/test_nntp.py index 6ce3c1afc..1cf5cfc61 100644 --- a/src/mailman/runners/tests/test_nntp.py +++ b/src/mailman/runners/tests/test_nntp.py @@ -17,12 +17,6 @@ """Test the NNTP runner and related utilities.""" -__all__ = [ - 'TestPrepareMessage', - 'TestNNTPRunner', - ] - - import socket import nntplib import unittest @@ -38,7 +32,6 @@ from mailman.testing.layers import ConfigLayer from unittest import mock - class TestPrepareMessage(unittest.TestCase): """Test message preparation.""" @@ -228,7 +221,6 @@ Testing self.assertEqual(fakes, ['one', 'two', 'three']) - class TestNNTPRunner(unittest.TestCase): """The NNTP runner hands messages off to the NNTP server.""" @@ -331,10 +323,9 @@ Testing log_message = mark.readline()[:-1] self.assertTrue(log_message.endswith( 'NNTP unexpected exception for test@example.com')) - messages = get_queue_messages('nntp') - self.assertEqual(len(messages), 1) - self.assertEqual(messages[0].msgdata['listid'], 'test.example.com') - self.assertEqual(messages[0].msg['subject'], 'A newsgroup posting') + items = get_queue_messages('nntp', expected_count=1) + self.assertEqual(items[0].msgdata['listid'], 'test.example.com') + self.assertEqual(items[0].msg['subject'], 'A newsgroup posting') @mock.patch('nntplib.NNTP', side_effect=nntplib.NNTPTemporaryError) def test_connection_never_gets_quit_after_failures(self, class_mock): diff --git a/src/mailman/runners/tests/test_outgoing.py b/src/mailman/runners/tests/test_outgoing.py index bc6e54bed..102a74d10 100644 --- a/src/mailman/runners/tests/test_outgoing.py +++ b/src/mailman/runners/tests/test_outgoing.py @@ -17,20 +17,11 @@ """Test the outgoing runner.""" -__all__ = [ - 'TestOnce', - 'TestSocketError', - 'TestSomeRecipientsFailed', - 'TestVERPSettings', - ] - - import os import socket import logging import unittest -from contextlib import contextmanager from datetime import datetime, timedelta from lazr.config import as_timedelta from mailman.app.bounces import send_probe @@ -44,14 +35,13 @@ from mailman.interfaces.pending import IPendings from mailman.interfaces.usermanager import IUserManager from mailman.runners.outgoing import OutgoingRunner from mailman.testing.helpers import ( - LogFileMark, get_queue_messages, make_testable_runner, + LogFileMark, configuration, get_queue_messages, make_testable_runner, specialized_message_from_string as message_from_string) from mailman.testing.layers import ConfigLayer, SMTPLayer from mailman.utilities.datetime import factory, now from zope.component import getUtility - def run_once(runner): """Predicate for make_testable_runner(). @@ -60,17 +50,6 @@ def run_once(runner): return True -@contextmanager -def temporary_config(name, settings): - """Temporarily set a configuration (use in a with-statement).""" - config.push(name, settings) - try: - yield - finally: - config.pop(name) - - - class TestOnce(unittest.TestCase): """Test outgoing runner message disposition.""" @@ -96,17 +75,16 @@ Message-Id: <first> self._outq.enqueue(self._msg, self._msgdata, tolist=True, listid='test.example.com') self._runner.run() - items = get_queue_messages('out') - self.assertEqual(len(items), 1) + items = get_queue_messages('out', expected_count=1) self.assertEqual(items[0].msgdata['deliver_after'], deliver_after) self.assertEqual(items[0].msg['message-id'], '<first>') - captured_mlist = None captured_msg = None captured_msgdata = None + def capture(mlist, msg, msgdata): global captured_mlist, captured_msg, captured_msgdata captured_mlist = mlist @@ -128,6 +106,7 @@ class TestVERPSettings(unittest.TestCase): [mta] outgoing: mailman.runners.tests.test_outgoing.capture """) + self.addCleanup(config.pop, 'fake outgoing') # Reset the captured data. captured_mlist = None captured_msg = None @@ -142,9 +121,6 @@ Message-Id: <first> """) - def tearDown(self): - config.pop('fake outgoing') - def test_delivery_callback(self): # Test that the configuration variable calls the appropriate callback. self._outq.enqueue(self._msg, {}, listid='test.example.com') @@ -170,10 +146,7 @@ Message-Id: <first> msgdata = {} self._mlist.personalize = Personalization.individual self._outq.enqueue(self._msg, msgdata, listid='test.example.com') - with temporary_config('personalize', """ - [mta] - verp_personalized_deliveries: yes - """): + with configuration('mta', verp_personalized_deliveries='yes'): self._runner.run() self.assertTrue(captured_msgdata['verp']) @@ -183,10 +156,7 @@ Message-Id: <first> msgdata = {} self._mlist.personalize = Personalization.full self._outq.enqueue(self._msg, msgdata, listid='test.example.com') - with temporary_config('personalize', """ - [mta] - verp_personalized_deliveries: yes - """): + with configuration('mta', verp_personalized_deliveries='yes'): self._runner.run() self.assertTrue(captured_msgdata['verp']) @@ -197,56 +167,43 @@ Message-Id: <first> self._mlist.personalize = Personalization.full self._outq.enqueue(self._msg, msgdata, listid='test.example.com') self._runner.run() - self.assertFalse('verp' in captured_msgdata) + self.assertNotIn('verp', captured_msgdata) def test_verp_never(self): # Never VERP when the interval is zero. msgdata = {} self._outq.enqueue(self._msg, msgdata, listid='test.example.com') - with temporary_config('personalize', """ - [mta] - verp_delivery_interval: 0 - """): + with configuration('mta', verp_delivery_interval=0): self._runner.run() - self.assertEqual(captured_msgdata['verp'], False) + self.assertFalse(captured_msgdata['verp']) def test_verp_always(self): # Always VERP when the interval is one. msgdata = {} self._outq.enqueue(self._msg, msgdata, listid='test.example.com') - with temporary_config('personalize', """ - [mta] - verp_delivery_interval: 1 - """): + with configuration('mta', verp_delivery_interval=1): self._runner.run() - self.assertEqual(captured_msgdata['verp'], True) + self.assertTrue(captured_msgdata['verp']) def test_verp_on_interval_match(self): # VERP every so often, when the post_id matches. self._mlist.post_id = 5 msgdata = {} self._outq.enqueue(self._msg, msgdata, listid='test.example.com') - with temporary_config('personalize', """ - [mta] - verp_delivery_interval: 5 - """): + with configuration('mta', verp_delivery_interval=5): self._runner.run() - self.assertEqual(captured_msgdata['verp'], True) + self.assertTrue(captured_msgdata['verp']) def test_no_verp_on_interval_miss(self): # VERP every so often, when the post_id matches. self._mlist.post_id = 4 msgdata = {} self._outq.enqueue(self._msg, msgdata, listid='test.example.com') - with temporary_config('personalize', """ - [mta] - verp_delivery_interval: 5 - """): + with configuration('mta', verp_delivery_interval=5): self._runner.run() - self.assertEqual(captured_msgdata['verp'], False) + self.assertFalse(captured_msgdata['verp']) - def raise_socket_error(mlist, msg, msgdata): raise socket.error @@ -264,6 +221,7 @@ class TestSocketError(unittest.TestCase): [mta] outgoing: mailman.runners.tests.test_outgoing.raise_socket_error """) + self.addCleanup(config.pop, 'fake outgoing') self._mlist = create_list('test@example.com') self._outq = config.switchboards['out'] self._runner = make_testable_runner(OutgoingRunner, 'out', run_once) @@ -274,9 +232,6 @@ Message-Id: <first> """) - def tearDown(self): - config.pop('fake outgoing') - def test_error_with_port_0(self): # Test the code path where a socket.error is raised in the delivery # function, and the MTA port is set to zero. The only real effect of @@ -286,10 +241,7 @@ Message-Id: <first> filename = error_log.handlers[0].filename filepos = os.stat(filename).st_size self._outq.enqueue(self._msg, {}, listid='test.example.com') - with temporary_config('port 0', """ - [mta] - smtp_port: 0 - """): + with configuration('mta', smtp_port=0): self._runner.run() with open(filename) as fp: fp.seek(filepos) @@ -307,10 +259,7 @@ Message-Id: <first> # the current file position. mark = LogFileMark('mailman.error') self._outq.enqueue(self._msg, {}, listid='test.example.com') - with temporary_config('port 0', """ - [mta] - smtp_port: 2112 - """): + with configuration('mta', smtp_port=2112): self._runner.run() line = mark.readline() # The log line will contain a variable timestamp, the PID, and a @@ -320,7 +269,6 @@ Message-Id: <first> 'Cannot connect to SMTP server localhost on port 2112') - temporary_failures = [] permanent_failures = [] @@ -346,6 +294,7 @@ class TestSomeRecipientsFailed(unittest.TestCase): [mta] outgoing: mailman.runners.tests.test_outgoing.raise_SomeRecipientsFailed """) + self.addCleanup(config.pop, 'fake outgoing') self._mlist = create_list('test@example.com') self._outq = config.switchboards['out'] self._runner = make_testable_runner(OutgoingRunner, 'out', run_once) @@ -356,9 +305,6 @@ Message-Id: <first> """) - def tearDown(self): - config.pop('fake outgoing') - def test_probe_failure(self): # When a probe message fails during SMTP, a bounce event is recorded # with the proper bounce context. @@ -377,7 +323,7 @@ Message-Id: <first> self.assertEqual(event.timestamp, datetime(2005, 8, 1, 7, 49, 23)) self.assertEqual(event.message_id, '<first>') self.assertEqual(event.context, BounceContext.probe) - self.assertEqual(event.processed, False) + self.assertFalse(event.processed) def test_confirmed_probe_failure(self): # This time, a probe also fails, but for some reason the probe token @@ -439,8 +385,7 @@ Message-Id: <first> self._runner.run() events = list(self._processor.unprocessed) self.assertEqual(len(events), 0) - items = get_queue_messages('retry') - self.assertEqual(len(items), 1) + items = get_queue_messages('retry', expected_count=1) self.assertEqual(self._msg.as_string(), items[0].msg.as_string()) # The metadata has three keys which are used two decide whether the # next temporary failure should be retried. @@ -460,10 +405,9 @@ Message-Id: <first> self._runner.run() events = list(self._processor.unprocessed) self.assertEqual(len(events), 0) - items = get_queue_messages('retry') # There's still only one item in the retry queue, but the metadata # contains both temporary failures. - self.assertEqual(len(items), 1) + items = get_queue_messages('retry', expected_count=1) self.assertEqual(items[0].msgdata['last_recip_count'], 2) self.assertEqual(items[0].msgdata['recipients'], ['cris@example.com', 'dave@example.com']) @@ -484,8 +428,7 @@ Message-Id: <first> self.assertEqual(events[1].email, 'fred@example.com') self.assertEqual(events[1].context, BounceContext.normal) # Let's look at the temporary failures. - items = get_queue_messages('retry') - self.assertEqual(len(items), 1) + items = get_queue_messages('retry', expected_count=1) self.assertEqual(items[0].msgdata['recipients'], ['gwen@example.com', 'herb@example.com']) @@ -504,8 +447,7 @@ Message-Id: <first> self._outq.enqueue(self._msg, msgdata, listid='test.example.com') self._runner.run() # The retry queue should have our message waiting to be retried. - items = get_queue_messages('retry') - self.assertEqual(len(items), 1) + items = get_queue_messages('retry', expected_count=1) self.assertEqual(items[0].msgdata['deliver_until'], deliver_until) self.assertEqual(items[0].msgdata['recipients'], ['iona@example.com', 'jeff@example.com']) @@ -526,8 +468,8 @@ Message-Id: <first> mark = LogFileMark('mailman.smtp') self._runner.run() # There should be no message in the retry or outgoing queues. - self.assertEqual(len(get_queue_messages('retry')), 0) - self.assertEqual(len(get_queue_messages('out')), 0) + get_queue_messages('retry', expected_count=0) + get_queue_messages('out', expected_count=0) # There should be a log message in the smtp log indicating that the # message has been discarded. line = mark.readline() diff --git a/src/mailman/runners/tests/test_owner.py b/src/mailman/runners/tests/test_owner.py index e5d319b7a..48ccaaba0 100644 --- a/src/mailman/runners/tests/test_owner.py +++ b/src/mailman/runners/tests/test_owner.py @@ -22,11 +22,6 @@ # tests. They're not exactly integration tests, but they do touch lots of # parts of the system. -__all__ = [ - 'TestEmailToOwner', - ] - - import unittest from mailman.app.lifecycle import create_list @@ -44,7 +39,6 @@ from operator import itemgetter from zope.component import getUtility - class TestEmailToOwner(unittest.TestCase): """Test emailing a mailing list's -owner address.""" diff --git a/src/mailman/runners/tests/test_pipeline.py b/src/mailman/runners/tests/test_pipeline.py index f8dcfc507..14f13883d 100644 --- a/src/mailman/runners/tests/test_pipeline.py +++ b/src/mailman/runners/tests/test_pipeline.py @@ -17,11 +17,6 @@ """Test the pipeline runner.""" -__all__ = [ - 'TestPipelineRunner', - ] - - import unittest from mailman.app.lifecycle import create_list @@ -35,7 +30,6 @@ from mailman.testing.layers import ConfigLayer from zope.interface import implementer - @implementer(IHandler) class MyTestHandler: """See `IHandler`.""" @@ -51,7 +45,6 @@ class MyTestHandler: self._test.mark(self._marker) - @implementer(IPipeline) class MyTestPipeline: name = 'test' @@ -65,7 +58,6 @@ class MyTestPipeline: yield MyTestHandler(self._marker, self._test) - class TestPipelineRunner(unittest.TestCase): """Test the pipeline runner.""" diff --git a/src/mailman/runners/tests/test_rest.py b/src/mailman/runners/tests/test_rest.py index 958908c3a..99e4dad02 100644 --- a/src/mailman/runners/tests/test_rest.py +++ b/src/mailman/runners/tests/test_rest.py @@ -17,11 +17,6 @@ """Test the REST runner.""" -__all__ = [ - 'TestRESTRunner', - ] - - import os import signal import unittest @@ -30,7 +25,6 @@ from mailman.testing.helpers import call_api, wait_for_webservice from mailman.testing.layers import RESTLayer - class TestRESTRunner(unittest.TestCase): """Test the REST runner.""" diff --git a/src/mailman/runners/tests/test_retry.py b/src/mailman/runners/tests/test_retry.py index 8d17fa276..739dd78c7 100644 --- a/src/mailman/runners/tests/test_retry.py +++ b/src/mailman/runners/tests/test_retry.py @@ -17,11 +17,6 @@ """Test the retry runner.""" -__all__ = [ - 'TestRetryRunner', - ] - - import unittest from mailman.app.lifecycle import create_list @@ -33,7 +28,6 @@ from mailman.testing.helpers import ( from mailman.testing.layers import ConfigLayer - class TestRetryRunner(unittest.TestCase): """Test the retry runner.""" @@ -55,4 +49,4 @@ Message-Id: <first> def test_message_put_in_outgoing_queue(self): self._retryq.enqueue(self._msg, self._msgdata) self._runner.run() - self.assertEqual(len(get_queue_messages('out')), 1) + get_queue_messages('out', expected_count=1) diff --git a/src/mailman/runners/virgin.py b/src/mailman/runners/virgin.py index 4172f04e4..a69d07bf7 100644 --- a/src/mailman/runners/virgin.py +++ b/src/mailman/runners/virgin.py @@ -23,16 +23,12 @@ to go through some minimal processing before they can be sent out to the recipient. """ -__all__ = [ - 'VirginRunner', - ] - - +from mailman import public from mailman.core.pipelines import process from mailman.core.runner import Runner - +@public class VirginRunner(Runner): def _dispose(self, mlist, msg, msgdata): # We need to fast track this message through any pipeline handlers |
