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 __author__ = 'kbaclawski (at] google.com (Krystian Baclawski)'
      6 
      7 from collections import namedtuple
      8 from cStringIO import StringIO
      9 import logging
     10 
     11 from summary import DejaGnuTestResult
     12 
     13 
     14 class Manifest(namedtuple('Manifest', 'tool board results')):
     15   """Stores a list of unsuccessful tests.
     16 
     17   Any line that starts with '#@' marker carries auxiliary data in form of a
     18   key-value pair, for example:
     19 
     20   #@ tool: *
     21   #@ board: unix
     22 
     23   So far tool and board parameters are recognized.  Their value can contain
     24   arbitrary glob expression.  Based on aforementioned parameters given manifest
     25   will be applied for all test results, but only in selected test runs.  Note
     26   that all parameters are optional.  Their default value is '*' (i.e. for all
     27   tools/boards).
     28 
     29   The meaning of lines above is as follows: corresponding test results to follow
     30   should only be suppressed if test run was performed on "unix" board.
     31 
     32   The summary line used to build the test result should have this format:
     33 
     34   attrlist | UNRESOLVED: gcc.dg/unroll_1.c (test for excess errors)
     35   ^^^^^^^^   ^^^^^^^^^^  ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
     36   optional   result      name              variant
     37   attributes
     38   """
     39   SUPPRESSIBLE_RESULTS = ['FAIL', 'UNRESOLVED', 'XPASS', 'ERROR']
     40 
     41   @classmethod
     42   def FromDejaGnuTestRun(cls, test_run):
     43     results = [result
     44                for result in test_run.results
     45                if result.result in cls.SUPPRESSIBLE_RESULTS]
     46 
     47     return cls(test_run.tool, test_run.board, results)
     48 
     49   @classmethod
     50   def FromFile(cls, filename):
     51     """Creates manifest instance from a file in format described above."""
     52     params = {}
     53     results = []
     54 
     55     with open(filename, 'r') as manifest_file:
     56       for line in manifest_file:
     57         if line.startswith('#@'):
     58           # parse a line with a parameter
     59           try:
     60             key, value = line[2:].split(':', 1)
     61           except ValueError:
     62             logging.warning('Malformed parameter line: "%s".', line)
     63           else:
     64             params[key.strip()] = value.strip()
     65         else:
     66           # remove comment
     67           try:
     68             line, _ = line.split('#', 1)
     69           except ValueError:
     70             pass
     71 
     72           line = line.strip()
     73 
     74           if line:
     75             # parse a line with a test result
     76             result = DejaGnuTestResult.FromLine(line)
     77 
     78             if result:
     79               results.append(result)
     80             else:
     81               logging.warning('Malformed test result line: "%s".', line)
     82 
     83     tool = params.get('tool', '*')
     84     board = params.get('board', '*')
     85 
     86     return cls(tool, board, results)
     87 
     88   def Generate(self):
     89     """Dumps manifest to string."""
     90     text = StringIO()
     91 
     92     for name in ['tool', 'board']:
     93       text.write('#@ {0}: {1}\n'.format(name, getattr(self, name)))
     94 
     95     text.write('\n')
     96 
     97     for result in sorted(self.results, key=lambda r: r.result):
     98       text.write('{0}\n'.format(result))
     99 
    100     return text.getvalue()
    101 
    102   def __iter__(self):
    103     return iter(self.results)
    104