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

Side by Side Diff: dashboard/dashboard/pinpoint_request.py

Issue 3016673002: Dashboard - Add pinpoint-perf-job-dialog for perf try jobs.
Patch Set: . Created 3 years, 2 months 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
OLDNEW
1 # Copyright 2017 The Chromium Authors. All rights reserved. 1 # Copyright 2017 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """URL endpoint containing server-side functionality for pinpoint jobs.""" 5 """URL endpoint containing server-side functionality for pinpoint jobs."""
6 6
7 import json 7 import json
8 8
9 from google.appengine.api import users 9 from google.appengine.api import users
10 from google.appengine.ext import ndb 10 from google.appengine.ext import ndb
11 11
12 from dashboard import start_try_job 12 from dashboard import start_try_job
13 from dashboard.common import namespaced_stored_object 13 from dashboard.common import namespaced_stored_object
14 from dashboard.common import request_handler 14 from dashboard.common import request_handler
15 from dashboard.common import utils 15 from dashboard.common import utils
16 from dashboard.services import crrev_service 16 from dashboard.services import crrev_service
17 from dashboard.services import pinpoint_service 17 from dashboard.services import pinpoint_service
18 18
19 _BOTS_TO_DIMENSIONS = 'bot_dimensions_map' 19 _BOTS_TO_DIMENSIONS = 'bot_dimensions_map'
20 _PINPOINT_REPOSITORIES = 'repositories' 20 _PINPOINT_REPOSITORIES = 'repositories'
21 _ISOLATE_TARGETS = [
22 'angle_perftests', 'cc_perftests', 'gpu_perftests',
23 'load_library_perf_tests', 'media_perftests', 'net_perftests',
24 'performance_browser_tests', 'telemetry_perf_tests',
25 'telemetry_perf_webview_tests', 'tracing_perftests']
21 26
22 27
23 class InvalidParamsError(Exception): 28 class InvalidParamsError(Exception):
24 pass 29 pass
25 30
26 31
27 class PinpointNewPrefillRequestHandler(request_handler.RequestHandler): 32 class PinpointNewPrefillRequestHandler(request_handler.RequestHandler):
28 def post(self): 33 def post(self):
29 story_filter = start_try_job.GuessStoryFilter(self.request.get('test_path')) 34 story_filter = start_try_job.GuessStoryFilter(self.request.get('test_path'))
30 self.response.write(json.dumps({'story_filter': story_filter})) 35 self.response.write(json.dumps({'story_filter': story_filter}))
31 36
32 37
33 class PinpointNewRequestHandler(request_handler.RequestHandler): 38 class PinpointNewBisectRequestHandler(request_handler.RequestHandler):
34 def post(self): 39 def post(self):
35 job_params = dict( 40 job_params = dict(
36 (a, self.request.get(a)) for a in self.request.arguments()) 41 (a, self.request.get(a)) for a in self.request.arguments())
37 42
38 try: 43 try:
39 pinpoint_params = PinpointParamsFromBisectParams(job_params) 44 pinpoint_params = PinpointParamsFromBisectParams(job_params)
40 except InvalidParamsError as e: 45 except InvalidParamsError as e:
41 self.response.write(json.dumps({'error': e.message})) 46 self.response.write(json.dumps({'error': e.message}))
42 return 47 return
43 48
44 self.response.write(json.dumps(pinpoint_service.NewJob(pinpoint_params))) 49 self.response.write(json.dumps(pinpoint_service.NewJob(pinpoint_params)))
45 50
46 51
52 class PinpointNewPerfTryRequestHandler(request_handler.RequestHandler):
53 def post(self):
54 job_params = dict(
55 (a, self.request.get(a)) for a in self.request.arguments())
56
57 try:
58 pinpoint_params = PinpointParamsFromPerfTryParams(job_params)
59 except InvalidParamsError as e:
60 self.response.write(json.dumps({'error': e.message}))
61 return
62
63 self.response.write(json.dumps(pinpoint_service.NewJob(pinpoint_params)))
64
65
47 def ParseMetricParts(test_path_parts): 66 def ParseMetricParts(test_path_parts):
48 metric_parts = test_path_parts[3:] 67 metric_parts = test_path_parts[3:]
49 68
50 # Normal test path structure, ie. M/B/S/foo/bar.html 69 # Normal test path structure, ie. M/B/S/foo/bar.html
51 if len(metric_parts) == 2: 70 if len(metric_parts) == 2:
52 return '', metric_parts[0], metric_parts[1] 71 return '', metric_parts[0], metric_parts[1]
53 72
54 # 3 part structure, so there's a TIR label in there. 73 # 3 part structure, so there's a TIR label in there.
55 # ie. M/B/S/timeToFirstMeaningfulPaint_avg/load_tools/load_tools_weather 74 # ie. M/B/S/timeToFirstMeaningfulPaint_avg/load_tools/load_tools_weather
56 if len(metric_parts) == 3: 75 if len(metric_parts) == 3:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 def ParseTIRLabelChartNameAndTraceName(test_path_parts): 107 def ParseTIRLabelChartNameAndTraceName(test_path_parts):
89 """Returns tir_label, chart_name, trace_name from a test path.""" 108 """Returns tir_label, chart_name, trace_name from a test path."""
90 test = ndb.Key('TestMetadata', '/'.join(test_path_parts)).get() 109 test = ndb.Key('TestMetadata', '/'.join(test_path_parts)).get()
91 110
92 tir_label, chart_name, trace_name = ParseMetricParts(test_path_parts) 111 tir_label, chart_name, trace_name = ParseMetricParts(test_path_parts)
93 if trace_name and test.unescaped_story_name: 112 if trace_name and test.unescaped_story_name:
94 trace_name = test.unescaped_story_name 113 trace_name = test.unescaped_story_name
95 return tir_label, chart_name, trace_name 114 return tir_label, chart_name, trace_name
96 115
97 116
117 def _BotDimensionsFromBotName(bot_name):
118 bots_to_dimensions = namespaced_stored_object.Get(_BOTS_TO_DIMENSIONS)
119 dimensions = bots_to_dimensions.get(bot_name)
120 if not dimensions:
121 raise InvalidParamsError('No dimensions for bot %s defined.' % bot_name)
122 return dimensions
123
124
125 def PinpointParamsFromPerfTryParams(params):
126 """Takes parameters from Dashboard's pinpoint-perf-job-dialog and returns
127 a dict with parameters for a new Pinpoint job.
128
129 Args:
130 params: A dict in the following format:
131 {
132 'test_path': Test path for the metric being bisected.
133 'start_commit': Git hash or commit position of earlier revision.
134 'end_commit': Git hash or commit position of later revision.
135 'start_repository': Repository for earlier revision.
136 'end_repository': Repository for later revision.
137 'extra_telemetry_args': Extra args for telemetry.
138 }
139
140 Returns:
141 A dict of params for passing to Pinpoint to start a job, or a dict with an
142 'error' field.
143 """
144 if not utils.IsValidSheriffUser():
145 user = users.get_current_user()
146 raise InvalidParamsError('User "%s" not authorized.' % user)
147
148 # Pinpoint takes swarming dimensions, so we need to map bot name to those.
149 test_path = params['test_path']
150 test_path_parts = test_path.split('/')
151 bot_name = test_path_parts[1]
152 suite = test_path_parts[2]
153
154 dimensions = _BotDimensionsFromBotName(bot_name)
155
156 # Pinpoint also requires you specify which isolate target to run the
157 # test, so we derive that from the suite name. Eventually, this would
158 # ideally be stored in a SparesDiagnostic but for now we can guess.
159 target = 'telemetry_perf_tests'
160 if suite in _ISOLATE_TARGETS:
161 raise InvalidParamsError('Only telemetry is supported at the moment.')
162 elif 'webview' in bot_name:
163 target = 'telemetry_perf_webview_tests'
164
165 start_repository = params['start_repository']
166 end_repository = params['end_repository']
167 start_commit = params['start_commit']
168 end_commit = params['end_commit']
169
170 start_git_hash = ResolveToGitHash(start_commit, start_repository)
171 end_git_hash = ResolveToGitHash(end_commit, end_repository)
172
173 supported_repositories = namespaced_stored_object.Get(_PINPOINT_REPOSITORIES)
174
175 # Bail if it's not a supported repository to bisect on
176 if not start_repository in supported_repositories:
177 raise InvalidParamsError('Invalid repository: %s' % start_repository)
178 if not end_repository in supported_repositories:
179 raise InvalidParamsError('Invalid repository: %s' % end_repository)
180
181 # Pinpoint only supports chromium at the moment, so just throw up a
182 # different error for now.
183 if start_repository != 'chromium' or end_repository != 'chromium':
184 raise InvalidParamsError('Only chromium perf try jobs supported currently.')
185
186 extra_telemetry_args = params['extra_telemetry_args']
187
188 email = users.get_current_user().email()
189 job_name = 'Job on [%s/%s] for [%s]' % (bot_name, suite, email)
190
191 browser = start_try_job.GuessBrowserName(bot_name)
192
193 return {
194 'configuration': bot_name,
195 'browser': browser,
196 'benchmark': suite,
197 'trace': '',
198 'chart': '',
199 'tir_label': '',
200 'story': '',
201 'start_repository': start_repository,
202 'end_repository': end_repository,
203 'start_git_hash': start_git_hash,
204 'end_git_hash': end_git_hash,
205 'extra_telemetry_args': json.dumps(extra_telemetry_args),
206 'bug_id': '',
207 'auto_explore': '0',
208 'target': target,
209 'dimensions': json.dumps(dimensions),
210 'email': email,
211 'name': job_name
212 }
213
214
98 def PinpointParamsFromBisectParams(params): 215 def PinpointParamsFromBisectParams(params):
99 """Takes parameters from Dashboard's pinpoint-job-dialog and returns 216 """Takes parameters from Dashboard's pinpoint-job-dialog and returns
100 a dict with parameters for a new Pinpoint job. 217 a dict with parameters for a new Pinpoint job.
101 218
102 Args: 219 Args:
103 params: A dict in the following format: 220 params: A dict in the following format:
104 { 221 {
105 'test_path': Test path for the metric being bisected. 222 'test_path': Test path for the metric being bisected.
106 'start_git_hash': Git hash of earlier revision. 223 'start_git_hash': Git hash of earlier revision.
107 'end_git_hash': Git hash of later revision. 224 'end_git_hash': Git hash of later revision.
108 'start_repository': Repository for earlier revision. 225 'start_repository': Repository for earlier revision.
109 'end_repository': Repository for later revision. 226 'end_repository': Repository for later revision.
110 'bug_id': Associated bug. 227 'bug_id': Associated bug.
111 } 228 }
112 229
113 Returns: 230 Returns:
114 A dict of params for passing to Pinpoint to start a job, or a dict with an 231 A dict of params for passing to Pinpoint to start a job, or a dict with an
115 'error' field. 232 'error' field.
116 """ 233 """
117 if not utils.IsValidSheriffUser(): 234 if not utils.IsValidSheriffUser():
118 user = users.get_current_user() 235 user = users.get_current_user()
119 raise InvalidParamsError('User "%s" not authorized.' % user) 236 raise InvalidParamsError('User "%s" not authorized.' % user)
120 237
121 bots_to_dimensions = namespaced_stored_object.Get(_BOTS_TO_DIMENSIONS)
122
123 # Pinpoint takes swarming dimensions, so we need to map bot name to those. 238 # Pinpoint takes swarming dimensions, so we need to map bot name to those.
124 test_path = params['test_path'] 239 test_path = params['test_path']
125 test_path_parts = test_path.split('/') 240 test_path_parts = test_path.split('/')
126 bot_name = test_path_parts[1] 241 bot_name = test_path_parts[1]
127 suite = test_path_parts[2] 242 suite = test_path_parts[2]
128 story_filter = params['story_filter'] 243 story_filter = params['story_filter']
129 244
130 # If functional bisects are speciied, Pinpoint expects these parameters to be 245 # If functional bisects are speciied, Pinpoint expects these parameters to be
131 # empty. 246 # empty.
132 bisect_mode = params['bisect_mode'] 247 bisect_mode = params['bisect_mode']
133 if bisect_mode != 'performance' and bisect_mode != 'functional': 248 if bisect_mode != 'performance' and bisect_mode != 'functional':
134 raise InvalidParamsError('Invalid bisect mode %s specified.' % bisect_mode) 249 raise InvalidParamsError('Invalid bisect mode %s specified.' % bisect_mode)
135 250
136 tir_label = '' 251 tir_label = ''
137 chart_name = '' 252 chart_name = ''
138 trace_name = '' 253 trace_name = ''
139 if bisect_mode == 'performance': 254 if bisect_mode == 'performance':
140 tir_label, chart_name, trace_name = ParseTIRLabelChartNameAndTraceName( 255 tir_label, chart_name, trace_name = ParseTIRLabelChartNameAndTraceName(
141 test_path_parts) 256 test_path_parts)
142 257
143 dimensions = bots_to_dimensions.get(bot_name) 258 dimensions = _BotDimensionsFromBotName(bot_name)
144 if not dimensions:
145 raise InvalidParamsError('No dimensions for bot %s defined.' % bot_name)
146 259
147 # Pinpoint also requires you specify which isolate target to run the 260 # Pinpoint also requires you specify which isolate target to run the
148 # test, so we derive that from the suite name. Eventually, this would 261 # test, so we derive that from the suite name. Eventually, this would
149 # ideally be stored in a SparesDiagnostic but for now we can guess. 262 # ideally be stored in a SparesDiagnostic but for now we can guess.
150 isolate_targets = [
151 'angle_perftests', 'cc_perftests', 'gpu_perftests',
152 'load_library_perf_tests', 'media_perftests', 'net_perftests',
153 'performance_browser_tests', 'telemetry_perf_tests',
154 'telemetry_perf_webview_tests', 'tracing_perftests']
155
156 target = 'telemetry_perf_tests' 263 target = 'telemetry_perf_tests'
157 if suite in isolate_targets: 264 if suite in _ISOLATE_TARGETS:
158 target = suite 265 target = suite
159 elif 'webview' in bot_name: 266 elif 'webview' in bot_name:
160 target = 'telemetry_perf_webview_tests' 267 target = 'telemetry_perf_webview_tests'
161 268
162 start_repository = params['start_repository'] 269 start_repository = params['start_repository']
163 end_repository = params['end_repository'] 270 end_repository = params['end_repository']
164 start_commit = params['start_commit'] 271 start_commit = params['start_commit']
165 end_commit = params['end_commit'] 272 end_commit = params['end_commit']
166 273
167 start_git_hash = ResolveToGitHash(start_commit, start_repository) 274 start_git_hash = ResolveToGitHash(start_commit, start_repository)
(...skipping 29 matching lines...) Expand all
197 'end_repository': end_repository, 304 'end_repository': end_repository,
198 'start_git_hash': start_git_hash, 305 'start_git_hash': start_git_hash,
199 'end_git_hash': end_git_hash, 306 'end_git_hash': end_git_hash,
200 'bug_id': params['bug_id'], 307 'bug_id': params['bug_id'],
201 'auto_explore': '1', 308 'auto_explore': '1',
202 'target': target, 309 'target': target,
203 'dimensions': json.dumps(dimensions), 310 'dimensions': json.dumps(dimensions),
204 'email': email, 311 'email': email,
205 'name': job_name 312 'name': job_name
206 } 313 }
OLDNEW
« no previous file with comments | « dashboard/dashboard/elements/trace-button.html ('k') | dashboard/dashboard/pinpoint_request_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698