Skip to content

Commit

Permalink
Allow testing via the system Python
Browse files Browse the repository at this point in the history
Signed-off-by: Bernat Gabor <bgabor8@bloomberg.net>
  • Loading branch information
gaborbernat committed Mar 18, 2020
1 parent 893050e commit db65f85
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 13 deletions.
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
.tox
pip-wheel-metadata
venv*
*.pyz
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ venv*

*wheel-store*

Dockerfile
Dockerfile*
.dockerignore
2 changes: 2 additions & 0 deletions docs/changelog/1721.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Allow the test suite to pass even when called with the system Python - to help repackaging of the tool for Linux
distributions - by :user:`gaborbernat`.
37 changes: 32 additions & 5 deletions tests/unit/create/test_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ def test_destination_exists_file(tmp_path, capsys):

@pytest.mark.skipif(sys.platform == "win32", reason="Windows only applies R/O to files")
def test_destination_not_write_able(tmp_path, capsys):
if hasattr(os, "geteuid"):
if os.geteuid() == 0:
pytest.skip("no way to check permission restriction when running under root")

target = tmp_path
prev_mod = target.stat().st_mode
target.chmod(S_IREAD | S_IRGRP | S_IROTH)
Expand Down Expand Up @@ -196,8 +200,8 @@ def list_to_str(iterable):
exes = ("python.exe",)
else:
exes = ("python", "python{}".format(*sys.version_info), "python{}.{}".format(*sys.version_info))
# pypy3<=7.3: https://bitbucket.org/pypy/pypy/pull-requests/697
if IS_PYPY and creator_key == "venv":
if creator_key == "venv":
# for venv some repackaging does not includes the pythonx.y
exes = exes[:-1]
for exe in exes:
exe_path = result.creator.bin_dir / exe
Expand All @@ -218,6 +222,10 @@ def list_to_str(iterable):

@pytest.mark.skipif(not CURRENT.has_venv, reason="requires interpreter with venv")
def test_venv_fails_not_inline(tmp_path, capsys, mocker):
if hasattr(os, "geteuid"):
if os.geteuid() == 0:
pytest.skip("no way to check permission restriction when running under root")

def _session_via_cli(args, options=None):
session = session_via_cli(args, options)
assert session.creator.can_be_inline is False
Expand Down Expand Up @@ -396,14 +404,33 @@ def test_create_distutils_cfg(creator, tmp_path, monkeypatch):

monkeypatch.chdir(dest) # distutils will read the setup.cfg from the cwd, so change to that

install_demo_cmd = [str(result.creator.script("pip")), "install", str(dest), "--no-use-pep517"]
install_demo_cmd = [
str(result.creator.script("pip")),
"--disable-pip-version-check",
"install",
str(dest),
"--no-use-pep517",
"-vv",
]
subprocess.check_call(install_demo_cmd)

magic = result.creator.script("magic") # console scripts are created in the right location
assert magic.exists()

package_folder = result.creator.platlib / "demo" # prefix is set to the virtualenv prefix for install
assert package_folder.exists()
package_folder = result.creator.purelib / "demo" # prefix is set to the virtualenv prefix for install
assert package_folder.exists(), list_files(str(tmp_path))


def list_files(path):
result = ""
for root, _, files in os.walk(path):
level = root.replace(path, "").count(os.sep)
indent = " " * 4 * level
result += "{}{}/\n".format(indent, os.path.basename(root))
sub = " " * 4 * (level + 1)
for f in files:
result += "{}{}\n".format(sub, f)
return result


@pytest.mark.parametrize("python_path_on", [True, False], ids=["on", "off"])
Expand Down
7 changes: 6 additions & 1 deletion tests/unit/create/test_interpreters.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,12 @@ def test_failed_to_find_bad_spec():
assert repr(context.value) == msg


@pytest.mark.parametrize("of_id", [sys.executable, PythonInfo.current_system().implementation])
SYSTEM = PythonInfo.current_system()


@pytest.mark.parametrize(
"of_id", ({sys.executable} if sys.executable != SYSTEM.executable else set()) | {SYSTEM.implementation}
)
def test_failed_to_find_implementation(of_id, mocker):
mocker.patch("virtualenv.run.plugin.creators.CreatorSelector._OPTIONS", return_value={})
with pytest.raises(RuntimeError) as context:
Expand Down
12 changes: 8 additions & 4 deletions tests/unit/discovery/py_info/test_py_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,13 @@ def test_py_info_cached_symlink_error(mocker, tmp_path, session_app_data):

def test_py_info_cache_clear(mocker, tmp_path, session_app_data):
spy = mocker.spy(cached_py_info, "_run_subprocess")
assert PythonInfo.from_exe(sys.executable, session_app_data) is not None
assert spy.call_count >= 2 # at least two, one for the venv, one more for the host
result = PythonInfo.from_exe(sys.executable, session_app_data)
assert result is not None
count = 1 if result.executable == sys.executable else 2 # at least two, one for the venv, one more for the host
assert spy.call_count >= count
PythonInfo.clear_cache(session_app_data)
assert PythonInfo.from_exe(sys.executable, session_app_data) is not None
assert spy.call_count >= 4
assert spy.call_count >= 2 * count


@pytest.mark.skipif(not fs_supports_symlink(), reason="symlink is not supported")
Expand All @@ -146,7 +148,9 @@ def test_py_info_cached_symlink(mocker, tmp_path, session_app_data):
first_result = PythonInfo.from_exe(sys.executable, session_app_data)
assert first_result is not None
count = spy.call_count
assert count >= 2 # at least two, one for the venv, one more for the host
# at least two, one for the venv, one more for the host
exp_count = 1 if first_result.executable == sys.executable else 2
assert count >= exp_count # at least two, one for the venv, one more for the host

new_exe = tmp_path / "a"
new_exe.symlink_to(sys.executable)
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/discovery/test_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

@pytest.mark.skipif(not fs_supports_symlink(), reason="symlink not supported")
@pytest.mark.parametrize("case", ["mixed", "lower", "upper"])
def test_discovery_via_path(monkeypatch, case, special_name_dir, caplog, session_app_data):
def test_discovery_via_path(monkeypatch, case, tmp_path, caplog, session_app_data):
caplog.set_level(logging.DEBUG)
current = PythonInfo.current_system(session_app_data)
core = "somethingVeryCryptic{}".format(".".join(str(i) for i in current.version_info[0:3]))
Expand All @@ -26,7 +26,7 @@ def test_discovery_via_path(monkeypatch, case, special_name_dir, caplog, session
elif case == "upper":
name = name.upper()
exe_name = "{}{}{}".format(name, current.version_info.major, ".exe" if sys.platform == "win32" else "")
target = special_name_dir / current.distutils_install["scripts"]
target = tmp_path / current.distutils_install["scripts"]
target.mkdir(parents=True)
executable = target / exe_name
os.symlink(sys.executable, ensure_text(str(executable)))
Expand Down

0 comments on commit db65f85

Please sign in to comment.