# Copyright 2021 Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # import sys import copy try: from unittest import mock except ImportError: import mock from validations_libs.cli import run from validations_libs.exceptions import ValidationRunException from validations_libs.tests import fakes from validations_libs.tests.cli.fakes import BaseCommand class TestRun(BaseCommand): def setUp(self): super(TestRun, self).setUp() self.cmd = run.Run(self.app, None) @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=None, autospec=True) def test_run_command_return_none(self, mock_run): args = self._set_args(['--validation', 'foo']) verifylist = [('validation_name', ['foo'])] parsed_args = self.check_parser(self.cmd, args, verifylist) self.assertRaises(ValidationRunException, self.cmd.take_action, parsed_args) @mock.patch('validations_libs.cli.common.open') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN), autospec=True) def test_run_command_success(self, mock_run, mock_open): args = self._set_args(['--validation', 'foo']) verifylist = [('validation_name', ['foo'])] parsed_args = self.check_parser(self.cmd, args, verifylist) self.cmd.take_action(parsed_args) def test_run_command_exclusive_group(self): arglist = ['--validation', 'foo', '--group', 'bar'] self._set_args(arglist) verifylist = [('validation_name', ['foo'], 'group', 'bar')] self.assertRaises(Exception, self.check_parser, self.cmd, arglist, verifylist) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('validations_libs.cli.common.print_dict') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN), autospec=True) @mock.patch('validations_libs.utils.load_config', return_value={}) def test_run_command_extra_vars(self, mock_config, mock_run, mock_user, mock_print, mock_log_dir): run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': {'key': 'value'}, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': None, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {} } arglist = ['--validation', 'foo', '--extra-vars', 'key=value'] verifylist = [('validation_name', ['foo']), ('extra_vars', {'key': 'value'})] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) call_args = mock_run.mock_calls[0][2] self.assertDictEqual(call_args, run_called_args) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('validations_libs.cli.common.print_dict') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN), autospec=True) @mock.patch('validations_libs.utils.load_config', return_value={}) def test_run_command_extra_vars_twice(self, mock_config, mock_run, mock_user, mock_print, mock_log_dir): run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': {'key': 'value2'}, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': None, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {} } arglist = ['--validation', 'foo', '--extra-vars', 'key=value1', '--extra-vars', 'key=value2'] verifylist = [('validation_name', ['foo']), ('extra_vars', {'key': 'value2'})] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) call_args = mock_run.mock_calls[0][2] self.assertDictEqual(call_args, run_called_args) def test_run_command_exclusive_vars(self): arglist = ['--validation', 'foo', '--extra-vars', 'key=value1', '--extra-vars-file', '/foo/vars.yaml'] verifylist = [('validation_name', ['foo']), ('extra_vars', {'key': 'value2'})] self.assertRaises(Exception, self.check_parser, self.cmd, arglist, verifylist) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('yaml.safe_load', return_value={'key': 'value'}) @mock.patch('builtins.open') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN), autospec=True) @mock.patch('validations_libs.utils.load_config', return_value={}) def test_run_command_extra_vars_file(self, mock_config, mock_run, mock_user, mock_open, mock_yaml, mock_log_dir): run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': {'key': 'value'}, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': None, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {} } arglist = ['--validation', 'foo', '--extra-vars-file', '/foo/vars.yaml'] verifylist = [('validation_name', ['foo']), ('extra_vars_file', '/foo/vars.yaml')] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) call_args = mock_run.mock_calls[0][2] self.assertDictEqual(call_args, run_called_args) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN), autospec=True) @mock.patch('validations_libs.utils.load_config', return_value={}) def test_run_command_extra_env_vars(self, mock_config, mock_run, mock_user, mock_log_dir): run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': None, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': {'key': 'value'}, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {} } arglist = ['--validation', 'foo', '--extra-env-vars', 'key=value'] verifylist = [('validation_name', ['foo']), ('extra_env_vars', {'key': 'value'})] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) call_args = mock_run.mock_calls[0][2] self.assertDictEqual(call_args, run_called_args) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN), autospec=True) @mock.patch('validations_libs.utils.load_config', return_value={}) def test_run_command_extra_env_vars_with_custom_callback(self, mock_config, mock_run, mock_user, mock_log_dir): run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'quiet': False, 'group': [], 'category': [], 'product': [], 'extra_vars': None, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': {'ANSIBLE_STDOUT_CALLBACK': 'default'}, 'python_interpreter': sys.executable, 'quiet': False, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {} } arglist = ['--validation', 'foo', '--extra-env-vars', 'ANSIBLE_STDOUT_CALLBACK=default'] verifylist = [('validation_name', ['foo']), ('extra_env_vars', {'ANSIBLE_STDOUT_CALLBACK': 'default'})] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) call_args = mock_run.mock_calls[0][2] self.assertDictEqual(call_args, run_called_args) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN), autospec=True) @mock.patch('validations_libs.utils.load_config', return_value={}) def test_run_command_extra_env_vars_twice(self, mock_config, mock_run, mock_user, mock_log_dir): run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': None, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': {'key': 'value2'}, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {} } arglist = ['--validation', 'foo', '--extra-env-vars', 'key=value1', '--extra-env-vars', 'key=value2'] verifylist = [('validation_name', ['foo']), ('extra_env_vars', {'key': 'value2'})] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) call_args = mock_run.mock_calls[0][2] self.assertDictEqual(call_args, run_called_args) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN), autospec=True) @mock.patch('validations_libs.utils.load_config', return_value={}) def test_run_command_extra_env_vars_and_extra_vars(self, mock_config, mock_run, mock_user, mock_log_dir): run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': {'key': 'value'}, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': {'key2': 'value2'}, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {} } arglist = ['--validation', 'foo', '--extra-vars', 'key=value', '--extra-env-vars', 'key2=value2'] verifylist = [('validation_name', ['foo']), ('extra_vars', {'key': 'value'}), ('extra_env_vars', {'key2': 'value2'})] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) call_args = mock_run.mock_calls[0][2] self.assertDictEqual(call_args, run_called_args) @mock.patch('validations_libs.utils.find_config_file', return_value="/etc/validations_foo.cfg") @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_FAILED_RUN), autospec=True) @mock.patch('validations_libs.utils.load_config', return_value={}) def test_run_command_failed_validation(self, mock_config, mock_run, mock_user, mock_log_dir, mock_config_file): run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': {'key': 'value'}, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': {'key2': 'value2'}, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {} } arglist = [ '--validation', 'foo', '--extra-vars', 'key=value', '--extra-env-vars', 'key2=value2'] verifylist = [ ('validation_name', ['foo']), ('extra_vars', {'key': 'value'}), ('extra_env_vars', {'key2': 'value2'})] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises(ValidationRunException, self.cmd.take_action, parsed_args) call_args = mock_run.mock_calls[0][2] self.assertDictEqual(call_args, run_called_args) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=[], autospec=True) def test_run_command_no_validation(self, mock_run, mock_user, mock_log_dir): run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': {'key': 'value'}, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': {'key2': 'value2'}, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': None, 'log_path': mock_log_dir} arglist = [ '--validation', 'foo', '--extra-vars', 'key=value', '--extra-env-vars', 'key2=value2'] verifylist = [ ('validation_name', ['foo']), ('extra_vars', {'key': 'value'}), ('extra_env_vars', {'key2': 'value2'})] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises(ValidationRunException, self.cmd.take_action, parsed_args) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=fakes.FAKE_SUCCESS_RUN) def test_run_with_wrong_config(self, mock_run, mock_user, mock_log_dir): arglist = ['--validation', 'foo', '--config', 'wrong.cfg'] verifylist = [('validation_name', ['foo']), ('config', 'wrong.cfg')] run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': None, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': None, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {} } self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) mock_run.assert_called_with(**run_called_args) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=fakes.FAKE_SUCCESS_RUN) @mock.patch('os.path.exists', return_value=True) def test_run_with_config(self, mock_exists, mock_run, mock_user, mock_log_dir): arglist = ['--validation', 'foo', '--config', 'config.cfg'] verifylist = [('validation_name', ['foo']), ('config', 'config.cfg')] run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': None, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': None, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {} } self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) mock_run.assert_called_with(**run_called_args) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('yaml.safe_load', return_value={'key': 'value'}) @mock.patch('builtins.open') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN)) @mock.patch('validations_libs.utils.load_config', return_value={}) def test_run_command_with_skip_list(self, mock_config, mock_run, mock_user, mock_open, mock_yaml, mock_log_dir): run_called_args = { 'inventory': 'localhost', 'limit_hosts': None, 'group': [], 'category': [], 'product': [], 'extra_vars': None, 'validations_dir': '/usr/share/ansible/validation-playbooks', 'base_dir': '/usr/share/ansible', 'validation_name': ['foo'], 'extra_env_vars': None, 'python_interpreter': sys.executable, 'quiet': True, 'ssh_user': 'doe', 'validation_config': {}, 'skip_list': {'key': 'value'} } arglist = ['--validation', 'foo', '--skiplist', '/foo/skip.yaml'] verifylist = [('validation_name', ['foo']), ('skip_list', '/foo/skip.yaml')] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) mock_run.assert_called_with(**run_called_args) @mock.patch('validations_libs.constants.VALIDATIONS_LOG_BASEDIR') @mock.patch('yaml.safe_load', return_value=[{'key': 'value'}]) @mock.patch('builtins.open') @mock.patch('getpass.getuser', return_value='doe') @mock.patch('validations_libs.validation_actions.ValidationActions.' 'run_validations', return_value=copy.deepcopy(fakes.FAKE_SUCCESS_RUN)) @mock.patch('validations_libs.utils.load_config', return_value={}) def test_run_command_with_skip_list_bad_format(self, mock_config, mock_run, mock_user, mock_open, mock_yaml, mock_log_dir): arglist = ['--validation', 'foo', '--skiplist', '/foo/skip.yaml'] verifylist = [('validation_name', ['foo']), ('skip_list', '/foo/skip.yaml')] self._set_args(arglist) parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.assertRaises(ValidationRunException, self.cmd.take_action, parsed_args)