From 702f3f68e1751186ebde1e0d216b366da4092e51 Mon Sep 17 00:00:00 2001 From: Joni Orponen Date: Mon, 1 Oct 2018 14:12:09 +0200 Subject: [PATCH] Enable picking a free port for ZServer layers automatically. --- CHANGES.rst | 4 +++- src/plone/testing/z2.py | 37 +++++++++++++++++++++++++++++++++---- src/plone/testing/z2.rst | 12 ------------ 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index c74a653..8174869 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,7 +6,9 @@ Changelog Breaking changes: -- *add item here* +- Default to picking a dynamical port for ZServer layers instead of a static + default port. + [Rotonen] New features: diff --git a/src/plone/testing/z2.py b/src/plone/testing/z2.py index 17f7a83..b83dd91 100644 --- a/src/plone/testing/z2.py +++ b/src/plone/testing/z2.py @@ -973,8 +973,10 @@ class ZServer(Layer): defaultBases = (STARTUP,) - host = os.environ.get('ZSERVER_HOST', 'localhost') - port = int(os.environ.get('ZSERVER_PORT', 55001)) + # Default to 'bindall' (marked by an empty string) from os.socket + host = os.environ.get('ZSERVER_HOST', '') + # Default to letting the OS allocate us a free port (marked by 0) + port = int(os.environ.get('ZSERVER_PORT', 0)) timeout = 5.0 log = None @@ -1044,6 +1046,17 @@ def setUpServer(self): self.zserver = server + # If we dynamically set the host/port, we want to reset it to localhost + # Otherwise this will depend on, for example, the local network setup + if self.host in ('', '0.0.0.0', '127.0.0.1', ): + self.zserver.server_name = 'localhost' + + # Refresh the hostname and port in case we dynamically picked them + self.host = self.zserver.server_name + self['host'] = self.host + self.port = self.zserver.server_port + self['port'] = self.port + def tearDownServer(self): """Close the ZServer socket """ @@ -1092,8 +1105,10 @@ class FTPServer(ZServer): defaultBases = (STARTUP,) - host = os.environ.get('FTPSERVER_HOST', 'localhost') - port = int(os.environ.get('FTPSERVER_PORT', 55002)) + # Default to 'bindall' (marked by an empty string) from os.socket + host = os.environ.get('FTPSERVER_HOST', '') + # Default to letting the OS allocate us a free port (marked by 0) + port = int(os.environ.get('FTPSERVER_PORT', 0)) threads = 1 timeout = 5.0 log = None @@ -1118,6 +1133,20 @@ def setUpServer(self): port=self.port, logger_object=zopeLog) + + # Refresh the hostname and port in case we dynamically picked them + self.host, self.port = self.ftpServer.socket.getsockname() + + # If we dynamically set the host/port, we want to reset it to localhost + # Otherwise this will depend on, for example, the local network setup + if self.host in ('', '0.0.0.0', '127.0.0.1', ): + self.host = 'localhost' + self.ftpServer.hostname = 'localhost' + self.ftpServer.ip = '127.0.0.1' + + self['host'] = self.host + self['port'] = self.port + def tearDownServer(self): """Close the FTPServer socket """ diff --git a/src/plone/testing/z2.rst b/src/plone/testing/z2.rst index 9ab1b67..8b922ba 100644 --- a/src/plone/testing/z2.rst +++ b/src/plone/testing/z2.rst @@ -467,13 +467,7 @@ The ``ZSERVER`` layer provides a ``FunctionalTesting`` layer that has ``ZSERVER_ After layer setup, the resources ``host`` and ``port`` are available, and indicate where Zope is running.:: >>> host = z2.ZSERVER['host'] - >>> host - 'localhost' - >>> port = z2.ZSERVER['port'] - >>> import os - >>> port == int(os.environ.get('ZSERVER_PORT', 55001)) - True Let's now simulate a test. Test setup does nothing beyond what the base layers do.:: @@ -573,13 +567,7 @@ The ``FTP_SERVER`` layer is based on ``FTP_SERVER_FIXTURE``, using the ``Functio After layer setup, the resources ``host`` and ``port`` are available, and indicate where Zope is running.:: >>> host = z2.FTP_SERVER['host'] - >>> host - 'localhost' - >>> port = z2.FTP_SERVER['port'] - >>> import os - >>> port == int(os.environ.get('FTPSERVER_PORT', 55002)) - True Let's now simulate a test. Test setup does nothing beyond what the base layers do.::