|
|
@ -40,9 +40,15 @@ |
|
|
|
Corollary 2: an empty 'properties' dictionary matches every property set. |
|
|
|
Corollary 2: an empty 'properties' dictionary matches every property set. |
|
|
|
|
|
|
|
|
|
|
|
3) If a matching matcher is found, its 'name' string is presumed to be the name |
|
|
|
3) If a matching matcher is found, its 'name' string is presumed to be the name |
|
|
|
of the configuration the XML file corresponds to. Otherwise, a warning is |
|
|
|
of the configuration the XML file corresponds to. A warning is printed if |
|
|
|
printed. A warning is also printed if two different property sets match to the |
|
|
|
two different property sets match to the same configuration name. |
|
|
|
same configuration name. |
|
|
|
|
|
|
|
|
|
|
|
4) If a such a matcher isn't found, if --include-unmatched was specified, the |
|
|
|
|
|
|
|
configuration name is assumed to be the relative path from the sheet's |
|
|
|
|
|
|
|
directory to the XML file's containing directory. If the XML file isinstance |
|
|
|
|
|
|
|
directly inside the sheet's directory, the configuration name is instead |
|
|
|
|
|
|
|
a dump of all its properties. If --include-unmatched wasn't specified, |
|
|
|
|
|
|
|
the XML file is ignored and a warning is printed. |
|
|
|
|
|
|
|
|
|
|
|
* 'configurations': [string] |
|
|
|
* 'configurations': [string] |
|
|
|
List of names for compile-time and runtime configurations of OpenCV. |
|
|
|
List of names for compile-time and runtime configurations of OpenCV. |
|
|
@ -97,18 +103,25 @@ error_speedup_style = xlwt.easyxf('pattern: pattern solid, fore_color orange') |
|
|
|
header_style = xlwt.easyxf('font: bold true; alignment: horizontal centre, vertical top, wrap True') |
|
|
|
header_style = xlwt.easyxf('font: bold true; alignment: horizontal centre, vertical top, wrap True') |
|
|
|
|
|
|
|
|
|
|
|
class Collector(object): |
|
|
|
class Collector(object): |
|
|
|
def __init__(self, config_match_func): |
|
|
|
def __init__(self, config_match_func, include_unmatched): |
|
|
|
self.__config_cache = {} |
|
|
|
self.__config_cache = {} |
|
|
|
self.config_match_func = config_match_func |
|
|
|
self.config_match_func = config_match_func |
|
|
|
|
|
|
|
self.include_unmatched = include_unmatched |
|
|
|
self.tests = {} |
|
|
|
self.tests = {} |
|
|
|
|
|
|
|
self.extra_configurations = set() |
|
|
|
|
|
|
|
|
|
|
|
# Format a sorted sequence of pairs as if it was a dictionary. |
|
|
|
# Format a sorted sequence of pairs as if it was a dictionary. |
|
|
|
# We can't just use a dictionary instead, since we want to preserve the sorted order of the keys. |
|
|
|
# We can't just use a dictionary instead, since we want to preserve the sorted order of the keys. |
|
|
|
@staticmethod |
|
|
|
@staticmethod |
|
|
|
def __format_config_cache_key(pairs): |
|
|
|
def __format_config_cache_key(pairs, multiline=False): |
|
|
|
return '{' + ', '.join(repr(k) + ': ' + repr(v) for (k, v) in pairs) + '}' |
|
|
|
return ( |
|
|
|
|
|
|
|
('{\n' if multiline else '{') + |
|
|
|
def collect_from(self, xml_path): |
|
|
|
(',\n' if multiline else ', ').join( |
|
|
|
|
|
|
|
(' ' if multiline else '') + repr(k) + ': ' + repr(v) for (k, v) in pairs) + |
|
|
|
|
|
|
|
('\n}\n' if multiline else '}') |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def collect_from(self, xml_path, default_configuration): |
|
|
|
run = parseLogFile(xml_path) |
|
|
|
run = parseLogFile(xml_path) |
|
|
|
|
|
|
|
|
|
|
|
module = run.properties['module_name'] |
|
|
|
module = run.properties['module_name'] |
|
|
@ -124,8 +137,17 @@ class Collector(object): |
|
|
|
configuration = self.config_match_func(properties) |
|
|
|
configuration = self.config_match_func(properties) |
|
|
|
|
|
|
|
|
|
|
|
if configuration is None: |
|
|
|
if configuration is None: |
|
|
|
logging.warning('failed to match properties to a configuration: %s', |
|
|
|
if self.include_unmatched: |
|
|
|
Collector.__format_config_cache_key(props_key)) |
|
|
|
if default_configuration is not None: |
|
|
|
|
|
|
|
configuration = default_configuration |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
configuration = Collector.__format_config_cache_key(props_key, multiline=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self.extra_configurations.add(configuration) |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
logging.warning('failed to match properties to a configuration: %s', |
|
|
|
|
|
|
|
Collector.__format_config_cache_key(props_key)) |
|
|
|
|
|
|
|
|
|
|
|
else: |
|
|
|
else: |
|
|
|
same_config_props = [it[0] for it in self.__config_cache.iteritems() if it[1] == configuration] |
|
|
|
same_config_props = [it[0] for it in self.__config_cache.iteritems() if it[1] == configuration] |
|
|
|
if len(same_config_props) > 0: |
|
|
|
if len(same_config_props) > 0: |
|
|
@ -160,6 +182,8 @@ def main(): |
|
|
|
arg_parser.add_argument('sheet_dirs', nargs='+', metavar='DIR', help='directory containing perf test logs') |
|
|
|
arg_parser.add_argument('sheet_dirs', nargs='+', metavar='DIR', help='directory containing perf test logs') |
|
|
|
arg_parser.add_argument('-o', '--output', metavar='XLS', default='report.xls', help='name of output file') |
|
|
|
arg_parser.add_argument('-o', '--output', metavar='XLS', default='report.xls', help='name of output file') |
|
|
|
arg_parser.add_argument('-c', '--config', metavar='CONF', help='global configuration file') |
|
|
|
arg_parser.add_argument('-c', '--config', metavar='CONF', help='global configuration file') |
|
|
|
|
|
|
|
arg_parser.add_argument('--include-unmatched', action='store_true', |
|
|
|
|
|
|
|
help='include results from XML files that were not recognized by configuration matchers') |
|
|
|
|
|
|
|
|
|
|
|
args = arg_parser.parse_args() |
|
|
|
args = arg_parser.parse_args() |
|
|
|
|
|
|
|
|
|
|
@ -187,12 +211,18 @@ def main(): |
|
|
|
config_names = sheet_conf.get('configurations', []) |
|
|
|
config_names = sheet_conf.get('configurations', []) |
|
|
|
config_matchers = sheet_conf.get('configuration_matchers', []) |
|
|
|
config_matchers = sheet_conf.get('configuration_matchers', []) |
|
|
|
|
|
|
|
|
|
|
|
collector = Collector(make_match_func(config_matchers)) |
|
|
|
collector = Collector(make_match_func(config_matchers), args.include_unmatched) |
|
|
|
|
|
|
|
|
|
|
|
for root, _, filenames in os.walk(sheet_path): |
|
|
|
for root, _, filenames in os.walk(sheet_path): |
|
|
|
logging.info('looking in %s', root) |
|
|
|
logging.info('looking in %s', root) |
|
|
|
for filename in fnmatch.filter(filenames, '*.xml'): |
|
|
|
for filename in fnmatch.filter(filenames, '*.xml'): |
|
|
|
collector.collect_from(os.path.join(root, filename)) |
|
|
|
if os.path.normpath(sheet_path) == os.path.normpath(root): |
|
|
|
|
|
|
|
default_conf = None |
|
|
|
|
|
|
|
else: |
|
|
|
|
|
|
|
default_conf = os.path.relpath(root, sheet_path) |
|
|
|
|
|
|
|
collector.collect_from(os.path.join(root, filename), default_conf) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
config_names.extend(sorted(collector.extra_configurations - set(config_names))) |
|
|
|
|
|
|
|
|
|
|
|
sheet = wb.add_sheet(sheet_conf.get('sheet_name', os.path.basename(os.path.abspath(sheet_path)))) |
|
|
|
sheet = wb.add_sheet(sheet_conf.get('sheet_name', os.path.basename(os.path.abspath(sheet_path)))) |
|
|
|
|
|
|
|
|
|
|
|