Skip to content

Commit 293bc55

Browse files
authored
Deselect DB tests at collection time instead of skipping at runtime (#63791)
Move DB/non-DB test filtering from pytest_runtest_setup (where each xdist worker had to import test modules only to skip them) to `pytest_collection_modifyitems` (where items are deselected before distribution). This avoids distributing ~6350 unwanted items to workers entirely, reducing memory usage and unnecessary imports.
1 parent 2d2d8a2 commit 293bc55

File tree

1 file changed

+37
-35
lines changed

1 file changed

+37
-35
lines changed

devel-common/src/tests_common/pytest_plugin.py

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -635,37 +635,6 @@ def skip_quarantined_test(item):
635635
)
636636

637637

638-
def skip_db_test(item):
639-
if next(item.iter_markers(name="db_test"), None):
640-
if next(item.iter_markers(name="non_db_test_override"), None):
641-
# non_db_test can override the db_test set for example on module or class level
642-
return
643-
pytest.skip(
644-
f"The test is skipped as it is DB test and --skip-db-tests is flag is passed to pytest. {item}"
645-
)
646-
if next(item.iter_markers(name="backend"), None):
647-
# also automatically skip tests marked with `backend` marker as they are implicitly
648-
# db tests
649-
pytest.skip(
650-
f"The test is skipped as it is DB test and --skip-db-tests is flag is passed to pytest. {item}"
651-
)
652-
653-
654-
def only_run_db_test(item):
655-
if next(item.iter_markers(name="db_test"), None) and not next(
656-
item.iter_markers(name="non_db_test_override"), None
657-
):
658-
# non_db_test at individual level can override the db_test set for example on module or class level
659-
return
660-
if next(item.iter_markers(name="backend"), None):
661-
# Also do not skip the tests marked with `backend` marker - as it is implicitly a db test
662-
return
663-
pytest.skip(
664-
f"The test is skipped as it is not a DB tests "
665-
f"and --run-db-tests-only flag is passed to pytest. {item}"
666-
)
667-
668-
669638
def skip_if_integration_disabled(marker, item):
670639
integration_name = marker.args[0]
671640
environment_variable_name = "INTEGRATION_" + integration_name.upper()
@@ -712,6 +681,43 @@ def skip_if_credential_file_missing(item):
712681
pytest.skip(f"The test requires credential file {credential_path}: {item}")
713682

714683

684+
def _is_db_test(item) -> bool:
685+
"""Check if a test item should be treated as a DB test."""
686+
if next(item.iter_markers(name="db_test"), None):
687+
if next(item.iter_markers(name="non_db_test_override"), None):
688+
return False
689+
return True
690+
if next(item.iter_markers(name="backend"), None):
691+
return True
692+
return False
693+
694+
695+
def pytest_collection_modifyitems(config, items):
696+
"""Deselect DB/non-DB tests early so pytest-xdist workers never receive them.
697+
698+
Previously these tests were skipped at runtime via pytest_runtest_setup, which
699+
still required every xdist worker to import the test modules. With thousands of
700+
DB tests being skipped in non-DB runs, this caused excessive memory usage — enough
701+
to OOM on Python 3.14 CI runners. Deselecting during collection avoids distributing
702+
these items to workers entirely.
703+
"""
704+
if not skip_db_tests and not run_db_tests_only:
705+
return
706+
707+
selected = []
708+
deselected = []
709+
for item in items:
710+
is_db = _is_db_test(item)
711+
if (skip_db_tests and is_db) or (run_db_tests_only and not is_db):
712+
deselected.append(item)
713+
else:
714+
selected.append(item)
715+
716+
if deselected:
717+
config.hook.pytest_deselected(items=deselected)
718+
items[:] = selected
719+
720+
715721
def pytest_runtest_setup(item):
716722
selected_integrations_list = item.config.option.integration
717723

@@ -737,10 +743,6 @@ def pytest_runtest_setup(item):
737743
skip_long_running_test(item)
738744
if not include_quarantined:
739745
skip_quarantined_test(item)
740-
if skip_db_tests:
741-
skip_db_test(item)
742-
if run_db_tests_only:
743-
only_run_db_test(item)
744746
skip_if_credential_file_missing(item)
745747

746748

0 commit comments

Comments
 (0)