1 #!/usr/bin/python 2 import json 3 import optparse 4 import os 5 import sys 6 7 from webkitpy.common.host import Host 8 9 def main(argv): 10 parser = optparse.OptionParser(usage='%prog [times_ms.json]') 11 parser.add_option('-f', '--forward', action='store', type='int', 12 help='group times by first N directories of test') 13 parser.add_option('-b', '--backward', action='store', type='int', 14 help='group times by last N directories of test') 15 16 epilog = """ 17 You can print out aggregate times per directory using the -f and -b 18 flags. The value passed to each flag indicates the "depth" of the flag, 19 similar to positive and negative arguments to python arrays. 20 21 For example, given fast/forms/week/week-input-type.html, -f 1 22 truncates to 'fast', -f 2 and -b 2 truncates to 'fast/forms', and -b 1 23 truncates to fast/forms/week . -f 0 truncates to '', which can be used 24 to produce a single total time for the run.""" 25 parser.epilog = '\n'.join(s.lstrip() for s in epilog.splitlines()) 26 27 options, args = parser.parse_args(argv) 28 host = Host() 29 if args and args[0]: 30 times_ms_path = args[0] 31 else: 32 times_ms_path = host.filesystem.join(host.port_factory.get().results_directory(), 'times_ms.json') 33 34 with open(times_ms_path, 'r') as fp: 35 times_trie = json.load(fp) 36 37 times = convert_trie_to_flat_paths(times_trie) 38 39 def key_for(path): 40 if options.forward is not None: 41 return os.sep.join(path.split(os.sep)[:-1][:options.forward]) 42 if options.backward is not None: 43 return os.sep.join(path.split(os.sep)[:-options.backward]) 44 return path 45 46 times_by_key = {} 47 for test_name in times: 48 key = key_for(test_name) 49 if key in times_by_key: 50 times_by_key[key] += times[test_name] 51 else: 52 times_by_key[key] = times[test_name] 53 54 for key in sorted(times_by_key): 55 print "%s %d" % (key, times_by_key[key]) 56 57 def convert_trie_to_flat_paths(trie, prefix=None): 58 # Cloned from webkitpy.layout_tests.layout_package.json_results_generator 59 # so that this code can stand alone. 60 result = {} 61 for name, data in trie.iteritems(): 62 if prefix: 63 name = prefix + "/" + name 64 if isinstance(data, int): 65 result[name] = data 66 else: 67 result.update(convert_trie_to_flat_paths(data, name)) 68 69 return result 70 71 72 if __name__ == '__main__': 73 sys.exit(main(sys.argv[1:])) 74