1# Copyright (c) 2013 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""Module containing base test results classes.""" 6 7class ResultType(object): 8 """Class enumerating test types.""" 9 PASS = 'PASS' 10 FAIL = 'FAIL' 11 CRASH = 'CRASH' 12 TIMEOUT = 'TIMEOUT' 13 UNKNOWN = 'UNKNOWN' 14 15 @staticmethod 16 def GetTypes(): 17 """Get a list of all test types.""" 18 return [ResultType.PASS, ResultType.FAIL, ResultType.CRASH, 19 ResultType.TIMEOUT, ResultType.UNKNOWN] 20 21 22class BaseTestResult(object): 23 """Base class for a single test result.""" 24 25 def __init__(self, name, test_type, log=''): 26 """Construct a BaseTestResult. 27 28 Args: 29 name: Name of the test which defines uniqueness. 30 test_type: Type of the test result as defined in ResultType. 31 log: An optional string listing any errors. 32 """ 33 assert name 34 assert test_type in ResultType.GetTypes() 35 self._name = name 36 self._test_type = test_type 37 self._log = log 38 39 def __str__(self): 40 return self._name 41 42 def __repr__(self): 43 return self._name 44 45 def __cmp__(self, other): 46 # pylint: disable=W0212 47 return cmp(self._name, other._name) 48 49 def __hash__(self): 50 return hash(self._name) 51 52 def SetName(self, name): 53 """Set the test name. 54 55 Because we're putting this into a set, this should only be used if moving 56 this test result into another set. 57 """ 58 self._name = name 59 60 def GetName(self): 61 """Get the test name.""" 62 return self._name 63 64 def GetType(self): 65 """Get the test result type.""" 66 return self._test_type 67 68 def GetLog(self): 69 """Get the test log.""" 70 return self._log 71 72 73class TestRunResults(object): 74 """Set of results for a test run.""" 75 76 def __init__(self): 77 self._results = set() 78 79 def GetLogs(self): 80 """Get the string representation of all test logs.""" 81 s = [] 82 for test_type in ResultType.GetTypes(): 83 if test_type != ResultType.PASS: 84 for t in sorted(self._GetType(test_type)): 85 log = t.GetLog() 86 if log: 87 s.append('[%s] %s:' % (test_type, t)) 88 s.append(log) 89 return '\n'.join(s) 90 91 def GetGtestForm(self): 92 """Get the gtest string representation of this object.""" 93 s = [] 94 plural = lambda n, s, p: '%d %s' % (n, p if n != 1 else s) 95 tests = lambda n: plural(n, 'test', 'tests') 96 97 s.append('[==========] %s ran.' % (tests(len(self.GetAll())))) 98 s.append('[ PASSED ] %s.' % (tests(len(self.GetPass())))) 99 100 not_passed = self.GetNotPass() 101 if len(not_passed) > 0: 102 s.append('[ FAILED ] %s, listed below:' % tests(len(self.GetNotPass()))) 103 for t in self.GetFail(): 104 s.append('[ FAILED ] %s' % str(t)) 105 for t in self.GetCrash(): 106 s.append('[ FAILED ] %s (CRASHED)' % str(t)) 107 for t in self.GetTimeout(): 108 s.append('[ FAILED ] %s (TIMEOUT)' % str(t)) 109 for t in self.GetUnknown(): 110 s.append('[ FAILED ] %s (UNKNOWN)' % str(t)) 111 s.append('') 112 s.append(plural(len(not_passed), 'FAILED TEST', 'FAILED TESTS')) 113 return '\n'.join(s) 114 115 def GetShortForm(self): 116 """Get the short string representation of this object.""" 117 s = [] 118 s.append('ALL: %d' % len(self._results)) 119 for test_type in ResultType.GetTypes(): 120 s.append('%s: %d' % (test_type, len(self._GetType(test_type)))) 121 return ''.join([x.ljust(15) for x in s]) 122 123 def __str__(self): 124 return self.GetLongForm() 125 126 def AddResult(self, result): 127 """Add |result| to the set. 128 129 Args: 130 result: An instance of BaseTestResult. 131 """ 132 assert isinstance(result, BaseTestResult) 133 self._results.add(result) 134 135 def AddResults(self, results): 136 """Add |results| to the set. 137 138 Args: 139 results: An iterable of BaseTestResult objects. 140 """ 141 for t in results: 142 self.AddResult(t) 143 144 def AddTestRunResults(self, results): 145 """Add the set of test results from |results|. 146 147 Args: 148 results: An instance of TestRunResults. 149 """ 150 assert isinstance(results, TestRunResults) 151 # pylint: disable=W0212 152 self._results.update(results._results) 153 154 def GetAll(self): 155 """Get the set of all test results.""" 156 return self._results.copy() 157 158 def _GetType(self, test_type): 159 """Get the set of test results with the given test type.""" 160 return set(t for t in self._results if t.GetType() == test_type) 161 162 def GetPass(self): 163 """Get the set of all passed test results.""" 164 return self._GetType(ResultType.PASS) 165 166 def GetFail(self): 167 """Get the set of all failed test results.""" 168 return self._GetType(ResultType.FAIL) 169 170 def GetCrash(self): 171 """Get the set of all crashed test results.""" 172 return self._GetType(ResultType.CRASH) 173 174 def GetTimeout(self): 175 """Get the set of all timed out test results.""" 176 return self._GetType(ResultType.TIMEOUT) 177 178 def GetUnknown(self): 179 """Get the set of all unknown test results.""" 180 return self._GetType(ResultType.UNKNOWN) 181 182 def GetNotPass(self): 183 """Get the set of all non-passed test results.""" 184 return self.GetAll() - self.GetPass() 185 186 def DidRunPass(self): 187 """Return whether the test run was successful.""" 188 return not self.GetNotPass() 189