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)
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
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
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')
44 """Fake MTA for testing purposes."""
46 implements(IMailTransportAgent
)
48 def create(self
, mlist
):
51 def delete(self
, mlist
):
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()
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
)
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
)
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.
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.
126 smtpd
= self
._connect
()
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)
134 """Return all the messages received by the SMTP server."""
139 """Clear all the messages from the queue."""