summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBarry Warsaw2016-03-25 18:03:12 -0400
committerBarry Warsaw2016-03-25 18:03:12 -0400
commit077a49a823af227c7038f9533eb8d9d55571bbe7 (patch)
treedd0d2710a8bad8da08b085ffc611fdd8f9642813 /src
parent142aca81121ec885d70ed74ea5a6b76ecf05221b (diff)
downloadmailman-077a49a823af227c7038f9533eb8d9d55571bbe7.tar.gz
mailman-077a49a823af227c7038f9533eb8d9d55571bbe7.tar.zst
mailman-077a49a823af227c7038f9533eb8d9d55571bbe7.zip
Diffstat (limited to 'src')
-rw-r--r--src/mailman/runners/archive.py13
-rw-r--r--src/mailman/runners/bounce.py5
-rw-r--r--src/mailman/runners/command.py17
-rw-r--r--src/mailman/runners/digest.py29
-rw-r--r--src/mailman/runners/incoming.py8
-rw-r--r--src/mailman/runners/lmtp.py21
-rw-r--r--src/mailman/runners/nntp.py19
-rw-r--r--src/mailman/runners/outgoing.py12
-rw-r--r--src/mailman/runners/pipeline.py8
-rw-r--r--src/mailman/runners/rest.py10
-rw-r--r--src/mailman/runners/retry.py8
-rw-r--r--src/mailman/runners/tests/test_archiver.py9
-rw-r--r--src/mailman/runners/tests/test_bounce.py42
-rw-r--r--src/mailman/runners/tests/test_confirm.py50
-rw-r--r--src/mailman/runners/tests/test_digest.py33
-rw-r--r--src/mailman/runners/tests/test_incoming.py17
-rw-r--r--src/mailman/runners/tests/test_join.py43
-rw-r--r--src/mailman/runners/tests/test_lmtp.py46
-rw-r--r--src/mailman/runners/tests/test_nntp.py15
-rw-r--r--src/mailman/runners/tests/test_outgoing.py110
-rw-r--r--src/mailman/runners/tests/test_owner.py6
-rw-r--r--src/mailman/runners/tests/test_pipeline.py8
-rw-r--r--src/mailman/runners/tests/test_rest.py6
-rw-r--r--src/mailman/runners/tests/test_retry.py8
-rw-r--r--src/mailman/runners/virgin.py8
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