Skip to content

Commit

Permalink
Do not collect symlinked tests under Windows
Browse files Browse the repository at this point in the history
The check for short paths under Windows via os.path.samefile, introduced in pytest-dev#11936, also found similar tests in symlinked tests in the GH Actions CI.
This checks additionally that one of the files is not a symlink.

Fixes pytest-dev#12039.
  • Loading branch information
mrbean-bremen committed Mar 3, 2024
1 parent 6ed0051 commit d417b44
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 2 deletions.
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ Mike Hoyle (hoylemd)
Mike Lundy
Milan Lesnek
Miro Hrončok
mrbean-bremen
Nathaniel Compton
Nathaniel Waisbrot
Ned Batchelder
Expand Down
1 change: 1 addition & 0 deletions changelog/12039.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed a regression in 8.0.2 where tests have been collected multiple times in the CI under Windows
9 changes: 8 additions & 1 deletion src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -924,7 +924,14 @@ def collect(self) -> Iterator[Union[nodes.Item, nodes.Collector]]:
if sys.platform == "win32" and not is_match:
# In case the file paths do not match, fallback to samefile() to
# account for short-paths on Windows (#11895).
is_match = os.path.samefile(node.path, matchparts[0])
same_file = os.path.samefile(node.path, matchparts[0])
# we don't want to find links, so we at least
# exclude symlinks to regular directories
is_match = (
same_file and
os.path.islink(node.path) == os.path.islink(matchparts[0])
)

# Name part e.g. `TestIt` in `/a/b/test_file.py::TestIt::test_it`.
else:
# TODO: Remove parametrized workaround once collection structure contains
Expand Down
11 changes: 10 additions & 1 deletion testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -1765,7 +1765,7 @@ def test_foo(): assert True

@pytest.mark.skipif(not sys.platform.startswith("win"), reason="Windows only")
def test_collect_short_file_windows(pytester: Pytester) -> None:
"""Reproducer for #11895: short paths not colleced on Windows."""
"""Reproducer for #11895: short paths not collected on Windows."""
short_path = tempfile.mkdtemp()
if "~" not in short_path: # pragma: no cover
if running_on_ci():
Expand Down Expand Up @@ -1832,3 +1832,12 @@ def test_pyargs_collection_tree(pytester: Pytester, monkeypatch: MonkeyPatch) ->
],
consecutive=True,
)


def test_collect_symlinks(pytester: Pytester, tmpdir) -> None:
"""Regression test for #12039: Tests collected multiple times under Windows."""
test_file = Path(tmpdir) / "symlink_collection_test.py"
test_file.write_text("def test(): pass", encoding="UTF-8")
result = pytester.runpytest(tmpdir)
# this failed in CI only (GitHub actions)
assert result.parseoutcomes() == {"passed": 1}

0 comments on commit d417b44

Please sign in to comment.