diff options
| author | Barry Warsaw | 2011-05-27 19:37:13 -0400 |
|---|---|---|
| committer | Barry Warsaw | 2011-05-27 19:37:13 -0400 |
| commit | c2167d784734f16adfd3abdc9573fd8f8d88d12f (patch) | |
| tree | b60e0c8dc70c195c9f0f97ea900d69065741d579 /src/mailman/testing/helpers.py | |
| parent | 091917126e7c58657310524882743e8391166fc3 (diff) | |
| parent | 5f93d80364aea9535c14f9f22c2fd7d02b8dd78d (diff) | |
| download | mailman-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.py | 28 |
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() |
