/
githubmirror
/
salt
Обзор
Документация
Войти
/
githubmirror
/
salt
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
tests/unit/modules/test_win_system.py
675 строк
22 KB
Pedro Algarvio
Update pre-commit hook versions
29 фев 2024, 15:30
Не верифицирован
29 фев 2024, 15:30
f454911
Код
Авторство
О чём код?
""" :codeauthor: Rahul Handay <rahulha@saltstack.com> """ import types from datetime import datetime import pytest import salt.modules.win_system as win_system import salt.utils.platform import salt.utils.stringutils from tests.support.mixins import LoaderModuleMockMixin from tests.support.mock import MagicMock, Mock, patch from tests.support.unit import TestCase try: import wmi HAS_WMI = True except ImportError: HAS_WMI = False class MockWMI_ComputerSystem: """ Mock WMI Win32_ComputerSystem Class """ BootupState = "Normal boot" Caption = "SALT SERVER" ChassisBootupState = 3 ChassisSKUNumber = "3.14159" DNSHostname = "SALT SERVER" Domain = "WORKGROUP" DomainRole = 2 Manufacturer = "Dell Inc." Model = "Dell 2980" NetworkServerModeEnabled = True PartOfDomain = False PCSystemType = 4 PowerState = 0 Status = "OK" SystemType = "x64-based PC" TotalPhysicalMemory = 17078214656 ThermalState = 3 Workgroup = "WORKGROUP" def __init__(self): pass @staticmethod def Rename(Name): return Name == Name @staticmethod def JoinDomainOrWorkgroup(Name): return [0] @staticmethod def UnjoinDomainOrWorkgroup(Password, UserName, FUnjoinOptions): return [0] class MockWMI_OperatingSystem: """ Mock WMI Win32_OperatingSystem Class """ Description = "Because salt goes EVERYWHERE" InstallDate = "20110211131800" LastBootUpTime = "19620612120000" Manufacturer = "Python" Caption = "Salty" NumberOfUsers = 7530000000 Organization = "SaltStack" OSArchitecture = "Windows" Primary = True ProductType = 3 RegisteredUser = "thatch@saltstack.com" SystemDirectory = "C:\\Windows\\System32" SystemDrive = "C:\\" Version = "10.0.17763" WindowsDirectory = "C:\\Windows" def __init__(self): pass class MockWMI_ComputerSystemProduct: def __init__(self): self.SKUNumber = None class MockWMI_Processor: """ Mock WMI Win32_Processor Class """ Manufacturer = "Intel" MaxClockSpeed = 2301 NumberOfLogicalProcessors = 8 NumberOfCores = 4 NumberOfEnabledCore = 4 def __init__(self): pass class MockWMI_BIOS: """ Mock WMI Win32_BIOS Class """ SerialNumber = "SALTY2011" Manufacturer = "Dell Inc." Version = "DELL - 10283849" Caption = "A12" BIOSVersion = [Version, Caption, "ASUS - 3948D"] Description = Caption def __init__(self): pass @pytest.mark.skipif(not HAS_WMI, reason="WMI only available on Windows") @pytest.mark.skip_unless_on_windows class WinSystemTestCase(TestCase, LoaderModuleMockMixin): """ Test cases for salt.modules.win_system """ def setup_loader_modules(self): modules_globals = {} # wmi and pythoncom modules are platform specific... mock_pythoncom = types.ModuleType(salt.utils.stringutils.to_str("pythoncom")) sys_modules_patcher = patch.dict("sys.modules", {"pythoncom": mock_pythoncom}) sys_modules_patcher.start() self.addCleanup(sys_modules_patcher.stop) self.WMI = Mock() self.addCleanup(delattr, self, "WMI") modules_globals["wmi"] = wmi if win_system.HAS_WIN32NET_MODS is False: win32api = types.ModuleType("win32api") now = datetime.now() win32api.GetLocalTime = MagicMock( return_value=[ now.year, now.month, now.weekday(), now.day, now.hour, now.minute, now.second, now.microsecond, ] ) modules_globals["win32api"] = win32api win32net = types.ModuleType("win32net") win32net.NetServerGetInfo = MagicMock() win32net.NetServerSetInfo = MagicMock() modules_globals["win32net"] = win32net return {win_system: modules_globals} def test_halt(self): """ Test to halt a running system """ mock = MagicMock(return_value="salt") with patch.object(win_system, "shutdown", mock): self.assertEqual(win_system.halt(), "salt") def test_init(self): """ Test to change the system runlevel on sysV compatible systems """ self.assertEqual(win_system.init(3), "Not implemented on Windows at this time.") @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_poweroff(self): """ Test to poweroff a running system """ mock = MagicMock(return_value="salt") with patch.object(win_system, "shutdown", mock): self.assertEqual(win_system.poweroff(), "salt") @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_reboot(self): """ Test to reboot the system """ with patch("salt.modules.win_system.shutdown", MagicMock(return_value=True)): self.assertEqual(win_system.reboot(), True) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_reboot_with_timeout_in_minutes(self): """ Test to reboot the system with a timeout """ with patch( "salt.modules.win_system.shutdown", MagicMock(return_value=True) ) as shutdown: self.assertEqual(win_system.reboot(5, in_seconds=False), True) shutdown.assert_called_with( timeout=5, in_seconds=False, reboot=True, only_on_pending_reboot=False ) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_reboot_with_timeout_in_seconds(self): """ Test to reboot the system with a timeout """ with patch( "salt.modules.win_system.shutdown", MagicMock(return_value=True) ) as shutdown: self.assertEqual(win_system.reboot(5, in_seconds=True), True) shutdown.assert_called_with( timeout=5, in_seconds=True, reboot=True, only_on_pending_reboot=False ) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_reboot_with_wait(self): """ Test to reboot the system with a timeout and wait for it to finish """ with patch( "salt.modules.win_system.shutdown", MagicMock(return_value=True) ), patch("salt.modules.win_system.time.sleep", MagicMock()) as time: self.assertEqual(win_system.reboot(wait_for_reboot=True), True) time.assert_called_with(330) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_shutdown(self): """ Test to shutdown a running system """ with patch( "salt.modules.win_system.win32api.InitiateSystemShutdown", MagicMock() ): self.assertEqual(win_system.shutdown(), True) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_shutdown_hard(self): """ Test to shutdown a running system with no timeout or warning """ with patch( "salt.modules.win_system.shutdown", MagicMock(return_value=True) ) as shutdown: self.assertEqual(win_system.shutdown_hard(), True) shutdown.assert_called_with(timeout=0) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_set_computer_name(self): """ Test to set the Windows computer name """ with patch( "salt.modules.win_system.windll.kernel32.SetComputerNameExW", MagicMock(return_value=True), ), patch.object( win_system, "get_computer_name", MagicMock(return_value="salt") ), patch.object( win_system, "get_pending_computer_name", MagicMock(return_value="salt_new"), ): self.assertDictEqual( win_system.set_computer_name("salt_new"), {"Computer Name": {"Current": "salt", "Pending": "salt_new"}}, ) # Test set_computer_name failure with patch( "salt.modules.win_system.windll.kernel32.SetComputerNameExW", MagicMock(return_value=False), ): self.assertFalse(win_system.set_computer_name("salt")) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_set_computer_desc(self): """ Test to set the Windows computer description """ mock = MagicMock() mock_get_info = MagicMock(return_value={"comment": ""}) mock_get_desc = MagicMock(return_value="Salt's comp") with patch( "salt.modules.win_system.win32net.NetServerGetInfo", mock_get_info ), patch( "salt.modules.win_system.win32net.NetServerSetInfo", mock ), patch.object( win_system, "get_computer_desc", mock_get_desc ): self.assertDictEqual( win_system.set_computer_desc("Salt's comp"), {"Computer Description": "Salt's comp"}, ) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_get_computer_desc(self): """ Test to get the Windows computer description """ with patch( "salt.modules.win_system.get_system_info", MagicMock( side_effect=[{"description": "salt description"}, {"description": None}] ), ): self.assertEqual(win_system.get_computer_desc(), "salt description") self.assertFalse(win_system.get_computer_desc()) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_join_domain(self): """ Test to join a computer to an Active Directory domain """ with patch( "salt.modules.win_system._join_domain", MagicMock(return_value=0) ), patch( "salt.modules.win_system.get_domain_workgroup", MagicMock(return_value={"Workgroup": "Workgroup"}), ): self.assertDictEqual( win_system.join_domain("saltstack", "salt", "salt@123"), {"Domain": "saltstack", "Restart": False}, ) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_join_domain_already_joined(self): """ Test to join a computer to an Active Directory domain when it is already joined """ with patch( "salt.modules.win_system._join_domain", MagicMock(return_value=0) ), patch( "salt.modules.win_system.get_domain_workgroup", MagicMock(return_value={"Domain": "saltstack"}), ): self.assertEqual( win_system.join_domain("saltstack", "salt", "salt@123"), "Already joined to saltstack", ) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_unjoin_domain(self): """ Test unjoining a computer from an Active Directory domain """ with patch("salt.utils.winapi.Com", MagicMock()), patch.object( self.WMI, "Win32_ComputerSystem", return_value=[MockWMI_ComputerSystem()] ), patch.object(wmi, "WMI", Mock(return_value=self.WMI)), patch( "salt.modules.win_system.get_domain_workgroup", MagicMock(return_value={"Domain": "contoso.com"}), ): self.assertDictEqual( win_system.unjoin_domain(), {"Workgroup": "WORKGROUP", "Restart": False}, ) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_unjoin_domain_already_unjoined(self): """ Test unjoining a computer from an Active Directory domain """ with patch("salt.utils.winapi.Com", MagicMock()), patch.object( self.WMI, "Win32_ComputerSystem", return_value=[MockWMI_ComputerSystem()] ), patch.object(wmi, "WMI", Mock(return_value=self.WMI)), patch( "salt.modules.win_system.get_domain_workgroup", MagicMock(return_value={"Workgroup": "WORKGROUP"}), ): self.assertEqual(win_system.unjoin_domain(), "Already joined to WORKGROUP") def test_get_system_time(self): """ Test to get system time """ tm = datetime.strftime(datetime.now(), "%I:%M:%S %p") win_tm = win_system.get_system_time() try: self.assertEqual(win_tm, tm) except AssertionError: # handle race condition import re self.assertTrue(re.search(r"^\d{2}:\d{2} \w{2}$", win_tm)) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_set_system_time(self): """ Test to set system time """ with patch( "salt.modules.win_system.set_system_date_time", MagicMock(side_effect=[False, True]), ): self.assertFalse(win_system.set_system_time("11:31:15 AM")) self.assertTrue(win_system.set_system_time("11:31:15 AM")) def test_get_system_date(self): """ Test to get system date """ date = datetime.strftime(datetime.now(), "%m/%d/%Y") self.assertEqual(win_system.get_system_date(), date) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_set_system_date(self): """ Test to set system date """ with patch( "salt.modules.win_system.set_system_date_time", MagicMock(side_effect=[False, True]), ): self.assertFalse(win_system.set_system_date("03-28-13")) self.assertTrue(win_system.set_system_date("03-28-13")) def test_start_time_service(self): """ Test to start the Windows time service """ mock = MagicMock(return_value=True) with patch.dict(win_system.__salt__, {"service.start": mock}): self.assertTrue(win_system.start_time_service()) def test_stop_time_service(self): """ Test to stop the windows time service """ mock = MagicMock(return_value=True) with patch.dict(win_system.__salt__, {"service.stop": mock}): self.assertTrue(win_system.stop_time_service()) def test_set_hostname(self): """ Test setting a new hostname """ with patch("salt.utils.winapi.Com", MagicMock()), patch.object( self.WMI, "Win32_ComputerSystem", return_value=[MockWMI_ComputerSystem()] ), patch.object(wmi, "WMI", Mock(return_value=self.WMI)): self.assertTrue(win_system.set_hostname("NEW")) def test_get_domain_workgroup(self): """ Test get_domain_workgroup """ with patch.object(wmi, "WMI", Mock(return_value=self.WMI)), patch( "salt.utils.winapi.Com", MagicMock() ), patch.object( self.WMI, "Win32_ComputerSystem", return_value=[MockWMI_ComputerSystem()] ): self.assertDictEqual( win_system.get_domain_workgroup(), {"Workgroup": "WORKGROUP"} ) def test_set_domain_workgroup(self): """ Test set_domain_workgroup """ with patch.object(wmi, "WMI", Mock(return_value=self.WMI)), patch( "salt.utils.winapi.Com", MagicMock() ), patch.object( self.WMI, "Win32_ComputerSystem", return_value=[MockWMI_ComputerSystem()] ): self.assertTrue(win_system.set_domain_workgroup("test")) def test_get_hostname(self): """ Test getting a new hostname """ cmd_run_mock = MagicMock(return_value="MINION") with patch.dict(win_system.__salt__, {"cmd.run": cmd_run_mock}): ret = win_system.get_hostname() self.assertEqual(ret, "MINION") cmd_run_mock.assert_called_once_with(cmd="hostname") @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_get_system_info(self): fields = [ "bios_caption", "bios_description", "bios_details", "bios_manufacturer", "bios_version", "bootup_state", "caption", "chassis_bootup_state", "chassis_sku_number", "description", "dns_hostname", "domain", "domain_role", "hardware_manufacturer", "hardware_model", "hardware_serial", "install_date", "last_boot", "name", "network_server_mode_enabled", "organization", "os_architecture", "os_manufacturer", "os_name", "os_type", "os_version", "part_of_domain", "pc_system_type", "power_state", "primary", "processor_cores", "processor_cores_enabled", "processor_manufacturer", "processor_max_clock_speed", "processors", "processors_logical", "registered_user", "status", "system_directory", "system_drive", "system_type", "thermal_state", "total_physical_memory", "total_physical_memory_raw", "users", "windows_directory", "workgroup", ] with patch("salt.utils.win_system.get_computer_name", MagicMock()), patch( "salt.utils.winapi.Com", MagicMock() ), patch.object( self.WMI, "Win32_OperatingSystem", return_value=[MockWMI_OperatingSystem()] ), patch.object( self.WMI, "Win32_ComputerSystem", return_value=[MockWMI_ComputerSystem()] ), patch.object( self.WMI, "Win32_ComputerSystemProduct", return_value=[MockWMI_ComputerSystemProduct()], ), patch.object( self.WMI, "Win32_Processor", return_value=[MockWMI_Processor(), MockWMI_Processor()], ), patch.object( self.WMI, "Win32_BIOS", return_value=[MockWMI_BIOS()] ), patch.object( wmi, "WMI", Mock(return_value=self.WMI) ): ret = win_system.get_system_info() # Make sure all the fields are in the return for field in fields: self.assertIn(field, ret) # os_type os_types = ["Work Station", "Domain Controller", "Server"] self.assertIn(ret["os_type"], os_types) domain_roles = [ "Standalone Workstation", "Member Workstation", "Standalone Server", "Member Server", "Backup Domain Controller", "Primary Domain Controller", ] self.assertIn(ret["domain_role"], domain_roles) system_types = [ "Unspecified", "Desktop", "Mobile", "Workstation", "Enterprise Server", "SOHO Server", "Appliance PC", "Performance Server", "Slate", "Maximum", ] self.assertIn(ret["pc_system_type"], system_types) warning_states = [ "Other", "Unknown", "Safe", "Warning", "Critical", "Non-recoverable", ] self.assertIn(ret["chassis_bootup_state"], warning_states) self.assertIn(ret["thermal_state"], warning_states) @pytest.mark.skipif( not win_system.HAS_WIN32NET_MODS, reason="Missing win32 libraries" ) def test_get_system_info_no_number_of_enabled_core(self): """ Tests get_system_info when there is no `NumberOfEnabledCore` property in the WMI Class Win32_Processor. Older versions of Windows are missing this property """ # Create a mock processor class that does not have the # NumberOfCoresEnabled property class MockWMIProcessor: """ Mock WMI Win32_Processor Class """ def __init__(self): self.Manufacturer = "Intel" self.MaxClockSpeed = 2301 self.NumberOfLogicalProcessors = 8 self.NumberOfCores = 4 with patch("salt.utils.win_system.get_computer_name", MagicMock()), patch( "salt.utils.winapi.Com", MagicMock() ), patch.object( self.WMI, "Win32_OperatingSystem", return_value=[MockWMI_OperatingSystem()] ), patch.object( self.WMI, "Win32_ComputerSystem", return_value=[MockWMI_ComputerSystem()] ), patch.object( self.WMI, "Win32_ComputerSystemProduct", return_value=[MockWMI_ComputerSystemProduct()], ), patch.object( self.WMI, "Win32_Processor", return_value=[MockWMIProcessor(), MockWMIProcessor()], ), patch.object( self.WMI, "Win32_BIOS", return_value=[MockWMI_BIOS()] ), patch.object( wmi, "WMI", Mock(return_value=self.WMI) ): ret = win_system.get_system_info() self.assertIn("processors", ret) self.assertIn("processors_logical", ret) self.assertIn("processor_cores", ret) self.assertIn("processor_manufacturer", ret) self.assertIn("processor_max_clock_speed", ret) self.assertNotIn("processor_cores_enabled", ret)