summaryrefslogtreecommitdiff
path: root/src/mailman/queue/tests/test_outgoing.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/queue/tests/test_outgoing.py')
-rw-r--r--src/mailman/queue/tests/test_outgoing.py97
1 files changed, 96 insertions, 1 deletions
diff --git a/src/mailman/queue/tests/test_outgoing.py b/src/mailman/queue/tests/test_outgoing.py
index c86a1efa7..da45dbdb5 100644
--- a/src/mailman/queue/tests/test_outgoing.py
+++ b/src/mailman/queue/tests/test_outgoing.py
@@ -31,11 +31,18 @@ import logging
import unittest
from contextlib import contextmanager
-from datetime import timedelta
+from datetime import datetime, timedelta
+from zope.component import getUtility
+from mailman.app.bounces import send_probe
from mailman.app.lifecycle import create_list
from mailman.config import config
+from mailman.interfaces.bounce import BounceContext, IBounceProcessor
from mailman.interfaces.mailinglist import Personalization
+from mailman.interfaces.member import MemberRole
+from mailman.interfaces.mta import SomeRecipientsFailed
+from mailman.interfaces.pending import IPendings
+from mailman.interfaces.usermanager import IUserManager
from mailman.queue.outgoing import OutgoingRunner
from mailman.testing.helpers import (
get_queue_messages,
@@ -319,9 +326,97 @@ Message-Id: <first>
+temporary_failures = []
+permanent_failures = []
+
+
+def raise_SomeRecipientsFailed(mlist, msg, msgdata):
+ raise SomeRecipientsFailed(temporary_failures, permanent_failures)
+
+
+class TestSomeRecipientsFailed(unittest.TestCase):
+ """Test socket.error occurring in the delivery function."""
+
+ layer = ConfigLayer
+
+ def setUp(self):
+ global temporary_failures, permanent_failures
+ del temporary_failures[:]
+ del permanent_failures[:]
+ # Push a config where actual delivery is handled by a dummy function.
+ # We generally don't care what this does, since we're just testing the
+ # setting of the 'verp' key in the metadata.
+ config.push('fake outgoing', """
+ [mta]
+ outgoing: mailman.queue.tests.test_outgoing.raise_SomeRecipientsFailed
+ """)
+ self._mlist = create_list('test@example.com')
+ self._outq = config.switchboards['out']
+ self._runner = make_testable_runner(OutgoingRunner, 'out', run_once)
+ self._msg = message_from_string("""\
+From: anne@example.com
+To: test@example.com
+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.
+ anne = getUtility(IUserManager).create_address('anne@example.com')
+ member = self._mlist.subscribe(anne, MemberRole.member)
+ token = send_probe(member, self._msg)
+ msgdata = dict(probe_token=token)
+ permanent_failures.append('anne@example.com')
+ self._outq.enqueue(self._msg, msgdata, listname='test@example.com')
+ self._runner.run()
+ events = list(getUtility(IBounceProcessor).unprocessed)
+ self.assertEqual(len(events), 1)
+ event = events[0]
+ self.assertEqual(event.list_name, 'test@example.com')
+ self.assertEqual(event.email, 'anne@example.com')
+ 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)
+
+ def test_confirmed_probe_failure(self):
+ # This time, a probe also fails, but for some reason the probe token
+ # has already been confirmed and no longer exists in the database.
+ anne = getUtility(IUserManager).create_address('anne@example.com')
+ member = self._mlist.subscribe(anne, MemberRole.member)
+ token = send_probe(member, self._msg)
+ getUtility(IPendings).confirm(token)
+ msgdata = dict(probe_token=token)
+ permanent_failures.append('anne@example.com')
+ self._outq.enqueue(self._msg, msgdata, listname='test@example.com')
+ self._runner.run()
+ events = list(getUtility(IBounceProcessor).unprocessed)
+ self.assertEqual(len(events), 0)
+
+ def test_probe_temporary_failure(self):
+ # This time, a probe also fails, but the failures are temporary so
+ # they are not registered.
+ anne = getUtility(IUserManager).create_address('anne@example.com')
+ member = self._mlist.subscribe(anne, MemberRole.member)
+ token = send_probe(member, self._msg)
+ getUtility(IPendings).confirm(token)
+ msgdata = dict(probe_token=token)
+ temporary_failures.append('anne@example.com')
+ self._outq.enqueue(self._msg, msgdata, listname='test@example.com')
+ self._runner.run()
+ events = list(getUtility(IBounceProcessor).unprocessed)
+ self.assertEqual(len(events), 0)
+
+
+
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestOnce))
suite.addTest(unittest.makeSuite(TestVERPSettings))
suite.addTest(unittest.makeSuite(TestSocketError))
+ suite.addTest(unittest.makeSuite(TestSomeRecipientsFailed))
return suite