Ram Gandikota
/
IOTMetronome
FRDM K64F Metronome
pal/Test/Unity/auto/unity_to_junit.py@0:dbad57390bd1, 2017-05-14 (annotated)
- Committer:
- ram54288
- Date:
- Sun May 14 18:37:05 2017 +0000
- Revision:
- 0:dbad57390bd1
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ram54288 | 0:dbad57390bd1 | 1 | import sys |
ram54288 | 0:dbad57390bd1 | 2 | import os |
ram54288 | 0:dbad57390bd1 | 3 | from glob import glob |
ram54288 | 0:dbad57390bd1 | 4 | |
ram54288 | 0:dbad57390bd1 | 5 | from pyparsing import * |
ram54288 | 0:dbad57390bd1 | 6 | from junit_xml import TestSuite, TestCase |
ram54288 | 0:dbad57390bd1 | 7 | |
ram54288 | 0:dbad57390bd1 | 8 | |
ram54288 | 0:dbad57390bd1 | 9 | class UnityTestSummary: |
ram54288 | 0:dbad57390bd1 | 10 | def __init__(self): |
ram54288 | 0:dbad57390bd1 | 11 | self.report = '' |
ram54288 | 0:dbad57390bd1 | 12 | self.total_tests = 0 |
ram54288 | 0:dbad57390bd1 | 13 | self.failures = 0 |
ram54288 | 0:dbad57390bd1 | 14 | self.ignored = 0 |
ram54288 | 0:dbad57390bd1 | 15 | self.targets = 0 |
ram54288 | 0:dbad57390bd1 | 16 | self.root = None |
ram54288 | 0:dbad57390bd1 | 17 | self.test_suites = dict() |
ram54288 | 0:dbad57390bd1 | 18 | |
ram54288 | 0:dbad57390bd1 | 19 | def run(self): |
ram54288 | 0:dbad57390bd1 | 20 | # Clean up result file names |
ram54288 | 0:dbad57390bd1 | 21 | results = [] |
ram54288 | 0:dbad57390bd1 | 22 | for target in self.targets: |
ram54288 | 0:dbad57390bd1 | 23 | results.append(target.replace('\\', '/')) |
ram54288 | 0:dbad57390bd1 | 24 | |
ram54288 | 0:dbad57390bd1 | 25 | # Dig through each result file, looking for details on pass/fail: |
ram54288 | 0:dbad57390bd1 | 26 | for result_file in results: |
ram54288 | 0:dbad57390bd1 | 27 | lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n'))) |
ram54288 | 0:dbad57390bd1 | 28 | if len(lines) == 0: |
ram54288 | 0:dbad57390bd1 | 29 | raise Exception("Empty test result file: %s" % result_file) |
ram54288 | 0:dbad57390bd1 | 30 | |
ram54288 | 0:dbad57390bd1 | 31 | # define an expression for your file reference |
ram54288 | 0:dbad57390bd1 | 32 | entry_one = Combine( |
ram54288 | 0:dbad57390bd1 | 33 | oneOf(list(alphas)) + ':/' + |
ram54288 | 0:dbad57390bd1 | 34 | Word(alphanums + '_-./')) |
ram54288 | 0:dbad57390bd1 | 35 | |
ram54288 | 0:dbad57390bd1 | 36 | entry_two = Word(printables + ' ', excludeChars=':') |
ram54288 | 0:dbad57390bd1 | 37 | entry = entry_one | entry_two |
ram54288 | 0:dbad57390bd1 | 38 | |
ram54288 | 0:dbad57390bd1 | 39 | delimiter = Literal(':').suppress() |
ram54288 | 0:dbad57390bd1 | 40 | tc_result_line = Group(entry.setResultsName('tc_file_name') + delimiter + entry.setResultsName( |
ram54288 | 0:dbad57390bd1 | 41 | 'tc_line_nr') + delimiter + entry.setResultsName('tc_name') + delimiter + entry.setResultsName( |
ram54288 | 0:dbad57390bd1 | 42 | 'tc_status') + Optional( |
ram54288 | 0:dbad57390bd1 | 43 | delimiter + entry.setResultsName('tc_msg'))).setResultsName("tc_line") |
ram54288 | 0:dbad57390bd1 | 44 | |
ram54288 | 0:dbad57390bd1 | 45 | eol = LineEnd().suppress() |
ram54288 | 0:dbad57390bd1 | 46 | sol = LineStart().suppress() |
ram54288 | 0:dbad57390bd1 | 47 | blank_line = sol + eol |
ram54288 | 0:dbad57390bd1 | 48 | |
ram54288 | 0:dbad57390bd1 | 49 | tc_summary_line = Group(Word(nums).setResultsName("num_of_tests") + "Tests" + Word(nums).setResultsName( |
ram54288 | 0:dbad57390bd1 | 50 | "num_of_fail") + "Failures" + Word(nums).setResultsName("num_of_ignore") + "Ignored").setResultsName( |
ram54288 | 0:dbad57390bd1 | 51 | "tc_summary") |
ram54288 | 0:dbad57390bd1 | 52 | tc_end_line = Or(Literal("FAIL"), Literal('Ok')).setResultsName("tc_result") |
ram54288 | 0:dbad57390bd1 | 53 | |
ram54288 | 0:dbad57390bd1 | 54 | # run it and see... |
ram54288 | 0:dbad57390bd1 | 55 | pp1 = tc_result_line | Optional(tc_summary_line | tc_end_line) |
ram54288 | 0:dbad57390bd1 | 56 | pp1.ignore(blank_line | OneOrMore("-")) |
ram54288 | 0:dbad57390bd1 | 57 | |
ram54288 | 0:dbad57390bd1 | 58 | result = list() |
ram54288 | 0:dbad57390bd1 | 59 | for l in lines: |
ram54288 | 0:dbad57390bd1 | 60 | result.append((pp1.parseString(l)).asDict()) |
ram54288 | 0:dbad57390bd1 | 61 | # delete empty results |
ram54288 | 0:dbad57390bd1 | 62 | result = filter(None, result) |
ram54288 | 0:dbad57390bd1 | 63 | |
ram54288 | 0:dbad57390bd1 | 64 | tc_list = list() |
ram54288 | 0:dbad57390bd1 | 65 | for r in result: |
ram54288 | 0:dbad57390bd1 | 66 | if 'tc_line' in r: |
ram54288 | 0:dbad57390bd1 | 67 | tmp_tc_line = r['tc_line'] |
ram54288 | 0:dbad57390bd1 | 68 | |
ram54288 | 0:dbad57390bd1 | 69 | # get only the file name which will be used as the classname |
ram54288 | 0:dbad57390bd1 | 70 | file_name = tmp_tc_line['tc_file_name'].split('\\').pop().split('/').pop().rsplit('.', 1)[0] |
ram54288 | 0:dbad57390bd1 | 71 | tmp_tc = TestCase(name=tmp_tc_line['tc_name'], classname=file_name) |
ram54288 | 0:dbad57390bd1 | 72 | if 'tc_status' in tmp_tc_line: |
ram54288 | 0:dbad57390bd1 | 73 | if str(tmp_tc_line['tc_status']) == 'IGNORE': |
ram54288 | 0:dbad57390bd1 | 74 | if 'tc_msg' in tmp_tc_line: |
ram54288 | 0:dbad57390bd1 | 75 | tmp_tc.add_skipped_info(message=tmp_tc_line['tc_msg'], |
ram54288 | 0:dbad57390bd1 | 76 | output=r'[File]={0}, [Line]={1}'.format( |
ram54288 | 0:dbad57390bd1 | 77 | tmp_tc_line['tc_file_name'], tmp_tc_line['tc_line_nr'])) |
ram54288 | 0:dbad57390bd1 | 78 | else: |
ram54288 | 0:dbad57390bd1 | 79 | tmp_tc.add_skipped_info(message=" ") |
ram54288 | 0:dbad57390bd1 | 80 | elif str(tmp_tc_line['tc_status']) == 'FAIL': |
ram54288 | 0:dbad57390bd1 | 81 | if 'tc_msg' in tmp_tc_line: |
ram54288 | 0:dbad57390bd1 | 82 | tmp_tc.add_failure_info(message=tmp_tc_line['tc_msg'], |
ram54288 | 0:dbad57390bd1 | 83 | output=r'[File]={0}, [Line]={1}'.format( |
ram54288 | 0:dbad57390bd1 | 84 | tmp_tc_line['tc_file_name'], tmp_tc_line['tc_line_nr'])) |
ram54288 | 0:dbad57390bd1 | 85 | else: |
ram54288 | 0:dbad57390bd1 | 86 | tmp_tc.add_failure_info(message=" ") |
ram54288 | 0:dbad57390bd1 | 87 | |
ram54288 | 0:dbad57390bd1 | 88 | tc_list.append((str(result_file), tmp_tc)) |
ram54288 | 0:dbad57390bd1 | 89 | |
ram54288 | 0:dbad57390bd1 | 90 | for k, v in tc_list: |
ram54288 | 0:dbad57390bd1 | 91 | try: |
ram54288 | 0:dbad57390bd1 | 92 | self.test_suites[k].append(v) |
ram54288 | 0:dbad57390bd1 | 93 | except KeyError: |
ram54288 | 0:dbad57390bd1 | 94 | self.test_suites[k] = [v] |
ram54288 | 0:dbad57390bd1 | 95 | ts = [] |
ram54288 | 0:dbad57390bd1 | 96 | for suite_name in self.test_suites: |
ram54288 | 0:dbad57390bd1 | 97 | ts.append(TestSuite(suite_name, self.test_suites[suite_name])) |
ram54288 | 0:dbad57390bd1 | 98 | |
ram54288 | 0:dbad57390bd1 | 99 | with open('result.xml', 'w') as f: |
ram54288 | 0:dbad57390bd1 | 100 | TestSuite.to_file(f, ts, prettyprint='True', encoding='utf-8') |
ram54288 | 0:dbad57390bd1 | 101 | |
ram54288 | 0:dbad57390bd1 | 102 | return self.report |
ram54288 | 0:dbad57390bd1 | 103 | |
ram54288 | 0:dbad57390bd1 | 104 | def set_targets(self, target_array): |
ram54288 | 0:dbad57390bd1 | 105 | self.targets = target_array |
ram54288 | 0:dbad57390bd1 | 106 | |
ram54288 | 0:dbad57390bd1 | 107 | def set_root_path(self, path): |
ram54288 | 0:dbad57390bd1 | 108 | self.root = path |
ram54288 | 0:dbad57390bd1 | 109 | |
ram54288 | 0:dbad57390bd1 | 110 | @staticmethod |
ram54288 | 0:dbad57390bd1 | 111 | def usage(err_msg=None): |
ram54288 | 0:dbad57390bd1 | 112 | print("\nERROR: ") |
ram54288 | 0:dbad57390bd1 | 113 | if err_msg: |
ram54288 | 0:dbad57390bd1 | 114 | print(err_msg) |
ram54288 | 0:dbad57390bd1 | 115 | print("\nUsage: unity_test_summary.py result_file_directory/ root_path/") |
ram54288 | 0:dbad57390bd1 | 116 | print(" result_file_directory - The location of your results files.") |
ram54288 | 0:dbad57390bd1 | 117 | print(" Defaults to current directory if not specified.") |
ram54288 | 0:dbad57390bd1 | 118 | print(" Should end in / if specified.") |
ram54288 | 0:dbad57390bd1 | 119 | print(" root_path - Helpful for producing more verbose output if using relative paths.") |
ram54288 | 0:dbad57390bd1 | 120 | sys.exit(1) |
ram54288 | 0:dbad57390bd1 | 121 | |
ram54288 | 0:dbad57390bd1 | 122 | |
ram54288 | 0:dbad57390bd1 | 123 | if __name__ == '__main__': |
ram54288 | 0:dbad57390bd1 | 124 | uts = UnityTestSummary() |
ram54288 | 0:dbad57390bd1 | 125 | try: |
ram54288 | 0:dbad57390bd1 | 126 | # look in the specified or current directory for result files |
ram54288 | 0:dbad57390bd1 | 127 | if len(sys.argv) > 1: |
ram54288 | 0:dbad57390bd1 | 128 | targets_dir = sys.argv[1] |
ram54288 | 0:dbad57390bd1 | 129 | else: |
ram54288 | 0:dbad57390bd1 | 130 | targets_dir = './' |
ram54288 | 0:dbad57390bd1 | 131 | targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*'))) |
ram54288 | 0:dbad57390bd1 | 132 | if len(targets) == 0: |
ram54288 | 0:dbad57390bd1 | 133 | raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir) |
ram54288 | 0:dbad57390bd1 | 134 | uts.set_targets(targets) |
ram54288 | 0:dbad57390bd1 | 135 | |
ram54288 | 0:dbad57390bd1 | 136 | # set the root path |
ram54288 | 0:dbad57390bd1 | 137 | if len(sys.argv) > 2: |
ram54288 | 0:dbad57390bd1 | 138 | root_path = sys.argv[2] |
ram54288 | 0:dbad57390bd1 | 139 | else: |
ram54288 | 0:dbad57390bd1 | 140 | root_path = os.path.split(__file__)[0] |
ram54288 | 0:dbad57390bd1 | 141 | uts.set_root_path(root_path) |
ram54288 | 0:dbad57390bd1 | 142 | |
ram54288 | 0:dbad57390bd1 | 143 | # run the summarizer |
ram54288 | 0:dbad57390bd1 | 144 | print(uts.run()) |
ram54288 | 0:dbad57390bd1 | 145 | except Exception as e: |
ram54288 | 0:dbad57390bd1 | 146 | UnityTestSummary.usage(e) |