def process(self, params, arg_data): # keys 'result_worst' and 'result_last' must be mutually exclusive if ('result_worst' in params) == ('result_last' in params): raise CheckbDirectiveError( "The exitcode directive requires exactly one of keys " "'result_worst' or 'result_last'.") if 'result_worst' in params: details = check.import_YAML(params['result_worst']) code = SUCCESS for detail in details: if detail.outcome not in ['PASSED', 'INFO']: code = FAILURE log.debug("Returning exitcode %d" % code) return code elif 'result_last' in params: details = check.import_YAML(params['result_last']) if details and details[-1].outcome not in ['PASSED', 'INFO']: log.debug("Returning exitcode %d" % FAILURE) return FAILURE else: log.debug("Returning exitcode %d" % SUCCESS) return SUCCESS else: assert False, "This should never occur"
def test_no_results(self): yaml_output = "{'results': []}" cds = check.import_YAML(yaml_output) assert len(cds) == 0 yaml_output = "{'results': null}" cds = check.import_YAML(yaml_output) assert len(cds) == 0
def main(): parser = get_argparser() args = vars(parser.parse_args()) output_file = args.pop('file') # parse additional key=value pairs keyvals = {} for var in args['keyval']: key, value = var.split('=', 1) keyvals[key] = value args['keyvals'] = keyvals args.pop('keyval') detail = CheckDetail(**args) if os.path.isfile(output_file): # if output file exists, parse its content and append new detail to it f = open(output_file, 'r+') yaml = f.read() details = import_YAML(yaml) if yaml else [] details.append(detail) f.seek(0) f.write(export_YAML(details)) f.close() else: # if output file doesn't exist, create it f = open(output_file, 'w') f.write(export_YAML([detail])) f.close()
def test_nonempty_run(self, monkeypatch): test_args = mock.MagicMock() test_args.__dict__ = { 'file': 'somefile', 'report_type': 'beer', 'item': 'punkipa', 'keyval': [], 'outcome': 'PASSED' } stub_parser = mock.MagicMock() stub_parser.parse_args = mock.MagicMock(return_value=test_args) stub_get_argparser = mock.MagicMock(return_value=stub_parser) monkeypatch.setattr(checkb_result, 'get_argparser', stub_get_argparser) stub_file = mock.MagicMock() stub_file.write = save_output stub_file.read = lambda: FILE monkeypatch.setattr(os.path, 'isfile', mock.MagicMock(return_value=True)) with mock.patch(builtin_open, mock.MagicMock(return_value=stub_file), create=True): checkb_result.main() assert OUTPUT == export_YAML( import_YAML(FILE) + [CheckDetail(**vars(test_args))])
def test_config_reporting_disabled(self): """Checks config option that disables reporting.""" conf = config.get_config() conf.report_to_resultsdb = False yaml = self.test_rdb.process(self.ref_input, self.ref_arg_data) cds = check.import_YAML(yaml) my_cd = check.import_YAML(check.export_YAML(self.cd)) # return value should be the same YAML assert len(cds) == 1 assert cds[0].__dict__ == my_cd[0].__dict__ # no call should have been made assert len(self.stub_rdb.mock_calls) == 0 config._config = None
def test_yaml_output(self): """Checks whether YAML is correctly mapped to the reporting method's arguments.""" output = self.test_rdb.process(self.ref_input, self.ref_arg_data) data = check.import_YAML(output) assert data[0]._internal['resultsdb_result_id'] == 1234
def test_import(self): cds = check.import_YAML(self.yaml_output) assert len(cds) == 1 assert isinstance(cds[0], check.CheckDetail) cd = cds[0] assert cd.item == self.cd.item assert cd.outcome == self.cd.outcome assert cd.note == self.cd.note assert cd.report_type == self.cd.report_type assert cd.keyvals == self.keyvals assert cd.checkname == self.checkname assert cd.artifact == self.artifact assert cd._internal == self._internal
def process(self, params, arg_data): if 'file' in params and 'results' in params: raise CheckbDirectiveError( "Either `file` or `results` can be used, not both.") if 'artifactsdir' not in params: detected_args = ', '.join(params.keys()) raise exc.CheckbDirectiveError( "The directive requires 'artifactsdir' as an " "argument. Detected arguments: %s" % detected_args) artifactsdir = params['artifactsdir'] try: if params.get('file', None): with open(params['file']) as resultfile: params['results'] = resultfile.read() check_details = check.import_YAML(params['results']) log.debug("YAML output parsed OK.") except (CheckbValueError, IOError) as e: raise CheckbDirectiveError("Failed to load results: %s" % e.message) log.debug('Generating report of %s results...', len(check_details)) results = [] for detail in check_details: results.append({ 'checkname': detail.checkname, 'outcome': detail.outcome, 'note': detail.note or '---', 'item': detail.item, 'type': detail.report_type, 'artifact': os.path.basename(detail.artifact) if detail.artifact else None, }) if 'path' in params: report_fname = os.path.join(artifactsdir, params['path']) else: report_fname = os.path.join(artifactsdir, 'report.html') if 'template' in params: template_fname = params['template'] else: template_fname = os.path.join(config.get_config()._data_dir, 'report_templates/html.j2') try: file_utils.makedirs(os.path.dirname(report_fname)) except OSError as e: raise CheckbDirectiveError(e) with open(template_fname) as f_template: with open(report_fname, 'w') as f_report: template = jinja2.Template(f_template.read()) report = template.render(results=results, artifactsdir=artifactsdir) f_report.write(report) log.info('Report generated in: %s', os.path.abspath(report_fname))
def process(self, params, arg_data): # checking if reporting is enabled is done after importing yaml which # serves as validation of input results if 'file' in params and 'results' in params: raise CheckbDirectiveError( "Either `file` or `results` can be used, not both.") try: if params.get('file', None): with open(params['file']) as resultfile: params['results'] = resultfile.read() check_details = check.import_YAML(params['results']) log.debug("YAML output parsed OK.") except (CheckbValueError, IOError) as e: raise CheckbDirectiveError("Failed to load results: %s" % e) for detail in check_details: if not (detail.item and detail.report_type and detail.checkname): raise CheckbDirectiveError( "The resultsdb directive requires 'item', 'type' and " "'checkname' to be present in the YAML data.") conf = config.get_config() if not conf.report_to_resultsdb: log.info( "Reporting to ResultsDB is disabled. Once enabled, the " "following would get reported:\n%s", params['results']) return check.export_YAML(check_details) artifactsdir_url = '%s/%s' % (self.artifacts_baseurl, arg_data['uuid']) # for now, we're creating the resultsdb group at reporting time group_data = self.create_resultsdb_group(uuid=arg_data['uuid']) log.info('Posting %s results to ResultsDB...' % len(check_details)) for detail in check_details: checkname = detail.checkname # find out if the task is allowed to post results into the namespace if config.get_config().profile == config.ProfileName.PRODUCTION: self.check_namespace(checkname, arg_data) self.ensure_testcase_exists(checkname) result_log_url = artifactsdir_url if detail.artifact: artifact_path = self.get_artifact_path( arg_data['artifactsdir'], detail.artifact) if artifact_path: result_log_url = "%s/%s" % (artifactsdir_url, artifact_path) try: result = self.resultsdb.create_result(outcome=detail.outcome, testcase=checkname, groups=[group_data], note=detail.note or None, ref_url=result_log_url, item=detail.item, type=detail.report_type, **detail.keyvals) log.debug('Result saved in ResultsDB:\n%s', pprint.pformat(result)) detail._internal['resultsdb_result_id'] = result['id'] except resultsdb_api.ResultsDBapiException as e: log.error(e) log.error("Failed to store to ResultsDB: `%s` `%s` `%s`", detail.item, checkname, detail.outcome) return check.export_YAML(check_details)
def test_aggregation_allpass(self, monkeypatch): self.params['aggregation'] = 'allpass' self._mock_open(monkeypatch, read_data=XML) output = self.directive.process(self.params, None) assert len(import_YAML(output)) == 1
def test_invalid_yaml_wrong_results_type(self): yaml_output = "{'results': {}}" with pytest.raises(exc.CheckbValueError): check.import_YAML(yaml_output)
def test_invalid_yaml_missing_results_key(self): yaml_output = "{}" with pytest.raises(exc.CheckbValueError): check.import_YAML(yaml_output)
def test_invalid_yaml_root_element_type(self): yaml_output = "[]" with pytest.raises(exc.CheckbValueError): check.import_YAML(yaml_output)
def test_invalid_yaml(self): yaml_output = "key:value\nkey: value" with pytest.raises(exc.CheckbValueError): check.import_YAML(yaml_output)
def test_no_yaml(self): yaml_output = None with pytest.raises(exc.CheckbValueError): check.import_YAML(yaml_output)