c1dfc2c307
OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=203
1862 lines
61 KiB
Diff
1862 lines
61 KiB
Diff
From 003266fc86c1364a41ac4bd35207290c036151a0 Mon Sep 17 00:00:00 2001
|
|
From: Victor Zhestkov <vzhestkov@suse.com>
|
|
Date: Mon, 27 Jun 2022 18:02:31 +0300
|
|
Subject: [PATCH] Set default target for pip from VENV_PIP_TARGET
|
|
environment variable
|
|
|
|
* Use VENV_PIP_TARGET as a target for pkg.install
|
|
|
|
if set and no target specified on the call
|
|
|
|
* Add test for VENV_PIP_TARGET environment variable
|
|
|
|
* Changelog entry
|
|
---
|
|
changelog/62089.changed | 1 +
|
|
salt/modules/pip.py | 6 +
|
|
tests/pytests/unit/modules/test_pip.py | 1806 ++++++++++++++++++++++++
|
|
3 files changed, 1813 insertions(+)
|
|
create mode 100644 changelog/62089.changed
|
|
create mode 100644 tests/pytests/unit/modules/test_pip.py
|
|
|
|
diff --git a/changelog/62089.changed b/changelog/62089.changed
|
|
new file mode 100644
|
|
index 0000000000..09feb2e922
|
|
--- /dev/null
|
|
+++ b/changelog/62089.changed
|
|
@@ -0,0 +1 @@
|
|
+Use VENV_PIP_TARGET environment variable as a default target for pip if present.
|
|
diff --git a/salt/modules/pip.py b/salt/modules/pip.py
|
|
index da26416662..9410024fd5 100644
|
|
--- a/salt/modules/pip.py
|
|
+++ b/salt/modules/pip.py
|
|
@@ -858,6 +858,12 @@ def install(
|
|
if build:
|
|
cmd.extend(["--build", build])
|
|
|
|
+ # Use VENV_PIP_TARGET environment variable value as target
|
|
+ # if set and no target specified on the function call
|
|
+ target_env = os.environ.get("VENV_PIP_TARGET", None)
|
|
+ if target is None and target_env is not None:
|
|
+ target = target_env
|
|
+
|
|
if target:
|
|
cmd.extend(["--target", target])
|
|
|
|
diff --git a/tests/pytests/unit/modules/test_pip.py b/tests/pytests/unit/modules/test_pip.py
|
|
new file mode 100644
|
|
index 0000000000..ae9005d806
|
|
--- /dev/null
|
|
+++ b/tests/pytests/unit/modules/test_pip.py
|
|
@@ -0,0 +1,1806 @@
|
|
+import os
|
|
+import sys
|
|
+
|
|
+import pytest
|
|
+import salt.modules.pip as pip
|
|
+import salt.utils.files
|
|
+import salt.utils.platform
|
|
+from salt.exceptions import CommandExecutionError
|
|
+from tests.support.mock import MagicMock, patch
|
|
+
|
|
+
|
|
+class FakeFopen:
|
|
+ def __init__(self, filename):
|
|
+ d = {
|
|
+ "requirements-0.txt": (
|
|
+ b"--index-url http://fake.com/simple\n\n"
|
|
+ b"one # -r wrong.txt, other\n"
|
|
+ b"two # --requirement wrong.exe;some\n"
|
|
+ b"three\n"
|
|
+ b"-r requirements-1.txt\n"
|
|
+ b"# nothing\n"
|
|
+ ),
|
|
+ "requirements-1.txt": (
|
|
+ "four\n"
|
|
+ "five\n"
|
|
+ "--requirement=requirements-2.txt\t# --requirements-2.txt\n\n"
|
|
+ ),
|
|
+ "requirements-2.txt": b"""six""",
|
|
+ "requirements-3.txt": (
|
|
+ b"# some comment\n"
|
|
+ b"-e git+ssh://git.example.com/MyProject#egg=MyProject # the project\n"
|
|
+ b"seven\n"
|
|
+ b"-e git+ssh://git.example.com/Example#egg=example\n"
|
|
+ b"eight # -e something#or other\n"
|
|
+ b"--requirement requirements-4.txt\n\n"
|
|
+ ),
|
|
+ "requirements-4.txt": "",
|
|
+ }
|
|
+ self.val = d[filename]
|
|
+
|
|
+ def __enter__(self):
|
|
+ return self
|
|
+
|
|
+ def __exit__(self, *args, **kwargs):
|
|
+ pass
|
|
+
|
|
+ def read(self):
|
|
+ return self.val
|
|
+
|
|
+
|
|
+@pytest.fixture
|
|
+def expected_user():
|
|
+ return "fnord"
|
|
+
|
|
+
|
|
+@pytest.fixture
|
|
+def configure_loader_modules():
|
|
+ return {pip: {"__salt__": {"cmd.which_bin": lambda _: "pip"}}}
|
|
+
|
|
+
|
|
+def test__pip_bin_env():
|
|
+ ret = pip._pip_bin_env(None, "C:/Users/ch44d/Documents/salt/tests/pip.exe")
|
|
+ if salt.utils.platform.is_windows():
|
|
+ assert ret == "C:/Users/ch44d/Documents/salt/tests"
|
|
+ else:
|
|
+ assert ret is None
|
|
+
|
|
+
|
|
+def test__pip_bin_env_no_change():
|
|
+ cwd = "C:/Users/ch44d/Desktop"
|
|
+ ret = pip._pip_bin_env(cwd, "C:/Users/ch44d/Documents/salt/tests/pip.exe")
|
|
+ assert ret == cwd
|
|
+
|
|
+
|
|
+def test__pip_bin_env_no_bin_env():
|
|
+ ret = pip._pip_bin_env(None, None)
|
|
+ assert ret is None
|
|
+
|
|
+
|
|
+def test_install_frozen_app():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch("sys.frozen", True, create=True):
|
|
+ with patch("sys._MEIPASS", True, create=True):
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "pip",
|
|
+ "install",
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ python_shell=False,
|
|
+ saltenv="base",
|
|
+ use_vt=False,
|
|
+ runas=None,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_source_app():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch("sys.frozen", False, create=True):
|
|
+ with patch("sys._MEIPASS", False, create=True):
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ python_shell=False,
|
|
+ saltenv="base",
|
|
+ use_vt=False,
|
|
+ runas=None,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_fix4361():
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(requirements="requirements.txt")
|
|
+ expected_cmd = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--requirement",
|
|
+ "requirements.txt",
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected_cmd,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_editable_without_egg_fails():
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pytest.raises(
|
|
+ CommandExecutionError,
|
|
+ pip.install,
|
|
+ editable="git+https://github.com/saltstack/salt-testing.git",
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_multiple_editable():
|
|
+ editables = [
|
|
+ "git+https://github.com/jek/blinker.git#egg=Blinker",
|
|
+ "git+https://github.com/saltstack/salt-testing.git#egg=SaltTesting",
|
|
+ ]
|
|
+
|
|
+ expected = [sys.executable, "-m", "pip", "install"]
|
|
+ for item in editables:
|
|
+ expected.extend(["--editable", item])
|
|
+
|
|
+ # Passing editables as a list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(editable=editables)
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing editables as a comma separated list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(editable=",".join(editables))
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_multiple_pkgs_and_editables():
|
|
+ pkgs = ["pep8", "salt"]
|
|
+ editables = [
|
|
+ "git+https://github.com/jek/blinker.git#egg=Blinker",
|
|
+ "git+https://github.com/saltstack/salt-testing.git#egg=SaltTesting",
|
|
+ ]
|
|
+
|
|
+ expected = [sys.executable, "-m", "pip", "install"]
|
|
+ expected.extend(pkgs)
|
|
+ for item in editables:
|
|
+ expected.extend(["--editable", item])
|
|
+
|
|
+ # Passing editables as a list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkgs=pkgs, editable=editables)
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing editables as a comma separated list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkgs=",".join(pkgs), editable=",".join(editables))
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # As single string (just use the first element from pkgs and editables)
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkgs=pkgs[0], editable=editables[0])
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ pkgs[0],
|
|
+ "--editable",
|
|
+ editables[0],
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_issue5940_install_multiple_pip_mirrors():
|
|
+ """
|
|
+ test multiple pip mirrors. This test only works with pip < 7.0.0
|
|
+ """
|
|
+ with patch.object(pip, "version", MagicMock(return_value="1.4")):
|
|
+ mirrors = [
|
|
+ "http://g.pypi.python.org",
|
|
+ "http://c.pypi.python.org",
|
|
+ "http://pypi.crate.io",
|
|
+ ]
|
|
+
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--use-mirrors"]
|
|
+ for item in mirrors:
|
|
+ expected.extend(["--mirrors", item])
|
|
+ expected.append("pep8")
|
|
+
|
|
+ # Passing mirrors as a list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkgs=["pep8"], mirrors=mirrors)
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing mirrors as a comma separated list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkgs=["pep8"], mirrors=",".join(mirrors))
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--use-mirrors",
|
|
+ "--mirrors",
|
|
+ mirrors[0],
|
|
+ "pep8",
|
|
+ ]
|
|
+
|
|
+ # As single string (just use the first element from mirrors)
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkgs=["pep8"], mirrors=mirrors[0])
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_with_multiple_find_links():
|
|
+ find_links = [
|
|
+ "http://g.pypi.python.org",
|
|
+ "http://c.pypi.python.org",
|
|
+ "http://pypi.crate.io",
|
|
+ ]
|
|
+ pkg = "pep8"
|
|
+
|
|
+ expected = [sys.executable, "-m", "pip", "install"]
|
|
+ for item in find_links:
|
|
+ expected.extend(["--find-links", item])
|
|
+ expected.append(pkg)
|
|
+
|
|
+ # Passing mirrors as a list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, find_links=find_links)
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing mirrors as a comma separated list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, find_links=",".join(find_links))
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Valid protos work?
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, find_links=find_links)
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--find-links",
|
|
+ find_links[0],
|
|
+ pkg,
|
|
+ ]
|
|
+
|
|
+ # As single string (just use the first element from find_links)
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, find_links=find_links[0])
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Invalid proto raises exception
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pytest.raises(
|
|
+ CommandExecutionError,
|
|
+ pip.install,
|
|
+ "'" + pkg + "'",
|
|
+ find_links="sftp://pypi.crate.io",
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_no_index_with_index_url_or_extra_index_url_raises():
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pytest.raises(
|
|
+ CommandExecutionError,
|
|
+ pip.install,
|
|
+ no_index=True,
|
|
+ index_url="http://foo.tld",
|
|
+ )
|
|
+
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pytest.raises(
|
|
+ CommandExecutionError,
|
|
+ pip.install,
|
|
+ no_index=True,
|
|
+ extra_index_url="http://foo.tld",
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_failed_cached_requirements():
|
|
+ with patch("salt.modules.pip._get_cached_requirements") as get_cached_requirements:
|
|
+ get_cached_requirements.return_value = False
|
|
+ ret = pip.install(requirements="salt://my_test_reqs")
|
|
+ assert False is ret["result"]
|
|
+ assert "my_test_reqs" in ret["comment"]
|
|
+
|
|
+
|
|
+def test_install_cached_requirements_used():
|
|
+ with patch("salt.modules.pip._get_cached_requirements") as get_cached_requirements:
|
|
+ get_cached_requirements.return_value = "my_cached_reqs"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(requirements="salt://requirements.txt")
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--requirement",
|
|
+ "my_cached_reqs",
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_venv():
|
|
+ with patch("os.path") as mock_path:
|
|
+
|
|
+ def join(*args):
|
|
+ return os.path.normpath(os.sep.join(args))
|
|
+
|
|
+ mock_path.is_file.return_value = True
|
|
+ mock_path.isdir.return_value = True
|
|
+ mock_path.join = join
|
|
+
|
|
+ if salt.utils.platform.is_windows():
|
|
+ venv_path = "C:\\test_env"
|
|
+ bin_path = os.path.join(venv_path, "python.exe")
|
|
+ else:
|
|
+ venv_path = "/test_env"
|
|
+ bin_path = os.path.join(venv_path, "python")
|
|
+
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ pip_bin = MagicMock(return_value=[bin_path, "-m", "pip"])
|
|
+
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}), patch.object(
|
|
+ pip, "_get_pip_bin", pip_bin
|
|
+ ):
|
|
+ pip.install("mock", bin_env=venv_path)
|
|
+ mock.assert_called_with(
|
|
+ [bin_path, "-m", "pip", "install", "mock"],
|
|
+ env={"VIRTUAL_ENV": venv_path},
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_log_argument_in_resulting_command():
|
|
+ with patch("os.access") as mock_path:
|
|
+ pkg = "pep8"
|
|
+ log_path = "/tmp/pip-install.log"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, log=log_path)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--log",
|
|
+ log_path,
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_non_writeable_log():
|
|
+ with patch("os.path") as mock_path:
|
|
+ # Let's fake a non-writable log file
|
|
+ pkg = "pep8"
|
|
+ log_path = "/tmp/pip-install.log"
|
|
+ mock_path.exists.side_effect = IOError("Fooo!")
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pytest.raises(IOError, pip.install, pkg, log=log_path)
|
|
+
|
|
+
|
|
+def test_install_timeout_argument_in_resulting_command():
|
|
+ # Passing an int
|
|
+ pkg = "pep8"
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--timeout"]
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, timeout=10)
|
|
+ mock.assert_called_with(
|
|
+ expected + [10, pkg],
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing an int as a string
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, timeout="10")
|
|
+ mock.assert_called_with(
|
|
+ expected + ["10", pkg],
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing a non-int to timeout
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pytest.raises(ValueError, pip.install, pkg, timeout="a")
|
|
+
|
|
+
|
|
+def test_install_index_url_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ index_url = "http://foo.tld"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, index_url=index_url)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--index-url",
|
|
+ index_url,
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_extra_index_url_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ extra_index_url = "http://foo.tld"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, extra_index_url=extra_index_url)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--extra-index-url",
|
|
+ extra_index_url,
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_no_index_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, no_index=True)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--no-index", pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_build_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ build = "/tmp/foo"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, build=build)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--build", build, pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_target_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ target = "/tmp/foo"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, target=target)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--target", target, pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_download_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ download = "/tmp/foo"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, download=download)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--download",
|
|
+ download,
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_no_download_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, no_download=True)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--no-download", pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_download_cache_dir_arguments_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ cache_dir_arg_mapping = {
|
|
+ "1.5.6": "--download-cache",
|
|
+ "6.0": "--cache-dir",
|
|
+ }
|
|
+ download_cache = "/tmp/foo"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ for pip_version, cmd_arg in cache_dir_arg_mapping.items():
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value=pip_version)):
|
|
+ # test `download_cache` kwarg
|
|
+ pip.install(pkg, download_cache="/tmp/foo")
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ cmd_arg,
|
|
+ download_cache,
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # test `cache_dir` kwarg
|
|
+ pip.install(pkg, cache_dir="/tmp/foo")
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_source_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ source = "/tmp/foo"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, source=source)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--source", source, pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_exists_action_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ for action in ("s", "i", "w", "b"):
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, exists_action=action)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--exists-action",
|
|
+ action,
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Test for invalid action
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pytest.raises(CommandExecutionError, pip.install, pkg, exists_action="d")
|
|
+
|
|
+
|
|
+def test_install_install_options_argument_in_resulting_command():
|
|
+ install_options = ["--exec-prefix=/foo/bar", "--install-scripts=/foo/bar/bin"]
|
|
+ pkg = "pep8"
|
|
+
|
|
+ expected = [sys.executable, "-m", "pip", "install"]
|
|
+ for item in install_options:
|
|
+ expected.extend(["--install-option", item])
|
|
+ expected.append(pkg)
|
|
+
|
|
+ # Passing options as a list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, install_options=install_options)
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing mirrors as a comma separated list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, install_options=",".join(install_options))
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing mirrors as a single string entry
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, install_options=install_options[0])
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--install-option",
|
|
+ install_options[0],
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_global_options_argument_in_resulting_command():
|
|
+ global_options = ["--quiet", "--no-user-cfg"]
|
|
+ pkg = "pep8"
|
|
+
|
|
+ expected = [sys.executable, "-m", "pip", "install"]
|
|
+ for item in global_options:
|
|
+ expected.extend(["--global-option", item])
|
|
+ expected.append(pkg)
|
|
+
|
|
+ # Passing options as a list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, global_options=global_options)
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing mirrors as a comma separated list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, global_options=",".join(global_options))
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing mirrors as a single string entry
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, global_options=global_options[0])
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--global-option",
|
|
+ global_options[0],
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_upgrade_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, upgrade=True)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--upgrade", pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_force_reinstall_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, force_reinstall=True)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--force-reinstall",
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_ignore_installed_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, ignore_installed=True)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--ignore-installed",
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_no_deps_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, no_deps=True)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--no-deps", pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_no_install_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, no_install=True)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--no-install", pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_proxy_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ proxy = "salt-user:salt-passwd@salt-proxy:3128"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(pkg, proxy=proxy)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--proxy", proxy, pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_proxy_false_argument_in_resulting_command():
|
|
+ """
|
|
+ Checking that there is no proxy set if proxy arg is set to False
|
|
+ even if the global proxy is set.
|
|
+ """
|
|
+ pkg = "pep8"
|
|
+ proxy = False
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ config_mock = {
|
|
+ "proxy_host": "salt-proxy",
|
|
+ "proxy_port": "3128",
|
|
+ "proxy_username": "salt-user",
|
|
+ "proxy_password": "salt-passwd",
|
|
+ }
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch.dict(pip.__opts__, config_mock):
|
|
+ pip.install(pkg, proxy=proxy)
|
|
+ expected = [sys.executable, "-m", "pip", "install", pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_global_proxy_in_resulting_command():
|
|
+ """
|
|
+ Checking that there is proxy set if global proxy is set.
|
|
+ """
|
|
+ pkg = "pep8"
|
|
+ proxy = "http://salt-user:salt-passwd@salt-proxy:3128"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ config_mock = {
|
|
+ "proxy_host": "salt-proxy",
|
|
+ "proxy_port": "3128",
|
|
+ "proxy_username": "salt-user",
|
|
+ "proxy_password": "salt-passwd",
|
|
+ }
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch.dict(pip.__opts__, config_mock):
|
|
+ pip.install(pkg)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--proxy",
|
|
+ proxy,
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_multiple_requirements_arguments_in_resulting_command():
|
|
+ with patch("salt.modules.pip._get_cached_requirements") as get_cached_requirements:
|
|
+ cached_reqs = ["my_cached_reqs-1", "my_cached_reqs-2"]
|
|
+ get_cached_requirements.side_effect = cached_reqs
|
|
+ requirements = ["salt://requirements-1.txt", "salt://requirements-2.txt"]
|
|
+
|
|
+ expected = [sys.executable, "-m", "pip", "install"]
|
|
+ for item in cached_reqs:
|
|
+ expected.extend(["--requirement", item])
|
|
+
|
|
+ # Passing option as a list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(requirements=requirements)
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing option as a comma separated list
|
|
+ get_cached_requirements.side_effect = cached_reqs
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(requirements=",".join(requirements))
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing option as a single string entry
|
|
+ get_cached_requirements.side_effect = [cached_reqs[0]]
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(requirements=requirements[0])
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ "--requirement",
|
|
+ cached_reqs[0],
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_extra_args_arguments_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.install(
|
|
+ pkg, extra_args=[{"--latest-pip-kwarg": "param"}, "--latest-pip-arg"]
|
|
+ )
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "install",
|
|
+ pkg,
|
|
+ "--latest-pip-kwarg",
|
|
+ "param",
|
|
+ "--latest-pip-arg",
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_extra_args_arguments_recursion_error():
|
|
+ pkg = "pep8"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+
|
|
+ pytest.raises(
|
|
+ TypeError,
|
|
+ lambda: pip.install(
|
|
+ pkg, extra_args=[{"--latest-pip-kwarg": ["param1", "param2"]}]
|
|
+ ),
|
|
+ )
|
|
+
|
|
+ pytest.raises(
|
|
+ TypeError,
|
|
+ lambda: pip.install(
|
|
+ pkg, extra_args=[{"--latest-pip-kwarg": [{"--too-deep": dict()}]}]
|
|
+ ),
|
|
+ )
|
|
+
|
|
+
|
|
+def test_uninstall_multiple_requirements_arguments_in_resulting_command():
|
|
+ with patch("salt.modules.pip._get_cached_requirements") as get_cached_requirements:
|
|
+ cached_reqs = ["my_cached_reqs-1", "my_cached_reqs-2"]
|
|
+ get_cached_requirements.side_effect = cached_reqs
|
|
+ requirements = ["salt://requirements-1.txt", "salt://requirements-2.txt"]
|
|
+
|
|
+ expected = [sys.executable, "-m", "pip", "uninstall", "-y"]
|
|
+ for item in cached_reqs:
|
|
+ expected.extend(["--requirement", item])
|
|
+
|
|
+ # Passing option as a list
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.uninstall(requirements=requirements)
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ cwd=None,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing option as a comma separated list
|
|
+ get_cached_requirements.side_effect = cached_reqs
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.uninstall(requirements=",".join(requirements))
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ cwd=None,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing option as a single string entry
|
|
+ get_cached_requirements.side_effect = [cached_reqs[0]]
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.uninstall(requirements=requirements[0])
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "uninstall",
|
|
+ "-y",
|
|
+ "--requirement",
|
|
+ cached_reqs[0],
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ cwd=None,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_uninstall_global_proxy_in_resulting_command():
|
|
+ """
|
|
+ Checking that there is proxy set if global proxy is set.
|
|
+ """
|
|
+ pkg = "pep8"
|
|
+ proxy = "http://salt-user:salt-passwd@salt-proxy:3128"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ config_mock = {
|
|
+ "proxy_host": "salt-proxy",
|
|
+ "proxy_port": "3128",
|
|
+ "proxy_username": "salt-user",
|
|
+ "proxy_password": "salt-passwd",
|
|
+ }
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch.dict(pip.__opts__, config_mock):
|
|
+ pip.uninstall(pkg)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "uninstall",
|
|
+ "-y",
|
|
+ "--proxy",
|
|
+ proxy,
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_uninstall_proxy_false_argument_in_resulting_command():
|
|
+ """
|
|
+ Checking that there is no proxy set if proxy arg is set to False
|
|
+ even if the global proxy is set.
|
|
+ """
|
|
+ pkg = "pep8"
|
|
+ proxy = False
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ config_mock = {
|
|
+ "proxy_host": "salt-proxy",
|
|
+ "proxy_port": "3128",
|
|
+ "proxy_username": "salt-user",
|
|
+ "proxy_password": "salt-passwd",
|
|
+ }
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch.dict(pip.__opts__, config_mock):
|
|
+ pip.uninstall(pkg, proxy=proxy)
|
|
+ expected = [sys.executable, "-m", "pip", "uninstall", "-y", pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_uninstall_log_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ log_path = "/tmp/pip-install.log"
|
|
+
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.uninstall(pkg, log=log_path)
|
|
+ expected = [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "uninstall",
|
|
+ "-y",
|
|
+ "--log",
|
|
+ log_path,
|
|
+ pkg,
|
|
+ ]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Let's fake a non-writable log file
|
|
+ with patch("os.path") as mock_path:
|
|
+ mock_path.exists.side_effect = IOError("Fooo!")
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pytest.raises(IOError, pip.uninstall, pkg, log=log_path)
|
|
+
|
|
+
|
|
+def test_uninstall_timeout_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ expected = [sys.executable, "-m", "pip", "uninstall", "-y", "--timeout"]
|
|
+ # Passing an int
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.uninstall(pkg, timeout=10)
|
|
+ mock.assert_called_with(
|
|
+ expected + [10, pkg],
|
|
+ cwd=None,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing an int as a string
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pip.uninstall(pkg, timeout="10")
|
|
+ mock.assert_called_with(
|
|
+ expected + ["10", pkg],
|
|
+ cwd=None,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ # Passing a non-int to timeout
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ pytest.raises(ValueError, pip.uninstall, pkg, timeout="a")
|
|
+
|
|
+
|
|
+def test_freeze_command():
|
|
+ expected = [sys.executable, "-m", "pip", "freeze"]
|
|
+ eggs = [
|
|
+ "M2Crypto==0.21.1",
|
|
+ "-e git+git@github.com:s0undt3ch/salt-testing.git@9ed81aa2f918d59d3706e56b18f0782d1ea43bf8#egg=SaltTesting-dev",
|
|
+ "bbfreeze==1.1.0",
|
|
+ "bbfreeze-loader==1.1.0",
|
|
+ "pycrypto==2.6",
|
|
+ ]
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": "\n".join(eggs)})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="6.1.1")):
|
|
+ ret = pip.freeze()
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+ assert ret == eggs
|
|
+
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": "\n".join(eggs)})
|
|
+ # Passing env_vars passes them to underlying command?
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="6.1.1")):
|
|
+ ret = pip.freeze(env_vars={"foo": "bar"})
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ env={"foo": "bar"},
|
|
+ )
|
|
+ assert ret == eggs
|
|
+
|
|
+ # Non zero returncode raises exception?
|
|
+ mock = MagicMock(return_value={"retcode": 1, "stderr": "CABOOOOMMM!"})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="6.1.1")):
|
|
+ pytest.raises(
|
|
+ CommandExecutionError,
|
|
+ pip.freeze,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_freeze_command_with_all():
|
|
+ eggs = [
|
|
+ "M2Crypto==0.21.1",
|
|
+ "-e git+git@github.com:s0undt3ch/salt-testing.git@9ed81aa2f918d59d3706e56b18f0782d1ea43bf8#egg=SaltTesting-dev",
|
|
+ "bbfreeze==1.1.0",
|
|
+ "bbfreeze-loader==1.1.0",
|
|
+ "pip==0.9.1",
|
|
+ "pycrypto==2.6",
|
|
+ "setuptools==20.10.1",
|
|
+ ]
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": "\n".join(eggs)})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="9.0.1")):
|
|
+ ret = pip.freeze()
|
|
+ expected = [sys.executable, "-m", "pip", "freeze", "--all"]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+ assert ret == eggs
|
|
+
|
|
+ # Non zero returncode raises exception?
|
|
+ mock = MagicMock(return_value={"retcode": 1, "stderr": "CABOOOOMMM!"})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="9.0.1")):
|
|
+ pytest.raises(
|
|
+ CommandExecutionError,
|
|
+ pip.freeze,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_list_command():
|
|
+ eggs = [
|
|
+ "M2Crypto==0.21.1",
|
|
+ "-e git+git@github.com:s0undt3ch/salt-testing.git@9ed81aa2f918d59d3706e56b18f0782d1ea43bf8#egg=SaltTesting-dev",
|
|
+ "bbfreeze==1.1.0",
|
|
+ "bbfreeze-loader==1.1.0",
|
|
+ "pycrypto==2.6",
|
|
+ ]
|
|
+ mock_version = "6.1.1"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": "\n".join(eggs)})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value=mock_version)):
|
|
+ ret = pip.list_()
|
|
+ expected = [sys.executable, "-m", "pip", "freeze"]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ python_shell=False,
|
|
+ use_vt=False,
|
|
+ )
|
|
+ assert ret == {
|
|
+ "SaltTesting-dev": "git+git@github.com:s0undt3ch/salt-testing.git@9ed81aa2f918d59d3706e56b18f0782d1ea43bf8",
|
|
+ "M2Crypto": "0.21.1",
|
|
+ "bbfreeze-loader": "1.1.0",
|
|
+ "bbfreeze": "1.1.0",
|
|
+ "pip": mock_version,
|
|
+ "pycrypto": "2.6",
|
|
+ }
|
|
+
|
|
+ # Non zero returncode raises exception?
|
|
+ mock = MagicMock(return_value={"retcode": 1, "stderr": "CABOOOOMMM!"})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="6.1.1")):
|
|
+ pytest.raises(
|
|
+ CommandExecutionError,
|
|
+ pip.list_,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_list_command_with_all():
|
|
+ eggs = [
|
|
+ "M2Crypto==0.21.1",
|
|
+ "-e git+git@github.com:s0undt3ch/salt-testing.git@9ed81aa2f918d59d3706e56b18f0782d1ea43bf8#egg=SaltTesting-dev",
|
|
+ "bbfreeze==1.1.0",
|
|
+ "bbfreeze-loader==1.1.0",
|
|
+ "pip==9.0.1",
|
|
+ "pycrypto==2.6",
|
|
+ "setuptools==20.10.1",
|
|
+ ]
|
|
+ # N.B.: this is deliberately different from the "output" of pip freeze.
|
|
+ # This is to demonstrate that the version reported comes from freeze
|
|
+ # instead of from the pip.version function.
|
|
+ mock_version = "9.0.0"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": "\n".join(eggs)})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value=mock_version)):
|
|
+ ret = pip.list_()
|
|
+ expected = [sys.executable, "-m", "pip", "freeze", "--all"]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ python_shell=False,
|
|
+ use_vt=False,
|
|
+ )
|
|
+ assert ret == {
|
|
+ "SaltTesting-dev": "git+git@github.com:s0undt3ch/salt-testing.git@9ed81aa2f918d59d3706e56b18f0782d1ea43bf8",
|
|
+ "M2Crypto": "0.21.1",
|
|
+ "bbfreeze-loader": "1.1.0",
|
|
+ "bbfreeze": "1.1.0",
|
|
+ "pip": "9.0.1",
|
|
+ "pycrypto": "2.6",
|
|
+ "setuptools": "20.10.1",
|
|
+ }
|
|
+
|
|
+ # Non zero returncode raises exception?
|
|
+ mock = MagicMock(return_value={"retcode": 1, "stderr": "CABOOOOMMM!"})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="6.1.1")):
|
|
+ pytest.raises(
|
|
+ CommandExecutionError,
|
|
+ pip.list_,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_list_command_with_prefix():
|
|
+ eggs = [
|
|
+ "M2Crypto==0.21.1",
|
|
+ "-e git+git@github.com:s0undt3ch/salt-testing.git@9ed81aa2f918d59d3706e56b18f0782d1ea43bf8#egg=SaltTesting-dev",
|
|
+ "bbfreeze==1.1.0",
|
|
+ "bbfreeze-loader==1.1.0",
|
|
+ "pycrypto==2.6",
|
|
+ ]
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": "\n".join(eggs)})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="6.1.1")):
|
|
+ ret = pip.list_(prefix="bb")
|
|
+ expected = [sys.executable, "-m", "pip", "freeze"]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ python_shell=False,
|
|
+ use_vt=False,
|
|
+ )
|
|
+ assert ret == {"bbfreeze-loader": "1.1.0", "bbfreeze": "1.1.0"}
|
|
+
|
|
+
|
|
+def test_list_upgrades_legacy():
|
|
+ eggs = [
|
|
+ "apache-libcloud (Current: 1.1.0 Latest: 2.2.1 [wheel])",
|
|
+ "appdirs (Current: 1.4.1 Latest: 1.4.3 [wheel])",
|
|
+ "awscli (Current: 1.11.63 Latest: 1.12.1 [sdist])",
|
|
+ ]
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": "\n".join(eggs)})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="6.1.1")):
|
|
+ ret = pip.list_upgrades()
|
|
+ mock.assert_called_with(
|
|
+ [sys.executable, "-m", "pip", "list", "--outdated"],
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ )
|
|
+ assert ret == {
|
|
+ "apache-libcloud": "2.2.1 [wheel]",
|
|
+ "appdirs": "1.4.3 [wheel]",
|
|
+ "awscli": "1.12.1 [sdist]",
|
|
+ }
|
|
+
|
|
+
|
|
+def test_list_upgrades_gt9():
|
|
+ eggs = """[{"latest_filetype": "wheel", "version": "1.1.0", "name": "apache-libcloud", "latest_version": "2.2.1"},
|
|
+ {"latest_filetype": "wheel", "version": "1.4.1", "name": "appdirs", "latest_version": "1.4.3"},
|
|
+ {"latest_filetype": "sdist", "version": "1.11.63", "name": "awscli", "latest_version": "1.12.1"}
|
|
+ ]"""
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": "{}".format(eggs)})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="9.1.1")):
|
|
+ ret = pip.list_upgrades()
|
|
+ mock.assert_called_with(
|
|
+ [
|
|
+ sys.executable,
|
|
+ "-m",
|
|
+ "pip",
|
|
+ "list",
|
|
+ "--outdated",
|
|
+ "--format=json",
|
|
+ ],
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ )
|
|
+ assert ret == {
|
|
+ "apache-libcloud": "2.2.1 [wheel]",
|
|
+ "appdirs": "1.4.3 [wheel]",
|
|
+ "awscli": "1.12.1 [sdist]",
|
|
+ }
|
|
+
|
|
+
|
|
+def test_is_installed_true():
|
|
+ eggs = [
|
|
+ "M2Crypto==0.21.1",
|
|
+ "-e git+git@github.com:s0undt3ch/salt-testing.git@9ed81aa2f918d59d3706e56b18f0782d1ea43bf8#egg=SaltTesting-dev",
|
|
+ "bbfreeze==1.1.0",
|
|
+ "bbfreeze-loader==1.1.0",
|
|
+ "pycrypto==2.6",
|
|
+ ]
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": "\n".join(eggs)})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="6.1.1")):
|
|
+ ret = pip.is_installed(pkgname="bbfreeze")
|
|
+ mock.assert_called_with(
|
|
+ [sys.executable, "-m", "pip", "freeze"],
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ python_shell=False,
|
|
+ use_vt=False,
|
|
+ )
|
|
+ assert ret
|
|
+
|
|
+
|
|
+def test_is_installed_false():
|
|
+ eggs = [
|
|
+ "M2Crypto==0.21.1",
|
|
+ "-e git+git@github.com:s0undt3ch/salt-testing.git@9ed81aa2f918d59d3706e56b18f0782d1ea43bf8#egg=SaltTesting-dev",
|
|
+ "bbfreeze==1.1.0",
|
|
+ "bbfreeze-loader==1.1.0",
|
|
+ "pycrypto==2.6",
|
|
+ ]
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": "\n".join(eggs)})
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="6.1.1")):
|
|
+ ret = pip.is_installed(pkgname="notexist")
|
|
+ mock.assert_called_with(
|
|
+ [sys.executable, "-m", "pip", "freeze"],
|
|
+ cwd=None,
|
|
+ runas=None,
|
|
+ python_shell=False,
|
|
+ use_vt=False,
|
|
+ )
|
|
+ assert not ret
|
|
+
|
|
+
|
|
+def test_install_pre_argument_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ # Lower than 1.4 versions don't end up with `--pre` in the resulting output
|
|
+ mock = MagicMock(
|
|
+ side_effect=[
|
|
+ {"retcode": 0, "stdout": "pip 1.2.0 /path/to/site-packages/pip"},
|
|
+ {"retcode": 0, "stdout": ""},
|
|
+ ]
|
|
+ )
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}):
|
|
+ with patch("salt.modules.pip.version", MagicMock(return_value="1.3")):
|
|
+ pip.install(pkg, pre_releases=True)
|
|
+ expected = [sys.executable, "-m", "pip", "install", pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+ mock_run = MagicMock(return_value="pip 1.4.1 /path/to/site-packages/pip")
|
|
+ mock_run_all = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ with patch.dict(
|
|
+ pip.__salt__, {"cmd.run_stdout": mock_run, "cmd.run_all": mock_run_all}
|
|
+ ):
|
|
+ with patch("salt.modules.pip._get_pip_bin", MagicMock(return_value=["pip"])):
|
|
+ pip.install(pkg, pre_releases=True)
|
|
+ expected = ["pip", "install", "--pre", pkg]
|
|
+ mock_run_all.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_resolve_requirements_chain_function():
|
|
+ with patch("salt.utils.files.fopen", FakeFopen):
|
|
+ chain = pip._resolve_requirements_chain(
|
|
+ ["requirements-0.txt", "requirements-3.txt"]
|
|
+ )
|
|
+ assert chain == [
|
|
+ "requirements-0.txt",
|
|
+ "requirements-1.txt",
|
|
+ "requirements-2.txt",
|
|
+ "requirements-3.txt",
|
|
+ "requirements-4.txt",
|
|
+ ]
|
|
+
|
|
+
|
|
+def test_when_upgrade_is_called_and_there_are_available_upgrades_it_should_call_correct_command(
|
|
+ expected_user,
|
|
+):
|
|
+ fake_run_all = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ pip_user = expected_user
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": fake_run_all}), patch(
|
|
+ "salt.modules.pip.list_upgrades", autospec=True, return_value=[pip_user]
|
|
+ ), patch(
|
|
+ "salt.modules.pip._get_pip_bin",
|
|
+ autospec=True,
|
|
+ return_value=["some-other-pip"],
|
|
+ ):
|
|
+ pip.upgrade(user=pip_user)
|
|
+
|
|
+ fake_run_all.assert_any_call(
|
|
+ ["some-other-pip", "install", "-U", "freeze", "--all", pip_user],
|
|
+ runas=pip_user,
|
|
+ cwd=None,
|
|
+ use_vt=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_when_list_upgrades_is_provided_a_user_it_should_be_passed_to_the_version_command(
|
|
+ expected_user,
|
|
+):
|
|
+ fake_run_all = MagicMock(return_value={"retcode": 0, "stdout": "{}"})
|
|
+ pip_user = expected_user
|
|
+
|
|
+ def all_new_commands(*args, **kwargs):
|
|
+ """
|
|
+ Without this, mutating the return value mutates the return value
|
|
+ for EVERYTHING.
|
|
+ """
|
|
+ return ["some-other-pip"]
|
|
+
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": fake_run_all}), patch(
|
|
+ "salt.modules.pip._get_pip_bin",
|
|
+ autospec=True,
|
|
+ side_effect=all_new_commands,
|
|
+ ):
|
|
+ pip._clear_context()
|
|
+ pip.list_upgrades(user=pip_user)
|
|
+ fake_run_all.assert_any_call(
|
|
+ ["some-other-pip", "--version"],
|
|
+ runas=expected_user,
|
|
+ cwd=None,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_when_install_is_provided_a_user_it_should_be_passed_to_the_version_command(
|
|
+ expected_user,
|
|
+):
|
|
+ fake_run_all = MagicMock(return_value={"retcode": 0, "stdout": "{}"})
|
|
+ pip_user = expected_user
|
|
+
|
|
+ def all_new_commands(*args, **kwargs):
|
|
+ """
|
|
+ Without this, mutating the return value mutates the return value
|
|
+ for EVERYTHING.
|
|
+ """
|
|
+ return ["some-other-pip"]
|
|
+
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": fake_run_all}), patch(
|
|
+ "salt.modules.pip._get_pip_bin",
|
|
+ autospec=True,
|
|
+ side_effect=all_new_commands,
|
|
+ ):
|
|
+ pip._clear_context()
|
|
+ pip.install(user=pip_user)
|
|
+ fake_run_all.assert_any_call(
|
|
+ ["some-other-pip", "--version"],
|
|
+ runas=pip_user,
|
|
+ cwd=None,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_when_version_is_called_with_a_user_it_should_be_passed_to_undelying_runas(
|
|
+ expected_user,
|
|
+):
|
|
+ fake_run_all = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ pip_user = expected_user
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": fake_run_all}), patch(
|
|
+ "salt.modules.pip.list_upgrades", autospec=True, return_value=[pip_user]
|
|
+ ), patch(
|
|
+ "salt.modules.pip._get_pip_bin",
|
|
+ autospec=True,
|
|
+ return_value=["some-new-pip"],
|
|
+ ):
|
|
+ pip.version(user=pip_user)
|
|
+ fake_run_all.assert_called_with(
|
|
+ ["some-new-pip", "--version"],
|
|
+ runas=pip_user,
|
|
+ cwd=None,
|
|
+ python_shell=False,
|
|
+ )
|
|
+
|
|
+
|
|
+def test_install_target_from_VENV_PIP_TARGET_in_resulting_command():
|
|
+ pkg = "pep8"
|
|
+ target = "/tmp/foo"
|
|
+ target_env = "/tmp/bar"
|
|
+ mock = MagicMock(return_value={"retcode": 0, "stdout": ""})
|
|
+ environment = os.environ.copy()
|
|
+ environment["VENV_PIP_TARGET"] = target_env
|
|
+ with patch.dict(pip.__salt__, {"cmd.run_all": mock}), patch.object(
|
|
+ os, "environ", environment
|
|
+ ):
|
|
+ pip.install(pkg)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--target", target_env, pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
+ mock.reset_mock()
|
|
+ pip.install(pkg, target=target)
|
|
+ expected = [sys.executable, "-m", "pip", "install", "--target", target, pkg]
|
|
+ mock.assert_called_with(
|
|
+ expected,
|
|
+ saltenv="base",
|
|
+ runas=None,
|
|
+ use_vt=False,
|
|
+ python_shell=False,
|
|
+ )
|
|
--
|
|
2.36.1
|
|
|
|
|