This class implements a test SMTP server. :param addr: A (host, port) tuple which the server listens on. You can specify a port value of zero: the server's *port* attribute will hold the actual port number used, which can be used in client
| 872 | # -- if it proves to be of wider utility than just test_logging |
| 873 | |
| 874 | class TestSMTPServer(smtpd.SMTPServer): |
| 875 | """ |
| 876 | This class implements a test SMTP server. |
| 877 | |
| 878 | :param addr: A (host, port) tuple which the server listens on. |
| 879 | You can specify a port value of zero: the server's |
| 880 | *port* attribute will hold the actual port number |
| 881 | used, which can be used in client connections. |
| 882 | :param handler: A callable which will be called to process |
| 883 | incoming messages. The handler will be passed |
| 884 | the client address tuple, who the message is from, |
| 885 | a list of recipients and the message data. |
| 886 | :param poll_interval: The interval, in seconds, used in the underlying |
| 887 | :func:`select` or :func:`poll` call by |
| 888 | :func:`asyncore.loop`. |
| 889 | :param sockmap: A dictionary which will be used to hold |
| 890 | :class:`asyncore.dispatcher` instances used by |
| 891 | :func:`asyncore.loop`. This avoids changing the |
| 892 | :mod:`asyncore` module's global state. |
| 893 | """ |
| 894 | |
| 895 | def __init__(self, addr, handler, poll_interval, sockmap): |
| 896 | smtpd.SMTPServer.__init__(self, addr, None, map=sockmap, |
| 897 | decode_data=True) |
| 898 | self.port = self.socket.getsockname()[1] |
| 899 | self._handler = handler |
| 900 | self._thread = None |
| 901 | self._quit = False |
| 902 | self.poll_interval = poll_interval |
| 903 | |
| 904 | def process_message(self, peer, mailfrom, rcpttos, data): |
| 905 | """ |
| 906 | Delegates to the handler passed in to the server's constructor. |
| 907 | |
| 908 | Typically, this will be a test case method. |
| 909 | :param peer: The client (host, port) tuple. |
| 910 | :param mailfrom: The address of the sender. |
| 911 | :param rcpttos: The addresses of the recipients. |
| 912 | :param data: The message. |
| 913 | """ |
| 914 | self._handler(peer, mailfrom, rcpttos, data) |
| 915 | |
| 916 | def start(self): |
| 917 | """ |
| 918 | Start the server running on a separate daemon thread. |
| 919 | """ |
| 920 | self._thread = t = threading.Thread(target=self.serve_forever, |
| 921 | args=(self.poll_interval,)) |
| 922 | t.daemon = True |
| 923 | t.start() |
| 924 | |
| 925 | def serve_forever(self, poll_interval): |
| 926 | """ |
| 927 | Run the :mod:`asyncore` loop until normal termination |
| 928 | conditions arise. |
| 929 | :param poll_interval: The interval, in seconds, used in the underlying |
| 930 | :func:`select` or :func:`poll` call by |
| 931 | :func:`asyncore.loop`. |
no outgoing calls
searching dependent graphs…