Skip to content

Commit 7282d75

Browse files
committed
Rename test databases when running parallel Tox
When tests are executed using Tox in parallel, modify the test database names, to avoid name collisions between processes. This change renames the existing `django_db_modify_db_settings_xdist_suffix` fixture, to a generic `django_db_modify_db_settings_parallel_suffix` one, in case more scenarios/tools have to be considered in the future. It also handles projects where both `pytest-xdist` and parallel `tox` are being using, generating database names like `test_default_py37-django21_gw0`. Resolves #678.
1 parent 82de481 commit 7282d75

File tree

3 files changed

+51
-25
lines changed

3 files changed

+51
-25
lines changed

docs/database.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -191,18 +191,18 @@ If you need to customize the location of your test database, this is the
191191
fixture you want to override.
192192

193193
The default implementation of this fixture requests the
194-
:fixture:`django_db_modify_db_settings_xdist_suffix` to provide compatibility
194+
:fixture:`django_db_modify_db_settings_parallel_suffix` to provide compatibility
195195
with pytest-xdist.
196196

197197
This fixture is by default requested from :fixture:`django_db_setup`.
198198

199-
django_db_modify_db_settings_xdist_suffix
200-
"""""""""""""""""""""""""""""""""""""""""
199+
django_db_modify_db_settings_parallel_suffix
200+
""""""""""""""""""""""""""""""""""""""""""""
201201

202-
.. fixture:: django_db_modify_db_settings_xdist_suffix
202+
.. fixture:: django_db_modify_db_settings_parallel_suffix
203203

204204
Requesting this fixture will add a suffix to the database name when the tests
205-
are run via pytest-xdist.
205+
are run via `pytest-xdist`, or via `tox` when running in parallel.
206206

207207
This fixture is by default requested from
208208
:fixture:`django_db_modify_db_settings`.

pytest_django/fixtures.py

Lines changed: 45 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,35 +33,36 @@
3333

3434

3535
@pytest.fixture(scope="session")
36-
def django_db_modify_db_settings_xdist_suffix(request):
36+
def django_db_modify_db_settings_tox_suffix(request):
3737
skip_if_no_django()
3838

39-
from django.conf import settings
39+
is_tox_parallel = os.environ.get("TOX_PARALLEL_ENV")
40+
tox_environment = os.environ.get("TOXENV")
41+
if is_tox_parallel and tox_environment:
42+
# Put a suffix like _py27-django21 on tox workers
43+
_set_suffix_to_test_databases(suffix=tox_environment)
4044

41-
for db_settings in settings.DATABASES.values():
42-
43-
try:
44-
test_name = db_settings["TEST"]["NAME"]
45-
except KeyError:
46-
test_name = None
4745

48-
if not test_name:
49-
if db_settings["ENGINE"] == "django.db.backends.sqlite3":
50-
return ":memory:"
51-
else:
52-
test_name = "test_{}".format(db_settings["NAME"])
46+
@pytest.fixture(scope="session")
47+
def django_db_modify_db_settings_xdist_suffix(request):
48+
skip_if_no_django()
5349

50+
xdist_suffix = getattr(request.config, "slaveinput", {}).get("slaveid")
51+
if xdist_suffix:
5452
# Put a suffix like _gw0, _gw1 etc on xdist processes
55-
xdist_suffix = getattr(request.config, "slaveinput", {}).get("slaveid")
56-
if test_name != ":memory:" and xdist_suffix is not None:
57-
test_name = "{}_{}".format(test_name, xdist_suffix)
53+
_set_suffix_to_test_databases(suffix=xdist_suffix)
5854

59-
db_settings.setdefault("TEST", {})
60-
db_settings["TEST"]["NAME"] = test_name
55+
56+
@pytest.fixture(scope="session")
57+
def django_db_modify_db_settings_parallel_suffix(
58+
django_db_modify_db_settings_tox_suffix,
59+
django_db_modify_db_settings_xdist_suffix,
60+
):
61+
skip_if_no_django()
6162

6263

6364
@pytest.fixture(scope="session")
64-
def django_db_modify_db_settings(django_db_modify_db_settings_xdist_suffix):
65+
def django_db_modify_db_settings(django_db_modify_db_settings_parallel_suffix):
6566
skip_if_no_django()
6667

6768

@@ -153,6 +154,31 @@ def _disable_native_migrations():
153154
settings.MIGRATION_MODULES = DisableMigrations()
154155

155156

157+
def _set_suffix_to_test_databases(suffix):
158+
if not suffix:
159+
return
160+
161+
from django.conf import settings
162+
163+
for db_settings in settings.DATABASES.values():
164+
165+
try:
166+
test_name = db_settings["TEST"]["NAME"]
167+
except KeyError:
168+
test_name = None
169+
170+
if not test_name:
171+
if db_settings["ENGINE"] == "django.db.backends.sqlite3":
172+
continue
173+
test_name = "test_{}".format(db_settings["NAME"])
174+
175+
if test_name == ":memory:":
176+
continue
177+
178+
db_settings.setdefault("TEST", {})
179+
db_settings["TEST"]["NAME"] = "{}_{}".format(test_name, suffix)
180+
181+
156182
# ############### User visible fixtures ################
157183

158184

pytest_django/plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from .fixtures import django_db_keepdb # noqa
2222
from .fixtures import django_db_createdb # noqa
2323
from .fixtures import django_db_modify_db_settings # noqa
24-
from .fixtures import django_db_modify_db_settings_xdist_suffix # noqa
24+
from .fixtures import django_db_modify_db_settings_parallel_suffix # noqa
2525
from .fixtures import _live_server_helper # noqa
2626
from .fixtures import admin_client # noqa
2727
from .fixtures import admin_user # noqa

0 commit comments

Comments
 (0)