Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(431)

Side by Side Diff: scripts/slave/recipe_modules/test_results/resources/upload_test_results.py

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

Powered by Google App Engine
This is Rietveld 408576698