def test_mail_with_compatible_smtputf8(self): handler = ReceivingHandler() controller = Controller(handler) controller.start() self.addCleanup(controller.stop) recipient = 'bart\[email protected]' sender = 'anne\[email protected]' with SMTP(controller.hostname, controller.port) as client: client.ehlo('example.com') client.send( bytes('MAIL FROM: <' + sender + '> SMTPUTF8\r\n', encoding='utf-8')) code, response = client.getreply() self.assertEqual(code, 250) self.assertEqual(response, b'OK') client.send( bytes('RCPT TO: <' + recipient + '>\r\n', encoding='utf-8')) code, response = client.getreply() self.assertEqual(code, 250) self.assertEqual(response, b'OK') code, response = client.data('') self.assertEqual(code, 250) self.assertEqual(response, b'OK') self.assertEqual(handler.box[0].rcpt_tos[0], recipient) self.assertEqual(handler.box[0].mail_from, sender)
def test_real_mail_aiosmtpd(self): """ Test sending messages with a real-world SMTPD server """ if aiosmtpd is None: self.skipTest('aiosmtpd not available') # Start an smtp server mail_handler = StashingHandler() controller = Controller(mail_handler, loop=None, hostname='localhost', port=self.smtpd_port) controller.start() # Give it time to settle sleep(0.5) # Initialize a Postman postman = Postman('*****@*****.**', NoLoginSMTP('localhost', self.smtpd_port, None, None)) # Send messages with postman.connect() as c: # Send plaintext message msg = Message(['*****@*****.**'], 'Subject', 'HTML message') c.sendmail(msg) # Send unicode message msg = Message(['*****@*****.**'], u'Håkon', u'Håkon') c.sendmail(msg) # Done controller.stop() # Test self.assertEqual(len(mail_handler.mail), 2)
async def amain(loop): """Instantiate a controller which runs the SMTP server in a separate thread with a dedicated event loop""" controller = Controller(MyHandler(), hostname=SMTPSERVER_CFG['Server']['BINDADDR'], port=SMTPSERVER_CFG['Server']['BINDPORT']) controller.start()
def test_hostname_empty(self): # WARNING: This test _always_ succeeds in Windows. cont = Controller(Sink(), hostname="") try: cont.start() finally: cont.stop()
class SMTPHandler(rpc.AttrHandler): def __init__(self): self.inbox = Inbox() self.controller = Controller(self.inbox, port=0, ready_timeout=1) self.controller.start() @property def port(self): return self.controller.server.sockets[0].getsockname()[1] @property def running(self): return self.controller.thread.is_alive() @rpc.method def inboxcount(self): return self.inbox.count @rpc.method def stop(self): # TODO Call later is currently needed to let the RPC client recieve a # response before the server exits. # See: https://github.com/aio-libs/aiozmq/issues/39 loop = asyncio.get_event_loop() loop.call_later(0.01, self.controller.stop)
def setUp(self): self.stream = StringIO() handler = Debugging(self.stream) controller = Controller(handler) controller.start() self.addCleanup(controller.stop) self.address = (controller.hostname, controller.port)
def setUp(self): # There are two controllers and two SMTPd's running here. The # "upstream" one listens on port 9025 and is connected to a "data # handler" which captures the messages it receives. The second -and # the one under test here- listens on port 9024 and proxies to the one # on port 9025. Because we need to set the decode_data flag # differently for each different test, the controller of the proxy is # created in the individual tests, not in the setup. self.upstream = DataHandler() upstream_controller = Controller(self.upstream, port=9025) upstream_controller.start() self.addCleanup(upstream_controller.stop) self.proxy = Proxy(upstream_controller.hostname, 9025) self.source = """\ From: Anne Person <*****@*****.**> To: Bart Person <*****@*****.**> Subject: A test Testing """ # The upstream SMTPd will always receive the content as bytes # delimited with CRLF. self.expected = CRLF.join([ 'From: Anne Person <*****@*****.**>', 'To: Bart Person <*****@*****.**>', 'Subject: A test', 'X-Peer: ::1', '', 'Testing\r\n']).encode('ascii')
def main(keywords, antivirus, in_port, server, port): in_port = in_port if in_port else IN_PORT server = server if server else MAIL_SERVER port = port if port else OUT_PORT filters = [] # add keyword filters if specified if keywords: keywords = keywords.split(",") for k in keywords: if not isfile(abspath(k)): print("%s: keywords file does not exist" % k) else: filters.append(KeywordFilter(k)) # add antivirus filter if specified if antivirus: filters.append(AntivirusFilter()) # create a gateway object containing the filters, start the server gateway = Gateway(server, port, filters) controller = Controller(MailHandler(gateway), hostname='localhost', port=in_port) try: controller.start() while True: pass finally: controller.stop()
def test_mail_with_compatible_smtputf8(self): handler = ReceivingHandler() controller = Controller(handler) controller.start() self.addCleanup(controller.stop) recipient = 'bart\[email protected]' sender = 'anne\[email protected]' with SMTP(controller.hostname, controller.port) as client: client.ehlo('example.com') client.send(bytes( 'MAIL FROM: <' + sender + '> SMTPUTF8\r\n', encoding='utf-8')) code, response = client.getreply() self.assertEqual(code, 250) self.assertEqual(response, b'OK') client.send(bytes( 'RCPT TO: <' + recipient + '>\r\n', encoding='utf-8')) code, response = client.getreply() self.assertEqual(code, 250) self.assertEqual(response, b'OK') code, response = client.data('') self.assertEqual(code, 250) self.assertEqual(response, b'OK') self.assertEqual(handler.box[0].rcpt_tos[0], recipient) self.assertEqual(handler.box[0].mail_from, sender)
def setUp(self): # There are two controllers and two SMTPd's running here. The # "upstream" one listens on port 9025 and is connected to a "data # handler" which captures the messages it receives. The second -and # the one under test here- listens on port 9024 and proxies to the one # on port 9025. Because we need to set the decode_data flag # differently for each different test, the controller of the proxy is # created in the individual tests, not in the setup. self.upstream = DataHandler() upstream_controller = Controller(self.upstream, port=9025) upstream_controller.start() self.addCleanup(upstream_controller.stop) self.proxy = Proxy(upstream_controller.hostname, 9025) self.source = """\ From: Anne Person <*****@*****.**> To: Bart Person <*****@*****.**> Subject: A test Testing """ # The upstream SMTPd will always receive the content as bytes # delimited with CRLF. self.expected = CRLF.join([ 'From: Anne Person <*****@*****.**>', 'To: Bart Person <*****@*****.**>', 'Subject: A test', 'X-Peer: ::1', '', 'Testing']).encode('ascii')
async def run_tests(): with tempfile.TemporaryDirectory() as maildir: # create temporary mailbox for d in ['cur', 'new', 'tmp']: maildirdir = os.path.join(maildir, d) os.mkdir(maildirdir) mailbox = Maildir(maildir) # start smtp server handler = MessageHandler(maildir) controller = Controller(handler) controller.start() # run tests tests = filter( lambda f: f.startswith('test_'), globals().keys(), ) for test in tests: print(test + '...', end=' ') try: await globals()[test](mailbox) except AssertionError: fail() continue succeed()
def _make_relay(code=OK_REPLY): port = unused_tcp_port_factory() handler = DataHandler(port, code) relay = Controller(handler, hostname='127.0.0.1', port=port) relay.start() relays.append(relay) return handler
def startsmtp(): """ async controller""" controller = Controller(SMTPHoney(), hostname="0.0.0.0", port=int(smtpport)) # It calls the class below as my handler. controller.start()
def test_normal_situation(self): cont = Controller(Sink()) try: cont.start() assert cont.smtpd is not None assert cont._thread_exception is None finally: cont.stop()
def test_reuse_loop(self, temp_event_loop): cont = Controller(Sink(), loop=temp_event_loop) assert cont.loop is temp_event_loop try: cont.start() assert cont.smtpd.loop is temp_event_loop finally: cont.stop()
def test_socket_error(self): # Testing starting a server with a port already in use s1 = Controller(Sink(), port=8025) s2 = Controller(Sink(), port=8025) self.addCleanup(s1.stop) self.addCleanup(s2.stop) s1.start() self.assertRaises(socket.error, s2.start)
def test_smtp_utf8(self): controller = Controller(Sink()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: code, response = client.ehlo('example.com') self.assertEqual(code, 250) self.assertIn(b'SMTPUTF8', response.splitlines())
async def amain(loop): #hostname is passed to your loop’s AbstractEventLoop.create_server() method as the host parameter, #except None (default) is translated to ‘::1’. #To bind dual-stack locally, use ‘localhost’. To bind dual-stack on all interfaces, use '' controller = Controller(ExampleHandler(), hostname='', port=os.environ.get("SMTP_PORT")) controller.start()
def test_helo_hook(self): controller = Controller(HELOHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: code, response = client.helo('me') self.assertEqual(code, 250) self.assertEqual(response, b'geddy.example.com')
def test_mail_with_unrequited_smtputf8(self): controller = Controller(Sink()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.ehlo('example.com') code, response = client.docmd('MAIL FROM: <*****@*****.**>') self.assertEqual(code, 250) self.assertEqual(response, b'OK')
def setUp(self): self.tempdir = TemporaryDirectory() self.addCleanup(self.tempdir.cleanup) self.maildir_path = os.path.join(self.tempdir.name, 'maildir') self.handler = handler = Mailbox(self.maildir_path) controller = Controller(handler) controller.start() self.addCleanup(controller.stop) self.address = (controller.hostname, controller.port)
def test_server_attribute(self): controller = Controller(Sink()) self.assertIsNone(controller.server) try: controller.start() self.assertIsNotNone(controller.server) finally: controller.stop() self.assertIsNone(controller.server)
def test_mail_hook(self): controller = Controller(MAILHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.helo('me') code, response = client.mail('*****@*****.**') self.assertEqual(code, 250) self.assertEqual(response, b'Yeah, sure')
def test_socket_error_dupe(self, plain_controller, client): contr2 = Controller(Sink(), hostname=Global.SrvAddr.host, port=Global.SrvAddr.port) try: with pytest.raises(socket.error): contr2.start() finally: contr2.stop()
def test_ehlo_hook(self): controller = Controller(EHLOHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: code, response = client.ehlo('me') self.assertEqual(code, 250) lines = response.decode('utf-8').splitlines() self.assertEqual(lines[-1], 'alex.example.com')
def test_default_greeting(self): controller = Controller(Sink()) controller.start() self.addCleanup(controller.stop) with SMTP() as client: code, msg = client.connect(controller.hostname, controller.port) self.assertEqual(code, 220) # The hostname prefix is unpredictable. self.assertEqual(msg[-len(GREETING):], bytes(GREETING, 'utf-8'))
def test_server_attribute(self): controller = Controller(Sink()) assert controller.server is None try: controller.start() assert controller.server is not None finally: controller.stop() assert controller.server is None
def test_testconn_raises(self, mocker: MockFixture): mocker.patch("socket.socket.recv", side_effect=RuntimeError("MockError")) cont = Controller(Sink(), hostname="") try: with pytest.raises(RuntimeError, match="MockError"): cont.start() finally: cont.stop()
def test_mail_with_incompatible_smtputf8(self): controller = Controller(Sink()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.ehlo('example.com') code, response = client.docmd( 'MAIL FROM: <*****@*****.**> SMTPUTF8=YES') self.assertEqual(code, 501) self.assertEqual(response, b'Error: SMTPUTF8 takes no arguments')
def test_socket_error_dupe(self, plain_controller, client): contr2 = Controller(Sink(), hostname=Global.SrvAddr.host, port=Global.SrvAddr.port) expectedre = r"error while attempting to bind on address" try: with pytest.raises(socket.error, match=expectedre): contr2.start() finally: contr2.stop()
async def amain(): handler = RelayHandler() cont = Controller(handler, hostname='', port=8025, authenticator=Authenticator(DB_AUTH)) try: cont.start() finally: cont.stop()
def test_mail_invalid_body(self): controller = Controller(Sink()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.ehlo('example.com') code, response = client.docmd( 'MAIL FROM: <*****@*****.**> BODY 9BIT') self.assertEqual(code, 501) self.assertEqual(response, b'Error: BODY can only be one of 7BIT, 8BITMIME')
async def amain(loop): try: controller = Controller(ExampleHandler(), loop=None, hostname=None, port=8025) controller.start() except Exception: loop.stop() sys.exit(0) pass
def test_deliver_bytes(self): with ExitStack() as resources: controller = Controller(self.proxy, port=9024) controller.start() resources.callback(controller.stop) client = resources.enter_context( SMTP(*(controller.hostname, controller.port))) client.sendmail( '*****@*****.**', ['*****@*****.**'], self.source) client.quit() self.assertEqual(self.upstream.content, self.expected) self.assertEqual(self.upstream.original_content, self.expected)
class CapturingAiosmtpdServer: """An async SMTP server / context manager for testing RPC effects.""" def __init__(self): self.messages = [] self.handler = CapturingAiosmtpdHandler(context=self) self.controller = Controller( handler=self.handler, hostname="localhost", port=10025) def __enter__(self): self.controller.start() return self def __exit__(self, *exc): self.controller.stop()
def test_data_hook(self): controller = Controller(DATAHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: with self.assertRaises(SMTPDataError) as cm: client.sendmail('*****@*****.**', ['*****@*****.**'], """\ From: [email protected] To: [email protected] Subject: Test Yikes """) self.assertEqual(cm.exception.smtp_code, 599) self.assertEqual(cm.exception.smtp_error, b'Not today')
def test_rcpt_hook(self): controller = Controller(RCPTHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: with self.assertRaises(SMTPRecipientsRefused) as cm: client.sendmail('*****@*****.**', ['*****@*****.**'], """\ From: [email protected] To: [email protected] Subject: Test """) self.assertEqual(cm.exception.recipients, { '*****@*****.**': (550, b'Rejected'), })
def test_no_hooks(self): controller = Controller(NoHooksHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.helo('me') client.mail('*****@*****.**') client.rcpt(['*****@*****.**']) code, response = client.data("""\ From: [email protected] To: [email protected] Subject: Test """) self.assertEqual(code, 250)
def test_process_message_error(self): controller = Controller(ErroringHandler()) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: code, response = client.ehlo('example.com') self.assertEqual(code, 250) with self.assertRaises(SMTPDataError) as cm: client.sendmail('*****@*****.**', ['*****@*****.**'], """\ From: [email protected] To: [email protected] Subject: A test Testing """) self.assertEqual(cm.exception.smtp_code, 499) self.assertEqual(cm.exception.smtp_error, b'Could not accept the message')
def test_message(self): # In this test, the message content comes in as a bytes. handler = DataHandler() controller = Controller(handler) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.sendmail('*****@*****.**', ['*****@*****.**'], """\ From: Anne Person <*****@*****.**> To: Bart Person <*****@*****.**> Subject: A test Message-ID: <ant> Testing """) # The content is not converted, so it's bytes. self.assertEqual(handler.content, handler.original_content) self.assertIsInstance(handler.content, bytes) self.assertIsInstance(handler.original_content, bytes)
def test_message(self): # In this test, the message data comes in as bytes. controller = Controller(self.handler) controller.start() self.addCleanup(controller.stop) with SMTP(controller.hostname, controller.port) as client: client.sendmail('*****@*****.**', ['*****@*****.**'], """\ From: Anne Person <*****@*****.**> To: Bart Person <*****@*****.**> Subject: A test Message-ID: <ant> Testing """) self.assertEqual(self.handled_message['subject'], 'A test') self.assertEqual(self.handled_message['message-id'], '<ant>') self.assertIsNotNone(self.handled_message['X-Peer']) self.assertEqual( self.handled_message['X-MailFrom'], '*****@*****.**') self.assertEqual(self.handled_message['X-RcptTo'], '*****@*****.**')
async def amain(loop): cont = Controller(Sink(), hostname='::0', port=8025) cont.start()
async def smtpd_main(self, hostname, port): cont = Controller(self, hostname=hostname, port=port) cont.start()
def setUp(self): controller = Controller(Sink) controller.start() self.addCleanup(controller.stop) self.address = (controller.hostname, controller.port)