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_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 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_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_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_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'] == []