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