A metronome using the FRDM K64F board

Committer:
ram54288
Date:
Sun May 14 18:40:18 2017 +0000
Revision:
0:a7a43371b306
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ram54288 0:a7a43371b306 1 #! python3
ram54288 0:a7a43371b306 2 # ==========================================
ram54288 0:a7a43371b306 3 # Unity Project - A Test Framework for C
ram54288 0:a7a43371b306 4 # Copyright (c) 2015 Alexander Mueller / XelaRellum@web.de
ram54288 0:a7a43371b306 5 # [Released under MIT License. Please refer to license.txt for details]
ram54288 0:a7a43371b306 6 # Based on the ruby script by Mike Karlesky, Mark VanderVoord, Greg Williams
ram54288 0:a7a43371b306 7 # ==========================================
ram54288 0:a7a43371b306 8 import sys
ram54288 0:a7a43371b306 9 import os
ram54288 0:a7a43371b306 10 import re
ram54288 0:a7a43371b306 11 from glob import glob
ram54288 0:a7a43371b306 12
ram54288 0:a7a43371b306 13 class UnityTestSummary:
ram54288 0:a7a43371b306 14 def __init__(self):
ram54288 0:a7a43371b306 15 self.report = ''
ram54288 0:a7a43371b306 16 self.total_tests = 0
ram54288 0:a7a43371b306 17 self.failures = 0
ram54288 0:a7a43371b306 18 self.ignored = 0
ram54288 0:a7a43371b306 19
ram54288 0:a7a43371b306 20 def run(self):
ram54288 0:a7a43371b306 21 # Clean up result file names
ram54288 0:a7a43371b306 22 results = []
ram54288 0:a7a43371b306 23 for target in self.targets:
ram54288 0:a7a43371b306 24 results.append(target.replace('\\', '/'))
ram54288 0:a7a43371b306 25
ram54288 0:a7a43371b306 26 # Dig through each result file, looking for details on pass/fail:
ram54288 0:a7a43371b306 27 failure_output = []
ram54288 0:a7a43371b306 28 ignore_output = []
ram54288 0:a7a43371b306 29
ram54288 0:a7a43371b306 30 for result_file in results:
ram54288 0:a7a43371b306 31 lines = list(map(lambda line: line.rstrip(), open(result_file, "r").read().split('\n')))
ram54288 0:a7a43371b306 32 if len(lines) == 0:
ram54288 0:a7a43371b306 33 raise Exception("Empty test result file: %s" % result_file)
ram54288 0:a7a43371b306 34
ram54288 0:a7a43371b306 35 details = self.get_details(result_file, lines)
ram54288 0:a7a43371b306 36 failures = details['failures']
ram54288 0:a7a43371b306 37 ignores = details['ignores']
ram54288 0:a7a43371b306 38 if len(failures) > 0: failure_output.append('\n'.join(failures))
ram54288 0:a7a43371b306 39 if len(ignores) > 0: ignore_output.append('n'.join(ignores))
ram54288 0:a7a43371b306 40 tests,failures,ignored = self.parse_test_summary('\n'.join(lines))
ram54288 0:a7a43371b306 41 self.total_tests += tests
ram54288 0:a7a43371b306 42 self.failures += failures
ram54288 0:a7a43371b306 43 self.ignored += ignored
ram54288 0:a7a43371b306 44
ram54288 0:a7a43371b306 45 if self.ignored > 0:
ram54288 0:a7a43371b306 46 self.report += "\n"
ram54288 0:a7a43371b306 47 self.report += "--------------------------\n"
ram54288 0:a7a43371b306 48 self.report += "UNITY IGNORED TEST SUMMARY\n"
ram54288 0:a7a43371b306 49 self.report += "--------------------------\n"
ram54288 0:a7a43371b306 50 self.report += "\n".join(ignore_output)
ram54288 0:a7a43371b306 51
ram54288 0:a7a43371b306 52 if self.failures > 0:
ram54288 0:a7a43371b306 53 self.report += "\n"
ram54288 0:a7a43371b306 54 self.report += "--------------------------\n"
ram54288 0:a7a43371b306 55 self.report += "UNITY FAILED TEST SUMMARY\n"
ram54288 0:a7a43371b306 56 self.report += "--------------------------\n"
ram54288 0:a7a43371b306 57 self.report += '\n'.join(failure_output)
ram54288 0:a7a43371b306 58
ram54288 0:a7a43371b306 59 self.report += "\n"
ram54288 0:a7a43371b306 60 self.report += "--------------------------\n"
ram54288 0:a7a43371b306 61 self.report += "OVERALL UNITY TEST SUMMARY\n"
ram54288 0:a7a43371b306 62 self.report += "--------------------------\n"
ram54288 0:a7a43371b306 63 self.report += "{total_tests} TOTAL TESTS {failures} TOTAL FAILURES {ignored} IGNORED\n".format(total_tests = self.total_tests, failures=self.failures, ignored=self.ignored)
ram54288 0:a7a43371b306 64 self.report += "\n"
ram54288 0:a7a43371b306 65
ram54288 0:a7a43371b306 66 return self.report
ram54288 0:a7a43371b306 67
ram54288 0:a7a43371b306 68 def set_targets(self, target_array):
ram54288 0:a7a43371b306 69 self.targets = target_array
ram54288 0:a7a43371b306 70
ram54288 0:a7a43371b306 71 def set_root_path(self, path):
ram54288 0:a7a43371b306 72 self.root = path
ram54288 0:a7a43371b306 73
ram54288 0:a7a43371b306 74 def usage(self, err_msg=None):
ram54288 0:a7a43371b306 75 print("\nERROR: ")
ram54288 0:a7a43371b306 76 if err_msg:
ram54288 0:a7a43371b306 77 print(err_msg)
ram54288 0:a7a43371b306 78 print("\nUsage: unity_test_summary.py result_file_directory/ root_path/")
ram54288 0:a7a43371b306 79 print(" result_file_directory - The location of your results files.")
ram54288 0:a7a43371b306 80 print(" Defaults to current directory if not specified.")
ram54288 0:a7a43371b306 81 print(" Should end in / if specified.")
ram54288 0:a7a43371b306 82 print(" root_path - Helpful for producing more verbose output if using relative paths.")
ram54288 0:a7a43371b306 83 sys.exit(1)
ram54288 0:a7a43371b306 84
ram54288 0:a7a43371b306 85 def get_details(self, result_file, lines):
ram54288 0:a7a43371b306 86 results = { 'failures': [], 'ignores': [], 'successes': [] }
ram54288 0:a7a43371b306 87 for line in lines:
ram54288 0:a7a43371b306 88 parts = line.split(':')
ram54288 0:a7a43371b306 89 if len(parts) != 5:
ram54288 0:a7a43371b306 90 continue
ram54288 0:a7a43371b306 91 src_file,src_line,test_name,status,msg = parts
ram54288 0:a7a43371b306 92 if len(self.root) > 0:
ram54288 0:a7a43371b306 93 line_out = "%s%s" % (self.root, line)
ram54288 0:a7a43371b306 94 else:
ram54288 0:a7a43371b306 95 line_out = line
ram54288 0:a7a43371b306 96 if status == 'IGNORE':
ram54288 0:a7a43371b306 97 results['ignores'].append(line_out)
ram54288 0:a7a43371b306 98 elif status == 'FAIL':
ram54288 0:a7a43371b306 99 results['failures'].append(line_out)
ram54288 0:a7a43371b306 100 elif status == 'PASS':
ram54288 0:a7a43371b306 101 results['successes'].append(line_out)
ram54288 0:a7a43371b306 102 return results
ram54288 0:a7a43371b306 103
ram54288 0:a7a43371b306 104 def parse_test_summary(self, summary):
ram54288 0:a7a43371b306 105 m = re.search(r"([0-9]+) Tests ([0-9]+) Failures ([0-9]+) Ignored", summary)
ram54288 0:a7a43371b306 106 if not m:
ram54288 0:a7a43371b306 107 raise Exception("Couldn't parse test results: %s" % summary)
ram54288 0:a7a43371b306 108
ram54288 0:a7a43371b306 109 return int(m.group(1)), int(m.group(2)), int(m.group(3))
ram54288 0:a7a43371b306 110
ram54288 0:a7a43371b306 111
ram54288 0:a7a43371b306 112 if __name__ == '__main__':
ram54288 0:a7a43371b306 113 uts = UnityTestSummary()
ram54288 0:a7a43371b306 114 try:
ram54288 0:a7a43371b306 115 #look in the specified or current directory for result files
ram54288 0:a7a43371b306 116 if len(sys.argv) > 1:
ram54288 0:a7a43371b306 117 targets_dir = sys.argv[1]
ram54288 0:a7a43371b306 118 else:
ram54288 0:a7a43371b306 119 targets_dir = './'
ram54288 0:a7a43371b306 120 targets = list(map(lambda x: x.replace('\\', '/'), glob(targets_dir + '*.test*')))
ram54288 0:a7a43371b306 121 if len(targets) == 0:
ram54288 0:a7a43371b306 122 raise Exception("No *.testpass or *.testfail files found in '%s'" % targets_dir)
ram54288 0:a7a43371b306 123 uts.set_targets(targets)
ram54288 0:a7a43371b306 124
ram54288 0:a7a43371b306 125 #set the root path
ram54288 0:a7a43371b306 126 if len(sys.argv) > 2:
ram54288 0:a7a43371b306 127 root_path = sys.argv[2]
ram54288 0:a7a43371b306 128 else:
ram54288 0:a7a43371b306 129 root_path = os.path.split(__file__)[0]
ram54288 0:a7a43371b306 130 uts.set_root_path(root_path)
ram54288 0:a7a43371b306 131
ram54288 0:a7a43371b306 132 #run the summarizer
ram54288 0:a7a43371b306 133 print(uts.run())
ram54288 0:a7a43371b306 134 except Exception as e:
ram54288 0:a7a43371b306 135 uts.usage(e)