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