You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The underlying event loop supports port=0 for letting the operating system pick a random free port.
This is useful when using the smtp server in unit tests.
However, aiosmtp does not work with port=0 because it tries to connect to this port in _trigger_server, not to the port actually chosen by the OS:
mock_mail_server.py:30: in start
s._controller.start()
venv-3.12\Lib\site-packages\aiosmtpd\controller.py:306: in start
self._trigger_server()
venv-3.12\Lib\site-packages\aiosmtpd\controller.py:501: in _trigger_server
InetMixin._trigger_server(self)
venv-3.12\Lib\site-packages\aiosmtpd\controller.py:444: in _trigger_server
s = stk.enter_context(create_connection((hostname, self.port), 1.0))
C:\Program Files\Python312\Lib\socket.py:852: in create_connection
E OSError: [WinError 10049] The requested address is not valid in its context
portpicker is a possible workaround, but requires complex setup (port server daemon) to avoid race conditions.
It would be better if aiosmtpd directly supported port=0. This would involve using server.sockets[0].get_sock_name() for finding the port actually used. There would also need to be some way for the code starting the server to wait until the socket is opened so that the port is known and can be passed to the code under test.
I've hacked together an external solution by deriving from Controller:
classControllerWithSupportForRandomPort(aiosmtpd.controller.Controller):
def__init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._port_known=threading.Event()
def_trigger_server(self):
# The InetMixin base class expects to be able to connect to# self.hostname/self.port, which are the parameters passed to __init__.# If port==0 (as in our tests), this does not work as the server chooses a random# free port. Instead use the port that was chosen by the operating system.assertself.serverisnotNoneactual_name=self.server.sockets[0].getsockname()
self.hostname=actual_name[0]
self.port=actual_name[1]
self._port_known.set()
returnsuper()._trigger_server()
defwait_for_port(self):
# Allows the unit test to wait until `self.port` is set correctly# before accessing that.self._port_known.wait()
The text was updated successfully, but these errors were encountered:
The underlying event loop supports
port=0
for letting the operating system pick a random free port.This is useful when using the smtp server in unit tests.
However, aiosmtp does not work with
port=0
because it tries to connect to this port in_trigger_server
, not to the port actually chosen by the OS:portpicker is a possible workaround, but requires complex setup (port server daemon) to avoid race conditions.
It would be better if aiosmtpd directly supported
port=0
. This would involve usingserver.sockets[0].get_sock_name()
for finding the port actually used. There would also need to be some way for the code starting the server to wait until the socket is opened so that the port is known and can be passed to the code under test.I've hacked together an external solution by deriving from
Controller
:The text was updated successfully, but these errors were encountered: