Example #1
0
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']
Example #2
0
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']
Example #3
0
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']
Example #4
0
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'] == {}
Example #5
0
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()
Example #6
0
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']
Example #7
0
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
Example #9
0
    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
Example #10
0
    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']
Example #12
0
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'] == []
Example #13
0
    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, )
Example #14
0
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
Example #15
0
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'] == []
Example #16
0
    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
Example #18
0
    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
Example #19
0
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)