Skip to content

Commit 6e925f3

Browse files
authored
Merge pull request #77 from acsone/master-distributed-run
Add support for distributed run
2 parents b4e05a5 + 0168a0e commit 6e925f3

File tree

2 files changed

+28
-1
lines changed

2 files changed

+28
-1
lines changed

README.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,5 @@ You can use the ``ODOO_RC`` environment variable using an odoo configuration fil
5151
export ODOO_RC=/path/to/odoo/config.cfg
5252
pytest ...
5353

54+
The plugin is also compatible with distributed run provided by the `pytest-xdist <https://pypi.org/project/pytest-xdist/>`_ library. When tests are distributed, a copy of the database is created for each worker at the start of the test session.
55+
This is useful to avoid concurrent access to the same database, which can lead to deadlocks. The provided database is therefore used only as template. At the end of the tests, all the created databases are dropped.

pytest_odoo.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import os
99
import signal
1010
import threading
11+
from contextlib import contextmanager
1112
from pathlib import Path
1213
from typing import Optional
1314

@@ -110,6 +111,28 @@ def load_http(request):
110111
signal.signal(signal.SIGINT, signal.default_int_handler)
111112

112113

114+
@contextmanager
115+
def _worker_db_name():
116+
# This method ensure that if tests are ran in a distributed way
117+
# thanks to the use of pytest-xdist addon, each worker will use
118+
# a specific copy of the initial database to run their tests.
119+
# In this way we prevent deadlock errors.
120+
xdist_worker = os.getenv("PYTEST_XDIST_WORKER")
121+
original_db_name = db_name = odoo.tests.common.get_db_name()
122+
try:
123+
if xdist_worker:
124+
db_name = f"{original_db_name}-{xdist_worker}"
125+
os.system(f"dropdb {db_name} --if-exists")
126+
os.system(f"createdb -T {original_db_name} {db_name}")
127+
odoo.tools.config["db_name"] = db_name
128+
yield db_name
129+
finally:
130+
if db_name != original_db_name:
131+
odoo.sql_db.close_db(db_name)
132+
os.system(f"dropdb {db_name}")
133+
odoo.tools.config["db_name"] = original_db_name
134+
135+
113136
@pytest.fixture(scope='session', autouse=True)
114137
def load_registry():
115138
# Initialize the registry before running tests.
@@ -121,7 +144,9 @@ def load_registry():
121144
# Finally we enable `testing` flag on current thread
122145
# since Odoo sets it when loading test suites.
123146
threading.current_thread().testing = True
124-
odoo.registry(odoo.tests.common.get_db_name())
147+
with _worker_db_name() as db_name:
148+
odoo.registry(db_name)
149+
yield
125150

126151

127152
@pytest.fixture(scope='module', autouse=True)

0 commit comments

Comments
 (0)