mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Add tests
This commit is contained in:
parent
608f7acfa2
commit
7c6d550123
8 changed files with 666 additions and 255 deletions
|
@ -20,6 +20,7 @@ log = logging.getLogger(__name__)
|
|||
|
||||
# Define the module's virtual name
|
||||
__virtualname__ = "wusa"
|
||||
__func_alias__ = {"list_": "list"}
|
||||
|
||||
|
||||
def __virtual__():
|
||||
|
@ -181,7 +182,7 @@ def uninstall(path, restart=False):
|
|||
return True
|
||||
|
||||
|
||||
def list():
|
||||
def list_():
|
||||
"""
|
||||
Get a list of updates installed on the machine
|
||||
|
||||
|
|
|
@ -26,9 +26,7 @@ def __virtual__():
|
|||
return __virtualname__
|
||||
|
||||
|
||||
def absent(
|
||||
name, query, include_store=False, frameworks=False, deprovision_only=False
|
||||
):
|
||||
def absent(name, query, include_store=False, frameworks=False, deprovision_only=False):
|
||||
"""
|
||||
Removes Microsoft Store packages from the system. If the package is part of
|
||||
a bundle, the entire bundle will be removed.
|
||||
|
@ -96,8 +94,9 @@ def absent(
|
|||
return ret
|
||||
|
||||
if __opts__["test"]:
|
||||
ret["changes"]["removed"] = matches
|
||||
ret["comment"] = "Matching apps will be removed"
|
||||
comment = ["The following apps will be removed:"]
|
||||
comment.extend(matches)
|
||||
ret["comment"] = "\n- ".join(comment)
|
||||
ret["result"] = None
|
||||
return ret
|
||||
|
||||
|
@ -106,7 +105,7 @@ def absent(
|
|||
query,
|
||||
include_store=include_store,
|
||||
frameworks=frameworks,
|
||||
deprovision_only=deprovision_only
|
||||
deprovision_only=deprovision_only,
|
||||
)
|
||||
|
||||
if status is None:
|
||||
|
|
216
tests/pytests/unit/modules/test_win_appx.py
Normal file
216
tests/pytests/unit/modules/test_win_appx.py
Normal file
|
@ -0,0 +1,216 @@
|
|||
import pytest
|
||||
|
||||
import salt.modules.win_appx as win_appx
|
||||
from tests.support.mock import MagicMock, patch
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.windows_whitelisted,
|
||||
pytest.mark.skip_unless_on_windows,
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def configure_loader_modules():
|
||||
return {win_appx: {}}
|
||||
|
||||
|
||||
def test__pkg_list_empty():
|
||||
assert win_appx._pkg_list("") is None
|
||||
|
||||
|
||||
def test__pkg_list_single():
|
||||
raw = {
|
||||
"Name": "MicrosoftTeams",
|
||||
"Version": "22042.702.1226.2352",
|
||||
"PackageFullName": "MicrosoftTeams_22042.702.1226.2352_x64__8wekyb3d8bbwe",
|
||||
"PackageFamilyName": "MicrosoftTeams_8wekyb3d8bbwe",
|
||||
}
|
||||
assert win_appx._pkg_list(raw=raw) == ["MicrosoftTeams"]
|
||||
|
||||
|
||||
def test__pkg_list_multiple():
|
||||
raw = [
|
||||
{
|
||||
"Name": "MicrosoftTeams",
|
||||
"Version": "22042.702.1226.2352",
|
||||
"PackageFullName": "MicrosoftTeams_22042.702.1226.2352_x64__8wekyb3d8bbwe",
|
||||
"PackageFamilyName": "MicrosoftTeams_8wekyb3d8bbwe",
|
||||
},
|
||||
{
|
||||
"Name": "Microsoft.BingWeather",
|
||||
"Version": "4.53.51361.0",
|
||||
"PackageFullName": "Microsoft.BingWeather_4.53.51361.0_x64__8wekyb3d8bbwe",
|
||||
"PackageFamilyName": "Microsoft.BingWeather_8wekyb3d8bbwe",
|
||||
},
|
||||
]
|
||||
assert win_appx._pkg_list(raw=raw) == ["MicrosoftTeams", "Microsoft.BingWeather"]
|
||||
|
||||
|
||||
def test__pkg_list_single_field():
|
||||
raw = {
|
||||
"Name": "MicrosoftTeams",
|
||||
"Version": "22042.702.1226.2352",
|
||||
"PackageFullName": "MicrosoftTeams_22042.702.1226.2352_x64__8wekyb3d8bbwe",
|
||||
"PackageFamilyName": "MicrosoftTeams_8wekyb3d8bbwe",
|
||||
}
|
||||
assert win_appx._pkg_list(raw=raw, field="PackageFamilyName") == [
|
||||
"MicrosoftTeams_8wekyb3d8bbwe"
|
||||
]
|
||||
|
||||
|
||||
def test__pkg_list_multiple_field():
|
||||
raw = [
|
||||
{
|
||||
"Name": "MicrosoftTeams",
|
||||
"Version": "22042.702.1226.2352",
|
||||
"PackageFullName": "MicrosoftTeams_22042.702.1226.2352_x64__8wekyb3d8bbwe",
|
||||
"PackageFamilyName": "MicrosoftTeams_8wekyb3d8bbwe",
|
||||
},
|
||||
{
|
||||
"Name": "Microsoft.BingWeather",
|
||||
"Version": "4.53.51361.0",
|
||||
"PackageFullName": "Microsoft.BingWeather_4.53.51361.0_x64__8wekyb3d8bbwe",
|
||||
"PackageFamilyName": "Microsoft.BingWeather_8wekyb3d8bbwe",
|
||||
},
|
||||
]
|
||||
assert win_appx._pkg_list(raw=raw, field="PackageFamilyName") == [
|
||||
"MicrosoftTeams_8wekyb3d8bbwe",
|
||||
"Microsoft.BingWeather_8wekyb3d8bbwe",
|
||||
]
|
||||
|
||||
|
||||
def test_list():
|
||||
mock_run_dict = MagicMock()
|
||||
with patch("salt.utils.win_pwsh.run_dict", mock_run_dict):
|
||||
win_appx.list_("*test*")
|
||||
cmd = [
|
||||
"Get-AppxPackage -AllUsers -PackageTypeFilter Bundle -Name *test*",
|
||||
'Where-Object {$_.name -notlike "Microsoft.WindowsStore*"}',
|
||||
"Where-Object -Property IsFramework -eq $false",
|
||||
"Where-Object -Property NonRemovable -eq $false",
|
||||
"Sort-Object Name",
|
||||
]
|
||||
mock_run_dict.assert_called_once_with(" | ".join(cmd))
|
||||
|
||||
|
||||
def test_list_field_none():
|
||||
mock_run_dict = MagicMock()
|
||||
with patch("salt.utils.win_pwsh.run_dict", mock_run_dict):
|
||||
win_appx.list_("*test*", field=None)
|
||||
cmd = [
|
||||
"Get-AppxPackage -AllUsers -PackageTypeFilter Bundle -Name *test*",
|
||||
'Where-Object {$_.name -notlike "Microsoft.WindowsStore*"}',
|
||||
"Where-Object -Property IsFramework -eq $false",
|
||||
"Where-Object -Property NonRemovable -eq $false",
|
||||
"Sort-Object Name",
|
||||
"Select Name, Version, PackageFullName, PackageFamilyName, IsBundle, IsFramework",
|
||||
]
|
||||
mock_run_dict.assert_called_once_with(" | ".join(cmd))
|
||||
|
||||
|
||||
def test_list_other_options_flipped():
|
||||
mock_run_dict = MagicMock()
|
||||
with patch("salt.utils.win_pwsh.run_dict", mock_run_dict):
|
||||
win_appx.list_("*test*", include_store=True, frameworks=True, bundles=False)
|
||||
cmd = [
|
||||
"Get-AppxPackage -AllUsers -Name *test*",
|
||||
"Where-Object -Property NonRemovable -eq $false",
|
||||
"Sort-Object Name",
|
||||
]
|
||||
mock_run_dict.assert_called_once_with(" | ".join(cmd))
|
||||
|
||||
|
||||
def test_remove():
|
||||
mock_run_dict = MagicMock()
|
||||
mock_list_return = {
|
||||
"Name": "Microsoft.BingWeather",
|
||||
"PackageFullName": "Microsoft.BingWeather_full_name",
|
||||
"IsBundle": True,
|
||||
}
|
||||
mock_list = MagicMock(return_value=mock_list_return)
|
||||
with patch("salt.utils.win_pwsh.run_dict", mock_run_dict), patch.object(
|
||||
win_appx, "list_", mock_list
|
||||
):
|
||||
assert win_appx.remove("*test*") is True
|
||||
cmd = "Remove-AppxPackage -AllUsers -Package Microsoft.BingWeather_full_name"
|
||||
mock_run_dict.assert_called_with(cmd)
|
||||
|
||||
|
||||
def test_remove_deprovision_only():
|
||||
mock_run_dict = MagicMock()
|
||||
mock_list_return = {
|
||||
"Name": "Microsoft.BingWeather",
|
||||
"PackageFullName": "Microsoft.BingWeather_full_name",
|
||||
"IsBundle": True,
|
||||
}
|
||||
mock_list = MagicMock(return_value=mock_list_return)
|
||||
with patch("salt.utils.win_pwsh.run_dict", mock_run_dict), patch.object(
|
||||
win_appx, "list_", mock_list
|
||||
):
|
||||
assert win_appx.remove("*test*", deprovision_only=True) is True
|
||||
cmd = "Remove-AppxProvisionedPackage -Online -PackageName Microsoft.BingWeather_full_name"
|
||||
mock_run_dict.assert_called_with(cmd)
|
||||
|
||||
|
||||
def test_remove_non_bundle():
|
||||
mock_run_dict = MagicMock()
|
||||
mock_list_return = [
|
||||
{
|
||||
"Name": "Microsoft.BingWeather",
|
||||
"PackageFullName": "Microsoft.BingWeather_non_bundle",
|
||||
"IsBundle": False,
|
||||
},
|
||||
{
|
||||
"Name": "Microsoft.BingWeather",
|
||||
"PackageFullName": "Microsoft.BingWeather_bundle",
|
||||
"IsBundle": True,
|
||||
},
|
||||
]
|
||||
mock_list = MagicMock(side_effect=mock_list_return)
|
||||
with patch("salt.utils.win_pwsh.run_dict", mock_run_dict), patch.object(
|
||||
win_appx, "list_", mock_list
|
||||
):
|
||||
assert win_appx.remove("*test*", deprovision_only=True) is True
|
||||
cmd = "Remove-AppxProvisionedPackage -Online -PackageName Microsoft.BingWeather_bundle"
|
||||
mock_run_dict.assert_called_with(cmd)
|
||||
|
||||
|
||||
def test_remove_not_found_empty_dict():
|
||||
mock_run_dict = MagicMock()
|
||||
mock_list_return = {}
|
||||
mock_list = MagicMock(return_value=mock_list_return)
|
||||
with patch("salt.utils.win_pwsh.run_dict", mock_run_dict), patch.object(
|
||||
win_appx, "list_", mock_list
|
||||
):
|
||||
assert win_appx.remove("*test*", deprovision_only=True) is None
|
||||
|
||||
|
||||
def test_remove_not_found_none():
|
||||
mock_run_dict = MagicMock()
|
||||
mock_list_return = None
|
||||
mock_list = MagicMock(return_value=mock_list_return)
|
||||
with patch("salt.utils.win_pwsh.run_dict", mock_run_dict), patch.object(
|
||||
win_appx, "list_", mock_list
|
||||
):
|
||||
assert win_appx.remove("*test*", deprovision_only=True) is None
|
||||
|
||||
|
||||
def test_list_deprovisioned():
|
||||
mock_list_keys = MagicMock(return_value=["Deprovisioned1", "Deprovisioned2"])
|
||||
with patch("salt.utils.win_reg.list_keys", mock_list_keys):
|
||||
expected = ["Deprovisioned1", "Deprovisioned2"]
|
||||
assert win_appx.list_deprovisioned() == expected
|
||||
|
||||
|
||||
def test_list_deprovisioned_query():
|
||||
mock_list_keys = MagicMock(return_value=["Deprovisioned1", "Deprovisioned2"])
|
||||
with patch("salt.utils.win_reg.list_keys", mock_list_keys):
|
||||
expected = ["Deprovisioned1"]
|
||||
assert win_appx.list_deprovisioned(query="*ed1*") == expected
|
||||
|
||||
|
||||
def test_install():
|
||||
mock_dism = MagicMock(return_value={"retcode": 0})
|
||||
with patch.dict(win_appx.__salt__, {"dism.add_provisioned_package": mock_dism}):
|
||||
assert win_appx.install("C:\\Test.appx") is True
|
||||
mock_dism.assert_called_once_with("C:\\Test.appx")
|
|
@ -46,9 +46,9 @@ def test_install():
|
|||
}
|
||||
|
||||
mock_reboot = MagicMock(return_value=True)
|
||||
with patch.object(
|
||||
win_servermanager, "_pshell_json", return_value=mock_out
|
||||
), patch.dict(win_servermanager.__salt__, {"system.reboot": mock_reboot}):
|
||||
with patch("salt.utils.win_pwsh.run_dict", return_value=mock_out), patch.dict(
|
||||
win_servermanager.__salt__, {"system.reboot": mock_reboot}
|
||||
):
|
||||
result = win_servermanager.install("XPS-Viewer")
|
||||
assert result == expected
|
||||
|
||||
|
@ -90,9 +90,9 @@ def test_install_restart():
|
|||
}
|
||||
|
||||
mock_reboot = MagicMock(return_value=True)
|
||||
with patch.object(
|
||||
win_servermanager, "_pshell_json", return_value=mock_out
|
||||
), patch.dict(win_servermanager.__salt__, {"system.reboot": mock_reboot}):
|
||||
with patch("salt.utils.win_pwsh.run_dict", return_value=mock_out), patch.dict(
|
||||
win_servermanager.__salt__, {"system.reboot": mock_reboot}
|
||||
):
|
||||
result = win_servermanager.install("XPS-Viewer", restart=True)
|
||||
mock_reboot.assert_called_once()
|
||||
assert result == expected
|
||||
|
|
245
tests/pytests/unit/modules/test_win_wusa.py
Normal file
245
tests/pytests/unit/modules/test_win_wusa.py
Normal file
|
@ -0,0 +1,245 @@
|
|||
"""
|
||||
Test the win_wusa execution module
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
import salt.modules.win_wusa as win_wusa
|
||||
from salt.exceptions import CommandExecutionError
|
||||
from tests.support.mock import MagicMock, patch
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.windows_whitelisted,
|
||||
pytest.mark.skip_unless_on_windows,
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def configure_loader_modules():
|
||||
return {win_wusa: {}}
|
||||
|
||||
|
||||
def test_is_installed_false():
|
||||
"""
|
||||
test is_installed function when the KB is not installed
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=1)
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
assert win_wusa.is_installed("KB123456") is False
|
||||
|
||||
|
||||
def test_is_installed_true():
|
||||
"""
|
||||
test is_installed function when the KB is installed
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
assert win_wusa.is_installed("KB123456") is True
|
||||
|
||||
|
||||
def test_list():
|
||||
"""
|
||||
test list function
|
||||
"""
|
||||
ret = [{"HotFixID": "KB123456"}, {"HotFixID": "KB123457"}]
|
||||
mock_all = MagicMock(return_value=ret)
|
||||
with patch("salt.utils.win_pwsh.run_dict", mock_all):
|
||||
expected = ["KB123456", "KB123457"]
|
||||
returned = win_wusa.list_()
|
||||
assert returned == expected
|
||||
|
||||
|
||||
def test_install():
|
||||
"""
|
||||
test install function
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
assert win_wusa.install(path) is True
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/norestart"], ignore_retcode=True
|
||||
)
|
||||
|
||||
|
||||
def test_install_restart():
|
||||
"""
|
||||
test install function with restart=True
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
assert win_wusa.install(path, restart=True) is True
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/forcerestart"], ignore_retcode=True
|
||||
)
|
||||
|
||||
|
||||
def test_install_already_installed():
|
||||
"""
|
||||
test install function when KB already installed
|
||||
"""
|
||||
retcode = 2359302
|
||||
mock_retcode = MagicMock(return_value=retcode)
|
||||
path = "C:\\KB123456.msu"
|
||||
name = "KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
with pytest.raises(CommandExecutionError) as excinfo:
|
||||
win_wusa.install(path)
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/norestart"], ignore_retcode=True
|
||||
)
|
||||
assert (
|
||||
f"{name} is already installed. Additional info follows:\n\n{retcode}"
|
||||
== excinfo.value.message
|
||||
)
|
||||
|
||||
|
||||
def test_install_reboot_needed():
|
||||
"""
|
||||
test install function when KB need a reboot
|
||||
"""
|
||||
retcode = 3010
|
||||
mock_retcode = MagicMock(return_value=retcode)
|
||||
path = "C:\\KB123456.msu"
|
||||
name = "KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
with pytest.raises(CommandExecutionError) as excinfo:
|
||||
win_wusa.install(path)
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/norestart"], ignore_retcode=True
|
||||
)
|
||||
assert (
|
||||
f"{name} correctly installed but server reboot is needed to complete installation. Additional info follows:\n\n{retcode}"
|
||||
== excinfo.value.message
|
||||
)
|
||||
|
||||
|
||||
def test_install_error_87():
|
||||
"""
|
||||
test install function when error 87 returned
|
||||
"""
|
||||
retcode = 87
|
||||
mock_retcode = MagicMock(return_value=retcode)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
with pytest.raises(CommandExecutionError) as excinfo:
|
||||
win_wusa.install(path)
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/norestart"], ignore_retcode=True
|
||||
)
|
||||
assert (
|
||||
f"Unknown error. Additional info follows:\n\n{retcode}" == excinfo.value.message
|
||||
)
|
||||
|
||||
|
||||
def test_install_error_other():
|
||||
"""
|
||||
test install function on other unknown error
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=1234)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
with pytest.raises(CommandExecutionError) as excinfo:
|
||||
win_wusa.install(path)
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/norestart"], ignore_retcode=True
|
||||
)
|
||||
assert "Unknown error: 1234" == excinfo.value.message
|
||||
|
||||
|
||||
def test_uninstall_kb():
|
||||
"""
|
||||
test uninstall function passing kb name
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
kb = "KB123456"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}), patch(
|
||||
"os.path.exists", MagicMock(return_value=False)
|
||||
):
|
||||
assert win_wusa.uninstall(kb) is True
|
||||
mock_retcode.assert_called_once_with(
|
||||
[
|
||||
"wusa.exe",
|
||||
"/uninstall",
|
||||
"/quiet",
|
||||
"/kb:{}".format(kb[2:]),
|
||||
"/norestart",
|
||||
],
|
||||
ignore_retcode=True,
|
||||
)
|
||||
|
||||
|
||||
def test_uninstall_path():
|
||||
"""
|
||||
test uninstall function passing full path to .msu file
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}), patch(
|
||||
"os.path.exists", MagicMock(return_value=True)
|
||||
):
|
||||
assert win_wusa.uninstall(path) is True
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", "/uninstall", "/quiet", path, "/norestart"],
|
||||
ignore_retcode=True,
|
||||
)
|
||||
|
||||
|
||||
def test_uninstall_path_restart():
|
||||
"""
|
||||
test uninstall function with full path and restart=True
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}), patch(
|
||||
"os.path.exists", MagicMock(return_value=True)
|
||||
):
|
||||
assert win_wusa.uninstall(path, restart=True) is True
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", "/uninstall", "/quiet", path, "/forcerestart"],
|
||||
ignore_retcode=True,
|
||||
)
|
||||
|
||||
|
||||
def test_uninstall_already_uninstalled():
|
||||
"""
|
||||
test uninstall function when KB already uninstalled
|
||||
"""
|
||||
retcode = 2359303
|
||||
mock_retcode = MagicMock(return_value=retcode)
|
||||
kb = "KB123456"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
with pytest.raises(CommandExecutionError) as excinfo:
|
||||
win_wusa.uninstall(kb)
|
||||
mock_retcode.assert_called_once_with(
|
||||
[
|
||||
"wusa.exe",
|
||||
"/uninstall",
|
||||
"/quiet",
|
||||
"/kb:{}".format(kb[2:]),
|
||||
"/norestart",
|
||||
],
|
||||
ignore_retcode=True,
|
||||
)
|
||||
assert (
|
||||
f"{kb} not installed. Additional info follows:\n\n{retcode}"
|
||||
== excinfo.value.message
|
||||
)
|
||||
|
||||
|
||||
def test_uninstall_path_error_other():
|
||||
"""
|
||||
test uninstall function with unknown error
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=1234)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}), patch(
|
||||
"os.path.exists", MagicMock(return_value=True)
|
||||
), pytest.raises(CommandExecutionError) as excinfo:
|
||||
win_wusa.uninstall(path)
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", "/uninstall", "/quiet", path, "/norestart"],
|
||||
ignore_retcode=True,
|
||||
)
|
||||
assert "Unknown error: 1234" == excinfo.value.message
|
86
tests/pytests/unit/states/test_win_appx.py
Normal file
86
tests/pytests/unit/states/test_win_appx.py
Normal file
|
@ -0,0 +1,86 @@
|
|||
import pytest
|
||||
|
||||
import salt.states.win_appx as win_appx
|
||||
from tests.support.mock import MagicMock, patch
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.windows_whitelisted,
|
||||
pytest.mark.skip_unless_on_windows,
|
||||
]
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def configure_loader_modules():
|
||||
return {win_appx: {}}
|
||||
|
||||
|
||||
def test_absent_missing():
|
||||
expected = {
|
||||
"comment": "No apps found matching query: *candy*",
|
||||
"changes": {},
|
||||
"name": "remove_candy",
|
||||
"result": True,
|
||||
}
|
||||
mock_list = MagicMock(return_value=["package1", "package2"])
|
||||
with patch.dict(win_appx.__salt__, {"appx.list": mock_list}):
|
||||
result = win_appx.absent("remove_candy", "*candy*")
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_absent_test_true():
|
||||
expected = {
|
||||
"comment": "The following apps will be removed:\n- king.com.CandyCrush",
|
||||
"changes": {},
|
||||
"name": "remove_candy",
|
||||
"result": None,
|
||||
}
|
||||
mock_list = MagicMock(return_value=["package1", "king.com.CandyCrush"])
|
||||
with patch.dict(win_appx.__salt__, {"appx.list": mock_list}):
|
||||
with patch.dict(win_appx.__opts__, {"test": True}):
|
||||
result = win_appx.absent("remove_candy", "*candy*")
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_absent_missing_after_test():
|
||||
expected = {
|
||||
"comment": "No apps found matching query: *candy*",
|
||||
"changes": {},
|
||||
"name": "remove_candy",
|
||||
"result": False,
|
||||
}
|
||||
mock_list = MagicMock(return_value=["package1", "king.com.CandyCrush"])
|
||||
with patch.dict(
|
||||
win_appx.__salt__,
|
||||
{
|
||||
"appx.list": mock_list,
|
||||
"appx.remove": MagicMock(return_value=None),
|
||||
},
|
||||
):
|
||||
with patch.dict(win_appx.__opts__, {"test": False}):
|
||||
result = win_appx.absent("remove_candy", "*candy*")
|
||||
assert result == expected
|
||||
|
||||
|
||||
def test_absent():
|
||||
expected = {
|
||||
"comment": "Removed apps matching query: *candy*",
|
||||
"changes": {"old": ["king.com.CandyCrush"]},
|
||||
"name": "remove_candy",
|
||||
"result": True,
|
||||
}
|
||||
mock_list = MagicMock(
|
||||
side_effect=(
|
||||
["package1", "king.com.CandyCrush"],
|
||||
["package1"],
|
||||
),
|
||||
)
|
||||
with patch.dict(
|
||||
win_appx.__salt__,
|
||||
{
|
||||
"appx.list": mock_list,
|
||||
"appx.remove": MagicMock(return_value=True),
|
||||
},
|
||||
):
|
||||
with patch.dict(win_appx.__opts__, {"test": False}):
|
||||
result = win_appx.absent("remove_candy", "*candy*")
|
||||
assert result == expected
|
106
tests/pytests/unit/utils/test_win_pwsh.py
Normal file
106
tests/pytests/unit/utils/test_win_pwsh.py
Normal file
|
@ -0,0 +1,106 @@
|
|||
import pytest
|
||||
|
||||
import salt.utils.win_pwsh as win_pwsh
|
||||
from salt.exceptions import CommandExecutionError
|
||||
from tests.support.mock import MagicMock, patch
|
||||
|
||||
pytestmark = [
|
||||
pytest.mark.windows_whitelisted,
|
||||
pytest.mark.skip_unless_on_windows,
|
||||
]
|
||||
|
||||
|
||||
def test_run_dict():
|
||||
"""
|
||||
Tests the run_dict function
|
||||
"""
|
||||
result = win_pwsh.run_dict("Get-Item C:\\Windows")
|
||||
assert result["Name"] == "Windows"
|
||||
assert result["FullName"] == "C:\\Windows"
|
||||
|
||||
|
||||
def test_run_dict_json_string():
|
||||
"""
|
||||
Tests the run_dict function with json string
|
||||
"""
|
||||
ret = {
|
||||
"pid": 1,
|
||||
"retcode": 0,
|
||||
"stderr": "",
|
||||
"stdout": '[{"HotFixID": "KB123456"}, {"HotFixID": "KB123457"}]',
|
||||
}
|
||||
mock_all = MagicMock(return_value=ret)
|
||||
with patch.dict(win_pwsh.__salt__, {"cmd.run_all": mock_all}):
|
||||
result = win_pwsh.run_dict("Junk-Command")
|
||||
assert result == [{"HotFixID": "KB123456"}, {"HotFixID": "KB123457"}]
|
||||
|
||||
|
||||
def test_run_dict_empty_return():
|
||||
"""
|
||||
Tests the run_dict function with json string
|
||||
"""
|
||||
ret = {
|
||||
"pid": 1,
|
||||
"retcode": 0,
|
||||
"stderr": "",
|
||||
"stdout": "",
|
||||
}
|
||||
mock_all = MagicMock(return_value=ret)
|
||||
with patch.dict(win_pwsh.__salt__, {"cmd.run_all": mock_all}):
|
||||
result = win_pwsh.run_dict("Junk-Command")
|
||||
assert result == {}
|
||||
|
||||
|
||||
def test_run_dict_stderr():
|
||||
ret = {
|
||||
"pid": 1,
|
||||
"retcode": 1,
|
||||
"stderr": "This is an error",
|
||||
"stdout": "",
|
||||
}
|
||||
mock_all = MagicMock(return_value=ret)
|
||||
with patch.dict(win_pwsh.__salt__, {"cmd.run_all": mock_all}):
|
||||
with pytest.raises(CommandExecutionError) as exc_info:
|
||||
win_pwsh.run_dict("Junk-Command")
|
||||
assert "This is an error" in exc_info.value.message
|
||||
|
||||
|
||||
def test_run_dict_missing_retcode():
|
||||
ret = {
|
||||
"pid": 1,
|
||||
"stderr": "",
|
||||
"stdout": "",
|
||||
}
|
||||
mock_all = MagicMock(return_value=ret)
|
||||
with patch.dict(win_pwsh.__salt__, {"cmd.run_all": mock_all}):
|
||||
with pytest.raises(CommandExecutionError) as exc_info:
|
||||
win_pwsh.run_dict("Junk-Command")
|
||||
assert "Issue executing PowerShell" in exc_info.value.message
|
||||
|
||||
|
||||
def test_run_dict_retcode_not_zero():
|
||||
ret = {
|
||||
"pid": 1,
|
||||
"retcode": 1,
|
||||
"stderr": "",
|
||||
"stdout": "",
|
||||
}
|
||||
mock_all = MagicMock(return_value=ret)
|
||||
with patch.dict(win_pwsh.__salt__, {"cmd.run_all": mock_all}):
|
||||
with pytest.raises(CommandExecutionError) as exc_info:
|
||||
win_pwsh.run_dict("Junk-Command")
|
||||
assert "Issue executing PowerShell" in exc_info.value.message
|
||||
|
||||
|
||||
def test_run_dict_invalid_json():
|
||||
ret = {
|
||||
"pid": 1,
|
||||
"retcode": 0,
|
||||
"stderr": "",
|
||||
"stdout": "Invalid Json",
|
||||
}
|
||||
mock_all = MagicMock(return_value=ret)
|
||||
with patch.dict(win_pwsh.__salt__, {"cmd.run_all": mock_all}):
|
||||
with pytest.raises(CommandExecutionError) as exc_info:
|
||||
win_pwsh.run_dict("Junk-Command")
|
||||
assert "No JSON results from PowerShell" in exc_info.value.message
|
|
@ -1,242 +0,0 @@
|
|||
"""
|
||||
Test the win_wusa execution module
|
||||
"""
|
||||
|
||||
import pytest
|
||||
|
||||
import salt.modules.win_wusa as win_wusa
|
||||
from salt.exceptions import CommandExecutionError
|
||||
from tests.support.mixins import LoaderModuleMockMixin
|
||||
from tests.support.mock import MagicMock, patch
|
||||
from tests.support.unit import TestCase
|
||||
|
||||
|
||||
@pytest.mark.skip_unless_on_windows
|
||||
class WinWusaTestCase(TestCase, LoaderModuleMockMixin):
|
||||
"""
|
||||
test the functions in the win_wusa execution module
|
||||
"""
|
||||
|
||||
def setup_loader_modules(self):
|
||||
return {win_wusa: {}}
|
||||
|
||||
def test_is_installed_false(self):
|
||||
"""
|
||||
test is_installed function when the KB is not installed
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=1)
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
self.assertFalse(win_wusa.is_installed("KB123456"))
|
||||
|
||||
def test_is_installed_true(self):
|
||||
"""
|
||||
test is_installed function when the KB is installed
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
self.assertTrue(win_wusa.is_installed("KB123456"))
|
||||
|
||||
def test_list(self):
|
||||
"""
|
||||
test list function
|
||||
"""
|
||||
ret = {
|
||||
"pid": 1,
|
||||
"retcode": 0,
|
||||
"stderr": "",
|
||||
"stdout": '[{"HotFixID": "KB123456"}, {"HotFixID": "KB123457"}]',
|
||||
}
|
||||
mock_all = MagicMock(return_value=ret)
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.run_all": mock_all}):
|
||||
expected = ["KB123456", "KB123457"]
|
||||
returned = win_wusa.list()
|
||||
self.assertListEqual(expected, returned)
|
||||
|
||||
def test_install(self):
|
||||
"""
|
||||
test install function
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
self.assertTrue(win_wusa.install(path))
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/norestart"], ignore_retcode=True
|
||||
)
|
||||
|
||||
def test_install_restart(self):
|
||||
"""
|
||||
test install function with restart=True
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
self.assertTrue(win_wusa.install(path, restart=True))
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/forcerestart"], ignore_retcode=True
|
||||
)
|
||||
|
||||
def test_install_already_installed(self):
|
||||
"""
|
||||
test install function when KB already installed
|
||||
"""
|
||||
retcode = 2359302
|
||||
mock_retcode = MagicMock(return_value=retcode)
|
||||
path = "C:\\KB123456.msu"
|
||||
name = "KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
with self.assertRaises(CommandExecutionError) as excinfo:
|
||||
win_wusa.install(path)
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/norestart"], ignore_retcode=True
|
||||
)
|
||||
self.assertEqual(
|
||||
"{} is already installed. Additional info follows:\n\n{}".format(
|
||||
name, retcode
|
||||
),
|
||||
excinfo.exception.strerror,
|
||||
)
|
||||
|
||||
def test_install_reboot_needed(self):
|
||||
"""
|
||||
test install function when KB need a reboot
|
||||
"""
|
||||
retcode = 3010
|
||||
mock_retcode = MagicMock(return_value=retcode)
|
||||
path = "C:\\KB123456.msu"
|
||||
name = "KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
with self.assertRaises(CommandExecutionError) as excinfo:
|
||||
win_wusa.install(path)
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/norestart"], ignore_retcode=True
|
||||
)
|
||||
self.assertEqual(
|
||||
"{} correctly installed but server reboot is needed to complete"
|
||||
" installation. Additional info follows:\n\n{}".format(name, retcode),
|
||||
excinfo.exception.strerror,
|
||||
)
|
||||
|
||||
def test_install_error_87(self):
|
||||
"""
|
||||
test install function when error 87 returned
|
||||
"""
|
||||
retcode = 87
|
||||
mock_retcode = MagicMock(return_value=retcode)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
with self.assertRaises(CommandExecutionError) as excinfo:
|
||||
win_wusa.install(path)
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/norestart"], ignore_retcode=True
|
||||
)
|
||||
self.assertEqual(
|
||||
"Unknown error. Additional info follows:\n\n{}".format(retcode),
|
||||
excinfo.exception.strerror,
|
||||
)
|
||||
|
||||
def test_install_error_other(self):
|
||||
"""
|
||||
test install function on other unknown error
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=1234)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
with self.assertRaises(CommandExecutionError) as excinfo:
|
||||
win_wusa.install(path)
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", path, "/quiet", "/norestart"], ignore_retcode=True
|
||||
)
|
||||
self.assertEqual("Unknown error: 1234", excinfo.exception.strerror)
|
||||
|
||||
def test_uninstall_kb(self):
|
||||
"""
|
||||
test uninstall function passing kb name
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
kb = "KB123456"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}), patch(
|
||||
"os.path.exists", MagicMock(return_value=False)
|
||||
):
|
||||
self.assertTrue(win_wusa.uninstall(kb))
|
||||
mock_retcode.assert_called_once_with(
|
||||
[
|
||||
"wusa.exe",
|
||||
"/uninstall",
|
||||
"/quiet",
|
||||
"/kb:{}".format(kb[2:]),
|
||||
"/norestart",
|
||||
],
|
||||
ignore_retcode=True,
|
||||
)
|
||||
|
||||
def test_uninstall_path(self):
|
||||
"""
|
||||
test uninstall function passing full path to .msu file
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}), patch(
|
||||
"os.path.exists", MagicMock(return_value=True)
|
||||
):
|
||||
self.assertTrue(win_wusa.uninstall(path))
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", "/uninstall", "/quiet", path, "/norestart"],
|
||||
ignore_retcode=True,
|
||||
)
|
||||
|
||||
def test_uninstall_path_restart(self):
|
||||
"""
|
||||
test uninstall function with full path and restart=True
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=0)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}), patch(
|
||||
"os.path.exists", MagicMock(return_value=True)
|
||||
):
|
||||
self.assertTrue(win_wusa.uninstall(path, restart=True))
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", "/uninstall", "/quiet", path, "/forcerestart"],
|
||||
ignore_retcode=True,
|
||||
)
|
||||
|
||||
def test_uninstall_already_uninstalled(self):
|
||||
"""
|
||||
test uninstall function when KB already uninstalled
|
||||
"""
|
||||
retcode = 2359303
|
||||
mock_retcode = MagicMock(return_value=retcode)
|
||||
kb = "KB123456"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}):
|
||||
with self.assertRaises(CommandExecutionError) as excinfo:
|
||||
win_wusa.uninstall(kb)
|
||||
mock_retcode.assert_called_once_with(
|
||||
[
|
||||
"wusa.exe",
|
||||
"/uninstall",
|
||||
"/quiet",
|
||||
"/kb:{}".format(kb[2:]),
|
||||
"/norestart",
|
||||
],
|
||||
ignore_retcode=True,
|
||||
)
|
||||
self.assertEqual(
|
||||
"{} not installed. Additional info follows:\n\n{}".format(kb, retcode),
|
||||
excinfo.exception.strerror,
|
||||
)
|
||||
|
||||
def test_uninstall_path_error_other(self):
|
||||
"""
|
||||
test uninstall function with unknown error
|
||||
"""
|
||||
mock_retcode = MagicMock(return_value=1234)
|
||||
path = "C:\\KB123456.msu"
|
||||
with patch.dict(win_wusa.__salt__, {"cmd.retcode": mock_retcode}), patch(
|
||||
"os.path.exists", MagicMock(return_value=True)
|
||||
), self.assertRaises(CommandExecutionError) as excinfo:
|
||||
win_wusa.uninstall(path)
|
||||
mock_retcode.assert_called_once_with(
|
||||
["wusa.exe", "/uninstall", "/quiet", path, "/norestart"],
|
||||
ignore_retcode=True,
|
||||
)
|
||||
self.assertEqual("Unknown error: 1234", excinfo.exception.strerror)
|
Loading…
Add table
Reference in a new issue