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