summaryrefslogtreecommitdiff
path: root/src/mailman/testing/helpers.py
diff options
context:
space:
mode:
authorBarry Warsaw2011-05-27 19:37:13 -0400
committerBarry Warsaw2011-05-27 19:37:13 -0400
commitc2167d784734f16adfd3abdc9573fd8f8d88d12f (patch)
treeb60e0c8dc70c195c9f0f97ea900d69065741d579 /src/mailman/testing/helpers.py
parent091917126e7c58657310524882743e8391166fc3 (diff)
parent5f93d80364aea9535c14f9f22c2fd7d02b8dd78d (diff)
downloadmailman-c2167d784734f16adfd3abdc9573fd8f8d88d12f.tar.gz
mailman-c2167d784734f16adfd3abdc9573fd8f8d88d12f.tar.zst
mailman-c2167d784734f16adfd3abdc9573fd8f8d88d12f.zip
Merge bounce cleanup branch. This is a major cleansing and refactoring of the
bounce processor. Note that one thing this does not do is implement any of the policy around bounce scores. It "merely" cleans up all the crud in the BounceRunner, and all the logic around registering bounce events. This means the bounce runner can actually be enabled again. More code needs to be written to process bounces events occasionally. Details: * maybe_forward() moved to app/bounces.py, and it can now discard the message, forward it to the list administrators (moderators + owners), or site owners. See UnrecognizedBounceDisposition. * scan_message() always returns a set of addresses. * The DSN bounce detector is cleaned up. * An IBounceProcessor utility is added. * IBounceEvents are added, with database support. * bounce_unrecognized_goes_to_list_owner -> forward_unrecognized_bounces_to * bounce_processing -> process_bounces * ReopenableFileHandler.filename is exposed as a public attribute. This aids in testing. * Fix the signature of UserNotification.__init__() to be more PEP 8 compliant. * Change the OwnerNotification.__init__() signature to take a roster object instead of `tomoderators`. When the roster is None, the site owner is used instead. * Fix the default style setting; s/personalization/personalize/ * BounceMixin is gone, baby gone. * Add tests for the OutgoingRunner. * make_testable_runner() can now take a predicate object, which can change how often the runner goes through its main loop. Use this e.g. to go through only once when a message does not get dequeued. * A new LogFileMark helper for testing messages to a log file.
Diffstat (limited to 'src/mailman/testing/helpers.py')
-rw-r--r--src/mailman/testing/helpers.py28
1 files changed, 25 insertions, 3 deletions
diff --git a/src/mailman/testing/helpers.py b/src/mailman/testing/helpers.py
index 71cddd0f4..ed579e39c 100644
--- a/src/mailman/testing/helpers.py
+++ b/src/mailman/testing/helpers.py
@@ -20,6 +20,7 @@ from __future__ import absolute_import, unicode_literals
__metaclass__ = type
__all__ = [
+ 'LogFileMark',
'TestableMaster',
'call_api',
'digest_mbox',
@@ -39,6 +40,7 @@ import time
import errno
import signal
import socket
+import logging
import smtplib
import datetime
import threading
@@ -63,7 +65,7 @@ from mailman.utilities.mailbox import Mailbox
-def make_testable_runner(runner_class, name=None):
+def make_testable_runner(runner_class, name=None, predicate=None):
"""Create a queue runner that runs until its queue is empty.
:param runner_class: The queue runner's class.
@@ -71,6 +73,10 @@ def make_testable_runner(runner_class, name=None):
:param name: Optional queue name; if not given, it is calculated from the
class name.
:type name: string or None
+ :param predicate: Optional alternative predicate for deciding when to stop
+ the queue runner. When None (the default) it stops when the queue is
+ empty.
+ :type predicate: callable that gets one argument, the queue runner.
:return: A runner instance.
"""
@@ -90,7 +96,10 @@ def make_testable_runner(runner_class, name=None):
def _do_periodic(self):
"""Stop when the queue is empty."""
- self._stop = (len(self.switchboard.files) == 0)
+ if predicate is None:
+ self._stop = (len(self.switchboard.files) == 0)
+ else:
+ self._stop = predicate(self)
return EmptyingRunner(name)
@@ -364,7 +373,7 @@ def reset_the_world():
config.db.commit()
# Reset the global style manager.
config.style_manager.populate()
-
+
def specialized_message_from_string(unicode_text):
@@ -384,3 +393,16 @@ def specialized_message_from_string(unicode_text):
message = message_from_string(text, Message)
message.original_size = original_size
return message
+
+
+
+class LogFileMark:
+ def __init__(self, log_name):
+ self._log = logging.getLogger(log_name)
+ self._filename = self._log.handlers[0].filename
+ self._filepos = os.stat(self._filename).st_size
+
+ def readline(self):
+ with open(self._filename) as fp:
+ fp.seek(self._filepos)
+ return fp.readline()