1import logging 2import os 3 4import salt.modules.cmdmod as cmdmod 5import salt.modules.pkg_resource as pkg_resource 6import salt.modules.rpm_lowpkg as rpm 7import salt.modules.yumpkg as yumpkg 8import salt.utils.platform 9from salt.exceptions import CommandExecutionError, SaltInvocationError 10from tests.support.mock import MagicMock, Mock, call, patch 11 12try: 13 import pytest 14except ImportError: 15 pytest = None 16 17log = logging.getLogger(__name__) 18 19 20@pytest.fixture(scope="module") 21def list_repos_var(): 22 23 return { 24 "base": { 25 "file": "/etc/yum.repos.d/CentOS-Base.repo", 26 "gpgcheck": "1", 27 "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7", 28 "mirrorlist": "http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=os&infra=$infra", 29 "name": "CentOS-$releasever - Base", 30 }, 31 "base-source": { 32 "baseurl": "http://vault.centos.org/centos/$releasever/os/Source/", 33 "enabled": "0", 34 "file": "/etc/yum.repos.d/CentOS-Sources.repo", 35 "gpgcheck": "1", 36 "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7", 37 "name": "CentOS-$releasever - Base Sources", 38 }, 39 "updates": { 40 "file": "/etc/yum.repos.d/CentOS-Base.repo", 41 "gpgcheck": "1", 42 "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7", 43 "mirrorlist": "http://mirrorlist.centos.org/?release=$releasever&arch=$basearch&repo=updates&infra=$infra", 44 "name": "CentOS-$releasever - Updates", 45 }, 46 "updates-source": { 47 "baseurl": "http://vault.centos.org/centos/$releasever/updates/Source/", 48 "enabled": "0", 49 "file": "/etc/yum.repos.d/CentOS-Sources.repo", 50 "gpgcheck": "1", 51 "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7", 52 "name": "CentOS-$releasever - Updates Sources", 53 }, 54 } 55 56 57@pytest.fixture 58def configure_loader_modules(): 59 60 return { 61 yumpkg: { 62 "__context__": {"yum_bin": "yum"}, 63 "__grains__": { 64 "osarch": "x86_64", 65 "os": "CentOS", 66 "os_family": "RedHat", 67 "osmajorrelease": 7, 68 }, 69 }, 70 pkg_resource: {}, 71 } 72 73 74def test_list_pkgs(): 75 """ 76 Test packages listing. 77 78 :return: 79 """ 80 81 def _add_data(data, key, value): 82 data.setdefault(key, []).append(value) 83 84 rpm_out = [ 85 "python-urlgrabber_|-(none)_|-3.10_|-8.el7_|-noarch_|-(none)_|-1487838471", 86 "alsa-lib_|-(none)_|-1.1.1_|-1.el7_|-x86_64_|-(none)_|-1487838475", 87 "gnupg2_|-(none)_|-2.0.22_|-4.el7_|-x86_64_|-(none)_|-1487838477", 88 "rpm-python_|-(none)_|-4.11.3_|-21.el7_|-x86_64_|-(none)_|-1487838477", 89 "pygpgme_|-(none)_|-0.3_|-9.el7_|-x86_64_|-(none)_|-1487838478", 90 "yum_|-(none)_|-3.4.3_|-150.el7.centos_|-noarch_|-(none)_|-1487838479", 91 "lzo_|-(none)_|-2.06_|-8.el7_|-x86_64_|-(none)_|-1487838479", 92 "qrencode-libs_|-(none)_|-3.4.1_|-3.el7_|-x86_64_|-(none)_|-1487838480", 93 "ustr_|-(none)_|-1.0.4_|-16.el7_|-x86_64_|-(none)_|-1487838480", 94 "shadow-utils_|-2_|-4.1.5.1_|-24.el7_|-x86_64_|-(none)_|-1487838481", 95 "util-linux_|-(none)_|-2.23.2_|-33.el7_|-x86_64_|-(none)_|-1487838484", 96 "openssh_|-(none)_|-6.6.1p1_|-33.el7_3_|-x86_64_|-(none)_|-1487838485", 97 "virt-what_|-(none)_|-1.13_|-8.el7_|-x86_64_|-(none)_|-1487838486", 98 ] 99 with patch.dict(yumpkg.__grains__, {"osarch": "x86_64"}), patch.dict( 100 yumpkg.__salt__, 101 {"cmd.run": MagicMock(return_value=os.linesep.join(rpm_out))}, 102 ), patch.dict(yumpkg.__salt__, {"pkg_resource.add_pkg": _add_data}), patch.dict( 103 yumpkg.__salt__, 104 {"pkg_resource.format_pkg_list": pkg_resource.format_pkg_list}, 105 ), patch.dict( 106 yumpkg.__salt__, {"pkg_resource.stringify": MagicMock()} 107 ), patch.dict( 108 pkg_resource.__salt__, {"pkg.parse_arch": yumpkg.parse_arch} 109 ): 110 pkgs = yumpkg.list_pkgs(versions_as_list=True) 111 for pkg_name, pkg_version in { 112 "python-urlgrabber": "3.10-8.el7", 113 "alsa-lib": "1.1.1-1.el7", 114 "gnupg2": "2.0.22-4.el7", 115 "rpm-python": "4.11.3-21.el7", 116 "pygpgme": "0.3-9.el7", 117 "yum": "3.4.3-150.el7.centos", 118 "lzo": "2.06-8.el7", 119 "qrencode-libs": "3.4.1-3.el7", 120 "ustr": "1.0.4-16.el7", 121 "shadow-utils": "2:4.1.5.1-24.el7", 122 "util-linux": "2.23.2-33.el7", 123 "openssh": "6.6.1p1-33.el7_3", 124 "virt-what": "1.13-8.el7", 125 }.items(): 126 assert pkgs.get(pkg_name) is not None 127 assert pkgs[pkg_name] == [pkg_version] 128 129 130def test_list_pkgs_no_context(): 131 """ 132 Test packages listing. 133 134 :return: 135 """ 136 137 def _add_data(data, key, value): 138 data.setdefault(key, []).append(value) 139 140 rpm_out = [ 141 "python-urlgrabber_|-(none)_|-3.10_|-8.el7_|-noarch_|-(none)_|-1487838471", 142 "alsa-lib_|-(none)_|-1.1.1_|-1.el7_|-x86_64_|-(none)_|-1487838475", 143 "gnupg2_|-(none)_|-2.0.22_|-4.el7_|-x86_64_|-(none)_|-1487838477", 144 "rpm-python_|-(none)_|-4.11.3_|-21.el7_|-x86_64_|-(none)_|-1487838477", 145 "pygpgme_|-(none)_|-0.3_|-9.el7_|-x86_64_|-(none)_|-1487838478", 146 "yum_|-(none)_|-3.4.3_|-150.el7.centos_|-noarch_|-(none)_|-1487838479", 147 "lzo_|-(none)_|-2.06_|-8.el7_|-x86_64_|-(none)_|-1487838479", 148 "qrencode-libs_|-(none)_|-3.4.1_|-3.el7_|-x86_64_|-(none)_|-1487838480", 149 "ustr_|-(none)_|-1.0.4_|-16.el7_|-x86_64_|-(none)_|-1487838480", 150 "shadow-utils_|-2_|-4.1.5.1_|-24.el7_|-x86_64_|-(none)_|-1487838481", 151 "util-linux_|-(none)_|-2.23.2_|-33.el7_|-x86_64_|-(none)_|-1487838484", 152 "openssh_|-(none)_|-6.6.1p1_|-33.el7_3_|-x86_64_|-(none)_|-1487838485", 153 "virt-what_|-(none)_|-1.13_|-8.el7_|-x86_64_|-(none)_|-1487838486", 154 ] 155 with patch.dict(yumpkg.__grains__, {"osarch": "x86_64"}), patch.dict( 156 yumpkg.__salt__, 157 {"cmd.run": MagicMock(return_value=os.linesep.join(rpm_out))}, 158 ), patch.dict(yumpkg.__salt__, {"pkg_resource.add_pkg": _add_data}), patch.dict( 159 yumpkg.__salt__, 160 {"pkg_resource.format_pkg_list": pkg_resource.format_pkg_list}, 161 ), patch.dict( 162 yumpkg.__salt__, {"pkg_resource.stringify": MagicMock()} 163 ), patch.dict( 164 pkg_resource.__salt__, {"pkg.parse_arch": yumpkg.parse_arch} 165 ), patch.object( 166 yumpkg, "_list_pkgs_from_context" 167 ) as list_pkgs_context_mock: 168 pkgs = yumpkg.list_pkgs(versions_as_list=True, use_context=False) 169 list_pkgs_context_mock.assert_not_called() 170 list_pkgs_context_mock.reset_mock() 171 172 pkgs = yumpkg.list_pkgs(versions_as_list=True, use_context=False) 173 list_pkgs_context_mock.assert_not_called() 174 list_pkgs_context_mock.reset_mock() 175 176 177def test_list_pkgs_with_attr(): 178 """ 179 Test packages listing with the attr parameter 180 181 :return: 182 """ 183 184 def _add_data(data, key, value): 185 data.setdefault(key, []).append(value) 186 187 rpm_out = [ 188 "python-urlgrabber_|-(none)_|-3.10_|-8.el7_|-noarch_|-(none)_|-1487838471", 189 "alsa-lib_|-(none)_|-1.1.1_|-1.el7_|-x86_64_|-(none)_|-1487838475", 190 "gnupg2_|-(none)_|-2.0.22_|-4.el7_|-x86_64_|-(none)_|-1487838477", 191 "rpm-python_|-(none)_|-4.11.3_|-21.el7_|-x86_64_|-(none)_|-1487838477", 192 "pygpgme_|-(none)_|-0.3_|-9.el7_|-x86_64_|-(none)_|-1487838478", 193 "yum_|-(none)_|-3.4.3_|-150.el7.centos_|-noarch_|-(none)_|-1487838479", 194 "lzo_|-(none)_|-2.06_|-8.el7_|-x86_64_|-(none)_|-1487838479", 195 "qrencode-libs_|-(none)_|-3.4.1_|-3.el7_|-x86_64_|-(none)_|-1487838480", 196 "ustr_|-(none)_|-1.0.4_|-16.el7_|-x86_64_|-(none)_|-1487838480", 197 "shadow-utils_|-2_|-4.1.5.1_|-24.el7_|-x86_64_|-(none)_|-1487838481", 198 "util-linux_|-(none)_|-2.23.2_|-33.el7_|-x86_64_|-(none)_|-1487838484", 199 "openssh_|-(none)_|-6.6.1p1_|-33.el7_3_|-x86_64_|-(none)_|-1487838485", 200 "virt-what_|-(none)_|-1.13_|-8.el7_|-x86_64_|-(none)_|-1487838486", 201 ] 202 with patch.dict(yumpkg.__grains__, {"osarch": "x86_64"}), patch.dict( 203 yumpkg.__salt__, 204 {"cmd.run": MagicMock(return_value=os.linesep.join(rpm_out))}, 205 ), patch.dict(yumpkg.__salt__, {"pkg_resource.add_pkg": _add_data}), patch.dict( 206 yumpkg.__salt__, 207 {"pkg_resource.format_pkg_list": pkg_resource.format_pkg_list}, 208 ), patch.dict( 209 yumpkg.__salt__, {"pkg_resource.stringify": MagicMock()} 210 ), patch.dict( 211 pkg_resource.__salt__, {"pkg.parse_arch": yumpkg.parse_arch} 212 ): 213 pkgs = yumpkg.list_pkgs( 214 attr=["epoch", "release", "arch", "install_date_time_t"] 215 ) 216 for pkg_name, pkg_attr in { 217 "python-urlgrabber": { 218 "version": "3.10", 219 "release": "8.el7", 220 "arch": "noarch", 221 "install_date_time_t": 1487838471, 222 "epoch": None, 223 }, 224 "alsa-lib": { 225 "version": "1.1.1", 226 "release": "1.el7", 227 "arch": "x86_64", 228 "install_date_time_t": 1487838475, 229 "epoch": None, 230 }, 231 "gnupg2": { 232 "version": "2.0.22", 233 "release": "4.el7", 234 "arch": "x86_64", 235 "install_date_time_t": 1487838477, 236 "epoch": None, 237 }, 238 "rpm-python": { 239 "version": "4.11.3", 240 "release": "21.el7", 241 "arch": "x86_64", 242 "install_date_time_t": 1487838477, 243 "epoch": None, 244 }, 245 "pygpgme": { 246 "version": "0.3", 247 "release": "9.el7", 248 "arch": "x86_64", 249 "install_date_time_t": 1487838478, 250 "epoch": None, 251 }, 252 "yum": { 253 "version": "3.4.3", 254 "release": "150.el7.centos", 255 "arch": "noarch", 256 "install_date_time_t": 1487838479, 257 "epoch": None, 258 }, 259 "lzo": { 260 "version": "2.06", 261 "release": "8.el7", 262 "arch": "x86_64", 263 "install_date_time_t": 1487838479, 264 "epoch": None, 265 }, 266 "qrencode-libs": { 267 "version": "3.4.1", 268 "release": "3.el7", 269 "arch": "x86_64", 270 "install_date_time_t": 1487838480, 271 "epoch": None, 272 }, 273 "ustr": { 274 "version": "1.0.4", 275 "release": "16.el7", 276 "arch": "x86_64", 277 "install_date_time_t": 1487838480, 278 "epoch": None, 279 }, 280 "shadow-utils": { 281 "epoch": "2", 282 "version": "4.1.5.1", 283 "release": "24.el7", 284 "arch": "x86_64", 285 "install_date_time_t": 1487838481, 286 }, 287 "util-linux": { 288 "version": "2.23.2", 289 "release": "33.el7", 290 "arch": "x86_64", 291 "install_date_time_t": 1487838484, 292 "epoch": None, 293 }, 294 "openssh": { 295 "version": "6.6.1p1", 296 "release": "33.el7_3", 297 "arch": "x86_64", 298 "install_date_time_t": 1487838485, 299 "epoch": None, 300 }, 301 "virt-what": { 302 "version": "1.13", 303 "release": "8.el7", 304 "install_date_time_t": 1487838486, 305 "arch": "x86_64", 306 "epoch": None, 307 }, 308 }.items(): 309 310 assert pkgs.get(pkg_name) is not None 311 assert pkgs[pkg_name] == [pkg_attr] 312 313 314def test_list_pkgs_with_attr_multiple_versions(): 315 """ 316 Test packages listing with the attr parameter reporting multiple version installed 317 318 :return: 319 """ 320 321 def _add_data(data, key, value): 322 data.setdefault(key, []).append(value) 323 324 rpm_out = [ 325 "glibc_|-(none)_|-2.12_|-1.212.el6_|-i686_|-(none)_|-1542394210" 326 "glibc_|-(none)_|-2.12_|-1.212.el6_|-x86_64_|-(none)_|-1542394204", 327 "virt-what_|-(none)_|-1.13_|-8.el7_|-x86_64_|-(none)_|-1487838486", 328 "virt-what_|-(none)_|-1.10_|-2.el7_|-x86_64_|-(none)_|-1387838486", 329 ] 330 with patch.dict(yumpkg.__grains__, {"osarch": "x86_64"}), patch.dict( 331 yumpkg.__salt__, 332 {"cmd.run": MagicMock(return_value=os.linesep.join(rpm_out))}, 333 ), patch.dict(yumpkg.__salt__, {"pkg_resource.add_pkg": _add_data}), patch.dict( 334 yumpkg.__salt__, 335 {"pkg_resource.format_pkg_list": pkg_resource.format_pkg_list}, 336 ), patch.dict( 337 yumpkg.__salt__, {"pkg_resource.stringify": MagicMock()} 338 ), patch.dict( 339 pkg_resource.__salt__, {"pkg.parse_arch": yumpkg.parse_arch} 340 ): 341 pkgs = yumpkg.list_pkgs( 342 attr=["epoch", "release", "arch", "install_date_time_t"] 343 ) 344 expected_pkg_list = { 345 "glibc": [ 346 { 347 "version": "2.12", 348 "release": "1.212.el6", 349 "install_date_time_t": 1542394210, 350 "arch": "i686", 351 "epoch": None, 352 }, 353 { 354 "version": "2.12", 355 "release": "1.212.el6", 356 "install_date_time_t": 1542394204, 357 "arch": "x86_64", 358 "epoch": None, 359 }, 360 ], 361 "virt-what": [ 362 { 363 "version": "1.10", 364 "release": "2.el7", 365 "install_date_time_t": 1387838486, 366 "arch": "x86_64", 367 "epoch": None, 368 }, 369 { 370 "version": "1.13", 371 "release": "8.el7", 372 "install_date_time_t": 1487838486, 373 "arch": "x86_64", 374 "epoch": None, 375 }, 376 ], 377 } 378 for pkgname, pkginfo in pkgs.items(): 379 assert pkginfo == expected_pkg_list[pkgname] 380 assert len(pkginfo) == len(expected_pkg_list[pkgname]) 381 382 383def test_list_patches(): 384 """ 385 Test patches listing. 386 387 :return: 388 """ 389 yum_out = [ 390 "i my-fake-patch-not-installed-1234 recommended " 391 " spacewalk-usix-2.7.5.2-2.2.noarch", 392 " my-fake-patch-not-installed-1234 recommended " 393 " spacewalksd-5.0.26.2-21.2.x86_64", 394 "i my-fake-patch-not-installed-1234 recommended " 395 " suseRegisterInfo-3.1.1-18.2.x86_64", 396 "i my-fake-patch-installed-1234 recommended " 397 " my-package-one-1.1-0.1.x86_64", 398 "i my-fake-patch-installed-1234 recommended " 399 " my-package-two-1.1-0.1.x86_64", 400 ] 401 402 expected_patches = { 403 "my-fake-patch-not-installed-1234": { 404 "installed": False, 405 "summary": [ 406 "spacewalk-usix-2.7.5.2-2.2.noarch", 407 "spacewalksd-5.0.26.2-21.2.x86_64", 408 "suseRegisterInfo-3.1.1-18.2.x86_64", 409 ], 410 }, 411 "my-fake-patch-installed-1234": { 412 "installed": True, 413 "summary": [ 414 "my-package-one-1.1-0.1.x86_64", 415 "my-package-two-1.1-0.1.x86_64", 416 ], 417 }, 418 } 419 420 with patch.dict(yumpkg.__grains__, {"osarch": "x86_64"}), patch.dict( 421 yumpkg.__salt__, 422 {"cmd.run_stdout": MagicMock(return_value=os.linesep.join(yum_out))}, 423 ): 424 patches = yumpkg.list_patches() 425 assert patches["my-fake-patch-not-installed-1234"]["installed"] is False 426 assert len(patches["my-fake-patch-not-installed-1234"]["summary"]) == 3 427 for _patch in expected_patches["my-fake-patch-not-installed-1234"]["summary"]: 428 assert _patch in patches["my-fake-patch-not-installed-1234"]["summary"] 429 430 assert patches["my-fake-patch-installed-1234"]["installed"] is True 431 assert len(patches["my-fake-patch-installed-1234"]["summary"]) == 2 432 for _patch in expected_patches["my-fake-patch-installed-1234"]["summary"]: 433 assert _patch in patches["my-fake-patch-installed-1234"]["summary"] 434 435 436def test_latest_version_with_options(): 437 with patch.object(yumpkg, "list_pkgs", MagicMock(return_value={})): 438 439 # with fromrepo 440 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 441 with patch.dict( 442 yumpkg.__salt__, 443 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=False)}, 444 ): 445 yumpkg.latest_version("foo", refresh=False, fromrepo="good", branch="foo") 446 cmd.assert_called_once_with( 447 [ 448 "yum", 449 "--quiet", 450 "--disablerepo=*", 451 "--enablerepo=good", 452 "--branch=foo", 453 "list", 454 "available", 455 "foo", 456 ], 457 env={}, 458 ignore_retcode=True, 459 output_loglevel="trace", 460 python_shell=False, 461 ) 462 463 # without fromrepo 464 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 465 with patch.dict( 466 yumpkg.__salt__, 467 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=False)}, 468 ): 469 yumpkg.latest_version( 470 "foo", 471 refresh=False, 472 enablerepo="good", 473 disablerepo="bad", 474 branch="foo", 475 ) 476 cmd.assert_called_once_with( 477 [ 478 "yum", 479 "--quiet", 480 "--disablerepo=bad", 481 "--enablerepo=good", 482 "--branch=foo", 483 "list", 484 "available", 485 "foo", 486 ], 487 env={}, 488 ignore_retcode=True, 489 output_loglevel="trace", 490 python_shell=False, 491 ) 492 493 # without fromrepo, but within the scope 494 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 495 with patch("salt.utils.systemd.has_scope", MagicMock(return_value=True)): 496 with patch.dict( 497 yumpkg.__salt__, 498 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=True)}, 499 ): 500 yumpkg.latest_version( 501 "foo", 502 refresh=False, 503 enablerepo="good", 504 disablerepo="bad", 505 branch="foo", 506 ) 507 cmd.assert_called_once_with( 508 [ 509 "systemd-run", 510 "--scope", 511 "yum", 512 "--quiet", 513 "--disablerepo=bad", 514 "--enablerepo=good", 515 "--branch=foo", 516 "list", 517 "available", 518 "foo", 519 ], 520 env={}, 521 ignore_retcode=True, 522 output_loglevel="trace", 523 python_shell=False, 524 ) 525 526 527def test_list_repo_pkgs_with_options(list_repos_var): 528 """ 529 Test list_repo_pkgs with and without fromrepo 530 531 NOTE: mock_calls is a stack. The most recent call is indexed 532 with 0, while the first call would have the highest index. 533 """ 534 really_old_yum = MagicMock(return_value="3.2.0") 535 older_yum = MagicMock(return_value="3.4.0") 536 newer_yum = MagicMock(return_value="3.4.5") 537 list_repos_mock = MagicMock(return_value=list_repos_var) 538 kwargs = { 539 "output_loglevel": "trace", 540 "ignore_retcode": True, 541 "python_shell": False, 542 "env": {}, 543 } 544 545 with patch.object(yumpkg, "list_repos", list_repos_mock): 546 547 # Test with really old yum. The fromrepo argument has no effect on 548 # the yum commands we'd run. 549 with patch.dict(yumpkg.__salt__, {"cmd.run": really_old_yum}): 550 551 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 552 with patch.dict( 553 yumpkg.__salt__, 554 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=False)}, 555 ): 556 yumpkg.list_repo_pkgs("foo") 557 # We should have called cmd.run_all twice 558 assert len(cmd.mock_calls) == 2 559 560 # Check args from first call 561 assert cmd.mock_calls[1][1] == ( 562 ["yum", "--quiet", "list", "available"], 563 ) 564 565 # Check kwargs from first call 566 assert cmd.mock_calls[1][2] == kwargs 567 568 # Check args from second call 569 assert cmd.mock_calls[0][1] == ( 570 ["yum", "--quiet", "list", "installed"], 571 ) 572 573 # Check kwargs from second call 574 assert cmd.mock_calls[0][2] == kwargs 575 576 # Test with really old yum. The fromrepo argument has no effect on 577 # the yum commands we'd run. 578 with patch.dict(yumpkg.__salt__, {"cmd.run": older_yum}): 579 580 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 581 with patch.dict( 582 yumpkg.__salt__, 583 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=False)}, 584 ): 585 yumpkg.list_repo_pkgs("foo") 586 # We should have called cmd.run_all twice 587 assert len(cmd.mock_calls) == 2 588 589 # Check args from first call 590 assert cmd.mock_calls[1][1] == ( 591 ["yum", "--quiet", "--showduplicates", "list", "available"], 592 ) 593 594 # Check kwargs from first call 595 assert cmd.mock_calls[1][2] == kwargs 596 597 # Check args from second call 598 assert cmd.mock_calls[0][1] == ( 599 ["yum", "--quiet", "--showduplicates", "list", "installed"], 600 ) 601 602 # Check kwargs from second call 603 assert cmd.mock_calls[0][2] == kwargs 604 605 # Test with newer yum. We should run one yum command per repo, so 606 # fromrepo would limit how many calls we make. 607 with patch.dict(yumpkg.__salt__, {"cmd.run": newer_yum}): 608 609 # When fromrepo is used, we would only run one yum command, for 610 # that specific repo. 611 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 612 with patch.dict( 613 yumpkg.__salt__, 614 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=False)}, 615 ): 616 yumpkg.list_repo_pkgs("foo", fromrepo="base") 617 # We should have called cmd.run_all once 618 assert len(cmd.mock_calls) == 1 619 620 # Check args 621 assert cmd.mock_calls[0][1] == ( 622 [ 623 "yum", 624 "--quiet", 625 "--showduplicates", 626 "repository-packages", 627 "base", 628 "list", 629 "foo", 630 ], 631 ) 632 # Check kwargs 633 assert cmd.mock_calls[0][2] == kwargs 634 635 # Test enabling base-source and disabling updates. We should 636 # get two calls, one for each enabled repo. Because dict 637 # iteration order will vary, different Python versions will be 638 # do them in different orders, which is OK, but it will just 639 # mean that we will have to check both the first and second 640 # mock call both times. 641 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 642 with patch.dict( 643 yumpkg.__salt__, 644 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=False)}, 645 ): 646 yumpkg.list_repo_pkgs( 647 "foo", enablerepo="base-source", disablerepo="updates" 648 ) 649 # We should have called cmd.run_all twice 650 assert len(cmd.mock_calls) == 2 651 652 for repo in ("base", "base-source"): 653 for index in (0, 1): 654 try: 655 # Check args 656 assert cmd.mock_calls[index][1] == ( 657 [ 658 "yum", 659 "--quiet", 660 "--showduplicates", 661 "repository-packages", 662 repo, 663 "list", 664 "foo", 665 ], 666 ) 667 # Check kwargs 668 assert cmd.mock_calls[index][2] == kwargs 669 break 670 except AssertionError: 671 continue 672 else: 673 pytest.fail("repo '{}' not checked".format(repo)) 674 675 676def test_list_upgrades_dnf(): 677 """ 678 The subcommand should be "upgrades" with dnf 679 """ 680 with patch.dict(yumpkg.__context__, {"yum_bin": "dnf"}): 681 # with fromrepo 682 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 683 with patch.dict( 684 yumpkg.__salt__, 685 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=False)}, 686 ): 687 yumpkg.list_upgrades(refresh=False, fromrepo="good", branch="foo") 688 cmd.assert_called_once_with( 689 [ 690 "dnf", 691 "--quiet", 692 "--disablerepo=*", 693 "--enablerepo=good", 694 "--branch=foo", 695 "list", 696 "upgrades", 697 ], 698 env={}, 699 output_loglevel="trace", 700 ignore_retcode=True, 701 python_shell=False, 702 ) 703 704 # without fromrepo 705 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 706 with patch.dict( 707 yumpkg.__salt__, 708 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=False)}, 709 ): 710 yumpkg.list_upgrades( 711 refresh=False, enablerepo="good", disablerepo="bad", branch="foo" 712 ) 713 cmd.assert_called_once_with( 714 [ 715 "dnf", 716 "--quiet", 717 "--disablerepo=bad", 718 "--enablerepo=good", 719 "--branch=foo", 720 "list", 721 "upgrades", 722 ], 723 env={}, 724 output_loglevel="trace", 725 ignore_retcode=True, 726 python_shell=False, 727 ) 728 729 730def test_list_upgrades_yum(): 731 """ 732 The subcommand should be "updates" with yum 733 """ 734 # with fromrepo 735 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 736 with patch.dict( 737 yumpkg.__salt__, 738 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=False)}, 739 ): 740 yumpkg.list_upgrades(refresh=False, fromrepo="good", branch="foo") 741 cmd.assert_called_once_with( 742 [ 743 "yum", 744 "--quiet", 745 "--disablerepo=*", 746 "--enablerepo=good", 747 "--branch=foo", 748 "list", 749 "updates", 750 ], 751 env={}, 752 output_loglevel="trace", 753 ignore_retcode=True, 754 python_shell=False, 755 ) 756 757 # without fromrepo 758 cmd = MagicMock(return_value={"retcode": 0, "stdout": ""}) 759 with patch.dict( 760 yumpkg.__salt__, 761 {"cmd.run_all": cmd, "config.get": MagicMock(return_value=False)}, 762 ): 763 yumpkg.list_upgrades( 764 refresh=False, enablerepo="good", disablerepo="bad", branch="foo" 765 ) 766 cmd.assert_called_once_with( 767 [ 768 "yum", 769 "--quiet", 770 "--disablerepo=bad", 771 "--enablerepo=good", 772 "--branch=foo", 773 "list", 774 "updates", 775 ], 776 env={}, 777 output_loglevel="trace", 778 ignore_retcode=True, 779 python_shell=False, 780 ) 781 782 783def test_refresh_db_with_options(): 784 785 with patch("salt.utils.pkg.clear_rtag", Mock()): 786 787 # With check_update=True we will do a cmd.run to run the clean_cmd, and 788 # then a separate cmd.retcode to check for updates. 789 790 # with fromrepo 791 yum_call = MagicMock() 792 with patch.dict( 793 yumpkg.__salt__, 794 {"cmd.run_all": yum_call, "config.get": MagicMock(return_value=False)}, 795 ): 796 yumpkg.refresh_db(check_update=True, fromrepo="good", branch="foo") 797 798 assert yum_call.call_count == 2 799 yum_call.assert_any_call( 800 [ 801 "yum", 802 "--quiet", 803 "--assumeyes", 804 "clean", 805 "expire-cache", 806 "--disablerepo=*", 807 "--enablerepo=good", 808 "--branch=foo", 809 ], 810 env={}, 811 ignore_retcode=True, 812 output_loglevel="trace", 813 python_shell=False, 814 ) 815 yum_call.assert_any_call( 816 [ 817 "yum", 818 "--quiet", 819 "--assumeyes", 820 "check-update", 821 "--setopt=autocheck_running_kernel=false", 822 "--disablerepo=*", 823 "--enablerepo=good", 824 "--branch=foo", 825 ], 826 output_loglevel="trace", 827 env={}, 828 ignore_retcode=True, 829 python_shell=False, 830 ) 831 832 # without fromrepo 833 yum_call = MagicMock() 834 with patch.dict( 835 yumpkg.__salt__, 836 {"cmd.run_all": yum_call, "config.get": MagicMock(return_value=False)}, 837 ): 838 yumpkg.refresh_db( 839 check_update=True, 840 enablerepo="good", 841 disablerepo="bad", 842 branch="foo", 843 ) 844 assert yum_call.call_count == 2 845 yum_call.assert_any_call( 846 [ 847 "yum", 848 "--quiet", 849 "--assumeyes", 850 "clean", 851 "expire-cache", 852 "--disablerepo=bad", 853 "--enablerepo=good", 854 "--branch=foo", 855 ], 856 env={}, 857 ignore_retcode=True, 858 output_loglevel="trace", 859 python_shell=False, 860 ) 861 yum_call.assert_any_call( 862 [ 863 "yum", 864 "--quiet", 865 "--assumeyes", 866 "check-update", 867 "--setopt=autocheck_running_kernel=false", 868 "--disablerepo=bad", 869 "--enablerepo=good", 870 "--branch=foo", 871 ], 872 output_loglevel="trace", 873 env={}, 874 ignore_retcode=True, 875 python_shell=False, 876 ) 877 878 # With check_update=False we will just do a cmd.run for the clean_cmd 879 880 # with fromrepo 881 yum_call = MagicMock() 882 with patch.dict( 883 yumpkg.__salt__, 884 {"cmd.run_all": yum_call, "config.get": MagicMock(return_value=False)}, 885 ): 886 yumpkg.refresh_db(check_update=False, fromrepo="good", branch="foo") 887 assert yum_call.call_count == 1 888 yum_call.assert_called_once_with( 889 [ 890 "yum", 891 "--quiet", 892 "--assumeyes", 893 "clean", 894 "expire-cache", 895 "--disablerepo=*", 896 "--enablerepo=good", 897 "--branch=foo", 898 ], 899 env={}, 900 output_loglevel="trace", 901 ignore_retcode=True, 902 python_shell=False, 903 ) 904 905 # without fromrepo 906 yum_call = MagicMock() 907 with patch.dict( 908 yumpkg.__salt__, 909 {"cmd.run_all": yum_call, "config.get": MagicMock(return_value=False)}, 910 ): 911 yumpkg.refresh_db( 912 check_update=False, 913 enablerepo="good", 914 disablerepo="bad", 915 branch="foo", 916 ) 917 assert yum_call.call_count == 1 918 yum_call.assert_called_once_with( 919 [ 920 "yum", 921 "--quiet", 922 "--assumeyes", 923 "clean", 924 "expire-cache", 925 "--disablerepo=bad", 926 "--enablerepo=good", 927 "--branch=foo", 928 ], 929 env={}, 930 output_loglevel="trace", 931 ignore_retcode=True, 932 python_shell=False, 933 ) 934 935 936def test_install_with_options(): 937 parse_targets = MagicMock(return_value=({"foo": None}, "repository")) 938 with patch.object(yumpkg, "list_pkgs", MagicMock(return_value={})), patch.object( 939 yumpkg, "list_holds", MagicMock(return_value=[]) 940 ), patch.dict( 941 yumpkg.__salt__, {"pkg_resource.parse_targets": parse_targets} 942 ), patch( 943 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 944 ): 945 946 # with fromrepo 947 cmd = MagicMock(return_value={"retcode": 0}) 948 with patch.dict(yumpkg.__salt__, {"cmd.run_all": cmd}): 949 yumpkg.install( 950 refresh=False, 951 fromrepo="good", 952 branch="foo", 953 setopt="obsoletes=0,plugins=0", 954 ) 955 cmd.assert_called_once_with( 956 [ 957 "yum", 958 "-y", 959 "--disablerepo=*", 960 "--enablerepo=good", 961 "--branch=foo", 962 "--setopt", 963 "obsoletes=0", 964 "--setopt", 965 "plugins=0", 966 "install", 967 "foo", 968 ], 969 env={}, 970 output_loglevel="trace", 971 python_shell=False, 972 ignore_retcode=False, 973 redirect_stderr=True, 974 ) 975 976 # without fromrepo 977 cmd = MagicMock(return_value={"retcode": 0}) 978 with patch.dict(yumpkg.__salt__, {"cmd.run_all": cmd}): 979 yumpkg.install( 980 refresh=False, 981 enablerepo="good", 982 disablerepo="bad", 983 branch="foo", 984 setopt="obsoletes=0,plugins=0", 985 ) 986 cmd.assert_called_once_with( 987 [ 988 "yum", 989 "-y", 990 "--disablerepo=bad", 991 "--enablerepo=good", 992 "--branch=foo", 993 "--setopt", 994 "obsoletes=0", 995 "--setopt", 996 "plugins=0", 997 "install", 998 "foo", 999 ], 1000 env={}, 1001 output_loglevel="trace", 1002 python_shell=False, 1003 ignore_retcode=False, 1004 redirect_stderr=True, 1005 ) 1006 1007 1008def test_remove_with_epoch(): 1009 """ 1010 Tests that we properly identify a version containing an epoch for 1011 deinstallation. 1012 1013 You can deinstall pkgs only without the epoch if no arch is provided: 1014 1015 .. code-block:: bash 1016 1017 yum remove PackageKit-yum-1.1.10-2.el7.centos 1018 """ 1019 name = "foo" 1020 installed = "8:3.8.12-4.n.el7" 1021 list_pkgs_mock = MagicMock( 1022 side_effect=lambda **kwargs: { 1023 name: [installed] if kwargs.get("versions_as_list", False) else installed 1024 } 1025 ) 1026 cmd_mock = MagicMock( 1027 return_value={"pid": 12345, "retcode": 0, "stdout": "", "stderr": ""} 1028 ) 1029 salt_mock = { 1030 "cmd.run_all": cmd_mock, 1031 "lowpkg.version_cmp": rpm.version_cmp, 1032 "pkg_resource.parse_targets": MagicMock( 1033 return_value=({name: installed}, "repository") 1034 ), 1035 } 1036 full_pkg_string = "-".join((name, installed[2:])) 1037 with patch.object(yumpkg, "list_pkgs", list_pkgs_mock), patch( 1038 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1039 ), patch.dict(yumpkg.__salt__, salt_mock): 1040 1041 with patch.dict(yumpkg.__grains__, {"os": "CentOS", "osrelease": 7}): 1042 expected = ["yum", "-y", "remove", full_pkg_string] 1043 yumpkg.remove(name) 1044 call = cmd_mock.mock_calls[0][1][0] 1045 assert call == expected, call 1046 1047 1048def test_remove_with_epoch_and_arch_info(): 1049 """ 1050 Tests that we properly identify a version containing an epoch and arch 1051 deinstallation. 1052 1053 You can deinstall pkgs with or without epoch in combination with the arch. 1054 Here we test for the absence of the epoch, but the presence for the arch: 1055 1056 .. code-block:: bash 1057 1058 yum remove PackageKit-yum-1.1.10-2.el7.centos.x86_64 1059 """ 1060 arch = "x86_64" 1061 name = "foo" 1062 name_and_arch = name + "." + arch 1063 installed = "8:3.8.12-4.n.el7" 1064 list_pkgs_mock = MagicMock( 1065 side_effect=lambda **kwargs: { 1066 name_and_arch: [installed] 1067 if kwargs.get("versions_as_list", False) 1068 else installed 1069 } 1070 ) 1071 cmd_mock = MagicMock( 1072 return_value={"pid": 12345, "retcode": 0, "stdout": "", "stderr": ""} 1073 ) 1074 salt_mock = { 1075 "cmd.run_all": cmd_mock, 1076 "lowpkg.version_cmp": rpm.version_cmp, 1077 "pkg_resource.parse_targets": MagicMock( 1078 return_value=({name_and_arch: installed}, "repository") 1079 ), 1080 } 1081 full_pkg_string = "-".join((name, installed[2:])) 1082 with patch.object(yumpkg, "list_pkgs", list_pkgs_mock), patch( 1083 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1084 ), patch.dict(yumpkg.__salt__, salt_mock): 1085 1086 with patch.dict(yumpkg.__grains__, {"os": "CentOS", "osrelease": 7}): 1087 expected = ["yum", "-y", "remove", full_pkg_string + "." + arch] 1088 yumpkg.remove(name) 1089 call = cmd_mock.mock_calls[0][1][0] 1090 assert call == expected, call 1091 1092 1093def test_remove_with_wildcard(): 1094 """ 1095 Tests that we properly identify a version containing an epoch for 1096 deinstallation. 1097 1098 You can deinstall pkgs only without the epoch if no arch is provided: 1099 1100 .. code-block:: bash 1101 1102 yum remove foo* 1103 1104 yum remove pkgs='[{"foo*": "8:3.8.12-4.n.el7"}]' 1105 """ 1106 name = "foobarpkg" 1107 installed = "8:3.8.12-4.n.el7" 1108 list_pkgs_mock = MagicMock( 1109 side_effect=lambda **kwargs: { 1110 name: [installed] if kwargs.get("versions_as_list", False) else installed 1111 } 1112 ) 1113 cmd_mock = MagicMock( 1114 return_value={"pid": 12345, "retcode": 0, "stdout": "", "stderr": ""} 1115 ) 1116 salt_mock = { 1117 "cmd.run_all": cmd_mock, 1118 "lowpkg.version_cmp": rpm.version_cmp, 1119 "pkg_resource.parse_targets": MagicMock( 1120 return_value=({name: installed}, "repository") 1121 ), 1122 } 1123 full_pkg_string = "-".join((name, installed[2:])) 1124 with patch.object(yumpkg, "list_pkgs", list_pkgs_mock), patch( 1125 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1126 ), patch.dict(yumpkg.__salt__, salt_mock): 1127 1128 with patch.dict(yumpkg.__grains__, {"os": "CentOS", "osrelease": 7}): 1129 expected = ["yum", "-y", "remove", full_pkg_string] 1130 yumpkg.remove("foo*") 1131 call = cmd_mock.mock_calls[0][1][0] 1132 assert call == expected, call 1133 1134 expected = ["yum", "-y", "remove", full_pkg_string] 1135 yumpkg.remove(pkgs=[{"foo*": "8:3.8.12-4.n.el7"}]) 1136 call = cmd_mock.mock_calls[0][1][0] 1137 assert call == expected, call 1138 1139 1140def test_install_with_epoch(): 1141 """ 1142 Tests that we properly identify a version containing an epoch as an 1143 upgrade instead of a downgrade. 1144 """ 1145 name = "foo" 1146 old = "8:3.8.12-6.n.el7" 1147 new = "9:3.8.12-4.n.el7" 1148 list_pkgs_mock = MagicMock( 1149 side_effect=lambda **kwargs: { 1150 name: [old] if kwargs.get("versions_as_list", False) else old 1151 } 1152 ) 1153 cmd_mock = MagicMock( 1154 return_value={"pid": 12345, "retcode": 0, "stdout": "", "stderr": ""} 1155 ) 1156 salt_mock = { 1157 "cmd.run_all": cmd_mock, 1158 "lowpkg.version_cmp": rpm.version_cmp, 1159 "pkg_resource.parse_targets": MagicMock( 1160 return_value=({name: new}, "repository") 1161 ), 1162 } 1163 full_pkg_string = "-".join((name, new[2:])) 1164 with patch.object(yumpkg, "list_pkgs", list_pkgs_mock), patch( 1165 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1166 ), patch.dict(yumpkg.__salt__, salt_mock): 1167 1168 # Test yum 1169 expected = ["yum", "-y", "install", full_pkg_string] 1170 with patch.dict(yumpkg.__context__, {"yum_bin": "yum"}), patch.dict( 1171 yumpkg.__grains__, {"os": "CentOS", "osrelease": 7} 1172 ): 1173 yumpkg.install("foo", version=new) 1174 call = cmd_mock.mock_calls[0][1][0] 1175 assert call == expected, call 1176 1177 # Test dnf 1178 expected = [ 1179 "dnf", 1180 "-y", 1181 "--best", 1182 "--allowerasing", 1183 "install", 1184 full_pkg_string, 1185 ] 1186 yumpkg.__context__.pop("yum_bin") 1187 cmd_mock.reset_mock() 1188 with patch.dict(yumpkg.__context__, {"yum_bin": "dnf"}), patch.dict( 1189 yumpkg.__grains__, {"os": "Fedora", "osrelease": 27} 1190 ): 1191 yumpkg.install("foo", version=new) 1192 call = cmd_mock.mock_calls[0][1][0] 1193 assert call == expected, call 1194 1195 1196@pytest.mark.skipif(not salt.utils.platform.is_linux(), reason="Only run on Linux") 1197def test_install_error_reporting(): 1198 """ 1199 Tests that we properly report yum/dnf errors. 1200 """ 1201 name = "foo" 1202 old = "8:3.8.12-6.n.el7" 1203 new = "9:3.8.12-4.n.el7" 1204 list_pkgs_mock = MagicMock( 1205 side_effect=lambda **kwargs: { 1206 name: [old] if kwargs.get("versions_as_list", False) else old 1207 } 1208 ) 1209 salt_mock = { 1210 "cmd.run_all": cmdmod.run_all, 1211 "lowpkg.version_cmp": rpm.version_cmp, 1212 "pkg_resource.parse_targets": MagicMock( 1213 return_value=({name: new}, "repository") 1214 ), 1215 } 1216 full_pkg_string = "-".join((name, new[2:])) 1217 with patch.object(yumpkg, "list_pkgs", list_pkgs_mock), patch( 1218 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1219 ), patch.dict(yumpkg.__salt__, salt_mock), patch.object( 1220 yumpkg, "_yum", MagicMock(return_value="cat") 1221 ): 1222 1223 expected = { 1224 "changes": {}, 1225 "errors": [ 1226 "cat: invalid option -- 'y'\nTry 'cat --help' for more information." 1227 ], 1228 } 1229 with pytest.raises(CommandExecutionError) as exc_info: 1230 yumpkg.install("foo", version=new) 1231 assert exc_info.value.info == expected, exc_info.value.info 1232 1233 1234def test_upgrade_with_options(): 1235 with patch.object(yumpkg, "list_pkgs", MagicMock(return_value={})), patch( 1236 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1237 ): 1238 1239 # with fromrepo 1240 cmd = MagicMock(return_value={"retcode": 0}) 1241 with patch.dict(yumpkg.__salt__, {"cmd.run_all": cmd}): 1242 yumpkg.upgrade( 1243 refresh=False, 1244 fromrepo="good", 1245 exclude="kernel*", 1246 branch="foo", 1247 setopt="obsoletes=0,plugins=0", 1248 ) 1249 cmd.assert_called_once_with( 1250 [ 1251 "yum", 1252 "--quiet", 1253 "-y", 1254 "--disablerepo=*", 1255 "--enablerepo=good", 1256 "--branch=foo", 1257 "--setopt", 1258 "obsoletes=0", 1259 "--setopt", 1260 "plugins=0", 1261 "--exclude=kernel*", 1262 "upgrade", 1263 ], 1264 env={}, 1265 output_loglevel="trace", 1266 python_shell=False, 1267 ) 1268 1269 # without fromrepo 1270 cmd = MagicMock(return_value={"retcode": 0}) 1271 with patch.dict(yumpkg.__salt__, {"cmd.run_all": cmd}): 1272 yumpkg.upgrade( 1273 refresh=False, 1274 enablerepo="good", 1275 disablerepo="bad", 1276 exclude="kernel*", 1277 branch="foo", 1278 setopt="obsoletes=0,plugins=0", 1279 ) 1280 cmd.assert_called_once_with( 1281 [ 1282 "yum", 1283 "--quiet", 1284 "-y", 1285 "--disablerepo=bad", 1286 "--enablerepo=good", 1287 "--branch=foo", 1288 "--setopt", 1289 "obsoletes=0", 1290 "--setopt", 1291 "plugins=0", 1292 "--exclude=kernel*", 1293 "upgrade", 1294 ], 1295 env={}, 1296 output_loglevel="trace", 1297 python_shell=False, 1298 ) 1299 1300 1301def test_info_installed_with_all_versions(): 1302 """ 1303 Test the return information of all versions for the named package(s), installed on the system. 1304 1305 :return: 1306 """ 1307 run_out = { 1308 "virgo-dummy": [ 1309 { 1310 "build_date": "2015-07-09T10:55:19Z", 1311 "vendor": "openSUSE Build Service", 1312 "description": ( 1313 "This is the Virgo dummy package used for testing SUSE Manager" 1314 ), 1315 "license": "GPL-2.0", 1316 "build_host": "sheep05", 1317 "url": "http://www.suse.com", 1318 "build_date_time_t": 1436432119, 1319 "relocations": "(not relocatable)", 1320 "source_rpm": "virgo-dummy-1.0-1.1.src.rpm", 1321 "install_date": "2016-02-23T16:31:57Z", 1322 "install_date_time_t": 1456241517, 1323 "summary": "Virgo dummy package", 1324 "version": "1.0", 1325 "signature": ( 1326 "DSA/SHA1, Thu Jul 9 08:55:33 2015, Key ID 27fa41bd8a7c64f9" 1327 ), 1328 "release": "1.1", 1329 "group": "Applications/System", 1330 "arch": "i686", 1331 "size": "17992", 1332 }, 1333 { 1334 "build_date": "2015-07-09T10:15:19Z", 1335 "vendor": "openSUSE Build Service", 1336 "description": ( 1337 "This is the Virgo dummy package used for testing SUSE Manager" 1338 ), 1339 "license": "GPL-2.0", 1340 "build_host": "sheep05", 1341 "url": "http://www.suse.com", 1342 "build_date_time_t": 1436432119, 1343 "relocations": "(not relocatable)", 1344 "source_rpm": "virgo-dummy-1.0-1.1.src.rpm", 1345 "install_date": "2016-02-23T16:31:57Z", 1346 "install_date_time_t": 14562415127, 1347 "summary": "Virgo dummy package", 1348 "version": "1.0", 1349 "signature": ( 1350 "DSA/SHA1, Thu Jul 9 08:55:33 2015, Key ID 27fa41bd8a7c64f9" 1351 ), 1352 "release": "1.1", 1353 "group": "Applications/System", 1354 "arch": "x86_64", 1355 "size": "13124", 1356 }, 1357 ], 1358 "libopenssl1_0_0": [ 1359 { 1360 "build_date": "2015-11-04T23:20:34Z", 1361 "vendor": "SUSE LLC <https://www.suse.com/>", 1362 "description": "The OpenSSL Project is a collaborative effort.", 1363 "license": "OpenSSL", 1364 "build_host": "sheep11", 1365 "url": "https://www.openssl.org/", 1366 "build_date_time_t": 1446675634, 1367 "relocations": "(not relocatable)", 1368 "source_rpm": "openssl-1.0.1i-34.1.src.rpm", 1369 "install_date": "2016-02-23T16:31:35Z", 1370 "install_date_time_t": 1456241495, 1371 "summary": "Secure Sockets and Transport Layer Security", 1372 "version": "1.0.1i", 1373 "signature": ( 1374 "RSA/SHA256, Wed Nov 4 22:21:34 2015, Key ID 70af9e8139db7c82" 1375 ), 1376 "release": "34.1", 1377 "group": "Productivity/Networking/Security", 1378 "packager": "https://www.suse.com/", 1379 "arch": "x86_64", 1380 "size": "2576912", 1381 } 1382 ], 1383 } 1384 with patch.dict(yumpkg.__salt__, {"lowpkg.info": MagicMock(return_value=run_out)}): 1385 installed = yumpkg.info_installed(all_versions=True) 1386 # Test overall products length 1387 assert len(installed) == 2 1388 1389 # Test multiple versions for the same package 1390 for pkg_name, pkg_info_list in installed.items(): 1391 assert len(pkg_info_list) == 2 if pkg_name == "virgo-dummy" else 1 1392 for info in pkg_info_list: 1393 assert info["arch"] in ("x86_64", "i686") 1394 1395 1396def test_pkg_hold_yum(): 1397 """ 1398 Tests that we properly identify versionlock plugin when using yum 1399 for RHEL/CentOS 7 and Fedora < 22 1400 """ 1401 1402 # Test RHEL/CentOS 7 1403 list_pkgs_mock = { 1404 "yum-plugin-versionlock": "0:1.0.0-0.n.el7", 1405 "yum-versionlock": "0:1.0.0-0.n.el7", 1406 } 1407 1408 cmd = MagicMock(return_value={"retcode": 0}) 1409 with patch.object( 1410 yumpkg, "list_pkgs", MagicMock(return_value=list_pkgs_mock) 1411 ), patch.object(yumpkg, "list_holds", MagicMock(return_value=[])), patch.dict( 1412 yumpkg.__salt__, {"cmd.run_all": cmd} 1413 ), patch( 1414 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1415 ): 1416 yumpkg.hold("foo") 1417 cmd.assert_called_once_with( 1418 ["yum", "versionlock", "foo"], 1419 env={}, 1420 output_loglevel="trace", 1421 python_shell=False, 1422 ) 1423 1424 # Test Fedora 20 1425 cmd = MagicMock(return_value={"retcode": 0}) 1426 with patch.dict(yumpkg.__context__, {"yum_bin": "yum"}), patch.dict( 1427 yumpkg.__grains__, {"os": "Fedora", "osrelease": 20} 1428 ), patch.object( 1429 yumpkg, "list_pkgs", MagicMock(return_value=list_pkgs_mock) 1430 ), patch.object( 1431 yumpkg, "list_holds", MagicMock(return_value=[]) 1432 ), patch.dict( 1433 yumpkg.__salt__, {"cmd.run_all": cmd} 1434 ), patch( 1435 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1436 ): 1437 yumpkg.hold("foo") 1438 cmd.assert_called_once_with( 1439 ["yum", "versionlock", "foo"], 1440 env={}, 1441 output_loglevel="trace", 1442 python_shell=False, 1443 ) 1444 1445 1446def test_pkg_hold_tdnf(): 1447 """ 1448 Tests that we raise a SaltInvocationError if we try to use 1449 hold-related functions on Photon OS. 1450 """ 1451 with patch.dict(yumpkg.__context__, {"yum_bin": "tdnf"}): 1452 with pytest.raises(SaltInvocationError) as exc_info: 1453 yumpkg.hold("foo") 1454 1455 1456def test_pkg_hold_dnf(): 1457 """ 1458 Tests that we properly identify versionlock plugin when using dnf 1459 for RHEL/CentOS 8 and Fedora >= 22 1460 """ 1461 1462 # Test RHEL/CentOS 8 1463 list_pkgs_mock = { 1464 "python2-dnf-plugin-versionlock": "0:1.0.0-0.n.el8", 1465 "python3-dnf-plugin-versionlock": "0:1.0.0-0.n.el8", 1466 } 1467 1468 yumpkg.__context__.pop("yum_bin") 1469 cmd = MagicMock(return_value={"retcode": 0}) 1470 with patch.dict(yumpkg.__context__, {"yum_bin": "dnf"}), patch.dict( 1471 yumpkg.__grains__, {"osmajorrelease": 8} 1472 ), patch.object( 1473 yumpkg, "list_pkgs", MagicMock(return_value=list_pkgs_mock) 1474 ), patch.object( 1475 yumpkg, "list_holds", MagicMock(return_value=[]) 1476 ), patch.dict( 1477 yumpkg.__salt__, {"cmd.run_all": cmd} 1478 ), patch( 1479 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1480 ): 1481 yumpkg.hold("foo") 1482 cmd.assert_called_once_with( 1483 ["dnf", "versionlock", "foo"], 1484 env={}, 1485 output_loglevel="trace", 1486 python_shell=False, 1487 ) 1488 1489 # Test Fedora 26+ 1490 cmd = MagicMock(return_value={"retcode": 0}) 1491 with patch.dict(yumpkg.__context__, {"yum_bin": "dnf"}), patch.dict( 1492 yumpkg.__grains__, {"os": "Fedora", "osrelease": 26} 1493 ), patch.object( 1494 yumpkg, "list_pkgs", MagicMock(return_value=list_pkgs_mock) 1495 ), patch.object( 1496 yumpkg, "list_holds", MagicMock(return_value=[]) 1497 ), patch.dict( 1498 yumpkg.__salt__, {"cmd.run_all": cmd} 1499 ), patch( 1500 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1501 ): 1502 yumpkg.hold("foo") 1503 cmd.assert_called_once_with( 1504 ["dnf", "versionlock", "foo"], 1505 env={}, 1506 output_loglevel="trace", 1507 python_shell=False, 1508 ) 1509 1510 # Test Fedora 22-25 1511 list_pkgs_mock = { 1512 "python-dnf-plugins-extras-versionlock": "0:1.0.0-0.n.el8", 1513 "python3-dnf-plugins-extras-versionlock": "0:1.0.0-0.n.el8", 1514 } 1515 1516 cmd = MagicMock(return_value={"retcode": 0}) 1517 with patch.dict(yumpkg.__context__, {"yum_bin": "dnf"}), patch.dict( 1518 yumpkg.__grains__, {"os": "Fedora", "osrelease": 25} 1519 ), patch.object( 1520 yumpkg, "list_pkgs", MagicMock(return_value=list_pkgs_mock) 1521 ), patch.object( 1522 yumpkg, "list_holds", MagicMock(return_value=[]) 1523 ), patch.dict( 1524 yumpkg.__salt__, {"cmd.run_all": cmd} 1525 ), patch( 1526 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1527 ): 1528 yumpkg.hold("foo") 1529 cmd.assert_called_once_with( 1530 ["dnf", "versionlock", "foo"], 1531 env={}, 1532 output_loglevel="trace", 1533 python_shell=False, 1534 ) 1535 1536 1537@pytest.mark.skipif(not yumpkg.HAS_YUM, reason="Could not import yum") 1538def test_yum_base_error(): 1539 with patch("yum.YumBase") as mock_yum_yumbase: 1540 mock_yum_yumbase.side_effect = CommandExecutionError 1541 with pytest.raises(CommandExecutionError): 1542 yumpkg._get_yum_config() 1543 1544 1545def test_group_info(): 1546 """ 1547 Test yumpkg.group_info parsing 1548 """ 1549 expected = { 1550 "conditional": [], 1551 "default": ["qgnomeplatform", "xdg-desktop-portal-gtk"], 1552 "description": ( 1553 "GNOME is a highly intuitive and user friendly desktop environment." 1554 ), 1555 "group": "GNOME", 1556 "id": "gnome-desktop", 1557 "mandatory": [ 1558 "NetworkManager-libreswan-gnome", 1559 "PackageKit-command-not-found", 1560 "PackageKit-gtk3-module", 1561 "abrt-desktop", 1562 "at-spi2-atk", 1563 "at-spi2-core", 1564 "avahi", 1565 "baobab", 1566 "caribou", 1567 "caribou-gtk2-module", 1568 "caribou-gtk3-module", 1569 "cheese", 1570 "chrome-gnome-shell", 1571 "compat-cheese314", 1572 "control-center", 1573 "dconf", 1574 "empathy", 1575 "eog", 1576 "evince", 1577 "evince-nautilus", 1578 "file-roller", 1579 "file-roller-nautilus", 1580 "firewall-config", 1581 "firstboot", 1582 "fprintd-pam", 1583 "gdm", 1584 "gedit", 1585 "glib-networking", 1586 "gnome-bluetooth", 1587 "gnome-boxes", 1588 "gnome-calculator", 1589 "gnome-classic-session", 1590 "gnome-clocks", 1591 "gnome-color-manager", 1592 "gnome-contacts", 1593 "gnome-dictionary", 1594 "gnome-disk-utility", 1595 "gnome-font-viewer", 1596 "gnome-getting-started-docs", 1597 "gnome-icon-theme", 1598 "gnome-icon-theme-extras", 1599 "gnome-icon-theme-symbolic", 1600 "gnome-initial-setup", 1601 "gnome-packagekit", 1602 "gnome-packagekit-updater", 1603 "gnome-screenshot", 1604 "gnome-session", 1605 "gnome-session-xsession", 1606 "gnome-settings-daemon", 1607 "gnome-shell", 1608 "gnome-software", 1609 "gnome-system-log", 1610 "gnome-system-monitor", 1611 "gnome-terminal", 1612 "gnome-terminal-nautilus", 1613 "gnome-themes-standard", 1614 "gnome-tweak-tool", 1615 "gnome-user-docs", 1616 "gnome-weather", 1617 "gucharmap", 1618 "gvfs-afc", 1619 "gvfs-afp", 1620 "gvfs-archive", 1621 "gvfs-fuse", 1622 "gvfs-goa", 1623 "gvfs-gphoto2", 1624 "gvfs-mtp", 1625 "gvfs-smb", 1626 "initial-setup-gui", 1627 "libcanberra-gtk2", 1628 "libcanberra-gtk3", 1629 "libproxy-mozjs", 1630 "librsvg2", 1631 "libsane-hpaio", 1632 "metacity", 1633 "mousetweaks", 1634 "nautilus", 1635 "nautilus-sendto", 1636 "nm-connection-editor", 1637 "orca", 1638 "redhat-access-gui", 1639 "sane-backends-drivers-scanners", 1640 "seahorse", 1641 "setroubleshoot", 1642 "sushi", 1643 "totem", 1644 "totem-nautilus", 1645 "vinagre", 1646 "vino", 1647 "xdg-user-dirs-gtk", 1648 "yelp", 1649 ], 1650 "optional": [ 1651 "", 1652 "alacarte", 1653 "dconf-editor", 1654 "dvgrab", 1655 "fonts-tweak-tool", 1656 "gconf-editor", 1657 "gedit-plugins", 1658 "gnote", 1659 "libappindicator-gtk3", 1660 "seahorse-nautilus", 1661 "seahorse-sharing", 1662 "vim-X11", 1663 "xguest", 1664 ], 1665 "type": "package group", 1666 } 1667 cmd_out = """Group: GNOME 1668 Group-Id: gnome-desktop 1669 Description: GNOME is a highly intuitive and user friendly desktop environment. 1670 Mandatory Packages: 1671 =NetworkManager-libreswan-gnome 1672 =PackageKit-command-not-found 1673 =PackageKit-gtk3-module 1674 abrt-desktop 1675 =at-spi2-atk 1676 =at-spi2-core 1677 =avahi 1678 =baobab 1679 -caribou 1680 -caribou-gtk2-module 1681 -caribou-gtk3-module 1682 =cheese 1683 =chrome-gnome-shell 1684 =compat-cheese314 1685 =control-center 1686 =dconf 1687 =empathy 1688 =eog 1689 =evince 1690 =evince-nautilus 1691 =file-roller 1692 =file-roller-nautilus 1693 =firewall-config 1694 =firstboot 1695 fprintd-pam 1696 =gdm 1697 =gedit 1698 =glib-networking 1699 =gnome-bluetooth 1700 =gnome-boxes 1701 =gnome-calculator 1702 =gnome-classic-session 1703 =gnome-clocks 1704 =gnome-color-manager 1705 =gnome-contacts 1706 =gnome-dictionary 1707 =gnome-disk-utility 1708 =gnome-font-viewer 1709 =gnome-getting-started-docs 1710 =gnome-icon-theme 1711 =gnome-icon-theme-extras 1712 =gnome-icon-theme-symbolic 1713 =gnome-initial-setup 1714 =gnome-packagekit 1715 =gnome-packagekit-updater 1716 =gnome-screenshot 1717 =gnome-session 1718 =gnome-session-xsession 1719 =gnome-settings-daemon 1720 =gnome-shell 1721 =gnome-software 1722 =gnome-system-log 1723 =gnome-system-monitor 1724 =gnome-terminal 1725 =gnome-terminal-nautilus 1726 =gnome-themes-standard 1727 =gnome-tweak-tool 1728 =gnome-user-docs 1729 =gnome-weather 1730 =gucharmap 1731 =gvfs-afc 1732 =gvfs-afp 1733 =gvfs-archive 1734 =gvfs-fuse 1735 =gvfs-goa 1736 =gvfs-gphoto2 1737 =gvfs-mtp 1738 =gvfs-smb 1739 initial-setup-gui 1740 =libcanberra-gtk2 1741 =libcanberra-gtk3 1742 =libproxy-mozjs 1743 =librsvg2 1744 =libsane-hpaio 1745 =metacity 1746 =mousetweaks 1747 =nautilus 1748 =nautilus-sendto 1749 =nm-connection-editor 1750 =orca 1751 -redhat-access-gui 1752 =sane-backends-drivers-scanners 1753 =seahorse 1754 =setroubleshoot 1755 =sushi 1756 =totem 1757 =totem-nautilus 1758 =vinagre 1759 =vino 1760 =xdg-user-dirs-gtk 1761 =yelp 1762 Default Packages: 1763 =qgnomeplatform 1764 =xdg-desktop-portal-gtk 1765 Optional Packages: 1766 alacarte 1767 dconf-editor 1768 dvgrab 1769 fonts-tweak-tool 1770 gconf-editor 1771 gedit-plugins 1772 gnote 1773 libappindicator-gtk3 1774 seahorse-nautilus 1775 seahorse-sharing 1776 vim-X11 1777 xguest 1778 """ 1779 with patch.dict( 1780 yumpkg.__salt__, {"cmd.run_stdout": MagicMock(return_value=cmd_out)} 1781 ): 1782 info = yumpkg.group_info("@gnome-desktop") 1783 assert info == expected 1784 1785 1786def test_get_repo_with_existent_repo(list_repos_var): 1787 """ 1788 Test get_repo with an existent repository 1789 Expected return is a populated dictionary 1790 """ 1791 repo = "base-source" 1792 kwargs = { 1793 "baseurl": "http://vault.centos.org/centos/$releasever/os/Source/", 1794 "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7", 1795 "name": "CentOS-$releasever - Base Sources", 1796 "enabled": True, 1797 } 1798 parse_repo_file_return = ( 1799 "", 1800 { 1801 "base-source": { 1802 "baseurl": "http://vault.centos.org/centos/$releasever/os/Source/", 1803 "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7", 1804 "name": "CentOS-$releasever - Base Sources", 1805 "enabled": "1", 1806 } 1807 }, 1808 ) 1809 expected = { 1810 "baseurl": "http://vault.centos.org/centos/$releasever/os/Source/", 1811 "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7", 1812 "name": "CentOS-$releasever - Base Sources", 1813 "enabled": "1", 1814 } 1815 patch_list_repos = patch.object( 1816 yumpkg, "list_repos", autospec=True, return_value=list_repos_var 1817 ) 1818 patch_parse_repo_file = patch.object( 1819 yumpkg, 1820 "_parse_repo_file", 1821 autospec=True, 1822 return_value=parse_repo_file_return, 1823 ) 1824 1825 with patch_list_repos, patch_parse_repo_file: 1826 ret = yumpkg.get_repo(repo, **kwargs) 1827 assert ret == expected, ret 1828 1829 1830def test_get_repo_with_non_existent_repo(list_repos_var): 1831 """ 1832 Test get_repo with an non existent repository 1833 Expected return is an empty dictionary 1834 """ 1835 repo = "non-existent-repository" 1836 kwargs = { 1837 "baseurl": "http://fake.centos.org/centos/$releasever/os/Non-Existent/", 1838 "gpgkey": "file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7", 1839 "name": "CentOS-$releasever - Non-Existent Repository", 1840 "enabled": True, 1841 } 1842 expected = {} 1843 patch_list_repos = patch.object( 1844 yumpkg, "list_repos", autospec=True, return_value=list_repos_var 1845 ) 1846 1847 with patch_list_repos: 1848 ret = yumpkg.get_repo(repo, **kwargs) 1849 assert ret == expected, ret 1850 1851 1852def test_pkg_update_dnf(): 1853 """ 1854 Tests that the proper CLI options are added when obsoletes=False 1855 """ 1856 name = "foo" 1857 old = "1.2.2-1.fc31" 1858 new = "1.2.3-1.fc31" 1859 cmd_mock = MagicMock(return_value={"retcode": 0}) 1860 list_pkgs_mock = MagicMock(side_effect=[{name: old}, {name: new}]) 1861 parse_targets_mock = MagicMock(return_value=({"foo": None}, "repository")) 1862 with patch.dict( 1863 yumpkg.__salt__, 1864 {"cmd.run_all": cmd_mock, "pkg_resource.parse_targets": parse_targets_mock}, 1865 ), patch.object(yumpkg, "refresh_db", MagicMock()), patch.object( 1866 yumpkg, "list_pkgs", list_pkgs_mock 1867 ), patch.object( 1868 yumpkg, "_yum", MagicMock(return_value="dnf") 1869 ), patch( 1870 "salt.utils.systemd.has_scope", MagicMock(return_value=False) 1871 ): 1872 ret = yumpkg.update(name, setopt="obsoletes=0,plugins=0") 1873 expected = {name: {"old": old, "new": new}} 1874 assert ret == expected, ret 1875 1876 cmd_mock.assert_called_once_with( 1877 [ 1878 "dnf", 1879 "--quiet", 1880 "-y", 1881 "--setopt", 1882 "plugins=0", 1883 "--setopt", 1884 "obsoletes=False", 1885 "upgrade", 1886 "foo", 1887 ], 1888 env={}, 1889 output_loglevel="trace", 1890 python_shell=False, 1891 ) 1892 1893 1894def test_call_yum_default(): 1895 """ 1896 Call default Yum/Dnf. 1897 :return: 1898 """ 1899 with patch.dict(yumpkg.__context__, {"yum_bin": "fake-yum"}): 1900 with patch.dict( 1901 yumpkg.__salt__, 1902 {"cmd.run_all": MagicMock(), "config.get": MagicMock(return_value=False)}, 1903 ): 1904 yumpkg._call_yum(["-y", "--do-something"]) # pylint: disable=W0106 1905 yumpkg.__salt__["cmd.run_all"].assert_called_once_with( 1906 ["fake-yum", "-y", "--do-something"], 1907 env={}, 1908 output_loglevel="trace", 1909 python_shell=False, 1910 ) 1911 1912 1913@patch("salt.utils.systemd.has_scope", MagicMock(return_value=True)) 1914def test_call_yum_in_scope(): 1915 """ 1916 Call Yum/Dnf within the scope. 1917 :return: 1918 """ 1919 with patch.dict(yumpkg.__context__, {"yum_bin": "fake-yum"}): 1920 with patch.dict( 1921 yumpkg.__salt__, 1922 {"cmd.run_all": MagicMock(), "config.get": MagicMock(return_value=True)}, 1923 ): 1924 yumpkg._call_yum(["-y", "--do-something"]) # pylint: disable=W0106 1925 yumpkg.__salt__["cmd.run_all"].assert_called_once_with( 1926 ["systemd-run", "--scope", "fake-yum", "-y", "--do-something"], 1927 env={}, 1928 output_loglevel="trace", 1929 python_shell=False, 1930 ) 1931 1932 1933def test_call_yum_with_kwargs(): 1934 """ 1935 Call Yum/Dnf with the optinal keyword arguments. 1936 :return: 1937 """ 1938 with patch.dict(yumpkg.__context__, {"yum_bin": "fake-yum"}): 1939 with patch.dict( 1940 yumpkg.__salt__, 1941 {"cmd.run_all": MagicMock(), "config.get": MagicMock(return_value=False)}, 1942 ): 1943 yumpkg._call_yum( 1944 ["-y", "--do-something"], 1945 python_shell=True, 1946 output_loglevel="quiet", 1947 ignore_retcode=False, 1948 username="Darth Vader", 1949 ) # pylint: disable=W0106 1950 yumpkg.__salt__["cmd.run_all"].assert_called_once_with( 1951 ["fake-yum", "-y", "--do-something"], 1952 env={}, 1953 ignore_retcode=False, 1954 output_loglevel="quiet", 1955 python_shell=True, 1956 username="Darth Vader", 1957 ) 1958 1959 1960@pytest.mark.skipif(not salt.utils.systemd.booted(), reason="Requires systemd") 1961def test_services_need_restart(): 1962 """ 1963 Test that dnf needs-restarting output is parsed and 1964 salt.utils.systemd.pid_to_service is called as expected. 1965 """ 1966 expected = ["firewalld", "salt-minion"] 1967 1968 dnf_mock = Mock( 1969 return_value="123 : /usr/bin/firewalld\n456 : /usr/bin/salt-minion\n" 1970 ) 1971 systemd_mock = Mock(side_effect=["firewalld", "salt-minion"]) 1972 with patch("salt.modules.yumpkg._yum", Mock(return_value="dnf")): 1973 with patch.dict(yumpkg.__salt__, {"cmd.run_stdout": dnf_mock}), patch( 1974 "salt.utils.systemd.pid_to_service", systemd_mock 1975 ): 1976 assert sorted(yumpkg.services_need_restart()) == expected 1977 systemd_mock.assert_has_calls([call("123"), call("456")]) 1978 1979 1980def test_services_need_restart_requires_systemd(): 1981 """Test that yumpkg.services_need_restart raises an error if systemd is unavailable.""" 1982 with patch("salt.modules.yumpkg._yum", Mock(return_value="dnf")): 1983 with patch("salt.utils.systemd.booted", Mock(return_value=False)): 1984 pytest.raises(CommandExecutionError, yumpkg.services_need_restart) 1985 1986 1987def test_services_need_restart_requires_dnf(): 1988 """Test that yumpkg.services_need_restart raises an error if DNF is unavailable.""" 1989 with patch("salt.modules.yumpkg._yum", Mock(return_value="yum")): 1990 pytest.raises(CommandExecutionError, yumpkg.services_need_restart) 1991 1992 1993def test_61003_pkg_should_not_fail_when_target_not_in_old_pkgs(): 1994 patch_list_pkgs = patch( 1995 "salt.modules.yumpkg.list_pkgs", return_value={}, autospec=True 1996 ) 1997 patch_salt = patch.dict( 1998 yumpkg.__salt__, 1999 { 2000 "pkg_resource.parse_targets": Mock( 2001 return_value=[ 2002 { 2003 "fnord-this-is-not-actually-a-package": "fnord-this-is-not-actually-a-package-1.2.3" 2004 } 2005 ] 2006 ) 2007 }, 2008 ) 2009 with patch_list_pkgs, patch_salt: 2010 # During the 3004rc1 we discoverd that if list_pkgs was missing 2011 # packages that were returned by parse_targets that yumpkg.remove would 2012 # catch on fire. This ensures that won't go undetected again. 2013 yumpkg.remove() 2014