Show that a max_sessions_per_connection == 0 means there's an unlimited number
[mailman.git] / src / mailman / testing / mta.py
blob62070cc5dc55e823c773d8062305e1c80c70f56f
1 # Copyright (C) 2009 by the Free Software Foundation, Inc.
3 # This file is part of GNU Mailman.
5 # GNU Mailman is free software: you can redistribute it and/or modify it under
6 # the terms of the GNU General Public License as published by the Free
7 # Software Foundation, either version 3 of the License, or (at your option)
8 # any later version.
10 # GNU Mailman is distributed in the hope that it will be useful, but WITHOUT
11 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 # more details.
15 # You should have received a copy of the GNU General Public License along with
16 # GNU Mailman. If not, see <http://www.gnu.org/licenses/>.
18 """Fake MTA for testing purposes."""
20 from __future__ import absolute_import, unicode_literals
22 __metaclass__ = type
23 __all__ = [
24 'FakeMTA',
28 import logging
30 from Queue import Queue
32 from lazr.smtptest.controller import QueueController
33 from lazr.smtptest.server import Channel, QueueServer
34 from zope.interface import implements
36 from mailman.interfaces.mta import IMailTransportAgent
39 log = logging.getLogger('lazr.smtptest')
43 class FakeMTA:
44 """Fake MTA for testing purposes."""
46 implements(IMailTransportAgent)
48 def create(self, mlist):
49 pass
51 def delete(self, mlist):
52 pass
54 def regenerate(self):
55 pass
59 class StatisticsChannel(Channel):
60 """A channel that can answers to the fake STAT command."""
62 def smtp_STAT(self, arg):
63 """Cause the server to send statistics to its controller."""
64 self._server.send_statistics()
65 self.push('250 Ok')
69 class ConnectionCountingServer(QueueServer):
70 """Count the number of SMTP connections opened."""
72 def __init__(self, host, port, queue, oob_queue):
73 """See `lazr.smtptest.server.QueueServer`."""
74 QueueServer.__init__(self, host, port, queue)
75 self._connection_count = 0
76 # The out-of-band queue is where the server sends statistics to the
77 # controller upon request.
78 self._oob_queue = oob_queue
80 def handle_accept(self):
81 """See `lazr.smtp.server.Server`."""
82 connection, address = self.accept()
83 self._connection_count += 1
84 log.info('[ConnectionCountingServer] accepted: %s', address)
85 StatisticsChannel(self, connection, address)
87 def reset(self):
88 """See `lazr.smtp.server.Server`."""
89 QueueServer.reset(self)
90 self._connection_count = 0
92 def send_statistics(self):
93 """Send the current connection statistics to the controller."""
94 # Do not count the connection caused by the STAT connect.
95 self._connection_count -= 1
96 self._oob_queue.put(self._connection_count)
100 class ConnectionCountingController(QueueController):
101 """Count the number of SMTP connections opened."""
103 def __init__(self, host, port):
104 """See `lazr.smtptest.controller.QueueController`."""
105 self.oob_queue = Queue()
106 QueueController.__init__(self, host, port)
108 def _make_server(self, host, port):
109 """See `lazr.smtptest.controller.QueueController`."""
110 self.server = ConnectionCountingServer(
111 host, port, self.queue, self.oob_queue)
113 def start(self):
114 """See `lazr.smtptest.controller.QueueController`."""
115 QueueController.start(self)
116 # Reset the connection statistics, since the base class's start()
117 # method causes a connection to occur.
118 self.reset()
120 def get_connection_count(self):
121 """Retrieve the number of connections.
123 :return: The number of connections to the server that have been made.
124 :rtype: integer
126 smtpd = self._connect()
127 smtpd.docmd('STAT')
128 # An Empty exception will occur if the data isn't available in 10
129 # seconds. Let that propagate.
130 return self.oob_queue.get(block=True, timeout=10)
132 @property
133 def messages(self):
134 """Return all the messages received by the SMTP server."""
135 for message in self:
136 yield message
138 def clear(self):
139 """Clear all the messages from the queue."""
140 list(self)