File add-rpm_vercmp-python-library-for-version-comparison.patch of Package salt.23536
From 30bacbdd374a90b33736bd7ba69e64039d6e6ede Mon Sep 17 00:00:00 2001
From: Victor Zhestkov <35733135+vzhestkov@users.noreply.github.com>
Date: Mon, 8 Nov 2021 18:07:06 +0300
Subject: [PATCH] Add rpm_vercmp python library for version comparison
- 3002.2 (#449)
* Add rpm_vercmp python library for version comparison
* Add rpm-vercmp to tiamat builds
* Put GPG tests back to test_rpm_lowpkg
Co-authored-by: Megan Wilhite <mwilhite@vmware.com>
---
changelog/60814.added | 1 +
requirements/static/ci/linux.in | 1 +
requirements/static/ci/py3.5/linux.txt | 1 +
requirements/static/ci/py3.6/docs.txt | 1 +
requirements/static/ci/py3.6/linux.txt | 1 +
requirements/static/ci/py3.7/docs.txt | 1 +
requirements/static/ci/py3.7/linux.txt | 1 +
requirements/static/ci/py3.8/docs.txt | 1 +
requirements/static/ci/py3.8/linux.txt | 1 +
requirements/static/ci/py3.9/docs.txt | 1 +
requirements/static/ci/py3.9/linux.txt | 1 +
requirements/static/pkg/linux.in | 1 +
requirements/static/pkg/py3.5/linux.txt | 1 +
requirements/static/pkg/py3.6/linux.txt | 1 +
requirements/static/pkg/py3.7/linux.txt | 1 +
requirements/static/pkg/py3.8/linux.txt | 1 +
requirements/static/pkg/py3.9/linux.txt | 1 +
salt/modules/rpm_lowpkg.py | 21 +-
tests/pytests/unit/modules/test_rpm_lowpkg.py | 545 ++++++++++++++++++
tests/unit/modules/test_rpm_lowpkg.py | 486 ----------------
20 files changed, 582 insertions(+), 487 deletions(-)
create mode 100644 changelog/60814.added
create mode 100644 tests/pytests/unit/modules/test_rpm_lowpkg.py
delete mode 100644 tests/unit/modules/test_rpm_lowpkg.py
diff --git a/changelog/60814.added b/changelog/60814.added
new file mode 100644
index 0000000000..7a9ffe1b25
--- /dev/null
+++ b/changelog/60814.added
@@ -0,0 +1 @@
+Add the python rpm-vercmp library in the rpm_lowpkg.py module.
diff --git a/requirements/static/ci/linux.in b/requirements/static/ci/linux.in
index c3dbbf7cd0..99e10fbc0b 100644
--- a/requirements/static/ci/linux.in
+++ b/requirements/static/ci/linux.in
@@ -26,6 +26,7 @@ paramiko>=2.1.6
pycurl
pygit2<=0.28.2; python_version < '3.8'
pygit2>=1.2.0; python_version >= '3.8'
+rpm-vercmp
pyiface
pyinotify
python-etcd>0.4.2
diff --git a/requirements/static/ci/py3.5/linux.txt b/requirements/static/ci/py3.5/linux.txt
index 6b64d844db..82450fa2be 100644
--- a/requirements/static/ci/py3.5/linux.txt
+++ b/requirements/static/ci/py3.5/linux.txt
@@ -203,6 +203,7 @@ rfc3987==1.3.8
rsa==4.0 # via google-auth
s3transfer==0.3.3 # via boto3
scp==0.13.2 # via junos-eznc
+rpm-vercmp==0.1.2
setproctitle==1.1.10
setuptools-scm==3.2.0
six==1.15.0
diff --git a/requirements/static/ci/py3.6/docs.txt b/requirements/static/ci/py3.6/docs.txt
index 29ea37911e..3dd44628a9 100644
--- a/requirements/static/ci/py3.6/docs.txt
+++ b/requirements/static/ci/py3.6/docs.txt
@@ -28,3 +28,4 @@ sphinxcontrib-jsmath==1.0.1 # via sphinx
sphinxcontrib-qthelp==1.0.3 # via sphinx
sphinxcontrib-serializinghtml==1.1.4 # via sphinx
urllib3==1.25.9 # via requests
+rpm-vercmp==0.1.2
diff --git a/requirements/static/ci/py3.6/linux.txt b/requirements/static/ci/py3.6/linux.txt
index 55800bfa25..8733ac1602 100644
--- a/requirements/static/ci/py3.6/linux.txt
+++ b/requirements/static/ci/py3.6/linux.txt
@@ -207,6 +207,7 @@ rfc3987==1.3.8
rsa==4.0 # via google-auth
s3transfer==0.3.3 # via boto3
scp==0.13.2 # via junos-eznc, napalm, netmiko
+rpm-vercmp==0.1.2
setproctitle==1.1.10
setuptools-scm==3.2.0
six==1.15.0
diff --git a/requirements/static/ci/py3.7/docs.txt b/requirements/static/ci/py3.7/docs.txt
index 6c8ec97880..6c08a48484 100644
--- a/requirements/static/ci/py3.7/docs.txt
+++ b/requirements/static/ci/py3.7/docs.txt
@@ -18,6 +18,7 @@ pygments==2.6.1 # via sphinx
pyparsing==2.4.7 # via packaging
pytz==2019.3 # via babel
requests==2.23.0 # via sphinx
+rpm-vercmp==0.1.2
six==1.15.0 # via packaging
snowballstemmer==2.0.0 # via sphinx
sphinx==3.0.1
diff --git a/requirements/static/ci/py3.7/linux.txt b/requirements/static/ci/py3.7/linux.txt
index c3490e6ba6..e8b0cdd804 100644
--- a/requirements/static/ci/py3.7/linux.txt
+++ b/requirements/static/ci/py3.7/linux.txt
@@ -205,6 +205,7 @@ rfc3987==1.3.8
rsa==4.0 # via google-auth
s3transfer==0.3.3 # via boto3
scp==0.13.2 # via junos-eznc, napalm, netmiko
+rpm-vercmp==0.1.2
setproctitle==1.1.10
setuptools-scm==3.2.0
six==1.15.0
diff --git a/requirements/static/ci/py3.8/docs.txt b/requirements/static/ci/py3.8/docs.txt
index b3ee53b4b5..178d52fd88 100644
--- a/requirements/static/ci/py3.8/docs.txt
+++ b/requirements/static/ci/py3.8/docs.txt
@@ -18,6 +18,7 @@ pygments==2.4.2 # via sphinx
pyparsing==2.4.0 # via packaging
pytz==2019.1 # via babel
requests==2.22.0 # via sphinx
+rpm-vercmp==0.1.2
six==1.15.0 # via packaging
snowballstemmer==1.2.1 # via sphinx
sphinx==3.0.4
diff --git a/requirements/static/ci/py3.8/linux.txt b/requirements/static/ci/py3.8/linux.txt
index da66159c3e..75e3d72b36 100644
--- a/requirements/static/ci/py3.8/linux.txt
+++ b/requirements/static/ci/py3.8/linux.txt
@@ -205,6 +205,7 @@ rfc3987==1.3.8
rsa==4.0 # via google-auth
s3transfer==0.3.3 # via boto3
scp==0.13.2 # via junos-eznc, napalm, netmiko
+rpm-vercmp==0.1.2
setproctitle==1.1.10
setuptools-scm==3.2.0
six==1.15.0
diff --git a/requirements/static/ci/py3.9/docs.txt b/requirements/static/ci/py3.9/docs.txt
index 79ebb08d1b..d9e7fdbee0 100644
--- a/requirements/static/ci/py3.9/docs.txt
+++ b/requirements/static/ci/py3.9/docs.txt
@@ -18,6 +18,7 @@ pygments==2.4.2 # via sphinx
pyparsing==2.4.0 # via packaging
pytz==2019.1 # via babel
requests==2.22.0 # via sphinx
+rpm-vercmp==0.1.2
six==1.15.0 # via packaging
snowballstemmer==1.2.1 # via sphinx
sphinx==3.0.4
diff --git a/requirements/static/ci/py3.9/linux.txt b/requirements/static/ci/py3.9/linux.txt
index d11c63ce7a..fe95d02273 100644
--- a/requirements/static/ci/py3.9/linux.txt
+++ b/requirements/static/ci/py3.9/linux.txt
@@ -205,6 +205,7 @@ rfc3987==1.3.8
rsa==4.0 # via google-auth
s3transfer==0.3.3 # via boto3
scp==0.13.2 # via junos-eznc, napalm, netmiko
+rpm-vercmp==0.1.2
setproctitle==1.1.10
setuptools-scm==3.2.0
six==1.15.0
diff --git a/requirements/static/pkg/linux.in b/requirements/static/pkg/linux.in
index ff88bf10c4..d03b2d3225 100644
--- a/requirements/static/pkg/linux.in
+++ b/requirements/static/pkg/linux.in
@@ -6,5 +6,6 @@ backports.ssl_match_hostname>=3.7.0.1; python_version < '3.7'
pyopenssl>=19.0.0
python-dateutil>=2.8.0
python-gnupg>=0.4.4
+rpm-vercmp
setproctitle>=1.1.10
timelib>=0.2.5
diff --git a/requirements/static/pkg/py3.5/linux.txt b/requirements/static/pkg/py3.5/linux.txt
index 8c52ce232e..e33f626de9 100644
--- a/requirements/static/pkg/py3.5/linux.txt
+++ b/requirements/static/pkg/py3.5/linux.txt
@@ -31,6 +31,7 @@ pytz==2020.1 # via tempora
pyyaml==5.3.1
pyzmq==18.0.1 ; python_version < "3.9"
requests==2.21.0
+rpm-vercmp==0.1.2
setproctitle==1.1.10
six==1.15.0 # via cheroot, cherrypy, cryptography, more-itertools, pyopenssl, python-dateutil, tempora
tempora==1.14.1 # via portend
diff --git a/requirements/static/pkg/py3.6/linux.txt b/requirements/static/pkg/py3.6/linux.txt
index e8370c3fcc..f8a5d2ef3e 100644
--- a/requirements/static/pkg/py3.6/linux.txt
+++ b/requirements/static/pkg/py3.6/linux.txt
@@ -31,6 +31,7 @@ pytz==2020.1 # via tempora
pyyaml==5.3.1
pyzmq==18.0.1 ; python_version < "3.9"
requests==2.21.0
+rpm-vercmp==0.1.2
setproctitle==1.1.10
six==1.15.0 # via cheroot, cherrypy, cryptography, more-itertools, pyopenssl, python-dateutil, tempora
tempora==1.14.1 # via portend
diff --git a/requirements/static/pkg/py3.7/linux.txt b/requirements/static/pkg/py3.7/linux.txt
index 49e6cdc2c4..0ae93dc5a3 100644
--- a/requirements/static/pkg/py3.7/linux.txt
+++ b/requirements/static/pkg/py3.7/linux.txt
@@ -30,6 +30,7 @@ pytz==2020.1 # via tempora
pyyaml==5.3.1
pyzmq==18.0.1 ; python_version < "3.9"
requests==2.21.0
+rpm-vercmp==0.1.2
setproctitle==1.1.10
six==1.15.0 # via cheroot, cherrypy, cryptography, more-itertools, pyopenssl, python-dateutil, tempora
tempora==1.14.1 # via portend
diff --git a/requirements/static/pkg/py3.8/linux.txt b/requirements/static/pkg/py3.8/linux.txt
index cfa3134780..895dcbe6f6 100644
--- a/requirements/static/pkg/py3.8/linux.txt
+++ b/requirements/static/pkg/py3.8/linux.txt
@@ -30,6 +30,7 @@ pytz==2020.1 # via tempora
pyyaml==5.3.1
pyzmq==19.0.0 ; python_version < "3.9"
requests==2.21.0
+rpm-vercmp==0.1.2
setproctitle==1.1.10
six==1.15.0 # via cheroot, cherrypy, cryptography, more-itertools, pyopenssl, python-dateutil, tempora
tempora==1.14.1 # via portend
diff --git a/requirements/static/pkg/py3.9/linux.txt b/requirements/static/pkg/py3.9/linux.txt
index 4e2ffc2c7e..af119f0e4d 100644
--- a/requirements/static/pkg/py3.9/linux.txt
+++ b/requirements/static/pkg/py3.9/linux.txt
@@ -30,6 +30,7 @@ pytz==2020.1 # via tempora
pyyaml==5.3.1
pyzmq==19.0.2 ; python_version >= "3.9"
requests==2.21.0
+rpm-vercmp==0.1.2
setproctitle==1.1.10
six==1.15.0 # via cheroot, cherrypy, cryptography, more-itertools, pyopenssl, python-dateutil, tempora
tempora==1.14.1 # via portend
diff --git a/salt/modules/rpm_lowpkg.py b/salt/modules/rpm_lowpkg.py
index 57f336bacf..025cfdfab0 100644
--- a/salt/modules/rpm_lowpkg.py
+++ b/salt/modules/rpm_lowpkg.py
@@ -36,6 +36,13 @@ try:
except ImportError:
HAS_RPMUTILS = False
+try:
+ import rpm_vercmp
+
+ HAS_PY_RPM = True
+except ImportError:
+ HAS_PY_RPM = False
+
log = logging.getLogger(__name__)
@@ -717,6 +724,8 @@ def version_cmp(ver1, ver2, ignore_epoch=False):
"labelCompare function. Not using rpm.labelCompare for "
"version comparison."
)
+ elif HAS_PY_RPM:
+ cmp_func = rpm_vercmp.vercmp
else:
log.warning(
"Please install a package that provides rpm.labelCompare for "
@@ -785,7 +794,17 @@ def version_cmp(ver1, ver2, ignore_epoch=False):
if not ver1_r or not ver2_r:
ver1_r = ver2_r = ""
- cmp_result = cmp_func((ver1_e, ver1_v, ver1_r), (ver2_e, ver2_v, ver2_r))
+ if HAS_PY_RPM:
+ # handle epoch version comparison first
+ # rpm_vercmp.vercmp does not handle epoch version comparison
+ ret = salt.utils.versions.version_cmp(ver1_e, ver2_e)
+ if ret in (1, -1):
+ return ret
+ cmp_result = cmp_func(ver1, ver2)
+ else:
+ cmp_result = cmp_func(
+ (ver1_e, ver1_v, ver1_r), (ver2_e, ver2_v, ver2_r)
+ )
if cmp_result not in (-1, 0, 1):
raise CommandExecutionError(
"Comparison result '{}' is invalid".format(cmp_result)
diff --git a/tests/pytests/unit/modules/test_rpm_lowpkg.py b/tests/pytests/unit/modules/test_rpm_lowpkg.py
new file mode 100644
index 0000000000..c9d1ac2b1c
--- /dev/null
+++ b/tests/pytests/unit/modules/test_rpm_lowpkg.py
@@ -0,0 +1,545 @@
+"""
+ :codeauthor: Jayesh Kariya <jayeshk@saltstack.com>
+"""
+
+
+import datetime
+import pytest
+import salt.modules.cmdmod
+import salt.modules.rpm_lowpkg as rpm
+import salt.utils.path
+from tests.support.mock import MagicMock, patch
+
+# pylint: disable=unused-import
+try:
+ import rpm as rpm_lib
+
+ HAS_RPM = True
+except ImportError:
+ HAS_RPM = False
+
+try:
+ import rpm_vercmp
+
+ HAS_PY_RPM = True
+except ImportError:
+ HAS_PY_RPM = False
+# pylint: enable=unused-import
+
+
+def _called_with_root(mock):
+ cmd = " ".join(mock.call_args[0][0])
+ return cmd.startswith("rpm --root /")
+
+
+@pytest.fixture
+def configure_loader_modules():
+ return {rpm: {"rpm": MagicMock(return_value=MagicMock)}}
+
+
+# 'list_pkgs' function tests: 2
+
+
+def test_list_pkgs():
+ """
+ Test if it list the packages currently installed in a dict
+ """
+ mock = MagicMock(return_value="")
+ with patch.dict(rpm.__salt__, {"cmd.run": mock}):
+ assert rpm.list_pkgs() == {}
+ assert not _called_with_root(mock)
+
+
+def test_list_pkgs_root():
+ """
+ Test if it list the packages currently installed in a dict,
+ called with root parameter
+ """
+ mock = MagicMock(return_value="")
+ with patch.dict(rpm.__salt__, {"cmd.run": mock}):
+ rpm.list_pkgs(root="/")
+ assert _called_with_root(mock)
+
+
+# 'verify' function tests: 2
+
+
+def test_verify():
+ """
+ Test if it runs an rpm -Va on a system, and returns the
+ results in a dict
+ """
+ mock = MagicMock(
+ return_value={"stdout": "", "stderr": "", "retcode": 0, "pid": 12345}
+ )
+ with patch.dict(rpm.__salt__, {"cmd.run_all": mock}):
+ assert rpm.verify("httpd") == {}
+ assert not _called_with_root(mock)
+
+
+def test_verify_root():
+ """
+ Test if it runs an rpm -Va on a system, and returns the
+ results in a dict, called with root parameter
+ """
+ mock = MagicMock(
+ return_value={"stdout": "", "stderr": "", "retcode": 0, "pid": 12345}
+ )
+ with patch.dict(rpm.__salt__, {"cmd.run_all": mock}):
+ rpm.verify("httpd", root="/")
+ assert _called_with_root(mock)
+
+
+# 'file_list' function tests: 2
+
+
+def test_file_list():
+ """
+ Test if it list the files that belong to a package.
+ """
+ mock = MagicMock(return_value="")
+ with patch.dict(rpm.__salt__, {"cmd.run": mock}):
+ assert rpm.file_list("httpd") == {"errors": [], "files": []}
+ assert not _called_with_root(mock)
+
+
+def test_file_list_root():
+ """
+ Test if it list the files that belong to a package, using the
+ root parameter.
+ """
+
+ mock = MagicMock(return_value="")
+ with patch.dict(rpm.__salt__, {"cmd.run": mock}):
+ rpm.file_list("httpd", root="/")
+ assert _called_with_root(mock)
+
+
+# 'file_dict' function tests: 2
+
+
+def test_file_dict():
+ """
+ Test if it list the files that belong to a package
+ """
+ mock = MagicMock(return_value="")
+ with patch.dict(rpm.__salt__, {"cmd.run": mock}):
+ assert rpm.file_dict("httpd") == {"errors": [], "packages": {}}
+ assert not _called_with_root(mock)
+
+
+def test_file_dict_root():
+ """
+ Test if it list the files that belong to a package
+ """
+ mock = MagicMock(return_value="")
+ with patch.dict(rpm.__salt__, {"cmd.run": mock}):
+ rpm.file_dict("httpd", root="/")
+ assert _called_with_root(mock)
+
+
+# 'owner' function tests: 1
+
+
+def test_owner():
+ """
+ Test if it return the name of the package that owns the file.
+ """
+ assert rpm.owner() == ""
+
+ ret = "file /usr/bin/salt-jenkins-build is not owned by any package"
+ mock = MagicMock(return_value=ret)
+ with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
+ assert rpm.owner("/usr/bin/salt-jenkins-build") == ""
+ assert not _called_with_root(mock)
+
+ ret = {
+ "/usr/bin/vim": "vim-enhanced-7.4.160-1.e17.x86_64",
+ "/usr/bin/python": "python-2.7.5-16.e17.x86_64",
+ }
+ mock = MagicMock(
+ side_effect=[
+ "python-2.7.5-16.e17.x86_64",
+ "vim-enhanced-7.4.160-1.e17.x86_64",
+ ]
+ )
+ with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
+ assert rpm.owner("/usr/bin/python", "/usr/bin/vim") == ret
+ assert not _called_with_root(mock)
+
+
+def test_owner_root():
+ """
+ Test if it return the name of the package that owns the file,
+ using the parameter root.
+ """
+ assert rpm.owner() == ""
+
+ ret = "file /usr/bin/salt-jenkins-build is not owned by any package"
+ mock = MagicMock(return_value=ret)
+ with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
+ rpm.owner("/usr/bin/salt-jenkins-build", root="/")
+ assert _called_with_root(mock)
+
+
+# 'checksum' function tests: 2
+
+
+def test_checksum():
+ """
+ Test if checksum validate as expected
+ """
+ ret = {
+ "file1.rpm": True,
+ "file2.rpm": False,
+ "file3.rpm": False,
+ }
+
+ mock = MagicMock(side_effect=[True, 0, True, 1, False, 0])
+ with patch.dict(rpm.__salt__, {"file.file_exists": mock, "cmd.retcode": mock}):
+ assert rpm.checksum("file1.rpm", "file2.rpm", "file3.rpm") == ret
+ assert not _called_with_root(mock)
+
+
+def test_checksum_root():
+ """
+ Test if checksum validate as expected, using the parameter
+ root
+ """
+ mock = MagicMock(side_effect=[True, 0])
+ with patch.dict(rpm.__salt__, {"file.file_exists": mock, "cmd.retcode": mock}):
+ rpm.checksum("file1.rpm", root="/")
+ assert _called_with_root(mock)
+
+
+@pytest.mark.parametrize("rpm_lib", ["HAS_RPM", "HAS_PY_RPM", "rpmdev-vercmp"])
+def test_version_cmp_rpm_all_libraries(rpm_lib):
+ """
+ Test package version when each library is installed
+ """
+ rpmdev = salt.utils.path.which("rpmdev-vercmp")
+ patch_cmd = patch.dict(rpm.__salt__, {"cmd.run_all": salt.modules.cmdmod.run_all})
+ if rpm_lib == "rpmdev-vercmp":
+ if rpmdev:
+ patch_rpm = patch("salt.modules.rpm_lowpkg.HAS_RPM", False)
+ patch_py_rpm = patch("salt.modules.rpm_lowpkg.HAS_PY_RPM", False)
+ else:
+ pytest.skip("The rpmdev-vercmp binary is not installed")
+ elif rpm_lib == "HAS_RPM":
+ if HAS_RPM:
+ patch_rpm = patch("salt.modules.rpm_lowpkg.HAS_RPM", True)
+ patch_py_rpm = patch("salt.modules.rpm_lowpkg.HAS_PY_RPM", False)
+ else:
+ pytest.skip("The RPM lib is not installed, skipping")
+ elif rpm_lib == "HAS_PY_RPM":
+ if HAS_PY_RPM:
+ patch_rpm = patch("salt.modules.rpm_lowpkg.HAS_RPM", False)
+ patch_py_rpm = patch("salt.modules.rpm_lowpkg.HAS_PY_RPM", True)
+ else:
+ pytest.skip("The Python RPM lib is not installed, skipping")
+
+ with patch_rpm, patch_py_rpm, patch_cmd:
+ assert -1 == rpm.version_cmp("1", "2")
+ assert -1 == rpm.version_cmp("2.9.1-6.el7_2.3", "2.9.1-6.el7.4")
+ assert 1 == rpm.version_cmp("3.2", "3.0")
+ assert 0 == rpm.version_cmp("3.0", "3.0")
+ assert 1 == rpm.version_cmp("1:2.9.1-6.el7_2.3", "2.9.1-6.el7.4")
+ assert -1 == rpm.version_cmp("1:2.9.1-6.el7_2.3", "1:2.9.1-6.el7.4")
+ assert 1 == rpm.version_cmp("2:2.9.1-6.el7_2.3", "1:2.9.1-6.el7.4")
+ assert 0 == rpm.version_cmp("3:2.9.1-6.el7.4", "3:2.9.1-6.el7.4")
+ assert -1 == rpm.version_cmp("3:2.9.1-6.el7.4", "3:2.9.1-7.el7.4")
+ assert 1 == rpm.version_cmp("3:2.9.1-8.el7.4", "3:2.9.1-7.el7.4")
+
+
+@patch("salt.modules.rpm_lowpkg.HAS_RPM", True)
+@patch("salt.modules.rpm_lowpkg.rpm.labelCompare", return_value=-1)
+@patch("salt.modules.rpm_lowpkg.log")
+def test_version_cmp_rpm(mock_log, mock_labelCompare):
+ """
+ Test package version if RPM-Python is installed
+
+ :return:
+ """
+ assert -1 == rpm.version_cmp("1", "2")
+ assert not mock_log.warning.called
+ assert mock_labelCompare.called
+
+
+@patch("salt.modules.rpm_lowpkg.HAS_RPM", False)
+@patch("salt.modules.rpm_lowpkg.HAS_RPMUTILS", True)
+@patch("salt.modules.rpm_lowpkg.HAS_PY_RPM", False)
+@patch("salt.modules.rpm_lowpkg.rpmUtils", create=True)
+@patch("salt.modules.rpm_lowpkg.log")
+def test_version_cmp_rpmutils(mock_log, mock_rpmUtils):
+ """
+ Test package version if rpmUtils.miscutils called
+
+ :return:
+ """
+ mock_rpmUtils.miscutils = MagicMock()
+ mock_rpmUtils.miscutils.compareEVR = MagicMock(return_value=-1)
+ assert -1 == rpm.version_cmp("1", "2")
+ assert mock_log.warning.called
+ assert mock_rpmUtils.miscutils.compareEVR.called
+ assert (
+ mock_log.warning.mock_calls[0][1][0]
+ == "Please install a package that provides rpm.labelCompare for more accurate version comparisons."
+ )
+
+
+@patch("salt.modules.rpm_lowpkg.HAS_RPM", False)
+@patch("salt.modules.rpm_lowpkg.HAS_RPMUTILS", False)
+@patch("salt.modules.rpm_lowpkg.HAS_PY_RPM", False)
+@patch("salt.utils.path.which", return_value=True)
+@patch("salt.modules.rpm_lowpkg.log")
+def test_version_cmp_rpmdev_vercmp(mock_log, mock_which):
+ """
+ Test package version if rpmdev-vercmp is installed
+
+ :return:
+ """
+ mock__salt__ = MagicMock(return_value={"retcode": 12})
+ with patch.dict(rpm.__salt__, {"cmd.run_all": mock__salt__}):
+ assert -1 == rpm.version_cmp("1", "2")
+ assert mock__salt__.called
+ assert mock_log.warning.called
+ assert (
+ mock_log.warning.mock_calls[0][1][0]
+ == "Please install a package that provides rpm.labelCompare for more accurate version comparisons."
+ )
+ assert (
+ mock_log.warning.mock_calls[1][1][0]
+ == "Installing the rpmdevtools package may surface dev tools in production."
+ )
+
+
+@patch("salt.modules.rpm_lowpkg.HAS_RPM", False)
+@patch("salt.modules.rpm_lowpkg.HAS_RPMUTILS", False)
+@patch("salt.modules.rpm_lowpkg.HAS_PY_RPM", False)
+@patch("salt.utils.versions.version_cmp", return_value=-1)
+@patch("salt.utils.path.which", return_value=False)
+@patch("salt.modules.rpm_lowpkg.log")
+def test_version_cmp_python(mock_log, mock_which, mock_version_cmp):
+ """
+ Test package version if falling back to python
+
+ :return:
+ """
+ assert -1 == rpm.version_cmp("1", "2")
+ assert mock_version_cmp.called
+ assert mock_log.warning.called
+ assert (
+ mock_log.warning.mock_calls[0][1][0]
+ == "Please install a package that provides rpm.labelCompare for more accurate version comparisons."
+ )
+ assert (
+ mock_log.warning.mock_calls[1][1][0]
+ == "Falling back on salt.utils.versions.version_cmp() for version comparisons"
+ )
+
+
+def test_list_gpg_keys_no_info():
+ """
+ Test list_gpg_keys with no extra information
+ """
+ mock = MagicMock(return_value="\n".join(["gpg-pubkey-1", "gpg-pubkey-2"]))
+ with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
+ assert rpm.list_gpg_keys() == ["gpg-pubkey-1", "gpg-pubkey-2"]
+ assert not _called_with_root(mock)
+
+
+def test_list_gpg_keys_no_info_root():
+ """
+ Test list_gpg_keys with no extra information and root
+ """
+ mock = MagicMock(return_value="\n".join(["gpg-pubkey-1", "gpg-pubkey-2"]))
+ with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
+ assert rpm.list_gpg_keys(root="/mnt") == ["gpg-pubkey-1", "gpg-pubkey-2"]
+ assert _called_with_root(mock)
+
+
+@patch("salt.modules.rpm_lowpkg.info_gpg_key")
+def test_list_gpg_keys_info(info_gpg_key):
+ """
+ Test list_gpg_keys with extra information
+ """
+ info_gpg_key.side_effect = lambda x, root: {"Description": "key for {}".format(x)}
+ mock = MagicMock(return_value="\n".join(["gpg-pubkey-1", "gpg-pubkey-2"]))
+ with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
+ assert rpm.list_gpg_keys(info=True) == {
+ "gpg-pubkey-1": {"Description": "key for gpg-pubkey-1"},
+ "gpg-pubkey-2": {"Description": "key for gpg-pubkey-2"},
+ }
+ assert not _called_with_root(mock)
+
+
+def test_info_gpg_key():
+ """
+ Test info_gpg_keys from a normal output
+ """
+ info = """Name : gpg-pubkey
+Version : 3dbdc284
+Release : 53674dd4
+Architecture: (none)
+Install Date: Fri 08 Mar 2019 11:57:44 AM UTC
+Group : Public Keys
+Size : 0
+License : pubkey
+Signature : (none)
+Source RPM : (none)
+Build Date : Mon 05 May 2014 10:37:40 AM UTC
+Build Host : localhost
+Packager : openSUSE Project Signing Key <opensuse@opensuse.org>
+Summary : gpg(openSUSE Project Signing Key <opensuse@opensuse.org>)
+Description :
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: rpm-4.14.2.1 (NSS-3)
+
+mQENBEkUTD8BCADWLy5d5IpJedHQQSXkC1VK/oAZlJEeBVpSZjMCn8LiHaI9Wq3G
+3Vp6wvsP1b3kssJGzVFNctdXt5tjvOLxvrEfRJuGfqHTKILByqLzkeyWawbFNfSQ
+93/8OunfSTXC1Sx3hgsNXQuOrNVKrDAQUqT620/jj94xNIg09bLSxsjN6EeTvyiO
+mtE9H1J03o9tY6meNL/gcQhxBvwuo205np0JojYBP0pOfN8l9hnIOLkA0yu4ZXig
+oKOVmf4iTjX4NImIWldT+UaWTO18NWcCrujtgHueytwYLBNV5N0oJIP2VYuLZfSD
+VYuPllv7c6O2UEOXJsdbQaVuzU1HLocDyipnABEBAAG0NG9wZW5TVVNFIFByb2pl
+Y3QgU2lnbmluZyBLZXkgPG9wZW5zdXNlQG9wZW5zdXNlLm9yZz6JATwEEwECACYC
+GwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAUCU2dN1AUJHR8ElQAKCRC4iy/UPb3C
+hGQrB/9teCZ3Nt8vHE0SC5NmYMAE1Spcjkzx6M4r4C70AVTMEQh/8BvgmwkKP/qI
+CWo2vC1hMXRgLg/TnTtFDq7kW+mHsCXmf5OLh2qOWCKi55Vitlf6bmH7n+h34Sha
+Ei8gAObSpZSF8BzPGl6v0QmEaGKM3O1oUbbB3Z8i6w21CTg7dbU5vGR8Yhi9rNtr
+hqrPS+q2yftjNbsODagaOUb85ESfQGx/LqoMePD+7MqGpAXjKMZqsEDP0TbxTwSk
+4UKnF4zFCYHPLK3y/hSH5SEJwwPY11l6JGdC1Ue8Zzaj7f//axUs/hTC0UZaEE+a
+5v4gbqOcigKaFs9Lc3Bj8b/lE10Y
+=i2TA
+-----END PGP PUBLIC KEY BLOCK-----
+
+"""
+ mock = MagicMock(return_value=info)
+ with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
+ assert rpm.info_gpg_key("key") == {
+ "Name": "gpg-pubkey",
+ "Version": "3dbdc284",
+ "Release": "53674dd4",
+ "Architecture": None,
+ "Install Date": datetime.datetime(2019, 3, 8, 11, 57, 44),
+ "Group": "Public Keys",
+ "Size": 0,
+ "License": "pubkey",
+ "Signature": None,
+ "Source RPM": None,
+ "Build Date": datetime.datetime(2014, 5, 5, 10, 37, 40),
+ "Build Host": "localhost",
+ "Packager": "openSUSE Project Signing Key <opensuse@opensuse.org>",
+ "Summary": "gpg(openSUSE Project Signing Key <opensuse@opensuse.org>)",
+ "Description": """-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: rpm-4.14.2.1 (NSS-3)
+
+mQENBEkUTD8BCADWLy5d5IpJedHQQSXkC1VK/oAZlJEeBVpSZjMCn8LiHaI9Wq3G
+3Vp6wvsP1b3kssJGzVFNctdXt5tjvOLxvrEfRJuGfqHTKILByqLzkeyWawbFNfSQ
+93/8OunfSTXC1Sx3hgsNXQuOrNVKrDAQUqT620/jj94xNIg09bLSxsjN6EeTvyiO
+mtE9H1J03o9tY6meNL/gcQhxBvwuo205np0JojYBP0pOfN8l9hnIOLkA0yu4ZXig
+oKOVmf4iTjX4NImIWldT+UaWTO18NWcCrujtgHueytwYLBNV5N0oJIP2VYuLZfSD
+VYuPllv7c6O2UEOXJsdbQaVuzU1HLocDyipnABEBAAG0NG9wZW5TVVNFIFByb2pl
+Y3QgU2lnbmluZyBLZXkgPG9wZW5zdXNlQG9wZW5zdXNlLm9yZz6JATwEEwECACYC
+GwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAUCU2dN1AUJHR8ElQAKCRC4iy/UPb3C
+hGQrB/9teCZ3Nt8vHE0SC5NmYMAE1Spcjkzx6M4r4C70AVTMEQh/8BvgmwkKP/qI
+CWo2vC1hMXRgLg/TnTtFDq7kW+mHsCXmf5OLh2qOWCKi55Vitlf6bmH7n+h34Sha
+Ei8gAObSpZSF8BzPGl6v0QmEaGKM3O1oUbbB3Z8i6w21CTg7dbU5vGR8Yhi9rNtr
+hqrPS+q2yftjNbsODagaOUb85ESfQGx/LqoMePD+7MqGpAXjKMZqsEDP0TbxTwSk
+4UKnF4zFCYHPLK3y/hSH5SEJwwPY11l6JGdC1Ue8Zzaj7f//axUs/hTC0UZaEE+a
+5v4gbqOcigKaFs9Lc3Bj8b/lE10Y
+=i2TA
+-----END PGP PUBLIC KEY BLOCK-----""",
+ }
+ assert not _called_with_root(mock)
+
+
+def test_info_gpg_key_extended():
+ """
+ Test info_gpg_keys from an extended output
+ """
+ info = """Name : gpg-pubkey
+Version : 3dbdc284
+Release : 53674dd4
+Architecture: (none)
+Install Date: Fri 08 Mar 2019 11:57:44 AM UTC
+Group : Public Keys
+Size : 0
+License : pubkey
+Signature : (none)
+Source RPM : (none)
+Build Date : Mon 05 May 2014 10:37:40 AM UTC
+Build Host : localhost
+Packager : openSUSE Project Signing Key <opensuse@opensuse.org>
+Summary : gpg(openSUSE Project Signing Key <opensuse@opensuse.org>)
+Description :
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: rpm-4.14.2.1 (NSS-3)
+
+mQENBEkUTD8BCADWLy5d5IpJedHQQSXkC1VK/oAZlJEeBVpSZjMCn8LiHaI9Wq3G
+3Vp6wvsP1b3kssJGzVFNctdXt5tjvOLxvrEfRJuGfqHTKILByqLzkeyWawbFNfSQ
+93/8OunfSTXC1Sx3hgsNXQuOrNVKrDAQUqT620/jj94xNIg09bLSxsjN6EeTvyiO
+mtE9H1J03o9tY6meNL/gcQhxBvwuo205np0JojYBP0pOfN8l9hnIOLkA0yu4ZXig
+oKOVmf4iTjX4NImIWldT+UaWTO18NWcCrujtgHueytwYLBNV5N0oJIP2VYuLZfSD
+VYuPllv7c6O2UEOXJsdbQaVuzU1HLocDyipnABEBAAG0NG9wZW5TVVNFIFByb2pl
+Y3QgU2lnbmluZyBLZXkgPG9wZW5zdXNlQG9wZW5zdXNlLm9yZz6JATwEEwECACYC
+GwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAUCU2dN1AUJHR8ElQAKCRC4iy/UPb3C
+hGQrB/9teCZ3Nt8vHE0SC5NmYMAE1Spcjkzx6M4r4C70AVTMEQh/8BvgmwkKP/qI
+CWo2vC1hMXRgLg/TnTtFDq7kW+mHsCXmf5OLh2qOWCKi55Vitlf6bmH7n+h34Sha
+Ei8gAObSpZSF8BzPGl6v0QmEaGKM3O1oUbbB3Z8i6w21CTg7dbU5vGR8Yhi9rNtr
+hqrPS+q2yftjNbsODagaOUb85ESfQGx/LqoMePD+7MqGpAXjKMZqsEDP0TbxTwSk
+4UKnF4zFCYHPLK3y/hSH5SEJwwPY11l6JGdC1Ue8Zzaj7f//axUs/hTC0UZaEE+a
+5v4gbqOcigKaFs9Lc3Bj8b/lE10Y
+=i2TA
+-----END PGP PUBLIC KEY BLOCK-----
+
+Distribution: (none)
+"""
+ mock = MagicMock(return_value=info)
+ with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
+ assert rpm.info_gpg_key("key") == {
+ "Name": "gpg-pubkey",
+ "Version": "3dbdc284",
+ "Release": "53674dd4",
+ "Architecture": None,
+ "Install Date": datetime.datetime(2019, 3, 8, 11, 57, 44),
+ "Group": "Public Keys",
+ "Size": 0,
+ "License": "pubkey",
+ "Signature": None,
+ "Source RPM": None,
+ "Build Date": datetime.datetime(2014, 5, 5, 10, 37, 40),
+ "Build Host": "localhost",
+ "Packager": "openSUSE Project Signing Key <opensuse@opensuse.org>",
+ "Summary": "gpg(openSUSE Project Signing Key <opensuse@opensuse.org>)",
+ "Description": """-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: rpm-4.14.2.1 (NSS-3)
+
+mQENBEkUTD8BCADWLy5d5IpJedHQQSXkC1VK/oAZlJEeBVpSZjMCn8LiHaI9Wq3G
+3Vp6wvsP1b3kssJGzVFNctdXt5tjvOLxvrEfRJuGfqHTKILByqLzkeyWawbFNfSQ
+93/8OunfSTXC1Sx3hgsNXQuOrNVKrDAQUqT620/jj94xNIg09bLSxsjN6EeTvyiO
+mtE9H1J03o9tY6meNL/gcQhxBvwuo205np0JojYBP0pOfN8l9hnIOLkA0yu4ZXig
+oKOVmf4iTjX4NImIWldT+UaWTO18NWcCrujtgHueytwYLBNV5N0oJIP2VYuLZfSD
+VYuPllv7c6O2UEOXJsdbQaVuzU1HLocDyipnABEBAAG0NG9wZW5TVVNFIFByb2pl
+Y3QgU2lnbmluZyBLZXkgPG9wZW5zdXNlQG9wZW5zdXNlLm9yZz6JATwEEwECACYC
+GwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAUCU2dN1AUJHR8ElQAKCRC4iy/UPb3C
+hGQrB/9teCZ3Nt8vHE0SC5NmYMAE1Spcjkzx6M4r4C70AVTMEQh/8BvgmwkKP/qI
+CWo2vC1hMXRgLg/TnTtFDq7kW+mHsCXmf5OLh2qOWCKi55Vitlf6bmH7n+h34Sha
+Ei8gAObSpZSF8BzPGl6v0QmEaGKM3O1oUbbB3Z8i6w21CTg7dbU5vGR8Yhi9rNtr
+hqrPS+q2yftjNbsODagaOUb85ESfQGx/LqoMePD+7MqGpAXjKMZqsEDP0TbxTwSk
+4UKnF4zFCYHPLK3y/hSH5SEJwwPY11l6JGdC1Ue8Zzaj7f//axUs/hTC0UZaEE+a
+5v4gbqOcigKaFs9Lc3Bj8b/lE10Y
+=i2TA
+-----END PGP PUBLIC KEY BLOCK-----""",
+ "Distribution": None,
+ }
+ assert not _called_with_root(mock)
+
+
+def test_remove_gpg_key():
+ """
+ Test remove_gpg_key
+ """
+ mock = MagicMock(return_value=0)
+ with patch.dict(rpm.__salt__, {"cmd.retcode": mock}):
+ assert rpm.remove_gpg_key("gpg-pubkey-1")
+ assert not _called_with_root(mock)
diff --git a/tests/unit/modules/test_rpm_lowpkg.py b/tests/unit/modules/test_rpm_lowpkg.py
deleted file mode 100644
index 84020263ea..0000000000
--- a/tests/unit/modules/test_rpm_lowpkg.py
+++ /dev/null
@@ -1,486 +0,0 @@
-"""
- :codeauthor: Jayesh Kariya <jayeshk@saltstack.com>
-"""
-
-import datetime
-
-import salt.modules.rpm_lowpkg as rpm
-from tests.support.mixins import LoaderModuleMockMixin
-from tests.support.mock import MagicMock, patch
-from tests.support.unit import TestCase
-
-
-def _called_with_root(mock):
- cmd = " ".join(mock.call_args[0][0])
- return cmd.startswith("rpm --root /")
-
-
-def _called_with_root(mock):
- cmd = " ".join(mock.call_args[0][0])
- return cmd.startswith("rpm --root /")
-
-
-class RpmTestCase(TestCase, LoaderModuleMockMixin):
- """
- Test cases for salt.modules.rpm
- """
-
- def setup_loader_modules(self):
- return {rpm: {"rpm": MagicMock(return_value=MagicMock)}}
-
- # 'list_pkgs' function tests: 2
-
- def test_list_pkgs(self):
- """
- Test if it list the packages currently installed in a dict
- """
- mock = MagicMock(return_value="")
- with patch.dict(rpm.__salt__, {"cmd.run": mock}):
- self.assertDictEqual(rpm.list_pkgs(), {})
- self.assertFalse(_called_with_root(mock))
-
- def test_list_pkgs_root(self):
- """
- Test if it list the packages currently installed in a dict,
- called with root parameter
- """
- mock = MagicMock(return_value="")
- with patch.dict(rpm.__salt__, {"cmd.run": mock}):
- rpm.list_pkgs(root="/")
- self.assertTrue(_called_with_root(mock))
-
- # 'verify' function tests: 2
-
- def test_verify(self):
- """
- Test if it runs an rpm -Va on a system, and returns the
- results in a dict
- """
- mock = MagicMock(
- return_value={"stdout": "", "stderr": "", "retcode": 0, "pid": 12345}
- )
- with patch.dict(rpm.__salt__, {"cmd.run_all": mock}):
- self.assertDictEqual(rpm.verify("httpd"), {})
- self.assertFalse(_called_with_root(mock))
-
- def test_verify_root(self):
- """
- Test if it runs an rpm -Va on a system, and returns the
- results in a dict, called with root parameter
- """
- mock = MagicMock(
- return_value={"stdout": "", "stderr": "", "retcode": 0, "pid": 12345}
- )
- with patch.dict(rpm.__salt__, {"cmd.run_all": mock}):
- rpm.verify("httpd", root="/")
- self.assertTrue(_called_with_root(mock))
-
- # 'file_list' function tests: 2
-
- def test_file_list(self):
- """
- Test if it list the files that belong to a package.
- """
- mock = MagicMock(return_value="")
- with patch.dict(rpm.__salt__, {"cmd.run": mock}):
- self.assertDictEqual(rpm.file_list("httpd"), {"errors": [], "files": []})
- self.assertFalse(_called_with_root(mock))
-
- def test_file_list_root(self):
- """
- Test if it list the files that belong to a package, using the
- root parameter.
- """
-
- mock = MagicMock(return_value="")
- with patch.dict(rpm.__salt__, {"cmd.run": mock}):
- rpm.file_list("httpd", root="/")
- self.assertTrue(_called_with_root(mock))
-
- # 'file_dict' function tests: 2
-
- def test_file_dict(self):
- """
- Test if it list the files that belong to a package
- """
- mock = MagicMock(return_value="")
- with patch.dict(rpm.__salt__, {"cmd.run": mock}):
- self.assertDictEqual(rpm.file_dict("httpd"), {"errors": [], "packages": {}})
- self.assertFalse(_called_with_root(mock))
-
- def test_file_dict_root(self):
- """
- Test if it list the files that belong to a package
- """
- mock = MagicMock(return_value="")
- with patch.dict(rpm.__salt__, {"cmd.run": mock}):
- self.assertDictEqual(rpm.file_dict("httpd"), {"errors": [], "packages": {}})
- self.assertFalse(_called_with_root(mock))
-
- def test_file_dict_root(self):
- """
- Test if it list the files that belong to a package
- """
- mock = MagicMock(return_value="")
- with patch.dict(rpm.__salt__, {"cmd.run": mock}):
- rpm.file_dict("httpd", root="/")
- self.assertTrue(_called_with_root(mock))
-
- # 'owner' function tests: 1
-
- def test_owner(self):
- """
- Test if it return the name of the package that owns the file.
- """
- self.assertEqual(rpm.owner(), "")
-
- ret = "file /usr/bin/salt-jenkins-build is not owned by any package"
- mock = MagicMock(return_value=ret)
- with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
- self.assertEqual(rpm.owner("/usr/bin/salt-jenkins-build"), "")
- self.assertFalse(_called_with_root(mock))
-
- ret = {
- "/usr/bin/vim": "vim-enhanced-7.4.160-1.e17.x86_64",
- "/usr/bin/python": "python-2.7.5-16.e17.x86_64",
- }
- mock = MagicMock(
- side_effect=[
- "python-2.7.5-16.e17.x86_64",
- "vim-enhanced-7.4.160-1.e17.x86_64",
- ]
- )
- with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
- self.assertDictEqual(rpm.owner("/usr/bin/python", "/usr/bin/vim"), ret)
- self.assertFalse(_called_with_root(mock))
-
- def test_owner_root(self):
- """
- Test if it return the name of the package that owns the file,
- using the parameter root.
- """
- self.assertEqual(rpm.owner(), "")
-
- ret = "file /usr/bin/salt-jenkins-build is not owned by any package"
- mock = MagicMock(return_value=ret)
- with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
- rpm.owner("/usr/bin/salt-jenkins-build", root="/")
- self.assertTrue(_called_with_root(mock))
-
- # 'checksum' function tests: 2
-
- def test_checksum(self):
- """
- Test if checksum validate as expected
- """
- ret = {
- "file1.rpm": True,
- "file2.rpm": False,
- "file3.rpm": False,
- }
-
- mock = MagicMock(side_effect=[True, 0, True, 1, False, 0])
- with patch.dict(rpm.__salt__, {"file.file_exists": mock, "cmd.retcode": mock}):
- self.assertDictEqual(
- rpm.checksum("file1.rpm", "file2.rpm", "file3.rpm"), ret
- )
- self.assertFalse(_called_with_root(mock))
-
- def test_checksum_root(self):
- """
- Test if checksum validate as expected, using the parameter
- root
- """
- mock = MagicMock(side_effect=[True, 0])
- with patch.dict(rpm.__salt__, {"file.file_exists": mock, "cmd.retcode": mock}):
- rpm.checksum("file1.rpm", root="/")
- self.assertTrue(_called_with_root(mock))
-
- @patch("salt.modules.rpm_lowpkg.HAS_RPM", True)
- @patch("salt.modules.rpm_lowpkg.rpm.labelCompare", return_value=-1)
- @patch("salt.modules.rpm_lowpkg.log")
- def test_version_cmp_rpm(self, mock_log, mock_labelCompare):
- """
- Test package version if RPM-Python is installed
-
- :return:
- """
- self.assertEqual(-1, rpm.version_cmp("1", "2"))
- self.assertEqual(mock_log.warning.called, False)
- self.assertEqual(mock_labelCompare.called, True)
-
- @patch("salt.modules.rpm_lowpkg.HAS_RPM", False)
- @patch("salt.modules.rpm_lowpkg.HAS_RPMUTILS", True)
- @patch("salt.modules.rpm_lowpkg.rpmUtils", create=True)
- @patch("salt.modules.rpm_lowpkg.log")
- def test_version_cmp_rpmutils(self, mock_log, mock_rpmUtils):
- """
- Test package version if rpmUtils.miscutils called
-
- :return:
- """
- mock_rpmUtils.miscutils = MagicMock()
- mock_rpmUtils.miscutils.compareEVR = MagicMock(return_value=-1)
- self.assertEqual(-1, rpm.version_cmp("1", "2"))
- self.assertEqual(mock_log.warning.called, True)
- self.assertEqual(mock_rpmUtils.miscutils.compareEVR.called, True)
- self.assertEqual(
- mock_log.warning.mock_calls[0][1][0],
- "Please install a package that provides rpm.labelCompare for more accurate version comparisons.",
- )
-
- @patch("salt.modules.rpm_lowpkg.HAS_RPM", False)
- @patch("salt.modules.rpm_lowpkg.HAS_RPMUTILS", False)
- @patch("salt.utils.path.which", return_value=True)
- @patch("salt.modules.rpm_lowpkg.log")
- def test_version_cmp_rpmdev_vercmp(self, mock_log, mock_which):
- """
- Test package version if rpmdev-vercmp is installed
-
- :return:
- """
- mock__salt__ = MagicMock(return_value={"retcode": 12})
- with patch.dict(rpm.__salt__, {"cmd.run_all": mock__salt__}):
- self.assertEqual(-1, rpm.version_cmp("1", "2"))
- self.assertEqual(mock__salt__.called, True)
- self.assertEqual(mock_log.warning.called, True)
- self.assertEqual(
- mock_log.warning.mock_calls[0][1][0],
- "Please install a package that provides rpm.labelCompare for more accurate version comparisons.",
- )
- self.assertEqual(
- mock_log.warning.mock_calls[1][1][0],
- "Installing the rpmdevtools package may surface dev tools in production.",
- )
-
- @patch("salt.modules.rpm_lowpkg.HAS_RPM", False)
- @patch("salt.modules.rpm_lowpkg.HAS_RPMUTILS", False)
- @patch("salt.utils.versions.version_cmp", return_value=-1)
- @patch("salt.utils.path.which", return_value=False)
- @patch("salt.modules.rpm_lowpkg.log")
- def test_version_cmp_python(self, mock_log, mock_which, mock_version_cmp):
- """
- Test package version if falling back to python
-
- :return:
- """
- with patch(
- "salt.modules.rpm_lowpkg.rpm.labelCompare", MagicMock(return_value=0)
- ), patch("salt.modules.rpm_lowpkg.HAS_RPM", False):
- self.assertEqual(
- -1, rpm.version_cmp("1", "2")
- ) # mock returns -1, a python implementation was called
-
- def test_list_gpg_keys_no_info(self):
- """
- Test list_gpg_keys with no extra information
- """
- mock = MagicMock(return_value="\n".join(["gpg-pubkey-1", "gpg-pubkey-2"]))
- with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
- self.assertEqual(rpm.list_gpg_keys(), ["gpg-pubkey-1", "gpg-pubkey-2"])
- self.assertFalse(_called_with_root(mock))
-
- def test_list_gpg_keys_no_info_root(self):
- """
- Test list_gpg_keys with no extra information and root
- """
- mock = MagicMock(return_value="\n".join(["gpg-pubkey-1", "gpg-pubkey-2"]))
- with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
- self.assertEqual(
- rpm.list_gpg_keys(root="/mnt"), ["gpg-pubkey-1", "gpg-pubkey-2"]
- )
- self.assertTrue(_called_with_root(mock))
-
- @patch("salt.modules.rpm_lowpkg.info_gpg_key")
- def test_list_gpg_keys_info(self, info_gpg_key):
- """
- Test list_gpg_keys with extra information
- """
- info_gpg_key.side_effect = lambda x, root: {
- "Description": "key for {}".format(x)
- }
- mock = MagicMock(return_value="\n".join(["gpg-pubkey-1", "gpg-pubkey-2"]))
- with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
- self.assertEqual(
- rpm.list_gpg_keys(info=True),
- {
- "gpg-pubkey-1": {"Description": "key for gpg-pubkey-1"},
- "gpg-pubkey-2": {"Description": "key for gpg-pubkey-2"},
- },
- )
- self.assertFalse(_called_with_root(mock))
-
- def test_info_gpg_key(self):
- """
- Test info_gpg_keys from a normal output
- """
- info = """Name : gpg-pubkey
-Version : 3dbdc284
-Release : 53674dd4
-Architecture: (none)
-Install Date: Fri 08 Mar 2019 11:57:44 AM UTC
-Group : Public Keys
-Size : 0
-License : pubkey
-Signature : (none)
-Source RPM : (none)
-Build Date : Mon 05 May 2014 10:37:40 AM UTC
-Build Host : localhost
-Packager : openSUSE Project Signing Key <opensuse@opensuse.org>
-Summary : gpg(openSUSE Project Signing Key <opensuse@opensuse.org>)
-Description :
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: rpm-4.14.2.1 (NSS-3)
-
-mQENBEkUTD8BCADWLy5d5IpJedHQQSXkC1VK/oAZlJEeBVpSZjMCn8LiHaI9Wq3G
-3Vp6wvsP1b3kssJGzVFNctdXt5tjvOLxvrEfRJuGfqHTKILByqLzkeyWawbFNfSQ
-93/8OunfSTXC1Sx3hgsNXQuOrNVKrDAQUqT620/jj94xNIg09bLSxsjN6EeTvyiO
-mtE9H1J03o9tY6meNL/gcQhxBvwuo205np0JojYBP0pOfN8l9hnIOLkA0yu4ZXig
-oKOVmf4iTjX4NImIWldT+UaWTO18NWcCrujtgHueytwYLBNV5N0oJIP2VYuLZfSD
-VYuPllv7c6O2UEOXJsdbQaVuzU1HLocDyipnABEBAAG0NG9wZW5TVVNFIFByb2pl
-Y3QgU2lnbmluZyBLZXkgPG9wZW5zdXNlQG9wZW5zdXNlLm9yZz6JATwEEwECACYC
-GwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAUCU2dN1AUJHR8ElQAKCRC4iy/UPb3C
-hGQrB/9teCZ3Nt8vHE0SC5NmYMAE1Spcjkzx6M4r4C70AVTMEQh/8BvgmwkKP/qI
-CWo2vC1hMXRgLg/TnTtFDq7kW+mHsCXmf5OLh2qOWCKi55Vitlf6bmH7n+h34Sha
-Ei8gAObSpZSF8BzPGl6v0QmEaGKM3O1oUbbB3Z8i6w21CTg7dbU5vGR8Yhi9rNtr
-hqrPS+q2yftjNbsODagaOUb85ESfQGx/LqoMePD+7MqGpAXjKMZqsEDP0TbxTwSk
-4UKnF4zFCYHPLK3y/hSH5SEJwwPY11l6JGdC1Ue8Zzaj7f//axUs/hTC0UZaEE+a
-5v4gbqOcigKaFs9Lc3Bj8b/lE10Y
-=i2TA
------END PGP PUBLIC KEY BLOCK-----
-
-"""
- mock = MagicMock(return_value=info)
- with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
- self.assertEqual(
- rpm.info_gpg_key("key"),
- {
- "Name": "gpg-pubkey",
- "Version": "3dbdc284",
- "Release": "53674dd4",
- "Architecture": None,
- "Install Date": datetime.datetime(2019, 3, 8, 11, 57, 44),
- "Group": "Public Keys",
- "Size": 0,
- "License": "pubkey",
- "Signature": None,
- "Source RPM": None,
- "Build Date": datetime.datetime(2014, 5, 5, 10, 37, 40),
- "Build Host": "localhost",
- "Packager": "openSUSE Project Signing Key <opensuse@opensuse.org>",
- "Summary": "gpg(openSUSE Project Signing Key <opensuse@opensuse.org>)",
- "Description": """-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: rpm-4.14.2.1 (NSS-3)
-
-mQENBEkUTD8BCADWLy5d5IpJedHQQSXkC1VK/oAZlJEeBVpSZjMCn8LiHaI9Wq3G
-3Vp6wvsP1b3kssJGzVFNctdXt5tjvOLxvrEfRJuGfqHTKILByqLzkeyWawbFNfSQ
-93/8OunfSTXC1Sx3hgsNXQuOrNVKrDAQUqT620/jj94xNIg09bLSxsjN6EeTvyiO
-mtE9H1J03o9tY6meNL/gcQhxBvwuo205np0JojYBP0pOfN8l9hnIOLkA0yu4ZXig
-oKOVmf4iTjX4NImIWldT+UaWTO18NWcCrujtgHueytwYLBNV5N0oJIP2VYuLZfSD
-VYuPllv7c6O2UEOXJsdbQaVuzU1HLocDyipnABEBAAG0NG9wZW5TVVNFIFByb2pl
-Y3QgU2lnbmluZyBLZXkgPG9wZW5zdXNlQG9wZW5zdXNlLm9yZz6JATwEEwECACYC
-GwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAUCU2dN1AUJHR8ElQAKCRC4iy/UPb3C
-hGQrB/9teCZ3Nt8vHE0SC5NmYMAE1Spcjkzx6M4r4C70AVTMEQh/8BvgmwkKP/qI
-CWo2vC1hMXRgLg/TnTtFDq7kW+mHsCXmf5OLh2qOWCKi55Vitlf6bmH7n+h34Sha
-Ei8gAObSpZSF8BzPGl6v0QmEaGKM3O1oUbbB3Z8i6w21CTg7dbU5vGR8Yhi9rNtr
-hqrPS+q2yftjNbsODagaOUb85ESfQGx/LqoMePD+7MqGpAXjKMZqsEDP0TbxTwSk
-4UKnF4zFCYHPLK3y/hSH5SEJwwPY11l6JGdC1Ue8Zzaj7f//axUs/hTC0UZaEE+a
-5v4gbqOcigKaFs9Lc3Bj8b/lE10Y
-=i2TA
------END PGP PUBLIC KEY BLOCK-----""",
- },
- )
- self.assertFalse(_called_with_root(mock))
-
- def test_info_gpg_key_extended(self):
- """
- Test info_gpg_keys from an extended output
- """
- info = """Name : gpg-pubkey
-Version : 3dbdc284
-Release : 53674dd4
-Architecture: (none)
-Install Date: Fri 08 Mar 2019 11:57:44 AM UTC
-Group : Public Keys
-Size : 0
-License : pubkey
-Signature : (none)
-Source RPM : (none)
-Build Date : Mon 05 May 2014 10:37:40 AM UTC
-Build Host : localhost
-Packager : openSUSE Project Signing Key <opensuse@opensuse.org>
-Summary : gpg(openSUSE Project Signing Key <opensuse@opensuse.org>)
-Description :
------BEGIN PGP PUBLIC KEY BLOCK-----
-Version: rpm-4.14.2.1 (NSS-3)
-
-mQENBEkUTD8BCADWLy5d5IpJedHQQSXkC1VK/oAZlJEeBVpSZjMCn8LiHaI9Wq3G
-3Vp6wvsP1b3kssJGzVFNctdXt5tjvOLxvrEfRJuGfqHTKILByqLzkeyWawbFNfSQ
-93/8OunfSTXC1Sx3hgsNXQuOrNVKrDAQUqT620/jj94xNIg09bLSxsjN6EeTvyiO
-mtE9H1J03o9tY6meNL/gcQhxBvwuo205np0JojYBP0pOfN8l9hnIOLkA0yu4ZXig
-oKOVmf4iTjX4NImIWldT+UaWTO18NWcCrujtgHueytwYLBNV5N0oJIP2VYuLZfSD
-VYuPllv7c6O2UEOXJsdbQaVuzU1HLocDyipnABEBAAG0NG9wZW5TVVNFIFByb2pl
-Y3QgU2lnbmluZyBLZXkgPG9wZW5zdXNlQG9wZW5zdXNlLm9yZz6JATwEEwECACYC
-GwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAUCU2dN1AUJHR8ElQAKCRC4iy/UPb3C
-hGQrB/9teCZ3Nt8vHE0SC5NmYMAE1Spcjkzx6M4r4C70AVTMEQh/8BvgmwkKP/qI
-CWo2vC1hMXRgLg/TnTtFDq7kW+mHsCXmf5OLh2qOWCKi55Vitlf6bmH7n+h34Sha
-Ei8gAObSpZSF8BzPGl6v0QmEaGKM3O1oUbbB3Z8i6w21CTg7dbU5vGR8Yhi9rNtr
-hqrPS+q2yftjNbsODagaOUb85ESfQGx/LqoMePD+7MqGpAXjKMZqsEDP0TbxTwSk
-4UKnF4zFCYHPLK3y/hSH5SEJwwPY11l6JGdC1Ue8Zzaj7f//axUs/hTC0UZaEE+a
-5v4gbqOcigKaFs9Lc3Bj8b/lE10Y
-=i2TA
------END PGP PUBLIC KEY BLOCK-----
-
-Distribution: (none)
-"""
- mock = MagicMock(return_value=info)
- with patch.dict(rpm.__salt__, {"cmd.run_stdout": mock}):
- self.assertEqual(
- rpm.info_gpg_key("key"),
- {
- "Name": "gpg-pubkey",
- "Version": "3dbdc284",
- "Release": "53674dd4",
- "Architecture": None,
- "Install Date": datetime.datetime(2019, 3, 8, 11, 57, 44),
- "Group": "Public Keys",
- "Size": 0,
- "License": "pubkey",
- "Signature": None,
- "Source RPM": None,
- "Build Date": datetime.datetime(2014, 5, 5, 10, 37, 40),
- "Build Host": "localhost",
- "Packager": "openSUSE Project Signing Key <opensuse@opensuse.org>",
- "Summary": "gpg(openSUSE Project Signing Key <opensuse@opensuse.org>)",
- "Description": """-----BEGIN PGP PUBLIC KEY BLOCK-----
-Version: rpm-4.14.2.1 (NSS-3)
-
-mQENBEkUTD8BCADWLy5d5IpJedHQQSXkC1VK/oAZlJEeBVpSZjMCn8LiHaI9Wq3G
-3Vp6wvsP1b3kssJGzVFNctdXt5tjvOLxvrEfRJuGfqHTKILByqLzkeyWawbFNfSQ
-93/8OunfSTXC1Sx3hgsNXQuOrNVKrDAQUqT620/jj94xNIg09bLSxsjN6EeTvyiO
-mtE9H1J03o9tY6meNL/gcQhxBvwuo205np0JojYBP0pOfN8l9hnIOLkA0yu4ZXig
-oKOVmf4iTjX4NImIWldT+UaWTO18NWcCrujtgHueytwYLBNV5N0oJIP2VYuLZfSD
-VYuPllv7c6O2UEOXJsdbQaVuzU1HLocDyipnABEBAAG0NG9wZW5TVVNFIFByb2pl
-Y3QgU2lnbmluZyBLZXkgPG9wZW5zdXNlQG9wZW5zdXNlLm9yZz6JATwEEwECACYC
-GwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAUCU2dN1AUJHR8ElQAKCRC4iy/UPb3C
-hGQrB/9teCZ3Nt8vHE0SC5NmYMAE1Spcjkzx6M4r4C70AVTMEQh/8BvgmwkKP/qI
-CWo2vC1hMXRgLg/TnTtFDq7kW+mHsCXmf5OLh2qOWCKi55Vitlf6bmH7n+h34Sha
-Ei8gAObSpZSF8BzPGl6v0QmEaGKM3O1oUbbB3Z8i6w21CTg7dbU5vGR8Yhi9rNtr
-hqrPS+q2yftjNbsODagaOUb85ESfQGx/LqoMePD+7MqGpAXjKMZqsEDP0TbxTwSk
-4UKnF4zFCYHPLK3y/hSH5SEJwwPY11l6JGdC1Ue8Zzaj7f//axUs/hTC0UZaEE+a
-5v4gbqOcigKaFs9Lc3Bj8b/lE10Y
-=i2TA
------END PGP PUBLIC KEY BLOCK-----""",
- "Distribution": None,
- },
- )
- self.assertFalse(_called_with_root(mock))
-
- def test_remove_gpg_key(self):
- """
- Test remove_gpg_key
- """
- mock = MagicMock(return_value=0)
- with patch.dict(rpm.__salt__, {"cmd.retcode": mock}):
- self.assertTrue(rpm.remove_gpg_key("gpg-pubkey-1"))
- self.assertFalse(_called_with_root(mock))
--
2.33.1