Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
15 changes: 13 additions & 2 deletions scripts/ci/detect_test_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -557,18 +557,29 @@ def _volume_split_count(selected_paths: list[str], repo_root: Path | None) -> in


def _count_test_files(selected_paths: list[str], repo_root: Path) -> int:
"""Count ``test_*.py`` files a selection covers.
"""Count the collectable test files a selection covers.

``selected_paths`` entries are either a directory (module-grain sentinel,
e.g. ``tests/unit/`` or ``tests/unit/cli/`` — walked recursively) or an
individual test FILE (OMN-14921 file-grain closure output, e.g.
``tests/unit/cli/test_foo.py`` — counted directly, no walk needed).

Directory walks count every name :func:`is_test_file_name` accepts — i.e.
the whole of ``TEST_FILE_PATTERNS``, which mirrors pytest's ``python_files``
— not just the ``test_*.py`` half. Counting only one pattern here while
``_contains_collectable_test`` admits both would let a directory be SELECTED
on the strength of files this function then does not count, undercounting
the volume and emitting too few matrix splits (OMN-16917 review finding).
"""
total = 0
for rel in selected_paths:
target = repo_root / rel
if target.is_dir():
total += sum(1 for _ in target.rglob("test_*.py"))
total += sum(
1
for candidate in target.rglob("*.py")
if is_test_file_name(candidate.name)
)
elif target.is_file():
total += 1
return total
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,10 @@

from scripts.ci.detect_test_paths import (
CI_CONTRACT_TEST_ROOT,
_count_test_files,
ci_contract_test_paths,
compute_selection,
is_test_file_name,
unnarrowable_test_paths,
)
from scripts.ci.test_selection_closure import compute_closure_selection
Expand Down Expand Up @@ -309,3 +311,28 @@ def test_source_only_diff_is_byte_for_byte_the_pre_existing_closure_path() -> No

assert selection.is_full_suite is False
assert selection.selected_paths == expected


def test_split_count_counts_every_configured_test_filename_pattern(
tmp_path: Path,
) -> None:
"""Volume counting honours ALL of ``TEST_FILE_PATTERNS``, not just half.

``_contains_collectable_test`` admits a directory on either pattern, so a
directory can be SELECTED on the strength of ``*_test.py`` files. If the
volume counter only globbed ``test_*.py`` it would not count the files that
justified the selection, undercount the volume, and emit too few matrix
splits — a selection whose own proof is invisible to its sizing.

Asserted against the counter directly so the invariant holds regardless of
which patterns happen to be populated in the live tree today.
"""
suite = tmp_path / "tests" / "suite"
suite.mkdir(parents=True)
(suite / "test_prefix_style.py").write_text("def test_a() -> None: ...\n")
(suite / "suffix_style_test.py").write_text("def test_b() -> None: ...\n")
(suite / "helper.py").write_text("VALUE = 1\n")

assert _count_test_files(["tests/suite/"], tmp_path) == 2
assert is_test_file_name("suffix_style_test.py") is True
assert is_test_file_name("helper.py") is False
Loading