| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2015 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 """See README.md for usage instructions. | |
| 7 | |
| 8 This file heavily modified from build/scripts/slave/gtest_slave_utils.py and | |
| 9 is intended to replace it as all tests move to swarming. | |
| 10 TODO(estaab): Remove build/scripts/slave/gtest.* once this is fully deployed. | |
| 11 """ | |
| 12 | |
| 13 | |
| 14 import json | |
| 15 import logging | |
| 16 import optparse | |
| 17 import os | |
| 18 import sys | |
| 19 | |
| 20 from json_results_generator import JSONResultsGenerator | |
| 21 import test_result | |
| 22 import test_results_uploader | |
| 23 | |
| 24 | |
| 25 FULL_RESULTS_FILENAME = 'full_results.json' | |
| 26 TIMES_MS_FILENAME = 'times_ms.json' | |
| 27 | |
| 28 | |
| 29 def get_results_map_from_json(results_json): | |
| 30 """Returns a map of test results given a gtest json string. | |
| 31 | |
| 32 Returns: | |
| 33 {'Test.Name': [TestResult, TestResult, ...], 'Test.Name2': [...]} | |
| 34 """ | |
| 35 contents = json.loads(results_json) | |
| 36 | |
| 37 test_results_map = {} | |
| 38 for test in contents.get('disabled_tests', []): | |
| 39 test_results_map[test_result.canonical_name(test)] = [ | |
| 40 test_result.TestResult(test, status='SKIPPED')] | |
| 41 for result_sets in contents.get('per_iteration_data', []): | |
| 42 for test, results in result_sets.iteritems(): | |
| 43 for result in results: | |
| 44 result = test_result.TestResult( | |
| 45 test, | |
| 46 status=result['status'], | |
| 47 elapsed_time=result.get('elapsed_time_ms', 0) / 1000.) | |
| 48 test_results_map.setdefault(test, []).append(result) | |
| 49 return test_results_map | |
| 50 | |
| 51 | |
| 52 def generate_json_results(test_results_map, builder_name, build_number, | |
| 53 results_directory, chrome_revision, master_name): | |
| 54 """Generates JSON results files from the given test_results_map. | |
| 55 | |
| 56 Args: | |
| 57 test_results_map: A map of TestResult. | |
| 58 """ | |
| 59 if not os.path.exists(results_directory): | |
| 60 os.makedirs(results_directory) | |
| 61 | |
| 62 print('Generating json: ' | |
| 63 'builder_name:%s, build_number:%s, ' | |
| 64 'results_directory:%s, ' | |
| 65 'chrome_revision:%s ' | |
| 66 'master_name:%s' % | |
| 67 (builder_name, build_number, | |
| 68 results_directory, | |
| 69 chrome_revision, | |
| 70 master_name)) | |
| 71 | |
| 72 # TODO(estaab): This doesn't need to be an object. Make it a simple function. | |
| 73 generator = JSONResultsGenerator( | |
| 74 builder_name, build_number, | |
| 75 results_directory, | |
| 76 test_results_map, | |
| 77 svn_revisions=[('chromium', chrome_revision)], | |
| 78 master_name=master_name) | |
| 79 generator.generate_json_output() | |
| 80 generator.generate_times_ms_file() | |
| 81 | |
| 82 | |
| 83 def main(): | |
| 84 option_parser = optparse.OptionParser() | |
| 85 option_parser.add_option('--test-type', | |
| 86 help='Test type that generated the results json,' | |
| 87 ' e.g. unit-tests.') | |
| 88 option_parser.add_option('--results-directory', default=os.getcwd(), | |
| 89 help='Output results directory source dir.') | |
| 90 option_parser.add_option('--input-gtest-json', | |
| 91 help='Test results json file (input for us).') | |
| 92 option_parser.add_option('--builder-name', | |
| 93 default='DUMMY_BUILDER_NAME', | |
| 94 help='The name of the builder shown on the ' | |
| 95 'waterfall running this script e.g. WebKit.') | |
| 96 option_parser.add_option('--build-number', | |
| 97 help='The build number of the builder running' | |
| 98 'this script.') | |
| 99 option_parser.add_option('--test-results-server', | |
| 100 help='The test results server to upload the ' | |
| 101 'results.') | |
| 102 option_parser.add_option('--master-name', | |
| 103 help='The name of the buildbot master. ' | |
| 104 'Both test-results-server and master-name ' | |
| 105 'need to be specified to upload the results ' | |
| 106 'to the server.') | |
| 107 option_parser.add_option('--chrome-revision', default='0', | |
| 108 help='The Chromium revision being tested. If not ' | |
| 109 'given, defaults to 0.') | |
| 110 | |
| 111 options = option_parser.parse_args()[0] | |
| 112 logging.basicConfig() | |
| 113 | |
| 114 if not options.test_type: | |
| 115 option_parser.error('--test-type needs to be specified.') | |
| 116 return 1 | |
| 117 | |
| 118 if not options.input_gtest_json: | |
| 119 option_parser.error('--input-gtest-json needs to be specified.') | |
| 120 return 1 | |
| 121 | |
| 122 if options.test_results_server and not options.master_name: | |
| 123 logging.warn('--test-results-server is given but ' | |
| 124 '--master-name is not specified; the results won\'t be ' | |
| 125 'uploaded to the server.') | |
| 126 | |
| 127 with file(options.input_gtest_json) as json_file: | |
| 128 results_map = get_results_map_from_json(json_file.read()) | |
| 129 | |
| 130 generate_json_results(results_map, options.builder_name, | |
| 131 options.build_number, options.results_directory, | |
| 132 options.chrome_revision, options.master_name) | |
| 133 | |
| 134 # Upload to a test results server if specified. | |
| 135 if options.test_results_server and options.master_name: | |
| 136 print 'Uploading JSON files for builder "%s" to server "%s"' % ( | |
| 137 options.builder_name, options.test_results_server) | |
| 138 attrs = [('builder', options.builder_name), | |
| 139 ('testtype', options.test_type), | |
| 140 ('master', options.master_name)] | |
| 141 | |
| 142 files = [(f, os.path.join(options.results_directory, f)) for f in | |
| 143 (FULL_RESULTS_FILENAME, TIMES_MS_FILENAME)] | |
| 144 | |
| 145 # Set uploading timeout in case appengine server is having problem. | |
| 146 # 120 seconds are more than enough to upload test results. | |
| 147 test_results_uploader.upload_test_results( | |
| 148 options.test_results_server, attrs, files, 120) | |
| 149 return 0 | |
| 150 | |
| 151 | |
| 152 if __name__ == '__main__': | |
| 153 sys.exit(main()) | |
| OLD | NEW |