From 6b3c81a177c8819bef3c4d41ede8b707492b01e8 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 21 Jan 2020 14:56:57 +0100 Subject: [PATCH] [FIX] make pytest cross-module-runnable The pytest suite had been partially unified between mergebot and forwardport but because of session-scoped modules it could not run across those. Make the db cache lazy and able to cache multiple databases, and move the "current required module" to function scoped, this way things should (and seem to) work properly on runs involving mergebot & fwbot. Next step: xdist! (need to randomise repo names for that, probably). --- conftest.py | 40 +++++++++++++++++++--------------- forwardport/tests/conftest.py | 2 +- runbot_merge/tests/conftest.py | 2 +- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/conftest.py b/conftest.py index 8610cac8..ff2d01fd 100644 --- a/conftest.py +++ b/conftest.py @@ -66,7 +66,6 @@ NGROK_CLI = [ def pytest_addoption(parser): parser.addoption('--addons-path') - parser.addoption('--db', help="DB to run the tests against", default='template_%s' % uuid.uuid4()) parser.addoption("--no-delete", action="store_true", help="Don't delete repo after a failed run") parser.addoption( @@ -79,9 +78,6 @@ def pytest_addoption(parser): "blow through the former); localtunnel has no rate-limiting but " "the servers are way less reliable") -def pytest_report_header(config): - return 'Running against database ' + config.getoption('--db') - @pytest.fixture(scope='session', autouse=True) def _set_socket_timeout(): """ Avoid unlimited wait on standard sockets during tests, this is mostly @@ -220,26 +216,36 @@ def tunnel(pytestconfig, port): else: raise ValueError("Unsupported %s tunnel method" % tunnel) +class DbDict(dict): + def __init__(self, adpath): + super().__init__() + self._adpath = adpath + def __missing__(self, module): + db = 'template_%s' % uuid.uuid4() + subprocess.run([ + 'odoo', '--no-http', + '--addons-path', self._adpath, + '-d', db, '-i', module, + '--max-cron-threads', '0', + '--stop-after-init' + ]) + self[module] = db + return db + @pytest.fixture(scope='session') -def dbcache(request, module): +def dbcache(request): """ Creates template DB once per run, then just duplicates it before starting odoo and running the testcase """ - db = request.config.getoption('--db') - subprocess.run([ - 'odoo', '--no-http', - '--addons-path', request.config.getoption('--addons-path'), - '-d', db, '-i', module, - '--max-cron-threads', '0', - '--stop-after-init' - ], check=True) - yield db - subprocess.run(['dropdb', db], check=True) + dbs = DbDict(request.config.getoption('--addons-path')) + yield dbs + for db in dbs.values(): + subprocess.run(['dropdb', db], check=True) @pytest.fixture -def db(request, dbcache): +def db(request, module, dbcache): rundb = str(uuid.uuid4()) - subprocess.run(['createdb', '-T', dbcache, rundb], check=True) + subprocess.run(['createdb', '-T', dbcache[module], rundb], check=True) yield rundb diff --git a/forwardport/tests/conftest.py b/forwardport/tests/conftest.py index efbeb2b6..3533de46 100644 --- a/forwardport/tests/conftest.py +++ b/forwardport/tests/conftest.py @@ -60,7 +60,7 @@ def _cleanup_cache(config, users): for login in users.values(): rmtree(cache_root / login, ignore_errors=True) -@pytest.fixture(scope='session') +@pytest.fixture() def module(): """ When a test function is (going to be) run, selects the containing module (as needing to be installed) diff --git a/runbot_merge/tests/conftest.py b/runbot_merge/tests/conftest.py index b33698dd..e16707d2 100644 --- a/runbot_merge/tests/conftest.py +++ b/runbot_merge/tests/conftest.py @@ -1,7 +1,7 @@ import pytest import requests -@pytest.fixture(scope='session') +@pytest.fixture() def module(): return 'runbot_merge'