[FIX] core: have HttpCase automatically set the base url

While HttpCase did set `web.base.url` before starting a browser, in
the non-browser test cases (or cases which would mix browser and
non-browser) it would not do so.

This is an issue when installing the database with one http-port and
running tests with an other e.g. after duplicating the database (or
even not duplicating it) in order to run multiple test instances
concurrently, which requires using different http ports.

Tests would then see the base url generated during installation,
embedding the port used at installation, and would break weirdly (at
best exploding due to not finding any server to bind to, and at worst
making request on the wrong instance entirely). Simply updating the
base url during setup seems to fix most of the tests.

Notes:

* Some tests (e.g. survey) don't flush() their create/update before
  calling `start_tour` or `browser_js`, the implicit flush because of
  the ICP handled the issue. Perform an explicit flush of base
  (similar to `url_open`) to ensure they keep working correctly.
* `url_join` should handle absolute URIs correctly, it does imply
  slightly different semantics in case the `base_url` has a non-empty
  path, but that seems like a very limited risk (and possibly
  convenient to boot).
* `payment` needed a fix because the vagaries of the MRO led to the
  extra parameter internally used by the thing to be passed to
  `HttpCase`'s `setUpClass`, which would not expect it.

closes odoo/odoo#72645

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
This commit is contained in:
Xavier Morel
2021-06-25 09:13:49 +00:00
parent 58503a248e
commit ded278b9c2
2 changed files with 15 additions and 11 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ from odoo.tests import HttpCase
from odoo.addons.payment.tests.utils import PaymentTestUtils
class PaymentHttpCommon(HttpCase, PaymentTestUtils):
class PaymentHttpCommon(PaymentTestUtils, HttpCase):
""" HttpCase common to build and simulate requests going through payment controllers.
Only use if you effectively want to test controllers.
+14 -10
View File
@@ -1365,6 +1365,14 @@ class HttpCase(TransactionCase):
cls = type(self)
cls._logger = logging.getLogger('%s.%s' % (cls.__module__, cls.__name__))
@classmethod
def setUpClass(cls):
super().setUpClass()
ICP = cls.env['ir.config_parameter']
ICP.set_param('web.base.url', cls.base_url())
ICP.flush()
def setUp(self):
super().setUp()
if self.registry_test_mode:
@@ -1482,16 +1490,8 @@ class HttpCase(TransactionCase):
try:
self.authenticate(login, login)
base_url = "http://%s:%s" % (HOST, odoo.tools.config['http_port'])
ICP = self.env['ir.config_parameter']
ICP.set_param('web.base.url', base_url)
# flush updates to the database before launching the client side,
# otherwise they simply won't be visible
ICP.flush()
if re.match('[a-z]*:', url_path or ''): # about:, http:, ...
url = url_path
else:
url = "%s%s" % (base_url, url_path or '/')
self.env['base'].flush()
url = werkzeug.urls.url_join(self.base_url(), url_path)
self._logger.info('Open "%s" in browser', url)
if self.browser.screencasts_dir:
@@ -1523,6 +1523,10 @@ class HttpCase(TransactionCase):
self.browser.clear()
self._wait_remaining_requests()
@classmethod
def base_url(cls):
return "http://%s:%s" % (HOST, odoo.tools.config['http_port'])
def start_tour(self, url_path, tour_name, step_delay=None, **kwargs):
"""Wrapper for `browser_js` to start the given `tour_name` with the
optional delay between steps `step_delay`. Other arguments from