------------------------------------------------------------
revno: 6602
committer: Barry Warsaw <[EMAIL PROTECTED]>
branch nick: 3.0
timestamp: Thu 2008-03-06 00:29:11 -0500
message:
Fix a typo in a roster name.
Remove an outdated comment.
Add an SMTPServer wrapper class to the test helpers module. This will be used
in tests of the outgoing queue, which actually needs to talk to an SMTP
server. Adapt the smtpd-based server to being run under thread control, and
remove some now unnecessary code.
renamed:
mailman/queue/docs/outgoing.txt => mailman/pipeline/docs/to-outgoing.txt
modified:
mailman/database/roster.py
mailman/queue/lmtp.py
mailman/tests/helpers.py
mailman/tests/smtplistener.py
=== modified file 'mailman/database/roster.py'
--- a/mailman/database/roster.py 2008-02-27 06:26:18 +0000
+++ b/mailman/database/roster.py 2008-03-06 05:29:11 +0000
@@ -181,7 +181,7 @@
class DigestMemberRoster(AbstractRoster):
"""Return all the regular delivery members of a list."""
- name = 'regular_members'
+ name = 'digest_members'
@property
def members(self):
=== renamed file 'mailman/queue/docs/outgoing.txt' =>
'mailman/pipeline/docs/to-outgoing.txt'
=== modified file 'mailman/queue/lmtp.py'
--- a/mailman/queue/lmtp.py 2008-02-27 06:26:18 +0000
+++ b/mailman/queue/lmtp.py 2008-03-06 05:29:11 +0000
@@ -38,8 +38,6 @@
mechanism.
"""
-# NOTE: LMTP delivery is experimental in Mailman 2.2.
-
import os
import email
import smtpd
=== modified file 'mailman/tests/helpers.py'
--- a/mailman/tests/helpers.py 2008-02-27 06:26:18 +0000
+++ b/mailman/tests/helpers.py 2008-03-06 05:29:11 +0000
@@ -32,16 +32,17 @@
import time
import errno
import mailbox
-import subprocess
+import smtplib
+import tempfile
+import threading
+from Queue import Empty, Queue
from datetime import datetime, timedelta
from mailman.bin.master import Loop as Master
from mailman.configuration import config
from mailman.queue import Switchboard
-
-
-WAIT_INTERVAL = timedelta(seconds=3)
+from mailman.tests.smtplistener import Server
@@ -132,3 +133,49 @@
"""The pids of all the child qrunner processes."""
for pid in self._started_kids:
yield pid
+
+
+
+class SMTPServer:
+ """An smtp server for testing."""
+
+ host = 'localhost'
+ port = 9025
+
+ def __init__(self):
+ self._messages = []
+ self._queue = Queue()
+ self._server = Server((self.host, self.port), self._queue)
+ self._thread = threading.Thread(target=self._server.start)
+
+ def start(self):
+ """Start the smtp server in a thread."""
+ self._thread.start()
+
+ def stop(self):
+ """Stop the smtp server."""
+ smtpd = smtplib.SMTP()
+ smtpd.connect(self.host, self.port)
+ smtpd.docmd('EXIT')
+ self.clear()
+ # Wait for the thread to exit.
+ self._thread.join()
+
+ @property
+ def messages(self):
+ """Return all the messages received by the smtp server."""
+ for message in self._messages:
+ # See if there's anything waiting in the queue.
+ try:
+ message = self._queue.get_nowait()
+ except Empty:
+ pass
+ else:
+ self._messages.append(message)
+ yield message
+
+ def clear(self):
+ """Clear all messages from the queue."""
+ # Just throw these away.
+ list(self._messages)
+ self._messages = []
=== modified file 'mailman/tests/smtplistener.py'
--- a/mailman/tests/smtplistener.py 2008-02-02 16:18:22 +0000
+++ b/mailman/tests/smtplistener.py 2008-03-06 05:29:11 +0000
@@ -17,17 +17,12 @@
"""A test SMTP listener."""
-import sys
import smtpd
-import signal
-import mailbox
import asyncore
-import optparse
from email import message_from_string
COMMASPACE = ', '
-DEFAULT_PORT = 9025
@@ -39,10 +34,10 @@
# Stash this here since the subclass uses private attributes. :(
self._server = server
- def smtp_RSET(self, arg):
- """Respond to RSET and clear the mailbox."""
- self._server.clear_mailbox()
- smtpd.SMTPChannel.smtp_RSET(self, arg)
+ def smtp_EXIT(self, arg):
+ """Respond to a new command EXIT by exiting the server."""
+ self.push('250 Ok')
+ self._server.stop()
def send(self, data):
"""Silence the bloody asynchat/asyncore broken pipe errors!"""
@@ -58,9 +53,9 @@
class Server(smtpd.SMTPServer):
"""An SMTP server that stores messages to a mailbox."""
- def __init__(self, localaddr, mailbox_path):
+ def __init__(self, localaddr, queue):
smtpd.SMTPServer.__init__(self, localaddr, None)
- self._mailbox = mailbox.Maildir(mailbox_path)
+ self._queue = queue
def handle_accept(self):
"""Handle connections by creating our own Channel object."""
@@ -69,62 +64,18 @@
def process_message(self, peer, mailfrom, rcpttos, data):
"""Process a message by adding it to the mailbox."""
- msg = message_from_string(data)
- msg['X-Peer'] = peer
- msg['X-MailFrom'] = mailfrom
- msg['X-RcptTo'] = COMMASPACE.join(rcpttos)
- self._mailbox.add(msg)
- self._mailbox.clean()
-
-
-
-def handle_signal(*ignore):
- """Handle signal sent by parent to kill the process."""
- asyncore.socket_map.clear()
-
-
-
-def main():
- parser = optparse.OptionParser(usage="""\
-%prog [options] mboxfile
-
-This starts a process listening on a specified host and port (by default
-localhost:9025) for SMTP conversations. All messages this process receives
-are stored in a specified mbox file for the parent process to investigate.
-
-This SMTP server responds to RSET commands by clearing the mbox file.
-""")
- parser.add_option('-a', '--address',
- type='string', default=None,
- help='host:port to listen on')
- opts, args = parser.parse_args()
- if len(args) == 0:
- parser.error('Missing mbox file')
- elif len(args) > 1:
- parser.error('Unexpected arguments')
-
- mboxfile = args[0]
- if opts.address is None:
- host = 'localhost'
- port = DEFAULT_PORT
- elif ':' not in opts.address:
- host = opts.address
- port = DEFAULT_PORT
- else:
- host, port = opts.address.split(':', 1)
- port = int(port)
-
- # Catch the parent's exit signal, and also C-c.
- signal.signal(signal.SIGTERM, handle_signal)
- signal.signal(signal.SIGINT, handle_signal)
-
- server = Server((host, port), mboxfile)
- asyncore.loop()
- asyncore.close_all()
- server.close()
- return 0
-
-
-
-if __name__ == '__main__':
- sys.exit(main())
+ message = message_from_string(data)
+ message['X-Peer'] = peer
+ message['X-MailFrom'] = mailfrom
+ message['X-RcptTo'] = COMMASPACE.join(rcpttos)
+ self._queue.put(message)
+
+ def start(self):
+ """Start the asyncore loop."""
+ asyncore.loop()
+
+ def stop(self):
+ """Stop the asyncore loop."""
+ asyncore.socket_map.clear()
+ asyncore.close_all()
+ self.close()
--
Primary development focus
https://code.launchpad.net/~mailman-coders/mailman/3.0
You are receiving this branch notification because you are subscribed to it.
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe:
http://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org