diff --git a/changelog/62030.fixed b/changelog/62030.fixed new file mode 100644 index 0000000000..bd60463606 --- /dev/null +++ b/changelog/62030.fixed @@ -0,0 +1 @@ +Fix inconsitency regarding name and pkgs parameters between zypperpkg.upgrade() and yumpkg.upgrade() diff --git a/changelog/62031.added b/changelog/62031.added new file mode 100644 index 0000000000..f0b66ff96f --- /dev/null +++ b/changelog/62031.added @@ -0,0 +1 @@ +Add `diff_attr` parameter to pkg.upgrade() (zypper/yum). diff --git a/changelog/62032.fixed b/changelog/62032.fixed new file mode 100644 index 0000000000..ceb3cc89b9 --- /dev/null +++ b/changelog/62032.fixed @@ -0,0 +1 @@ +Fix attr=all handling in pkg.list_pkgs() (yum/zypper). diff --git a/salt/modules/yumpkg.py b/salt/modules/yumpkg.py index f52e084346..fcfc5d4045 100644 --- a/salt/modules/yumpkg.py +++ b/salt/modules/yumpkg.py @@ -735,7 +735,7 @@ def list_pkgs(versions_as_list=False, **kwargs): return {} attr = kwargs.get("attr") - if attr is not None: + if attr is not None and attr != "all": attr = salt.utils.args.split_input(attr) contextkey = "pkg.list_pkgs" @@ -1844,6 +1844,7 @@ def upgrade( normalize=True, minimal=False, obsoletes=True, + diff_attr=None, **kwargs ): """ @@ -2000,7 +2001,7 @@ def upgrade( if salt.utils.data.is_true(refresh): refresh_db(**kwargs) - old = list_pkgs() + old = list_pkgs(attr=diff_attr) targets = [] if name or pkgs: @@ -2032,7 +2033,7 @@ def upgrade( cmd.extend(targets) result = _call_yum(cmd) __context__.pop("pkg.list_pkgs", None) - new = list_pkgs() + new = list_pkgs(attr=diff_attr) ret = salt.utils.data.compare_dicts(old, new) if result["retcode"] != 0: diff --git a/salt/modules/zypperpkg.py b/salt/modules/zypperpkg.py index 4e3006a8cd..cbfbc4b78d 100644 --- a/salt/modules/zypperpkg.py +++ b/salt/modules/zypperpkg.py @@ -939,7 +939,7 @@ def list_pkgs(versions_as_list=False, root=None, includes=None, **kwargs): return {} attr = kwargs.get("attr") - if attr is not None: + if attr is not None and attr != "all": attr = salt.utils.args.split_input(attr) includes = includes if includes else [] @@ -1791,6 +1791,8 @@ def install( def upgrade( + name=None, + pkgs=None, refresh=True, dryrun=False, dist_upgrade=False, @@ -1800,6 +1802,7 @@ def upgrade( skip_verify=False, no_recommends=False, root=None, + diff_attr=None, **kwargs ): # pylint: disable=unused-argument """ @@ -1819,6 +1822,27 @@ def upgrade( Run a full system upgrade, a zypper upgrade + name + The name of the package to be installed. Note that this parameter is + ignored if ``pkgs`` is passed or if ``dryrun`` is set to True. + + CLI Example: + + .. code-block:: bash + + salt '*' pkg.install name= + + pkgs + A list of packages to install from a software repository. Must be + passed as a python list. Note that this parameter is ignored if + ``dryrun`` is set to True. + + CLI Examples: + + .. code-block:: bash + + salt '*' pkg.install pkgs='["foo", "bar"]' + refresh force a refresh if set to True (default). If set to False it depends on zypper if a refresh is @@ -1850,6 +1874,24 @@ def upgrade( root Operate on a different root directory. + diff_attr: + If a list of package attributes is specified, returned value will + contain them, eg.:: + + {'': { + 'old': { + 'version': '', + 'arch': ''}, + + 'new': { + 'version': '', + 'arch': ''}}} + + Valid attributes are: ``epoch``, ``version``, ``release``, ``arch``, + ``install_date``, ``install_date_time_t``. + + If ``all`` is specified, all valid attributes will be returned. + Returns a dictionary containing the changes: .. code-block:: python @@ -1857,11 +1899,27 @@ def upgrade( {'': {'old': '', 'new': ''}} + If an attribute list is specified in ``diff_attr``, the dict will also contain + any specified attribute, eg.:: + + .. code-block:: python + + {'': { + 'old': { + 'version': '', + 'arch': ''}, + + 'new': { + 'version': '', + 'arch': ''}}} + CLI Example: .. code-block:: bash salt '*' pkg.upgrade + salt '*' pkg.upgrade name=mypackage + salt '*' pkg.upgrade pkgs='["package1", "package2"]' salt '*' pkg.upgrade dist_upgrade=True fromrepo='["MyRepoName"]' novendorchange=True salt '*' pkg.upgrade dist_upgrade=True dryrun=True """ @@ -1897,12 +1955,24 @@ def upgrade( allowvendorchange, novendorchange ).noraise.call(*cmd_update + ["--debug-solver"]) - old = list_pkgs(root=root) + if not dist_upgrade: + if name or pkgs: + try: + (pkg_params, _) = __salt__["pkg_resource.parse_targets"]( + name=name, pkgs=pkgs, sources=None, **kwargs + ) + if pkg_params: + cmd_update.extend(pkg_params.keys()) + + except MinionError as exc: + raise CommandExecutionError(exc) + + old = list_pkgs(root=root, attr=diff_attr) __zypper__(systemd_scope=_systemd_scope(), root=root).allow_vendor_change( allowvendorchange, novendorchange ).noraise.call(*cmd_update) _clean_cache() - new = list_pkgs(root=root) + new = list_pkgs(root=root, attr=diff_attr) ret = salt.utils.data.compare_dicts(old, new) if __zypper__.exit_code not in __zypper__.SUCCESS_EXIT_CODES: diff --git a/tests/pytests/unit/modules/test_zypperpkg.py b/tests/pytests/unit/modules/test_zypperpkg.py index 351a173b81..84dc7a10b4 100644 --- a/tests/pytests/unit/modules/test_zypperpkg.py +++ b/tests/pytests/unit/modules/test_zypperpkg.py @@ -4,17 +4,31 @@ import os +import textwrap import pytest import salt.modules.pkg_resource as pkg_resource import salt.modules.zypperpkg as zypper -from salt.exceptions import SaltInvocationError +from salt.exceptions import CommandExecutionError, SaltInvocationError from tests.support.mock import MagicMock, mock_open, patch @pytest.fixture def configure_loader_modules(): - return {zypper: {"rpm": None}, pkg_resource: {}} + return { + zypper: { + "rpm": None, + "_systemd_scope": MagicMock(return_value=False), + "osrelease_info": [15, 3], + "__salt__": {"pkg_resource.parse_targets": pkg_resource.parse_targets}, + }, + pkg_resource: {"__grains__": {"os": "SUSE"}}, + } + + +@pytest.fixture(autouse=True) +def fresh_zypper_instance(): + zypper.__zypper__ = zypper._Zypper() def test_list_pkgs_no_context(): @@ -254,3 +268,262 @@ def test_del_repo_key(): with patch.dict(zypper.__salt__, salt_mock): assert zypper.del_repo_key(keyid="keyid", root="/mnt") salt_mock["lowpkg.remove_gpg_key"].assert_called_once_with("keyid", "/mnt") + +@pytest.mark.parametrize( + "zypper_version,lowpkg_version_cmp,expected_inst_avc,expected_dup_avc", + [ + ("0.5", [-1, -1], False, False), + ("1.11.34", [0, -1], False, True), + ("1.14.8", [0, 0], True, True), + ], +) +def test_refresh_zypper_flags( + zypper_version, lowpkg_version_cmp, expected_inst_avc, expected_dup_avc +): + with patch( + "salt.modules.zypperpkg.version", MagicMock(return_value=zypper_version) + ), patch.dict( + zypper.__salt__, + {"lowpkg.version_cmp": MagicMock(side_effect=lowpkg_version_cmp)}, + ): + _zypper = zypper._Zypper() + _zypper.refresh_zypper_flags() + assert _zypper.inst_avc == expected_inst_avc + assert _zypper.dup_avc == expected_dup_avc + + +@pytest.mark.parametrize( + "inst_avc,dup_avc,avc,allowvendorchange_param,novendorchange_param,expected", + [ + # inst_avc = True, dup_avc = True + (True, True, False, False, False, True), + (True, True, False, True, False, True), + (True, True, False, False, True, False), + (True, True, False, True, True, True), + # inst_avc = False, dup_avc = True + (False, True, False, False, False, True), + (False, True, False, True, False, True), + (False, True, False, False, True, False), + (False, True, False, True, True, True), + # inst_avc = False, dup_avc = False + (False, False, False, False, False, False), + (False, False, False, True, False, False), + (False, False, False, False, True, False), + (False, False, False, True, True, False), + ], +) +@patch("salt.modules.zypperpkg._Zypper.refresh_zypper_flags", MagicMock()) +def test_allow_vendor_change( + inst_avc, + dup_avc, + avc, + allowvendorchange_param, + novendorchange_param, + expected, +): + _zypper = zypper._Zypper() + _zypper.inst_avc = inst_avc + _zypper.dup_avc = dup_avc + _zypper.avc = avc + _zypper.allow_vendor_change(allowvendorchange_param, novendorchange_param) + assert _zypper.avc == expected + + +@pytest.mark.parametrize( + "package,pre_version,post_version,fromrepo_param,name_param,pkgs_param,diff_attr_param", + [ + ("vim", "1.1", "1.2", [], "", [], "all"), + ("kernel-default", "1.1", "1.1,1.2", ["dummy", "dummy2"], "", [], None), + ("vim", "1.1", "1.2", [], "vim", [], None), + ], +) +@patch.object(zypper, "refresh_db", MagicMock(return_value=True)) +def test_upgrade( + package, + pre_version, + post_version, + fromrepo_param, + name_param, + pkgs_param, + diff_attr_param, +): + with patch( + "salt.modules.zypperpkg.__zypper__.noraise.call" + ) as zypper_mock, patch.object( + zypper, + "list_pkgs", + MagicMock(side_effect=[{package: pre_version}, {package: post_version}]), + ) as list_pkgs_mock: + expected_call = ["update", "--auto-agree-with-licenses"] + for repo in fromrepo_param: + expected_call.extend(["--repo", repo]) + + if pkgs_param: + expected_call.extend(pkgs_param) + elif name_param: + expected_call.append(name_param) + + result = zypper.upgrade( + name=name_param, + pkgs=pkgs_param, + fromrepo=fromrepo_param, + diff_attr=diff_attr_param, + ) + zypper_mock.assert_any_call(*expected_call) + assert result == {package: {"old": pre_version, "new": post_version}} + list_pkgs_mock.assert_any_call(root=None, attr=diff_attr_param) + + +@pytest.mark.parametrize( + "package,pre_version,post_version,fromrepo_param", + [ + ("vim", "1.1", "1.2", []), + ("emacs", "1.1", "1.2", ["Dummy", "Dummy2"]), + ], +) +@patch.object(zypper, "refresh_db", MagicMock(return_value=True)) +def test_dist_upgrade(package, pre_version, post_version, fromrepo_param): + with patch( + "salt.modules.zypperpkg.__zypper__.noraise.call" + ) as zypper_mock, patch.object( + zypper, + "list_pkgs", + MagicMock(side_effect=[{package: pre_version}, {package: post_version}]), + ): + expected_call = ["dist-upgrade", "--auto-agree-with-licenses"] + + for repo in fromrepo_param: + expected_call.extend(["--from", repo]) + + result = zypper.upgrade(dist_upgrade=True, fromrepo=fromrepo_param) + zypper_mock.assert_any_call(*expected_call) + assert result == {package: {"old": pre_version, "new": post_version}} + + +@pytest.mark.parametrize( + "package,pre_version,post_version,dup_avc,novendorchange_param,allowvendorchange_param,vendor_change", + [ + # dup_avc = True, both params = default -> no vendor change + ("vim", "1.1", "1.2", True, True, False, False), + # dup_avc = True, allowvendorchange = True -> vendor change + ( + "emacs", + "1.1", + "1.2", + True, + True, + True, + True, + ), + # dup_avc = True, novendorchange = False -> vendor change + ("joe", "1.1", "1.2", True, False, False, True), + # dup_avc = True, both params = toggled -> vendor change + ("kate", "1.1", "1.2", True, False, True, True), + # dup_avc = False -> no vendor change + ( + "gedit", + "1.1", + "1.2", + False, + False, + True, + False + ), + ], +) +@patch.object(zypper, "refresh_db", MagicMock(return_value=True)) +def test_dist_upgrade_vendorchange( + package, + pre_version, + post_version, + dup_avc, + novendorchange_param, + allowvendorchange_param, + vendor_change +): + cmd_run_mock = MagicMock(return_value={"retcode": 0, "stdout": None}) + with patch.object( + zypper, + "list_pkgs", + MagicMock(side_effect=[{package: pre_version}, {package: post_version}]), + ), patch("salt.modules.zypperpkg.__zypper__.refresh_zypper_flags",), patch.dict( + zypper.__salt__, {"cmd.run_all": cmd_run_mock} + ): + expected_cmd = ["zypper", "--non-interactive", "--no-refresh", "dist-upgrade"] + # --allow-vendor-change is injected right after "dist-upgrade" + if vendor_change: + expected_cmd.append("--allow-vendor-change") + expected_cmd.append("--auto-agree-with-licenses") + + zypper.__zypper__.dup_avc = dup_avc + zypper.upgrade( + dist_upgrade=True, + allowvendorchange=allowvendorchange_param, + novendorchange=novendorchange_param, + ) + cmd_run_mock.assert_any_call( + expected_cmd, output_loglevel="trace", python_shell=False, env={} + ) + + +@pytest.mark.parametrize( + "package,pre_version,post_version,fromrepo_param", + [ + ("vim", "1.1", "1.1", []), + ("emacs", "1.1", "1.1", ["Dummy", "Dummy2"]), + ], +) +@patch.object(zypper, "refresh_db", MagicMock(return_value=True)) +def test_dist_upgrade_dry_run(package, pre_version, post_version, fromrepo_param): + with patch( + "salt.modules.zypperpkg.__zypper__.noraise.call" + ) as zypper_mock, patch.object( + zypper, + "list_pkgs", + MagicMock(side_effect=[{package: pre_version}, {package: post_version}]), + ): + expected_call = ["dist-upgrade", "--auto-agree-with-licenses", "--dry-run"] + + for repo in fromrepo_param: + expected_call.extend(["--from", repo]) + + zypper.upgrade(dist_upgrade=True, dryrun=True, fromrepo=fromrepo_param) + zypper_mock.assert_any_call(*expected_call) + # dryrun=True causes two calls, one with a trailing --debug-solver flag + expected_call.append("--debug-solver") + zypper_mock.assert_any_call(*expected_call) + + +@patch.object(zypper, "refresh_db", MagicMock(return_value=True)) +def test_dist_upgrade_failure(): + zypper_output = textwrap.dedent( + """\ + Loading repository data... + Reading installed packages... + Computing distribution upgrade... + Use 'zypper repos' to get the list of defined repositories. + Repository 'DUMMY' not found by its alias, number, or URI. + """ + ) + call_spy = MagicMock() + zypper_mock = MagicMock() + zypper_mock.stdout = zypper_output + zypper_mock.stderr = "" + zypper_mock.exit_code = 3 + zypper_mock.noraise.call = call_spy + with patch("salt.modules.zypperpkg.__zypper__", zypper_mock), patch.object( + zypper, "list_pkgs", MagicMock(side_effect=[{"vim": 1.1}, {"vim": 1.1}]) + ): + expected_call = [ + "dist-upgrade", + "--auto-agree-with-licenses", + "--from", + "Dummy", + ] + + with pytest.raises(CommandExecutionError) as exc: + zypper.upgrade(dist_upgrade=True, fromrepo=["Dummy"]) + call_spy.assert_called_with(*expected_call) + + assert exc.exception.info["changes"] == {} + assert exc.exception.info["result"]["stdout"] == zypper_output diff --git a/tests/unit/modules/test_zypperpkg.py b/tests/unit/modules/test_zypperpkg.py index 39f28f2198..fea6eeb004 100644 --- a/tests/unit/modules/test_zypperpkg.py +++ b/tests/unit/modules/test_zypperpkg.py @@ -610,151 +610,6 @@ def test_latest_version(self): {"vim": "7.4.326-2.62", "fakepkg": ""}, ) - def test_upgrade_without_vendor_change(self): - """ - Dist-upgrade without vendor change option. - """ - with patch( - "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True) - ), patch( - "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False) - ): - with patch( - "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock() - ) as zypper_mock: - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.2"}]), - ): - ret = zypper.upgrade(dist_upgrade=True) - self.assertDictEqual(ret, {"vim": {"old": "1.1", "new": "1.2"}}) - zypper_mock.assert_any_call( - "dist-upgrade", "--auto-agree-with-licenses", - ) - - def test_refresh_zypper_flags(self): - zypper.__zypper__._reset() - with patch( - "salt.modules.zypperpkg.version", MagicMock(return_value="0.5") - ), patch.dict( - zypper.__salt__, {"lowpkg.version_cmp": MagicMock(side_effect=[-1, -1])} - ): - zypper.__zypper__.refresh_zypper_flags() - assert zypper.__zypper__.inst_avc == False - assert zypper.__zypper__.dup_avc == False - with patch( - "salt.modules.zypperpkg.version", MagicMock(return_value="1.11.34") - ), patch.dict( - zypper.__salt__, {"lowpkg.version_cmp": MagicMock(side_effect=[0, -1])} - ): - zypper.__zypper__.refresh_zypper_flags() - assert zypper.__zypper__.inst_avc == False - assert zypper.__zypper__.dup_avc == True - with patch( - "salt.modules.zypperpkg.version", MagicMock(return_value="1.14.8") - ), patch.dict( - zypper.__salt__, {"lowpkg.version_cmp": MagicMock(side_effect=[0, 0])} - ): - zypper.__zypper__.refresh_zypper_flags() - assert zypper.__zypper__.inst_avc == True - assert zypper.__zypper__.dup_avc == True - - @patch("salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock()) - def test_allow_vendor_change_function(self): - zypper.__zypper__._reset() - zypper.__zypper__.inst_avc = True - zypper.__zypper__.dup_avc = True - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(False, False) - assert zypper.__zypper__.avc == True - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(True, False) - assert zypper.__zypper__.avc == True - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(False, True) - assert zypper.__zypper__.avc == False - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(True, True) - assert zypper.__zypper__.avc == True - - zypper.__zypper__._reset() - zypper.__zypper__.inst_avc = False - zypper.__zypper__.dup_avc = True - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(False, False) - assert zypper.__zypper__.avc == True - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(True, False) - assert zypper.__zypper__.avc == True - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(False, True) - assert zypper.__zypper__.avc == False - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(True, True) - assert zypper.__zypper__.avc == True - - zypper.__zypper__._reset() - zypper.__zypper__.inst_avc = False - zypper.__zypper__.dup_avc = False - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(False, False) - assert zypper.__zypper__.avc == False - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(True, False) - assert zypper.__zypper__.avc == False - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(False, True) - assert zypper.__zypper__.avc == False - zypper.__zypper__.avc = False - zypper.__zypper__.allow_vendor_change(True, True) - assert zypper.__zypper__.avc == False - - @patch( - "salt.utils.environment.get_module_environment", - MagicMock(return_value={"SALT_RUNNING": "1"}), - ) - def test_zypper_call_dist_upgrade_with_avc_true(self): - cmd_run_mock = MagicMock(return_value={"retcode": 0, "stdout": None}) - zypper.__zypper__._reset() - with patch.dict(zypper.__salt__, {"cmd.run_all": cmd_run_mock}), patch( - "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock() - ), patch("salt.modules.zypperpkg.__zypper__._reset", MagicMock()): - zypper.__zypper__.dup_avc = True - zypper.__zypper__.avc = True - zypper.__zypper__.call("dist-upgrade") - cmd_run_mock.assert_any_call( - [ - "zypper", - "--non-interactive", - "--no-refresh", - "dist-upgrade", - "--allow-vendor-change", - ], - output_loglevel="trace", - python_shell=False, - env={"SALT_RUNNING": "1"}, - ) - - @patch( - "salt.utils.environment.get_module_environment", - MagicMock(return_value={"SALT_RUNNING": "1"}), - ) - def test_zypper_call_dist_upgrade_with_avc_false(self): - cmd_run_mock = MagicMock(return_value={"retcode": 0, "stdout": None}) - zypper.__zypper__._reset() - with patch.dict(zypper.__salt__, {"cmd.run_all": cmd_run_mock}), patch( - "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock() - ), patch("salt.modules.zypperpkg.__zypper__._reset", MagicMock()): - zypper.__zypper__.dup_avc = False - zypper.__zypper__.avc = False - zypper.__zypper__.call("dist-upgrade") - cmd_run_mock.assert_any_call( - ["zypper", "--non-interactive", "--no-refresh", "dist-upgrade",], - output_loglevel="trace", - python_shell=False, - env={"SALT_RUNNING": "1"}, - ) - @patch( "salt.utils.environment.get_module_environment", MagicMock(return_value={"SALT_RUNNING": "1"}), @@ -802,296 +657,6 @@ def test_zypper_call_install_with_avc_false(self): env={"SALT_RUNNING": "1"}, ) - def test_upgrade_with_novendorchange_true(self): - """ - Dist-upgrade without vendor change option. - """ - zypper.__zypper__._reset() - with patch( - "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True) - ), patch( - "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock() - ) as refresh_flags_mock, patch( - "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False) - ): - with patch( - "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock() - ) as zypper_mock: - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.2"}]), - ): - ret = zypper.upgrade(dist_upgrade=True, novendorchange=True) - refresh_flags_mock.assert_not_called() - zypper_mock.assert_any_call( - "dist-upgrade", "--auto-agree-with-licenses", - ) - - def test_upgrade_with_novendorchange_false(self): - """ - Perform dist-upgrade with novendorchange set to False. - """ - zypper.__zypper__._reset() - with patch( - "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True) - ), patch( - "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock() - ), patch( - "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False) - ): - with patch( - "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock() - ) as zypper_mock: - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]), - ): - zypper.__zypper__.inst_avc = True - zypper.__zypper__.dup_avc = True - with patch.dict( - zypper.__salt__, - { - "pkg_resource.version": MagicMock(return_value="1.15"), - "lowpkg.version_cmp": MagicMock(return_value=1), - }, - ): - ret = zypper.upgrade( - dist_upgrade=True, - dryrun=True, - fromrepo=["Dummy", "Dummy2"], - novendorchange=False, - ) - assert zypper.__zypper__.avc == True - - def test_upgrade_with_allowvendorchange_true(self): - """ - Perform dist-upgrade with allowvendorchange set to True. - """ - zypper.__zypper__._reset() - with patch( - "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True) - ), patch( - "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock() - ), patch( - "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False) - ): - with patch( - "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock() - ) as zypper_mock: - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]), - ): - with patch.dict( - zypper.__salt__, - { - "pkg_resource.version": MagicMock(return_value="1.15"), - "lowpkg.version_cmp": MagicMock(return_value=1), - }, - ): - - zypper.__zypper__.inst_avc = True - zypper.__zypper__.dup_avc = True - ret = zypper.upgrade( - dist_upgrade=True, - dryrun=True, - fromrepo=["Dummy", "Dummy2"], - allowvendorchange=True, - ) - assert zypper.__zypper__.avc == True - - def test_upgrade_with_allowvendorchange_false(self): - """ - Perform dist-upgrade with allowvendorchange set to False. - """ - zypper.__zypper__._reset() - with patch( - "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True) - ), patch( - "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock() - ), patch( - "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False) - ): - with patch( - "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock() - ) as zypper_mock: - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]), - ): - with patch.dict( - zypper.__salt__, - { - "pkg_resource.version": MagicMock(return_value="1.15"), - "lowpkg.version_cmp": MagicMock(return_value=1), - }, - ): - - zypper.__zypper__.inst_avc = True - zypper.__zypper__.dup_avc = True - ret = zypper.upgrade( - dist_upgrade=True, - dryrun=True, - fromrepo=["Dummy", "Dummy2"], - allowvendorchange=False, - ) - assert zypper.__zypper__.avc == False - - def test_upgrade_old_zypper(self): - zypper.__zypper__._reset() - with patch( - "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True) - ), patch( - "salt.modules.zypperpkg.__zypper__.refresh_zypper_flags", MagicMock() - ) as refresh_flags_mock, patch( - "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False) - ): - with patch( - "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock() - ) as zypper_mock: - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]), - ): - with patch.dict( - zypper.__salt__, - { - "pkg_resource.version": MagicMock(return_value="1.11"), - "lowpkg.version_cmp": MagicMock(return_value=-1), - }, - ): - zypper.__zypper__.inst_avc = False - zypper.__zypper__.dup_avc = False - ret = zypper.upgrade( - dist_upgrade=True, - dryrun=True, - fromrepo=["Dummy", "Dummy2"], - novendorchange=False, - ) - zypper.__zypper__.avc = False - - def test_upgrade_success(self): - """ - Test system upgrade and dist-upgrade success. - - :return: - """ - with patch( - "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True) - ), patch( - "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False) - ): - with patch( - "salt.modules.zypperpkg.__zypper__.noraise.call", MagicMock() - ) as zypper_mock: - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.2"}]), - ): - ret = zypper.upgrade() - self.assertDictEqual(ret, {"vim": {"old": "1.1", "new": "1.2"}}) - zypper_mock.assert_any_call("update", "--auto-agree-with-licenses") - - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock( - side_effect=[ - {"kernel-default": "1.1"}, - {"kernel-default": "1.1,1.2"}, - ] - ), - ): - ret = zypper.upgrade() - self.assertDictEqual( - ret, {"kernel-default": {"old": "1.1", "new": "1.1,1.2"}} - ) - zypper_mock.assert_any_call("update", "--auto-agree-with-licenses") - - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1,1.2"}]), - ): - ret = zypper.upgrade() - self.assertDictEqual(ret, {"vim": {"old": "1.1", "new": "1.1,1.2"}}) - zypper_mock.assert_any_call("update", "--auto-agree-with-licenses") - - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]), - ): - ret = zypper.upgrade(dist_upgrade=True, dryrun=True) - zypper_mock.assert_any_call( - "dist-upgrade", "--auto-agree-with-licenses", "--dry-run" - ) - zypper_mock.assert_any_call( - "dist-upgrade", - "--auto-agree-with-licenses", - "--dry-run", - "--debug-solver", - ) - - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]), - ): - ret = zypper.upgrade( - dist_upgrade=False, fromrepo=["Dummy", "Dummy2"], dryrun=False - ) - zypper_mock.assert_any_call( - "update", - "--auto-agree-with-licenses", - "--repo", - "Dummy", - "--repo", - "Dummy2", - ) - - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]), - ): - ret = zypper.upgrade( - dist_upgrade=True, - dryrun=True, - fromrepo=["Dummy", "Dummy2"], - novendorchange=True, - ) - zypper_mock.assert_any_call( - "dist-upgrade", - "--auto-agree-with-licenses", - "--dry-run", - "--from", - "Dummy", - "--from", - "Dummy2", - ) - zypper_mock.assert_any_call( - "dist-upgrade", - "--auto-agree-with-licenses", - "--dry-run", - "--from", - "Dummy", - "--from", - "Dummy2", - "--debug-solver", - ) - - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]), - ): - ret = zypper.upgrade( - dist_upgrade=False, fromrepo=["Dummy", "Dummy2"], dryrun=False - ) - zypper_mock.assert_any_call( - "update", - "--auto-agree-with-licenses", - "--repo", - "Dummy", - "--repo", - "Dummy2", - ) - def test_upgrade_kernel(self): """ Test kernel package upgrade success. @@ -1136,53 +701,6 @@ def test_upgrade_kernel(self): }, ) - def test_upgrade_failure(self): - """ - Test system upgrade failure. - - :return: - """ - zypper_out = """ -Loading repository data... -Reading installed packages... -Computing distribution upgrade... -Use 'zypper repos' to get the list of defined repositories. -Repository 'DUMMY' not found by its alias, number, or URI. -""" - - class FailingZypperDummy: - def __init__(self): - self.stdout = zypper_out - self.stderr = "" - self.pid = 1234 - self.exit_code = 555 - self.noraise = MagicMock() - self.allow_vendor_change = self - self.SUCCESS_EXIT_CODES = [0] - - def __call__(self, *args, **kwargs): - return self - - with patch( - "salt.modules.zypperpkg.__zypper__", FailingZypperDummy() - ) as zypper_mock, patch( - "salt.modules.zypperpkg.refresh_db", MagicMock(return_value=True) - ), patch( - "salt.modules.zypperpkg._systemd_scope", MagicMock(return_value=False) - ): - zypper_mock.noraise.call = MagicMock() - with patch( - "salt.modules.zypperpkg.list_pkgs", - MagicMock(side_effect=[{"vim": "1.1"}, {"vim": "1.1"}]), - ): - with self.assertRaises(CommandExecutionError) as cmd_exc: - ret = zypper.upgrade(dist_upgrade=True, fromrepo=["DUMMY"]) - self.assertEqual(cmd_exc.exception.info["changes"], {}) - self.assertEqual(cmd_exc.exception.info["result"]["stdout"], zypper_out) - zypper_mock.noraise.call.assert_called_with( - "dist-upgrade", "--auto-agree-with-licenses", "--from", "DUMMY", - ) - def test_upgrade_available(self): """ Test whether or not an upgrade is available for a given package.