def test_get_results(self, mock_open, mock_json, mock_get_validation): mock_get_validation.return_value = \ ['/tmp/123_foo_2020-03-30T13:17:22.447857Z.json'] vlogs = ValidationLogs('/tmp/foo') content = vlogs.get_results(uuid='123', validation_id='foo') self.assertEquals(content, [{'UUID': '123', 'Validations': 'foo', 'Status': 'PASSED', 'Status_by_Host': 'undercloud,PASSED', 'Host_Group': 'undercloud', 'Unreachable_Hosts': '', 'Duration': '0:00:03.753', 'Validations': 'foo'}])
def run_validations(self, validation_name=None, inventory='localhost', group=None, extra_vars=None, validations_dir=None, extra_env_vars=None, ansible_cfg=None, quiet=True, workdir=None, limit_hosts=None, run_async=False, base_dir=constants.DEFAULT_VALIDATIONS_BASEDIR, log_path=None, python_interpreter=None, output_callback='validation_stdout', skip_list=None): """Run one or multiple validations by name(s) or by group(s) :param validation_name: A list of validation names :type validation_name: ``list`` :param inventory: Either proper inventory file, or a comma-separated list. (Defaults to ``localhost``) :type inventory: ``string`` :param group: A list of group names :type group: ``list`` :param extra_vars: Set additional variables as a Dict or the absolute path of a JSON or YAML file type. :type extra_vars: Either a Dict or the absolute path of JSON or YAML :param validations_dir: The absolute path of the validations playbooks :type validations_dir: ``string`` :param extra_env_vars: Set additional ansible variables using an extravar dictionary. :type extra_env_vars: ``dict`` :param ansible_cfg: Path to an ansible configuration file. One will be generated in the artifact path if this option is None. :type ansible_cfg: ``string`` :param quiet: Disable all output (Defaults to ``True``) :type quiet: ``Boolean`` :param workdir: Location of the working directory :type workdir: ``string`` :param limit_hosts: Limit the execution to the hosts. :type limit_hosts: ``string`` :param run_async: Enable the Ansible asynchronous mode (Defaults to ``False``) :type run_async: ``boolean`` :param base_dir: The absolute path of the validations base directory (Defaults to ``constants.DEFAULT_VALIDATIONS_BASEDIR``) :type base_dir: ``string`` :param log_path: The absolute path of the validations logs directory :type log_path: ``string`` :param python_interpreter: Path to the Python interpreter to be used for module execution on remote targets, or an automatic discovery mode (``auto``, ``auto_silent`` or the default one ``auto_legacy``) :type python_interpreter: ``string`` :param output_callback: The Callback plugin to use. (Defaults to 'validation_stdout') :type output_callback: ``string`` :param skip_list: List of validations to skip during the Run form as {'xyz': {'hosts': 'ALL', 'reason': None, 'lp': None} } (Defaults to 'None') :type skip_list: ``dict`` :return: A list of dictionary containing the informations of the validations executions (Validations, Duration, Host_Group, Status, Status_by_Host, UUID and Unreachable_Hosts) :rtype: ``list`` :Example: >>> path = "/u/s/a" >>> validation_name = ['foo', 'bar'] >>> actions = ValidationActions(validation_path=path) >>> results = actions.run_validations(inventory='localhost', validation_name=validation_name, quiet=True) >>> print(results) [{'Duration': '0:00:02.285', 'Host_Group': 'all', 'Status': 'PASSED', 'Status_by_Host': 'localhost,PASSED', 'UUID': '62d4d54c-7cce-4f38-9091-292cf49268d7', 'Unreachable_Hosts': '', 'Validations': 'foo'}, {'Duration': '0:00:02.237', 'Host_Group': 'all', 'Status': 'PASSED', 'Status_by_Host': 'localhost,PASSED', 'UUID': '04e6165c-7c33-4881-bac7-73ff3f909c24', 'Unreachable_Hosts': '', 'Validations': 'bar'}] """ self.log = logging.getLogger(__name__ + ".run_validations") playbooks = [] validations_dir = (validations_dir if validations_dir else self.validation_path) if group: self.log.debug('Getting the validations list by group') try: validations = v_utils.parse_all_validations_on_disk( validations_dir, group) for val in validations: playbooks.append(val.get('id') + '.yaml') except Exception as e: raise(e) elif validation_name: validation_name = v_utils.convert_data(validation_name) playbooks = v_utils.get_validations_playbook(validations_dir, validation_name, group) if not playbooks or len(validation_name) != len(playbooks): p = [] for play in playbooks: p.append(os.path.basename(os.path.splitext(play)[0])) unknown_validation = list(set(validation_name) - set(p)) msg = "Validation {} not found in {}.".format( unknown_validation, validations_dir) raise RuntimeError(msg) else: raise RuntimeError("No validations found") self.log.debug('Running the validations with Ansible') results = [] for playbook in playbooks: # Check if playbook should be skipped and on which hosts play_name = os.path.basename(os.path.splitext(playbook)[0]) _play, _hosts = self._skip_playbook(skip_list, play_name, limit_hosts) if _play: validation_uuid, artifacts_dir = v_utils.create_artifacts_dir( dir_path=log_path, prefix=os.path.basename(playbook)) run_ansible = v_ansible(validation_uuid) _playbook, _rc, _status = run_ansible.run( workdir=artifacts_dir, playbook=playbook, base_dir=base_dir, playbook_dir=validations_dir, parallel_run=True, inventory=inventory, output_callback=output_callback, quiet=quiet, extra_vars=extra_vars, limit_hosts=_hosts, extra_env_variables=extra_env_vars, ansible_cfg=ansible_cfg, gathering_policy='explicit', ansible_artifact_path=artifacts_dir, log_path=log_path, run_async=run_async, python_interpreter=python_interpreter) results.append({'playbook': _playbook, 'rc_code': _rc, 'status': _status, 'validations': _playbook.split('.')[0], 'UUID': validation_uuid, }) else: self.log.debug('Skipping Validations: {}'.format(playbook)) if run_async: return results # Return log results uuid = [id['UUID'] for id in results] vlog = ValidationLogs() return vlog.get_results(uuid)