| #!/usr/bin/python |
| """Convert the wvtest results into standard gunit xml output.'. |
| |
| ^Testing ".+" in .+:$ marks starts of a test file |
| ^! .+$ marks a test case status |
| |
| Examples: |
| Testing "cwmpd" in unknown: |
| ! unknown:0 running cwmpd ok |
| ! unknown:0 grep X_CATAWAMPUS-ORG_CATAWAMPUS ok |
| ! unknown:0 NOT(grep NON_EXISTENT_NAME) ok |
| make[2]: Leaving directory |
| `/usr/local/google/brucefan/bruno-git/vendor/google/test' |
| make[2]: Entering directory |
| `/usr/local/google/brucefan/bruno-git/vendor/google/test' |
| echo "Testing 002-pytest.py" |
| Testing 002-pytest.py |
| ssh -l root 192.168.1.3 \ |
| 'cd /tmp/tests && python ./wvtest/wvtest.py 002-pytest.py' </dev/null |
| Importing: 002-pytest |
| |
| Testing "TestBasicPython" in 002-pytest.py: |
| ! 002-pytest.py:14 True ok |
| ! 002-pytest.py:15 1 == 1 ok |
| ! 002-pytest.py:16 1 != 2 ok |
| |
| The test result will be saved to a .xml file that can be used by our dashboard |
| system to stream the data into Sponge easily. |
| """ |
| |
| __author__ = 'brucefan@google.com (Chun Fan)' |
| |
| |
| from lxml import etree |
| import os |
| import re |
| import sys |
| |
| |
| class TestSuitesResult(object): |
| |
| def __init__(self, name): |
| self.name = name |
| self.test_suite_results = [] |
| |
| def AddTestSuiteResult(self, test_suite_result): |
| self.test_suite_results.append(test_suite_result) |
| |
| def ToXml(self): |
| el = etree.Element('testsuites') |
| el.set('name', self.name) |
| el.set('disabled', '0') |
| el.set('time', '0.0') |
| el.set('errors', '0') |
| for ts in self.test_suite_results: |
| el.append(ts.ToXml()) |
| self.total_tests = sum( |
| [ts.total_tests for ts in self.test_suite_results]) |
| self.failures = sum( |
| [ts.failures for ts in self.test_suite_results]) |
| el.set('failures', str(self.failures)) |
| el.set('tests', str(self.total_tests)) |
| return el |
| |
| |
| class TestSuiteResult(object): |
| |
| def __init__(self, name): |
| self.name = name |
| self.test_case_results = [] |
| |
| def AddTestCaseResult(self, test_case_result): |
| self.test_case_results.append(test_case_result) |
| |
| def ToXml(self): |
| el = etree.Element('testsuite') |
| el.set('name', self.name) |
| el.set('disabled', '0') |
| el.set('time', '0.0') |
| el.set('errors', '0') |
| for tc in self.test_case_results: |
| el.append(tc.ToXml()) |
| self.total_tests = len(self.test_case_results) |
| self.failures = len([tc for tc in self.test_case_results if tc.result]) |
| el.set('failures', str(self.failures)) |
| el.set('tests', str(self.total_tests)) |
| return el |
| |
| |
| class TestCaseResult(object): |
| |
| PASSED = 0 |
| FAILED = 1 |
| ERROR = 2 |
| |
| def __init__(self, name, class_name, result, result_msg=None): |
| self.name = name |
| self.class_name = class_name |
| self.result = result |
| self.result_msg = result_msg |
| |
| def ToXml(self): |
| el = etree.Element('testcase') |
| el.set('name', self.name) |
| el.set('classname', self.class_name) |
| el.set('time', '0') |
| el.set('status', 'run') |
| if self.result: |
| print 'Test case: ', self.name, 'FAILED with result code', self.result |
| failure = etree.Element('failure') |
| failure.text = self.result_msg |
| el.append(failure) |
| else: |
| print 'Test case: ', self.name, 'PASSED with result code', self.result |
| return el |
| |
| |
| def ParseTestResult(result_file, output_xml_file): |
| """Parse the given result file and dump out parsed data to given output.""" |
| if not os.path.exists(result_file): |
| print 'Error: Given result file does not exist: ', result_file |
| return |
| test_suites = TestSuitesResult('Bruno Release Smoke') |
| current_test_suite = None |
| with open(result_file, 'r') as f: |
| for line in f: |
| m = re.search(r'^Testing \"(.+)\" in (.+):$', line) |
| if m: |
| # a new start for a test file |
| suite_name = m.group(1) |
| file_name = m.group(2) |
| print 'Processing suite', suite_name, 'in file', file_name |
| current_test_suite = TestSuiteResult(suite_name) |
| test_suites.AddTestSuiteResult(current_test_suite) |
| continue |
| if line.startswith('! '): |
| if not current_test_suite: |
| print 'WARNING: Encounter a test case before a test suite is seen.' |
| continue |
| # Found a test case result |
| parts = line.strip().split(' ') |
| test_case_name = ' '.join(parts[2:-2]).strip() |
| test_case_class_name = '%s-%s' % ( |
| current_test_suite.name, test_case_name) |
| test_case_result = TestCaseResult.PASSED |
| test_case_result_msg = '' |
| if parts[-1] != 'ok': |
| test_case_result = TestCaseResult.FAILED |
| test_case_result_msg = line |
| print 'Processing test case: ', test_case_name, test_case_result |
| current_test_suite.AddTestCaseResult( |
| TestCaseResult( |
| name=test_case_name, |
| class_name=test_case_class_name, |
| result=test_case_result, |
| result_msg=test_case_result_msg)) |
| # Now it is time to write the xml output |
| with open(output_xml_file, 'w') as f: |
| f.write(etree.tostring(test_suites.ToXml(), pretty_print=True)) |
| |
| |
| def main(argv): |
| ParseTestResult(sys.argv[1], sys.argv[2]) |
| |
| |
| if __name__ == '__main__': |
| main(sys.argv) |