diff --git a/modules/ts/misc/perf_tests_timing.py b/modules/ts/misc/perf_tests_timing.py new file mode 100644 index 0000000000..70d2aa2f03 --- /dev/null +++ b/modules/ts/misc/perf_tests_timing.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python + +import testlog_parser, sys, os, xml, glob, re +from table_formatter import * +from optparse import OptionParser +from operator import itemgetter, attrgetter +from summary import getSetName, alphanum_keyselector + +if __name__ == "__main__": + usage = "%prog .xml [...]" + parser = OptionParser(usage = usage) + + parser.add_option("-o", "--output", dest = "format", + help = "output results in text format (can be 'txt', 'html' or 'auto' - default)", + metavar = 'FMT', default = 'auto') + + (options, args) = parser.parse_args() + if 1 != len(args): + parser.print_help() + exit(0) + + options.generateHtml = detectHtmlOutputType(options.format) + + # expand wildcards and filter duplicates + file = os.path.abspath(args[0]) + if not os.path.isfile(file): + sys.stderr.write("IOError reading \"" + file + "\" - " + str(err) + os.linesep) + parser.print_help() + exit(0) + + # read all passed files + test_sets = [] + try: + tests = testlog_parser.parseLogFile(file) + if tests: + test_sets.append((os.path.basename(file), tests)) + except IOError as err: + sys.stderr.write("IOError reading \"" + file + "\" - " + str(err) + os.linesep) + except xml.parsers.expat.ExpatError as err: + sys.stderr.write("ExpatError reading \"" + file + "\" - " + str(err) + os.linesep) + + if not test_sets: + sys.stderr.write("Error: no test data found" + os.linesep) + quit() + + # find matches + setsCount = len(test_sets) + test_cases = {} + + name_extractor = lambda name: str(name) + + for i in range(setsCount): + for case in test_sets[i][1]: + name = name_extractor(case) + if name not in test_cases: + test_cases[name] = [None] * setsCount + test_cases[name][i] = case + + testsuits = [] # testsuit name, time, flag for failed tests + + prevGroupName = None + suit_time = 0 + has_failed = False + for name in sorted(test_cases.iterkeys(), key=alphanum_keyselector): + cases = test_cases[name] + + groupName = next(c for c in cases if c).shortName() + if groupName != prevGroupName: + if prevGroupName != None: + testsuits.append({'name': prevGroupName, 'time': suit_time, \ + 'failed': has_failed}) + has_failed = False + suit_time = 0 + prevGroupName = groupName + + for i in range(setsCount): + case = cases[i] + if not case is None: + if case.get('status') == 'run': + suit_time += case.get('time') + if case.get('status') == 'failed': + has_failed = True + + tbl = table() + + # header + tbl.newColumn('name', 'Name of testsuit', align = 'left', cssclass = 'col_name') + tbl.newColumn('time', 'Time (ms)', align = 'left', cssclass = 'col_name') + tbl.newColumn('failed', 'Failed tests', align = 'center', cssclass = 'col_name') + + # rows + for suit in sorted(testsuits, key = lambda suit: suit['time'], reverse = True): + tbl.newRow() + tbl.newCell('name', suit['name']) + tbl.newCell('time', formatValue(suit['time'], '', ''), suit['time']) + if (suit['failed']): + tbl.newCell('failed', 'Yes') + else: + tbl.newCell('failed', ' ') + + # output table + if options.generateHtml: + tbl.htmlPrintTable(sys.stdout) + htmlPrintFooter(sys.stdout) + else: + tbl.consolePrintTable(sys.stdout) \ No newline at end of file diff --git a/modules/ts/misc/testlog_parser.py b/modules/ts/misc/testlog_parser.py index ce55b8b1de..f61b47bba9 100755 --- a/modules/ts/misc/testlog_parser.py +++ b/modules/ts/misc/testlog_parser.py @@ -30,6 +30,7 @@ class TestInfo(object): self.parseLongMetric(xmlnode, "mean"); self.parseLongMetric(xmlnode, "stddev"); self.parseFloatMetric(xmlnode, "gstddev"); + self.parseFloatMetric(xmlnode, "time"); def parseLongMetric(self, xmlnode, name, default = 0): if xmlnode.hasAttribute(name): @@ -78,6 +79,8 @@ class TestInfo(object): val = self.metrix.get(name, None) if not val: return val + if name == "time": + return self.metrix.get("time") if name in ["gmean", "min", "mean", "median", "stddev"]: scale = 1.0 frequency = self.metrix.get("frequency", 1.0) or 1.0