Skip to content

tests: re-harden test_cmdline_python_package_symlink #6733

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

Closed
wants to merge 8 commits into from
33 changes: 14 additions & 19 deletions testing/acceptance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,21 +762,13 @@ def test():
result = testdir.runpytest(str(p) + "::test", "--doctest-modules")
result.stdout.fnmatch_lines(["*1 passed*"])

def test_cmdline_python_package_symlink(self, testdir, monkeypatch):
def test_cmdline_python_package_symlink(
self, testdir, monkeypatch, symlink_or_skip
):
"""
test --pyargs option with packages with path containing symlink can
have conftest.py in their package (#2985)
"""
# dummy check that we can actually create symlinks: on Windows `os.symlink` is available,
# but normal users require special admin privileges to create symlinks.
if sys.platform == "win32":
try:
os.symlink(
str(testdir.tmpdir.ensure("tmpfile")),
str(testdir.tmpdir.join("tmpfile2")),
)
except OSError as e:
pytest.skip(str(e.args[0]))
monkeypatch.delenv("PYTHONDONTWRITEBYTECODE", raising=False)

dirname = "lib"
Expand All @@ -794,7 +786,11 @@ def test_cmdline_python_package_symlink(self, testdir, monkeypatch):

d_local = testdir.mkdir("local")
symlink_location = os.path.join(str(d_local), "lib")
os.symlink(str(d), symlink_location, target_is_directory=True)
try:
symlink_or_skip(str(d), symlink_location, target_is_directory=True)
has_symlinks = True
except pytest.skip.Exception:
has_symlinks = False

# The structure of the test directory is now:
# .
Expand All @@ -816,22 +812,21 @@ def test_cmdline_python_package_symlink(self, testdir, monkeypatch):

# module picked up in symlink-ed directory:
# It picks up local/lib/foo/bar (symlink) via sys.path.
result = testdir.runpytest("--pyargs", "-v", "foo.bar")
testdir.chdir()
result = testdir.runpytest("--pyargs", "-vv", "foo.bar")
assert result.ret == 0
if hasattr(py.path.local, "mksymlinkto"):
if has_symlinks:
result.stdout.fnmatch_lines(
[
"lib/foo/bar/test_bar.py::test_bar PASSED*",
"lib/foo/bar/test_bar.py::test_other PASSED*",
"lib/foo/bar/test_bar.py::test_bar <- local/lib/foo/bar/test_bar.py PASSED*",
"lib/foo/bar/test_bar.py::test_other <- local/lib/foo/bar/test_bar.py PASSED*",
"*2 passed*",
]
)
else:
result.stdout.fnmatch_lines(
[
"*lib/foo/bar/test_bar.py::test_bar PASSED*",
"*lib/foo/bar/test_bar.py::test_other PASSED*",
"local/lib/foo/bar/test_bar.py::test_bar PASSED*",
"local/lib/foo/bar/test_bar.py::test_other PASSED*",
"*2 passed*",
]
)
Expand Down
19 changes: 19 additions & 0 deletions testing/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import re
import sys
from typing import List
Expand Down Expand Up @@ -136,6 +137,24 @@ def testdir(testdir: Testdir) -> Testdir:
return testdir


@pytest.fixture
def symlink_or_skip():
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Slightly improved version used in #6733.

"""Return a function that creates a symlink or raises ``Skip``.

On Windows `os.symlink` is available, but normal users require special
admin privileges to create symlinks.
"""

def wrap_os_symlink(src, dst, *args, **kwargs):
try:
os.symlink(src, dst, *args, **kwargs)
except OSError as e:
pytest.skip("os.symlink({!r}) failed: {!r}".format((src, dst), e))
assert os.path.islink(dst)

return wrap_os_symlink


@pytest.fixture(scope="session")
def color_mapping():
"""Returns a utility class which can replace keys in strings in the form "{NAME}"
Expand Down