def _mkreport(self, msg_tag, code, _tc, message): """ Generate a failure report """ # FIXME: initialize this in the core, so it shows in test_dump_kws*.py kws = commonl.dict_missing_c(_tc.kws) kws['msg_tag'] = msg_tag kws['result'] = tcfl.tc.valid_results.get( msg_tag, ( None, "BUG-RESULT-%s" % msg_tag))[0] kws['result_past'] = tcfl.tc.valid_results.get( msg_tag, ( None, "BUG-RESULT-%s" % msg_tag))[1] kws['message'] = message tfids = [] for target_want_name, target in _tc.targets.iteritems(): if len(target.rt.get('bsp_models', {})) > 1: tfids.append( '(' + target.fullid + ' and bsp_model == "%s")' % target.bsp_model) else: tfids.append(target.fullid) if tfids: kws['t_option'] = " -t '" + " or ".join(tfids) + "'" else: kws['t_option'] = "" # tcfl.config.VARNAME -> tcfl_config_VARNAME # this makes it easy to publish configuration items into the # tcfl.config space that then can be used in templates. It's a # hack, but makes configuration later on way easier tcfl_config = sys.modules['tcfl.config'] for symbol in dir(tcfl_config): value = getattr(tcfl_config, symbol) if symbol.startswith("__"): continue elif callable(value): continue elif any([ isinstance(value, i) for i in (list, dict, tuple, basestring, int)]): kws['tcfl_config_%s' % symbol] = value else: pass kws['targets'] = [] for target_want_name, target in _tc.targets.iteritems(): entry = {} entry['want_name'] = target_want_name entry['fullid'] = target.fullid entry['type'] = _tc.type_map.get(target.type, target.type) kws['targets'].append(entry) kws['tags'] = {} for tag in _tc._tags: (value, origin) = _tc.tag_get(tag, None, None) kws['tags'][tag] = dict(value = value, origin = origin) kws['count'] = 1 kws['count_passed'] = 1 if msg_tag == 'PASS' else 0 kws['count_failed'] = 1 if msg_tag == 'FAIL' else 0 kws['count_errored'] = 1 if msg_tag == 'ERRR' else 0 kws['count_skipped'] = 1 if msg_tag == 'SKIP' else 0 kws['count_blocked'] = 1 if msg_tag == 'BLCK' else 0 kws['ts_start'] = _tc.ts_end kws['ts_start_h'] = time.ctime(_tc.ts_end) kws['ts_end'] = _tc.ts_end kws['ts_end_h'] = time.ctime(_tc.ts_end) kws['duration_s'] = _tc.ts_end - _tc.ts_start for hook in self.hooks: hook(self, _tc, kws) # Write to report file # FIXME: consider compiling the template as we'll keep reusing it template_path = [ i for i in reversed(tcfl.config.path) ] \ + [ tcfl.config.share_path ] j2_env = jinja2.Environment( loader = jinja2.FileSystemLoader(template_path)) j2_env.filters['xml_escape'] = jinja2_xml_escape for entry_name, template_entry in self.templates.iteritems(): template_name = template_entry['name'] if message.startswith("COMPLETION failed") \ and not template_entry.get('report_fail', True): _tc.log.info("%s|%s: reporting failed disabled" % (entry_name, template_name)) continue elif message.startswith("COMPLETION error") \ and not template_entry.get('report_error', True): _tc.log.info("%s|%s: reporting errors disabled" % (entry_name, template_name)) continue elif message.startswith("COMPLETION skipped") \ and not template_entry.get('report_skip', False): _tc.log.info("%s|%s: reporting skips disabled" % (entry_name, template_name)) continue elif message.startswith("COMPLETION blocked") \ and not template_entry.get('report_block', True): _tc.log.info("%s|%s: reporting blockages disabled" % (entry_name, template_name)) continue elif message.startswith("COMPLETION passed") \ and not template_entry.get('report_pass', False): _tc.log.info("%s|%s: reporting pass disabled" % (entry_name, template_name)) continue else: assert True, "Unknown COMPLETION message: %s" % message # Need to do this every time so the iterator is reset kws['log'] = self._log_iterator(code) template = j2_env.get_template(template_name) file_name = template_entry['output_file_name'] % kws if not os.path.isabs(file_name): file_name = os.path.join(self.log_dir, file_name) # the template might specify a new directory path that # still does not exist commonl.makedirs_p(os.path.dirname(file_name), 0o750) with codecs.open(file_name, "w", encoding = 'utf-8', errors = 'ignore') as fo: for text in template.generate(**kws): fo.write(text)
def _mkreport(self, msg_tag, code, _tc, message): """ Generate a failure report """ # FIXME: initialize this in the core, so it shows in test_dump_kws*.py kws = commonl.dict_missing_c(_tc.kws) kws['msg_tag'] = msg_tag kws['result'] = tcfl.tc.valid_results.get( msg_tag, (None, "BUG-RESULT-%s" % msg_tag))[0] kws['result_past'] = tcfl.tc.valid_results.get( msg_tag, (None, "BUG-RESULT-%s" % msg_tag))[1] kws['message'] = message tfids = [] for target_want_name, target in _tc.targets.iteritems(): if len(target.rt.get('bsp_models', {})) > 1: tfids.append('(' + target.fullid + ' and bsp_model == "%s")' % target.bsp_model) else: tfids.append(target.fullid) if tfids: kws['t_option'] = " -t '" + " or ".join(tfids) + "'" else: kws['t_option'] = "" # tcfl.config.VARNAME -> tcfl_config_VARNAME # this makes it easy to publish configuration items into the # tcfl.config space that then can be used in templates. It's a # hack, but makes configuration later on way easier tcfl_config = sys.modules['tcfl.config'] for symbol in dir(tcfl_config): value = getattr(tcfl_config, symbol) if symbol.startswith("__"): continue elif callable(value): continue elif any([ isinstance(value, i) for i in (list, dict, tuple, basestring, int) ]): kws['tcfl_config_%s' % symbol] = value else: pass kws['targets'] = [] for target_want_name, target in _tc.targets.iteritems(): entry = {} entry['want_name'] = target_want_name entry['fullid'] = target.fullid entry['type'] = _tc.type_map.get(target.type, target.type) kws['targets'].append(entry) kws['tags'] = {} for tag in _tc._tags: (value, origin) = _tc.tag_get(tag, None, None) kws['tags'][tag] = dict(value=value, origin=origin) kws['count'] = 1 kws['count_passed'] = 1 if msg_tag == 'PASS' else 0 kws['count_failed'] = 1 if msg_tag == 'FAIL' else 0 kws['count_errored'] = 1 if msg_tag == 'ERRR' else 0 kws['count_skipped'] = 1 if msg_tag == 'SKIP' else 0 kws['count_blocked'] = 1 if msg_tag == 'BLCK' else 0 kws['ts_start'] = _tc.ts_end kws['ts_start_h'] = time.ctime(_tc.ts_end) kws['ts_end'] = _tc.ts_end kws['ts_end_h'] = time.ctime(_tc.ts_end) kws['duration_s'] = _tc.ts_end - _tc.ts_start for hook in self.hooks: hook(self, _tc, kws) # Write to report file # FIXME: consider compiling the template as we'll keep reusing it template_path = [ i for i in reversed(tcfl.config.path) ] \ + [ tcfl.config.share_path ] j2_env = jinja2.Environment( loader=jinja2.FileSystemLoader(template_path)) j2_env.filters['xml_escape'] = jinja2_xml_escape for entry_name, template_entry in self.templates.iteritems(): template_name = template_entry['name'] if message.startswith("COMPLETION failed") \ and not template_entry.get('report_fail', True): _tc.log.info("%s|%s: reporting failed disabled" % (entry_name, template_name)) continue elif message.startswith("COMPLETION error") \ and not template_entry.get('report_error', True): _tc.log.info("%s|%s: reporting errors disabled" % (entry_name, template_name)) continue elif message.startswith("COMPLETION skipped") \ and not template_entry.get('report_skip', False): _tc.log.info("%s|%s: reporting skips disabled" % (entry_name, template_name)) continue elif message.startswith("COMPLETION blocked") \ and not template_entry.get('report_block', True): _tc.log.info("%s|%s: reporting blockages disabled" % (entry_name, template_name)) continue elif message.startswith("COMPLETION passed") \ and not template_entry.get('report_pass', False): _tc.log.info("%s|%s: reporting pass disabled" % (entry_name, template_name)) continue else: assert True, "Unknown COMPLETION message: %s" % message # Need to do this every time so the iterator is reset kws['log'] = self._log_iterator(code) template = j2_env.get_template(template_name) file_name = template_entry['output_file_name'] % kws if not os.path.isabs(file_name): file_name = os.path.join(self.log_dir, file_name) # the template might specify a new directory path that # still does not exist commonl.makedirs_p(os.path.dirname(file_name), 0o750) with codecs.open(file_name, "w", encoding='utf-8', errors='replace') as fo: for text in template.generate(**kws): fo.write(text)
def _mkreport(self, msg_tag, code, _tc, message, f): """ Generate a failure report """ # FIXME: break out into smaller flows global targets_all kws = commonl.dict_missing_c(_tc.kws) kws['msg_tag'] = msg_tag kws['message'] = message # Once the rest of the keys are available, generate the # user-provided ones if self.helpurl: kws['helpurl'] = self.helpurl % kws else: kws['heluprl'] = "" if self.report_header: kws['report_header'] = self.report_header % kws else: kws['report_header'] = "" # Seriously, I can't get right the Unicode and Python misterious ways # without getting thrown exceptions in the middle, so open the output # file normally and we just forcibly write unicode/utf-8 to it in # _fwrite(). As well, re-open the input file in utf-8 mode to # avoid doing manual conversion. kws['t_option'] = " " with self.lock: header = self._mkreport_header(_tc, kws) output = self._mkreport_output(kws, f) tag_info = u""" Testcase tags ============= """ col_tags = ['Tag'] col_values = ['Value'] col_origins = ['Origin'] for tag in _tc._tags: (value, origin) = _tc.tag_get(tag, None, None) if value == None: continue col_tags.append(tag) col_values.append(str(value)) # in case int/bool, etc.. col_origins.append(str(origin)) width_tag = max([len(tag) for tag in col_tags]) + 1 width_value = max([len(value) for value in col_values]) + 1 width_origin = max([len(origin) for origin in col_origins]) + 1 for (index, tag) in enumerate(col_tags): tag_info += u"{tag:{width_tag}} {value:{width_value}} " \ "{origin:{width_origin}}\n".format( tag = tag, width_tag = width_tag, value = col_values[index], width_value = width_value, origin = col_origins[index], width_origin = width_origin) if index == 0: # print a header separator tag_info += u"{tag:{width_tag}} {value:{width_value}} " \ "{origin:{width_origin}}\n".format( tag = "-" * (width_tag - 1), width_tag = width_tag, value = "-" * (width_value - 1), width_value = width_value, origin = "-" * (width_origin - 1), width_origin = width_origin) tag_info += "\n" # Write to report file if self.text and (msg_tag == "PASS" and self.text_report_pass or msg_tag != "PASS"): with codecs.open(os.path.join(self.log_dir, "report-" + code + ".txt"), "w", encoding='utf-8', errors='ignore') as fo: fo.write(header) fo.write(output) fo.write(tag_info) if self.text_reproduction != None: template = jinja2.Template(self.text_reproduction) elif self.reproduction != None: template = jinja2.Template(self.reproduction) else: template = None if template: fo.write( template.render(tcfl_config_urls=tcfl.config.urls, **kws)) if self.junit: if self.junit_reproduction != None: template = jinja2.Template(self.junit_reproduction) elif self.reproduction != None: template = jinja2.Template(self.reproduction) else: template = None if template: reproduction = template.render( tcfl_config_urls=tcfl.config.urls, **kws) else: reproduction = "" self._mkreport_junit(_tc, kws, header, output, tag_info, reproduction)