Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for distributed run #77

Merged
merged 2 commits into from
Oct 7, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,5 @@ You can use the ``ODOO_RC`` environment variable using an odoo configuration fil
export ODOO_RC=/path/to/odoo/config.cfg
pytest ...

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.
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.
29 changes: 28 additions & 1 deletion pytest_odoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
import signal
import threading
from contextlib import contextmanager
from pathlib import Path
from typing import Optional

Expand Down Expand Up @@ -110,6 +111,30 @@ def load_http(request):
signal.signal(signal.SIGINT, signal.default_int_handler)


@contextmanager
def _worker_db_name():
# This method ensure that if tests are ran in a distributed way
# thanks to the use of pytest-xdist addon, each worker will use
# a specific copy of the initial database to run their tests.
# In this way we prevent deadlock errors.
xdist_worker = os.getenv("PYTEST_XDIST_WORKER")
original_db_name = db_name = odoo.tests.common.get_db_name()
try:
if xdist_worker:
db_name = f"{original_db_name}-{xdist_worker}"
ret = os.system(f"psql -lqt | cut -d \| -f 1 | grep -w {db_name}")
if ret == 0:
os.system(f"dropdb {db_name}")
lmignon marked this conversation as resolved.
Show resolved Hide resolved
os.system(f"createdb -T {original_db_name} {db_name}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this sounds a very opinionated way to connect to the database, probably we should at least add such limitation in the Readme file or read odoo config file to retrieves host and credentials informations

Copy link
Member

@yvaucher yvaucher Oct 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can already configure psql with env var to get to the right config with PGDATABASE, PGUSER, PGHOST and so on. Using psql, dropdb and createdb without params seems fine to me.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes indeed 👍 !

odoo.tools.config["db_name"] = db_name
yield db_name
finally:
if db_name != original_db_name:
odoo.sql_db.close_db(db_name)
os.system(f"dropdb {db_name}")
odoo.tools.config["db_name"] = original_db_name


@pytest.fixture(scope='session', autouse=True)
def load_registry():
# Initialize the registry before running tests.
Expand All @@ -121,7 +146,9 @@ def load_registry():
# Finally we enable `testing` flag on current thread
# since Odoo sets it when loading test suites.
threading.current_thread().testing = True
odoo.registry(odoo.tests.common.get_db_name())
with _worker_db_name() as db_name:
odoo.registry(db_name)
yield


@pytest.fixture(scope='module', autouse=True)
Expand Down
Loading