1# Copyright 2011 Google Inc. All Rights Reserved. 2# Author: kbaclawski@google.com (Krystian Baclawski) 3# 4 5__author__ = 'kbaclawski@google.com (Krystian Baclawski)' 6 7from collections import namedtuple 8from cStringIO import StringIO 9import logging 10 11from summary import DejaGnuTestResult 12 13 14class 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