xref: /aosp_15_r20/external/linux-kselftest/tools/testing/selftests/tc-testing/TdcResults.py (revision 053f45be4e351dfd5e965df293cd45b779f579ee)
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