13d69d8b76f487f74be152ed15b75438e7de947bdkbaclawski# Copyright 2011 Google Inc. All Rights Reserved. 23d69d8b76f487f74be152ed15b75438e7de947bdkbaclawski# Author: kbaclawski@google.com (Krystian Baclawski) 33d69d8b76f487f74be152ed15b75438e7de947bdkbaclawski# 43d69d8b76f487f74be152ed15b75438e7de947bdkbaclawski 5fe30dd5ad4357e9846038cb5fe0e4bf4a17a3f71kbaclawskiimport logging 63d69d8b76f487f74be152ed15b75438e7de947bdkbaclawskiimport os.path 73d69d8b76f487f74be152ed15b75438e7de947bdkbaclawski 8ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawskiRESULT_DESCRIPTION = { 9ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'ERROR': 'DejaGNU errors', 10ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'FAIL': 'Failed tests', 11ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'NOTE': 'DejaGNU notices', 12ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'PASS': 'Passed tests', 13ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'UNRESOLVED': 'Unresolved tests', 14ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'UNSUPPORTED': 'Unsupported tests', 15ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'UNTESTED': 'Not executed tests', 16ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'WARNING': 'DejaGNU warnings', 17ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'XFAIL': 'Expected test failures', 18f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano 'XPASS': 'Unexpectedly passed tests' 19f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano} 20ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 21ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawskiRESULT_GROUPS = { 22ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'Successes': ['PASS', 'XFAIL'], 23ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'Failures': ['FAIL', 'XPASS', 'UNRESOLVED'], 24ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'Suppressed': ['!FAIL', '!XPASS', '!UNRESOLVED', '!ERROR'], 25f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano 'Framework': ['UNTESTED', 'UNSUPPORTED', 'ERROR', 'WARNING', 'NOTE'] 26f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano} 27ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 28ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawskiROOT_PATH = os.path.dirname(os.path.abspath(__file__)) 29ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 30ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 31ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawskidef _GetResultDescription(name): 32ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski if name.startswith('!'): 33ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski name = name[1:] 34ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 35ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski try: 36ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski return RESULT_DESCRIPTION[name] 37ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski except KeyError: 38ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski raise ValueError('Unknown result: "%s"' % name) 39ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 40ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 41ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawskidef _PrepareSummary(res_types, summary): 42f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano 43ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski def GetResultCount(res_type): 44ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski return summary.get(res_type, 0) 45ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 46f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano return [(_GetResultDescription(rt), GetResultCount(rt)) for rt in res_types] 47ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 48ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 49ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawskidef _PrepareTestList(res_types, tests): 50f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano 51ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski def GetTestsByResult(res_type): 52ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski return [(test.name, test.variant or '') 53f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano for test in sorted(tests) if test.result == res_type] 54ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 55ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski return [(_GetResultDescription(rt), GetTestsByResult(rt)) 56ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski for rt in res_types if rt != 'PASS'] 57ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 58ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 59ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawskidef Generate(test_runs, manifests): 60ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski """Generate HTML report from provided test runs. 61ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 62ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski Args: 63ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski test_runs: DejaGnuTestRun objects list. 64ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski manifests: Manifest object list that will drive test result suppression. 65ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 66ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski Returns: 67ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski String to which the HTML report was rendered. 68ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski """ 69ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski tmpl_args = [] 70ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 71ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski for test_run_id, test_run in enumerate(test_runs): 72ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski logging.info('Generating report for: %s.', test_run) 73ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 74ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski test_run.CleanUpTestResults() 75ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski test_run.SuppressTestResults(manifests) 76ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 77ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski # Generate summary and test list for each result group 78ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski groups = {} 79ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 80ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski for res_group, res_types in RESULT_GROUPS.items(): 81ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski summary_all = _PrepareSummary(res_types, test_run.summary) 82ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski tests_all = _PrepareTestList(res_types, test_run.results) 83ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 84ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski has_2nd = lambda tuple2: bool(tuple2[1]) 85ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski summary = filter(has_2nd, summary_all) 86ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski tests = filter(has_2nd, tests_all) 87ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 88ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski if summary or tests: 89ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski groups[res_group] = {'summary': summary, 'tests': tests} 90ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 91ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski tmpl_args.append({ 92ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'id': test_run_id, 93ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 'name': '%s @%s' % (test_run.tool, test_run.board), 94f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano 'groups': groups 95f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano }) 96ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 97ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski logging.info('Rendering report in HTML format.') 98ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 99ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski try: 100ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski from django import template 101ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski from django.template import loader 102ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski from django.conf import settings 103ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski except ImportError: 104ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski logging.error('Django framework not installed!') 105ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski logging.error('Failed to generate report in HTML format!') 106ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski return '' 107ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 108f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano settings.configure(DEBUG=True, 109f2a3ef46f75d2196a93d3ed27f4d1fcf22b54fbeLuis Lozano TEMPLATE_DEBUG=True, 110ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski TEMPLATE_DIRS=(ROOT_PATH,)) 111ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 112ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski tmpl = loader.get_template('report.html') 113ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski ctx = template.Context({'test_runs': tmpl_args}) 114ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski 115ee9d100c66939659aa3f3e5377772da59615f4e1kbaclawski return tmpl.render(ctx) 116