1*053f45beSAndroid Build Coastguard Worker#!/usr/bin/env python3 2*053f45beSAndroid Build Coastguard Worker 3*053f45beSAndroid Build Coastguard Workerfrom enum import Enum 4*053f45beSAndroid Build Coastguard Worker 5*053f45beSAndroid Build Coastguard Workerclass ResultState(Enum): 6*053f45beSAndroid Build Coastguard Worker noresult = -1 7*053f45beSAndroid Build Coastguard Worker skip = 0 8*053f45beSAndroid Build Coastguard Worker success = 1 9*053f45beSAndroid Build Coastguard Worker fail = 2 10*053f45beSAndroid Build Coastguard Worker 11*053f45beSAndroid Build Coastguard Workerclass TestResult: 12*053f45beSAndroid Build Coastguard Worker def __init__(self, test_id="", test_name=""): 13*053f45beSAndroid Build Coastguard Worker self.test_id = test_id 14*053f45beSAndroid Build Coastguard Worker self.test_name = test_name 15*053f45beSAndroid Build Coastguard Worker self.result = ResultState.noresult 16*053f45beSAndroid Build Coastguard Worker self.failmsg = "" 17*053f45beSAndroid Build Coastguard Worker self.errormsg = "" 18*053f45beSAndroid Build Coastguard Worker self.steps = [] 19*053f45beSAndroid Build Coastguard Worker 20*053f45beSAndroid Build Coastguard Worker def set_result(self, result): 21*053f45beSAndroid Build Coastguard Worker if (isinstance(result, ResultState)): 22*053f45beSAndroid Build Coastguard Worker self.result = result 23*053f45beSAndroid Build Coastguard Worker return True 24*053f45beSAndroid Build Coastguard Worker else: 25*053f45beSAndroid Build Coastguard Worker raise TypeError('Unknown result type, must be type ResultState') 26*053f45beSAndroid Build Coastguard Worker 27*053f45beSAndroid Build Coastguard Worker def get_result(self): 28*053f45beSAndroid Build Coastguard Worker return self.result 29*053f45beSAndroid Build Coastguard Worker 30*053f45beSAndroid Build Coastguard Worker def set_errormsg(self, errormsg): 31*053f45beSAndroid Build Coastguard Worker self.errormsg = errormsg 32*053f45beSAndroid Build Coastguard Worker return True 33*053f45beSAndroid Build Coastguard Worker 34*053f45beSAndroid Build Coastguard Worker def append_errormsg(self, errormsg): 35*053f45beSAndroid Build Coastguard Worker self.errormsg = '{}\n{}'.format(self.errormsg, errormsg) 36*053f45beSAndroid Build Coastguard Worker 37*053f45beSAndroid Build Coastguard Worker def get_errormsg(self): 38*053f45beSAndroid Build Coastguard Worker return self.errormsg 39*053f45beSAndroid Build Coastguard Worker 40*053f45beSAndroid Build Coastguard Worker def set_failmsg(self, failmsg): 41*053f45beSAndroid Build Coastguard Worker self.failmsg = failmsg 42*053f45beSAndroid Build Coastguard Worker return True 43*053f45beSAndroid Build Coastguard Worker 44*053f45beSAndroid Build Coastguard Worker def append_failmsg(self, failmsg): 45*053f45beSAndroid Build Coastguard Worker self.failmsg = '{}\n{}'.format(self.failmsg, failmsg) 46*053f45beSAndroid Build Coastguard Worker 47*053f45beSAndroid Build Coastguard Worker def get_failmsg(self): 48*053f45beSAndroid Build Coastguard Worker return self.failmsg 49*053f45beSAndroid Build Coastguard Worker 50*053f45beSAndroid Build Coastguard Worker def add_steps(self, newstep): 51*053f45beSAndroid Build Coastguard Worker if type(newstep) == list: 52*053f45beSAndroid Build Coastguard Worker self.steps.extend(newstep) 53*053f45beSAndroid Build Coastguard Worker elif type(newstep) == str: 54*053f45beSAndroid Build Coastguard Worker self.steps.append(step) 55*053f45beSAndroid Build Coastguard Worker else: 56*053f45beSAndroid Build Coastguard Worker raise TypeError('TdcResults.add_steps() requires a list or str') 57*053f45beSAndroid Build Coastguard Worker 58*053f45beSAndroid Build Coastguard Worker def get_executed_steps(self): 59*053f45beSAndroid Build Coastguard Worker return self.steps 60*053f45beSAndroid Build Coastguard Worker 61*053f45beSAndroid Build Coastguard Workerclass TestSuiteReport(): 62*053f45beSAndroid Build Coastguard Worker _testsuite = [] 63*053f45beSAndroid Build Coastguard Worker 64*053f45beSAndroid Build Coastguard Worker def add_resultdata(self, result_data): 65*053f45beSAndroid Build Coastguard Worker if isinstance(result_data, TestResult): 66*053f45beSAndroid Build Coastguard Worker self._testsuite.append(result_data) 67*053f45beSAndroid Build Coastguard Worker return True 68*053f45beSAndroid Build Coastguard Worker 69*053f45beSAndroid Build Coastguard Worker def count_tests(self): 70*053f45beSAndroid Build Coastguard Worker return len(self._testsuite) 71*053f45beSAndroid Build Coastguard Worker 72*053f45beSAndroid Build Coastguard Worker def count_failures(self): 73*053f45beSAndroid Build Coastguard Worker return sum(1 for t in self._testsuite if t.result == ResultState.fail) 74*053f45beSAndroid Build Coastguard Worker 75*053f45beSAndroid Build Coastguard Worker def count_skips(self): 76*053f45beSAndroid Build Coastguard Worker return sum(1 for t in self._testsuite if t.result == ResultState.skip) 77*053f45beSAndroid Build Coastguard Worker 78*053f45beSAndroid Build Coastguard Worker def find_result(self, test_id): 79*053f45beSAndroid Build Coastguard Worker return next((tr for tr in self._testsuite if tr.test_id == test_id), None) 80*053f45beSAndroid Build Coastguard Worker 81*053f45beSAndroid Build Coastguard Worker def update_result(self, result_data): 82*053f45beSAndroid Build Coastguard Worker orig = self.find_result(result_data.test_id) 83*053f45beSAndroid Build Coastguard Worker if orig != None: 84*053f45beSAndroid Build Coastguard Worker idx = self._testsuite.index(orig) 85*053f45beSAndroid Build Coastguard Worker self._testsuite[idx] = result_data 86*053f45beSAndroid Build Coastguard Worker else: 87*053f45beSAndroid Build Coastguard Worker self.add_resultdata(result_data) 88*053f45beSAndroid Build Coastguard Worker 89*053f45beSAndroid Build Coastguard Worker def format_tap(self): 90*053f45beSAndroid Build Coastguard Worker ftap = "" 91*053f45beSAndroid Build Coastguard Worker ftap += '1..{}\n'.format(self.count_tests()) 92*053f45beSAndroid Build Coastguard Worker index = 1 93*053f45beSAndroid Build Coastguard Worker for t in self._testsuite: 94*053f45beSAndroid Build Coastguard Worker if t.result == ResultState.fail: 95*053f45beSAndroid Build Coastguard Worker ftap += 'not ' 96*053f45beSAndroid Build Coastguard Worker ftap += 'ok {} {} - {}'.format(str(index), t.test_id, t.test_name) 97*053f45beSAndroid Build Coastguard Worker if t.result == ResultState.skip or t.result == ResultState.noresult: 98*053f45beSAndroid Build Coastguard Worker ftap += ' # skipped - {}\n'.format(t.errormsg) 99*053f45beSAndroid Build Coastguard Worker elif t.result == ResultState.fail: 100*053f45beSAndroid Build Coastguard Worker if len(t.steps) > 0: 101*053f45beSAndroid Build Coastguard Worker ftap += '\tCommands executed in this test case:' 102*053f45beSAndroid Build Coastguard Worker for step in t.steps: 103*053f45beSAndroid Build Coastguard Worker ftap += '\n\t\t{}'.format(step) 104*053f45beSAndroid Build Coastguard Worker ftap += '\n\t{}'.format(t.failmsg) 105*053f45beSAndroid Build Coastguard Worker ftap += '\n' 106*053f45beSAndroid Build Coastguard Worker index += 1 107*053f45beSAndroid Build Coastguard Worker return ftap 108*053f45beSAndroid Build Coastguard Worker 109*053f45beSAndroid Build Coastguard Worker def format_xunit(self): 110*053f45beSAndroid Build Coastguard Worker from xml.sax.saxutils import escape 111*053f45beSAndroid Build Coastguard Worker xunit = "<testsuites>\n" 112*053f45beSAndroid Build Coastguard Worker xunit += '\t<testsuite tests=\"{}\" skips=\"{}\">\n'.format(self.count_tests(), self.count_skips()) 113*053f45beSAndroid Build Coastguard Worker for t in self._testsuite: 114*053f45beSAndroid Build Coastguard Worker xunit += '\t\t<testcase classname=\"{}\" '.format(escape(t.test_id)) 115*053f45beSAndroid Build Coastguard Worker xunit += 'name=\"{}\">\n'.format(escape(t.test_name)) 116*053f45beSAndroid Build Coastguard Worker if t.failmsg: 117*053f45beSAndroid Build Coastguard Worker xunit += '\t\t\t<failure>\n' 118*053f45beSAndroid Build Coastguard Worker if len(t.steps) > 0: 119*053f45beSAndroid Build Coastguard Worker xunit += 'Commands executed in this test case:\n' 120*053f45beSAndroid Build Coastguard Worker for step in t.steps: 121*053f45beSAndroid Build Coastguard Worker xunit += '\t{}\n'.format(escape(step)) 122*053f45beSAndroid Build Coastguard Worker xunit += 'FAILURE: {}\n'.format(escape(t.failmsg)) 123*053f45beSAndroid Build Coastguard Worker xunit += '\t\t\t</failure>\n' 124*053f45beSAndroid Build Coastguard Worker if t.errormsg: 125*053f45beSAndroid Build Coastguard Worker xunit += '\t\t\t<error>\n{}\n'.format(escape(t.errormsg)) 126*053f45beSAndroid Build Coastguard Worker xunit += '\t\t\t</error>\n' 127*053f45beSAndroid Build Coastguard Worker if t.result == ResultState.skip: 128*053f45beSAndroid Build Coastguard Worker xunit += '\t\t\t<skipped/>\n' 129*053f45beSAndroid Build Coastguard Worker xunit += '\t\t</testcase>\n' 130*053f45beSAndroid Build Coastguard Worker xunit += '\t</testsuite>\n' 131*053f45beSAndroid Build Coastguard Worker xunit += '</testsuites>\n' 132*053f45beSAndroid Build Coastguard Worker return xunit 133