17757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#!/usr/bin/python
27757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
37757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# Copyright (C) 2012 Google Inc. All rights reserved.
47757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#
57757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# Redistribution and use in source and binary forms, with or without
67757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# modification, are permitted provided that the following conditions are
77757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# met:
87757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#
97757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#     * Redistributions of source code must retain the above copyright
107757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# notice, this list of conditions and the following disclaimer.
117757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#     * Redistributions in binary form must reproduce the above
127757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# copyright notice, this list of conditions and the following disclaimer
137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# in the documentation and/or other materials provided with the
147757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# distribution.
157757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#     * Neither the name of Google Inc. nor the names of its
167757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# contributors may be used to endorse or promote products derived from
177757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# this software without specific prior written permission.
187757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#
197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
207757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
237757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
247757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
267757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
277757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
287757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
297757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
307757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochimport json
327757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochimport optparse
337757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochimport sys
347757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
357757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochfrom webkitpy.common.host import Host
367757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
377757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochdef main(argv):
387757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    parser = optparse.OptionParser(usage='%prog [stats.json]')
397757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    parser.description = "Prints out lists of tests run on each worker as per the stats.json file."
407757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    options, args = parser.parse_args(argv)
417757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
427757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    if args and args[0]:
437757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        stats_path = args[0]
447757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    else:
457757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        host = Host()
467757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        stats_path = host.filesystem.join(host.port_factory.get().results_directory(), 'stats.json')
477757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    with open(stats_path, 'r') as fp:
497757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch         stats_trie = json.load(fp)
507757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    stats = convert_trie_to_flat_paths(stats_trie)
527757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    stats_by_worker = {}
537757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    for test_name, data in stats.items():
547757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        worker = "worker/" + str(data["results"][0])
557757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if worker not in stats_by_worker:
567757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            stats_by_worker[worker] = []
577757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        test_number = data["results"][1]
587757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        stats_by_worker[worker].append({
597757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "name": test_name,
607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            "number": test_number
617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        })
627757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
637757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    for worker in sorted(stats_by_worker.keys()):
647757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        print worker + ':'
657757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        for test in sorted(stats_by_worker[worker], key=lambda test:test["number"]):
667757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            print test["name"]
677757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        print
687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
697757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochdef convert_trie_to_flat_paths(trie, prefix=None):
707757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    # Cloned from webkitpy.layout_tests.layout_package.json_results_generator
717757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    # so that this code can stand alone.
727757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    result = {}
737757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    for name, data in trie.iteritems():
747757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if prefix:
757757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            name = prefix + "/" + name
767757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        if "results" in data:
777757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            result[name] = data
787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch        else:
797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch            result.update(convert_trie_to_flat_paths(data, name))
807757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
817757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    return result
827757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
837757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
847757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochif __name__ ==  '__main__':
857757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    sys.exit(main(sys.argv[1:]))
86