def test_install_with_initial_reboot_required_but_no_reboot(monkeypatch): reboot_mock = MagicMock() reboot_mock.return_value = {'failed': False} monkeypatch.setattr(win_updates, 'reboot_host', reboot_mock) actual = run_action(monkeypatch, 'install_reboot_req_no_reboot.txt', { 'category_names': ['*'], }) assert reboot_mock.call_count == 0 assert not actual['changed'] assert actual['failed'] assert actual[ 'msg'] == 'A reboot is required before more updates can be installed' assert actual['reboot_required'] assert actual['found_update_count'] == 5 assert actual['failed_update_count'] == 0 assert actual['installed_update_count'] == 0 assert actual['filtered_updates'] == [] assert len(actual['updates']) == 5 for u in actual['updates']: assert u['id'] in UPDATE_INFO u_info = UPDATE_INFO[u['id']] assert u['title'] == u_info['title'] assert u['kb'] == [u_info['kb']] assert u['categories'] == u_info['categories'] assert not u['downloaded'] assert not u['installed']
def test_install_with_multiple_reboots(monkeypatch): # Was tested against a Server 2019 host with the parameters set below. reboot_mock = MagicMock() reboot_mock.return_value = {'failed': False} monkeypatch.setattr(win_updates, 'reboot_host', reboot_mock) actual = run_action(monkeypatch, 'full_run.txt', { 'category_names': '*', 'state': 'installed', 'reboot': 'yes', }) assert reboot_mock.call_count == 2 assert actual['changed'] assert not actual['reboot_required'] assert actual['found_update_count'] == 8 assert actual['failed_update_count'] == 0 assert actual['installed_update_count'] == 8 assert actual['filtered_updates'] == [] assert len(actual['updates']) == 8 for u in actual['updates']: assert u['id'] in UPDATE_INFO u_info = UPDATE_INFO[u['id']] assert u['title'] == u_info['title'] assert u['kb'] == [u_info['kb']] assert u['categories'] == u_info['categories'] assert u['downloaded'] assert u['installed']
def test_install_with_initial_reboot_required(monkeypatch): reboot_mock = MagicMock() reboot_mock.return_value = {'failed': False} monkeypatch.setattr(win_updates, 'reboot_host', reboot_mock) actual = run_action(monkeypatch, 'install_reboot_req.txt', { 'category_names': ['*'], 'reboot': True, }) assert reboot_mock.call_count == 2 assert actual['changed'] assert not actual['reboot_required'] assert actual['found_update_count'] == 6 assert actual['failed_update_count'] == 0 assert actual[ 'installed_update_count'] == 5 # 1 found update was already installed at the beginning assert actual['filtered_updates'] == [] assert len(actual['updates']) == 6 for u in actual['updates']: assert u['id'] in UPDATE_INFO u_info = UPDATE_INFO[u['id']] assert u['title'] == u_info['title'] assert u['kb'] == [u_info['kb']] assert u['categories'] == u_info['categories'] if u_info['kb'] == '5003171': assert not u['downloaded'] assert not u['installed'] else: assert u['downloaded'] assert u['installed']
def test_run_with_async(monkeypatch): plugin = win_updates_init({}, async_val=1) execute_module = MagicMock() execute_module.return_value = { 'invocation': { 'module_args': { '_wait': True, 'accept_list': [] } }, 'updates': ['test'] } monkeypatch.setattr(plugin, '_execute_module', execute_module) # Running with async should just call the module and return back the result - sans the _wait invocation arg actual = plugin.run() assert actual == { 'invocation': { 'module_args': { 'accept_list': [] } }, 'updates': ['test'] } assert execute_module.call_count == 1 assert execute_module.call_args[1][ 'module_name'] == 'ansible.windows.win_updates' assert execute_module.call_args[1]['module_args']['_wait'] assert execute_module.call_args[1]['module_args']['_output_path'] is None assert execute_module.call_args[1]['task_vars'] == {}
def run_action(monkeypatch, test_id, task_vars, check_mode=False, poll_rc=0, poll_stderr=b''): module_arg_return = task_vars.copy() module_arg_return['_wait'] = False plugin = win_updates_init(task_vars, check_mode=check_mode, connection=mock_connection_init( test_id, default_rc=poll_rc, default_stderr=poll_stderr)) execute_module = MagicMock() execute_module.return_value = { 'invocation': { 'module_args': module_arg_return }, 'output_path': 'update_output_path', 'task_pid': 666, 'cancel_id': 'update_cancel_id', } monkeypatch.setattr(plugin, '_execute_module', execute_module) monkeypatch.setattr(plugin, '_transfer_file', MagicMock()) return plugin.run()
def test_install_with_reboot_check_mode(monkeypatch): reboot_mock = MagicMock() reboot_mock.return_value = { 'failed': True, 'msg': 'Failure msg from reboot' } monkeypatch.setattr(win_updates, 'reboot_host', reboot_mock) actual = run_action(monkeypatch, 'install_reboot_req_failure.txt', { 'category_names': ['*'], 'reboot': True, }, check_mode=True) assert reboot_mock.call_count == 0 assert actual['changed'] assert not actual['reboot_required'] assert 'failed' not in actual assert 'msg' not in actual assert actual['found_update_count'] == 6 assert actual['failed_update_count'] == 0 assert actual['installed_update_count'] == 0 assert actual['filtered_updates'] == [] assert len(actual['updates']) == 6 for u in actual['updates']: assert u['id'] in UPDATE_INFO u_info = UPDATE_INFO[u['id']] assert u['title'] == u_info['title'] assert u['kb'] == [u_info['kb']] assert u['categories'] == u_info['categories'] assert not u['downloaded'] assert not u['installed']
def mock_connection_init(test_id, default_rc=0, default_stderr=b''): progress_helper = UpdateProgressHelper(test_id, default_rc=default_rc, default_stderr=default_stderr) mock_connection = MagicMock() mock_connection._shell.tmpdir = 'shell_tmpdir' mock_connection._shell.join_path = ntpath.join mock_connection.exec_command = progress_helper.poll return mock_connection
def test_fail_install(monkeypatch): reboot_mock = MagicMock() reboot_mock.return_value = {'failed': False} monkeypatch.setattr(win_updates, 'reboot_host', reboot_mock) actual = run_action( monkeypatch, 'failed_install.txt', { 'category_names': ['SecurityUpdates', 'DefinitionUpdates'], 'accept_list': ['KB5003171', 'KB2267602'], }) assert reboot_mock.call_count == 0 assert actual['changed'] assert actual['failed'] assert actual['reboot_required'] assert actual['found_update_count'] == 2 assert actual['failed_update_count'] == 1 assert actual['installed_update_count'] == 1 assert len(actual['filtered_updates']) == 4 for u_id, u in actual['filtered_updates'].items(): assert u['id'] == u_id assert u['id'] in UPDATE_INFO u_info = UPDATE_INFO[u['id']] assert u['title'] == u_info['title'] assert u['kb'] == [u_info['kb']] assert u['categories'] == u_info['categories'] assert not u['downloaded'] assert not u['installed'] assert u['filtered_reason'] == 'whitelist' if u_info['kb'] == '4580325': assert u['filtered_reasons'] == ['accept_list'] else: assert u['filtered_reasons'] == ['accept_list', 'category_names'] assert len(actual['updates']) == 2 for u_id, u in actual['updates'].items(): assert u['id'] == u_id assert u['id'] in UPDATE_INFO u_info = UPDATE_INFO[u['id']] assert u['title'] == u_info['title'] assert u['kb'] == [u_info['kb']] assert u['categories'] == u_info['categories'] assert u['downloaded'] if u_info['kb'] == '2267602': assert not u['installed'] assert u['failure_hresult_code'] == 2147944003 assert u[ 'failure_msg'] == 'Unknown WUA HRESULT 2147944003 (UNKNOWN 80070643)' else: assert u['installed'] assert 'failure_hresult_code' not in u
def test_exec_with_become_no_plugin_set_use_task(self, test_win_updates): set_become_mock = MagicMock() test_win_updates._connection.become = None test_win_updates._connection.set_become_plugin = set_become_mock with patch('ansible.plugins.action.ActionBase._execute_module', new=MagicMock()): test_win_updates._execute_module_with_become( 'win_updates', {}, {}, True, True) assert set_become_mock.call_count == 1 assert set_become_mock.mock_calls[0][1][0] is None
def test_exec_with_become(self, test_win_updates): test_become = os.urandom(8) set_become_mock = MagicMock() test_win_updates._connection.become = test_become test_win_updates._connection.set_become_plugin = set_become_mock with patch('ansible.plugins.action.ActionBase._execute_module', new=MagicMock()): test_win_updates._execute_module_with_become( 'win_updates', {}, {}, True, False) # Asserts we don't override the become plugin. assert set_become_mock.call_count == 1 assert set_become_mock.mock_calls[0][1][0] == test_become
def test_install_without_reboot(monkeypatch): reboot_mock = MagicMock() reboot_mock.return_value = {'failed': False} monkeypatch.setattr(win_updates, 'reboot_host', reboot_mock) actual = run_action(monkeypatch, 'install_no_reboot.txt', { 'reject_list': ['KB2267602'], }) assert reboot_mock.call_count == 0 assert actual['changed'] assert actual['reboot_required'] assert actual['found_update_count'] == 3 assert actual['failed_update_count'] == 0 assert actual['installed_update_count'] == 3 assert len(actual['filtered_updates']) == 3 for u_id, u in actual['filtered_updates'].items(): assert u['id'] == u_id assert u['id'] in UPDATE_INFO u_info = UPDATE_INFO[u['id']] assert u['title'] == u_info['title'] assert u['kb'] == [u_info['kb']] assert u['categories'] == u_info['categories'] assert not u['downloaded'] assert not u['installed'] if u_info['kb'] == '2267602': assert u['filtered_reason'] == 'blacklist' assert u['filtered_reasons'] == ['reject_list', 'category_names'] else: assert u['filtered_reason'] == 'category_names' assert u['filtered_reasons'] == ['category_names'] assert len(actual['updates']) == 3 for u_id, u in actual['updates'].items(): assert u['id'] == u_id assert u['id'] in UPDATE_INFO u_info = UPDATE_INFO[u['id']] assert u['title'] == u_info['title'] assert u['kb'] == [u_info['kb']] assert u['categories'] == u_info['categories'] assert u['downloaded'] assert u['installed']
def test_failed_to_start_module(monkeypatch): plugin = win_updates_init({}, ) execute_module = MagicMock() execute_module.return_value = { 'failed': True, 'msg': 'Failed to start module details', } monkeypatch.setattr(plugin, '_execute_module', execute_module) monkeypatch.setattr(plugin, '_transfer_file', MagicMock()) actual = plugin.run() assert actual['failed'] assert actual['msg'] == 'Failed to start module details' assert 'exception' in actual assert actual['found_update_count'] == 0 assert actual['failed_update_count'] == 0 assert actual['installed_update_count'] == 0 assert actual['filtered_updates'] == [] assert actual['updates'] == []
def test_exec_with_become_no_plugin_set(self, test_win_updates): set_become_mock = MagicMock() test_win_updates._connection.become = None test_win_updates._connection.set_become_plugin = set_become_mock with patch('ansible.plugins.action.ActionBase._execute_module', new=MagicMock()): test_win_updates._execute_module_with_become( 'win_updates', {}, {}, True, False) assert set_become_mock.call_count == 2 assert isinstance(set_become_mock.mock_calls[0][1][0], BecomeModule) assert set_become_mock.mock_calls[0][1][0].name == 'runas' assert set_become_mock.mock_calls[0][1][0].get_option( 'become_user') == 'SYSTEM' assert set_become_mock.mock_calls[0][1][0].get_option( 'become_flags') == '' assert set_become_mock.mock_calls[0][1][0].get_option( 'become_pass') is None assert set_become_mock.mock_calls[1][1] == (None, )
def test_win_updates(): task = MagicMock(Task) task.args = {} connection = MagicMock() connection.module_implementation_preferences = ('.ps1', '.exe', '') play_context = MagicMock() play_context.check_mode = False plugin = ActionModule(task, connection, play_context, loader=None, templar=None, shared_loader_obj=None) return plugin
def test_install_reboot_with_two_failures(monkeypatch): reboot_mock = MagicMock() reboot_mock.return_value = {'failed': False} monkeypatch.setattr(win_updates, 'reboot_host', reboot_mock) actual = run_action(monkeypatch, 'install_reboot_two_failures.txt', { 'category_names': ['*'], 'reboot': True, }) assert reboot_mock.call_count == 1 assert actual['changed'] assert not actual['reboot_required'] assert actual['failed'] assert actual['msg'] == 'Searching for updates: Exception from HRESULT: 0x80240032 - The search criteria string was invalid ' \ '(WU_E_INVALID_CRITERIA 80240032)' assert 'exception' in actual assert actual['found_update_count'] == 0 assert actual['failed_update_count'] == 0 assert actual['installed_update_count'] == 0 assert actual['filtered_updates'] == [] assert actual['updates'] == []
def test_invalid_options(self, task_args, async_val, expected): task = MagicMock(Task) task.args = task_args task.async_val = async_val connection = MagicMock() play_context = MagicMock() play_context.check_mode = False plugin = ActionModule(task, connection, play_context, loader=None, templar=None, shared_loader_obj=None) res = plugin.run() assert res['failed'] assert expected in res['msg']
def win_updates_init(task_args, async_val=0, check_mode=False, connection=None): task = MagicMock(Task) task.args = task_args task.check_mode = check_mode task.async_val = async_val connection = connection or MagicMock() # Used for older Ansible versions play_context = MagicMock() play_context.check_mode = check_mode plugin = win_updates.ActionModule(task, connection, play_context, loader=None, templar=None, shared_loader_obj=None) return plugin
def test_module_exec_async_result(self, monkeypatch): return_val = { "ansible_async_watchdog_pid": 7584, "ansible_job_id": "545519115287.9620", "changed": True, "finished": 0, "results_file": r"C:\.ansible_async\545519115287.9620", "started": 1 } mock_execute = MagicMock(return_value=return_val) monkeypatch.setattr(ActionModule, '_execute_module', mock_execute) task = MagicMock(Task) task.args = {} task.async_val = 10 connection = MagicMock() connection.module_implementation_preferences = ('.ps1', '.exe', '') play_context = MagicMock() play_context.check_mode = False play_context.become = True play_context.become_method = 'runas' play_context.become_user = '******' plugin = ActionModule(task, connection, play_context, loader=None, templar=None, shared_loader_obj=None) actual = plugin.run(None, {}) assert actual.get('failed') is None assert actual['ansible_async_watchdog_pid'] == 7584 assert actual['ansible_job_id'] == "545519115287.9620" assert actual['changed'] is True assert actual['finished'] == 0 assert actual['results_file'] == r"C:\.ansible_async\545519115287.9620" assert actual['started'] == 1
from __future__ import (absolute_import, division, print_function) __metaclass__ = type from ansible_collections.ansible.windows.tests.unit.compat.mock import MagicMock from ansible.utils.path import unfrackpath mock_unfrackpath_noop = MagicMock(spec_set=unfrackpath, side_effect=lambda x, *args, **kwargs: x)