From c5f043eb50e735418287ee394410e5cd66d07033 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com> Date: Tue, 12 Jul 2022 22:25:47 +0900 Subject: [PATCH] ERP5Type/tests: support Zope4's Testing.makerequest.makerequest On Zope2, there was support for starting a ZServer (in Testing.ZopeTestCase.utils.startZServer) and there was another makerequest (in Testing.ZopeTestCase.utils.makerequest) which had knowledge of this ZServer address. We are using our own implementation of startZServer, which also knows how to start a WSGI server, but we we were interacting with Testing.ZopeTestCase.utils so that its makerequest knows about our web server. On Zope4 there is no utility to start an http server from the tests and the makerequest is also gone. This revisits the web server from test interaction with makerequest: - no longer use PortalTestCase._app which creates an app with a request to http://nohost, but implement our own _app which creates a request to our web server - store our server address as class attributes on ProcessingNodeTestCase instead of patching pseudo constants in utils (these pseudo constants no longer exist) - in the case of ERP5TypeLiveTestCase, also rewrap the site to use a request to our web server (which was done on Zope2 by using Testing.ZopeTestCase.utils.makerequest and not Testing.makerequest.makerequest directly) --- .../ERP5Type/tests/ERP5TypeLiveTestCase.py | 12 +++++++-- product/ERP5Type/tests/ERP5TypeTestCase.py | 25 ++++++++++++++++--- .../ERP5Type/tests/ProcessingNodeTestCase.py | 12 ++++----- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/product/ERP5Type/tests/ERP5TypeLiveTestCase.py b/product/ERP5Type/tests/ERP5TypeLiveTestCase.py index 6bcac550455..dd9d9a4a738 100644 --- a/product/ERP5Type/tests/ERP5TypeLiveTestCase.py +++ b/product/ERP5Type/tests/ERP5TypeLiveTestCase.py @@ -89,12 +89,20 @@ class ERP5TypeLiveTestCase(ERP5TypeTestCaseMixin): site = getSite() # reconstruct the acquisition chain with an independent request. # RequestContainer -> Application -> Site - from Testing.ZopeTestCase.utils import makerequest + from Testing.makerequest import makerequest + environ = {} + if self._server_address: + host, port = self._server_address + environ={ + 'SERVER_NAME': host, + 'SERVER_PORT': port, + } portal = getattr( - makerequest(aq_base(site.aq_parent)), + makerequest(aq_base(site.aq_parent), environ=environ), site.getId()) # Make the various get_request patches return this request. + # TODO: check this is still needed # This is for ERP5TypeTestCase patch from Testing.ZopeTestCase.connections import registry if registry: diff --git a/product/ERP5Type/tests/ERP5TypeTestCase.py b/product/ERP5Type/tests/ERP5TypeTestCase.py index 738dec13de4..41a4cd95114 100644 --- a/product/ERP5Type/tests/ERP5TypeTestCase.py +++ b/product/ERP5Type/tests/ERP5TypeTestCase.py @@ -57,7 +57,8 @@ getRequest.__code__ = (lambda: get_request()).__code__ from zope.site.hooks import setSite from Testing import ZopeTestCase -from Testing.ZopeTestCase import PortalTestCase, user_name +from Testing.makerequest import makerequest +from Testing.ZopeTestCase import PortalTestCase, user_name, ZopeLite from Products.ERP5Type.Core.Workflow import ValidationFailed from Products.PythonScripts.PythonScript import PythonScript from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter @@ -1019,9 +1020,25 @@ class ERP5TypeCommandLineTestCase(ERP5TypeTestCaseMixin): def _app(self): '''Opens a ZODB connection and returns the app object. - We override it to patch HTTP_ACCEPT_CHARSET into REQUEST to get the zpt - unicode conflict resolver to work properly''' - app = PortalTestCase._app(self) + We override this method so that the request knows about the address of + our http server and also to set HTTP_ACCEPT_CHARSET set in REQUEST, to + get the zpt unicode conflict resolver to + work properly. + + We reimplement PortalTestCase._app instead of calling it, because it + opens a ZODB connection and wrap the root object a request to + http://nohost, but we prefer to create directly a connection to the + app wrapped in a request to our web server. + ''' + app = ZopeLite.app() + environ = {} + if self._server_address: + host, port = self._server_address + environ['SERVER_NAME'] = host + environ['SERVER_PORT'] = port + + app = makerequest(app, environ=environ) + registry.register(app) app.REQUEST['HTTP_ACCEPT_CHARSET'] = 'utf-8' return app diff --git a/product/ERP5Type/tests/ProcessingNodeTestCase.py b/product/ERP5Type/tests/ProcessingNodeTestCase.py index 667394b5167..3ff1296ad27 100644 --- a/product/ERP5Type/tests/ProcessingNodeTestCase.py +++ b/product/ERP5Type/tests/ProcessingNodeTestCase.py @@ -138,6 +138,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase): the node running the unit tests to tell other nodes on which portal activities should be processed. """ + _server_address = None # (host, port) of the http server if it was started, None otherwise @staticmethod def asyncore_loop(): @@ -149,8 +150,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase): def startZServer(self, verbose=False): """Start HTTP ZServer in background""" - utils = ZopeTestCase.utils - if utils._Z2HOST is None: + if self._server_address is None: from Products.ERP5Type.tests.runUnitTest import log_directory log = os.path.join(log_directory, "Z2.log") message = "Running %s server at %s:%s\n" @@ -192,7 +192,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase): logger.propagate = False hs = createServer(app_wrapper(webdav_ports=webdav_ports), logger, sockets=sockets) - utils._Z2HOST, utils._Z2PORT = hs.addr + ProcessingNodeTestCase._server_address = hs.addr t = Thread(target=hs.run) t.setDaemon(1) t.start() @@ -204,7 +204,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase): except RuntimeError as e: ZopeTestCase._print(str(e)) else: - utils._Z2HOST, utils._Z2PORT = hs.server_name, hs.server_port + ProcessingNodeTestCase._server_address = hs.server_name, hs.server_port _print(hs) try: _print(createZServer(log, zserver_type='webdav')) @@ -220,7 +220,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase): if ActivityTool.currentNode == ActivityTool._server_address: ActivityTool.currentNode = None ActivityTool._server_address = None - return utils._Z2HOST, utils._Z2PORT + return self._server_address def _registerNode(self, distributing, processing): """Register node to process and/or distribute activities""" @@ -241,7 +241,7 @@ class ProcessingNodeTestCase(ZopeTestCase.TestCase): @classmethod def unregisterNode(cls): - if ZopeTestCase.utils._Z2HOST is not None: + if cls._server_address is not None: self = cls('unregisterNode') self.app = self._app() self._registerNode(distributing=0, processing=0) -- 2.30.9