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

Side by Side Diff: scripts/slave/recipe_modules/auto_bisect/api.py

Issue 2247373002: Refactor stages 1, 2 and test_api overhaul. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/build.git@master
Patch Set: Created 4 years, 4 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 2015 The Chromium Authors. All rights reserved. 1 # Copyright 2015 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 """API for the bisect recipe module. 5 """API for the bisect recipe module.
6 6
7 This API is meant to enable the bisect recipe to bisect any chromium-supported 7 This API is meant to enable the bisect recipe to bisect any chromium-supported
8 platform for any test that can be run via buildbot, perf or otherwise. 8 platform for any test that can be run via buildbot, perf or otherwise.
9 """ 9 """
10 10
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 """ 127 """
128 step_name = 'Reading culprit cl information.' 128 step_name = 'Reading culprit cl information.'
129 # Use gitiles to get commit information. 129 # Use gitiles to get commit information.
130 if revision.depot_name == 'android-chrome': # pragma: no cover 130 if revision.depot_name == 'android-chrome': # pragma: no cover
131 commit_url = depot_config.DEPOT_DEPS_NAME[revision.depot_name]['url'] 131 commit_url = depot_config.DEPOT_DEPS_NAME[revision.depot_name]['url']
132 return self._commit_info(revision.commit_hash, commit_url, step_name) 132 return self._commit_info(revision.commit_hash, commit_url, step_name)
133 result = self.m.python( 133 result = self.m.python(
134 step_name, 134 step_name,
135 self.resource('fetch_revision_info.py'), 135 self.resource('fetch_revision_info.py'),
136 [revision.commit_hash, revision.depot_name], 136 [revision.commit_hash, revision.depot_name],
137 stdout=self.m.json.output()) 137 stdout=self.m.json.output(),
138 step_test_data=lambda: self._test_data['cl_info'][revision.commit_hash],
139 )
138 return result.stdout 140 return result.stdout
139 141
140 def _commit_info(self, commit_hash, url, step_name=None): # pragma: no cover 142 def _commit_info(self, commit_hash, url, step_name=None): # pragma: no cover
141 """Fetches information about a given commit. 143 """Fetches information about a given commit.
142 144
143 Args: 145 Args:
144 commit_hash (str): A git commit hash. 146 commit_hash (str): A git commit hash.
145 url (str): The URL of a repository, e.g. 147 url (str): The URL of a repository, e.g.
146 "https://chromium.googlesource.com/chromium/src". 148 "https://chromium.googlesource.com/chromium/src".
147 step_name (str): Optional step name. 149 step_name (str): Optional step name.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 '--build-properties', 198 '--build-properties',
197 self.m.json.dumps(dict(self.m.properties.legacy())), 199 self.m.json.dumps(dict(self.m.properties.legacy())),
198 ] 200 ]
199 self.m.chromium.runtest( 201 self.m.chromium.runtest(
200 self.m.path['checkout'].join('tools', 'run-bisect-perf-regression.py'), 202 self.m.path['checkout'].join('tools', 'run-bisect-perf-regression.py'),
201 ['-w', self.m.path['cache'].join('bisect')] + args, 203 ['-w', self.m.path['cache'].join('bisect')] + args,
202 name='Running Bisection', 204 name='Running Bisection',
203 xvfb=True, **kwargs) 205 xvfb=True, **kwargs)
204 206
205 def run_local_test_run(self, test_config_params, 207 def run_local_test_run(self, test_config_params,
206 skip_download=False): # pragma: no cover 208 skip_download=False, **kwargs): # pragma: no cover
207 """Starts a test run on the same machine. 209 """Starts a test run on the same machine.
208 210
209 This is for the merged director/tester flow. 211 This is for the merged director/tester flow.
210 """ 212 """
211 if self.m.platform.is_win: 213 if self.m.platform.is_win:
212 self.m.chromium.taskkill() 214 self.m.chromium.taskkill()
213 215
214 if skip_download: 216 if skip_download:
215 update_step = None 217 update_step = None
216 else: 218 else:
217 update_step = self._SyncRevisionToTest(test_config_params) 219 update_step = self._SyncRevisionToTest(test_config_params)
218 self.start_test_run_for_bisect(update_step, self.bot_db, 220 return self.start_test_run_for_bisect(
219 test_config_params, run_locally=True, 221 update_step, self.bot_db, test_config_params, run_locally=True,
220 skip_download=skip_download) 222 skip_download=skip_download, **kwargs)
221 223
222 def ensure_checkout(self, *args, **kwargs): 224 def ensure_checkout(self, *args, **kwargs):
223 if self.working_dir: 225 if self.working_dir:
224 kwargs.setdefault('cwd', self.working_dir) 226 kwargs.setdefault('cwd', self.working_dir)
225 227
226 return self.m.bot_update.ensure_checkout(*args, **kwargs) 228 return self.m.bot_update.ensure_checkout(*args, **kwargs)
227 229
228 def _SyncRevisionToTest(self, test_config_params): # pragma: no cover 230 def _SyncRevisionToTest(self, test_config_params): # pragma: no cover
229 if not self.internal_bisect: 231 if not self.internal_bisect:
230 return self.ensure_checkout( 232 return self.ensure_checkout(
231 root_solution_revision=test_config_params['revision']) 233 root_solution_revision=test_config_params['revision'])
232 else: 234 else:
233 return self._SyncRevisionsForAndroidChrome( 235 return self._SyncRevisionsForAndroidChrome(
234 test_config_params['revision_ladder']) 236 test_config_params['revision_ladder'])
235 237
236 def _SyncRevisionsForAndroidChrome(self, revision_ladder): # pragma: no cover 238 def _SyncRevisionsForAndroidChrome(self, revision_ladder): # pragma: no cover
237 """Syncs android-chrome and chromium repos to particular revision.""" 239 """Syncs android-chrome and chromium repos to particular revision."""
238 revisions = [] 240 revisions = []
239 for d, r in revision_ladder.iteritems(): 241 for d, r in revision_ladder.iteritems():
240 revisions.append('%s@%s' % (depot_config.DEPOT_DEPS_NAME[d]['src'], r)) 242 revisions.append('%s@%s' % (depot_config.DEPOT_DEPS_NAME[d]['src'], r))
241 params = ['sync', '--verbose', '--nohooks', '--force', 243 params = ['sync', '--verbose', '--nohooks', '--force',
242 '--delete_unversioned_trees'] 244 '--delete_unversioned_trees']
243 for revision in revisions: 245 for revision in revisions:
244 params.extend(['--revision', revision]) 246 params.extend(['--revision', revision])
245 self.m.gclient('sync %s' % '-'.join(revisions), params) 247 self.m.gclient('sync %s' % '-'.join(revisions), params)
246 return None 248 return None
247 249
248 def start_test_run_for_bisect(self, update_step, bot_db, 250 def start_test_run_for_bisect(self, update_step, bot_db,
249 test_config_params, run_locally=False, 251 test_config_params, run_locally=False,
250 skip_download=False): 252 skip_download=False, **kwargs):
251 mastername = self.m.properties.get('mastername') 253 mastername = self.m.properties.get('mastername')
252 buildername = self.m.properties.get('buildername') 254 buildername = self.m.properties.get('buildername')
253 bot_config = bot_db.get_bot_config(mastername, buildername) 255 bot_config = bot_db.get_bot_config(mastername, buildername)
254 build_archive_url = test_config_params['parent_build_archive_url'] 256 build_archive_url = test_config_params['parent_build_archive_url']
255 if not run_locally:
256 self.m.bisect_tester.upload_job_url()
257 if not skip_download: 257 if not skip_download:
258 if self.m.chromium.c.TARGET_PLATFORM == 'android': 258 if self.m.chromium.c.TARGET_PLATFORM == 'android':
259 # The best way to ensure the old build directory is not used is to 259 # The best way to ensure the old build directory is not used is to
260 # remove it. 260 # remove it.
261 build_dir = self.m.chromium.c.build_dir.join( 261 build_dir = self.m.chromium.c.build_dir.join(
262 self.m.chromium.c.build_config_fs) 262 self.m.chromium.c.build_config_fs)
263 self.m.file.rmtree('build directory', build_dir) 263 self.m.file.rmtree('build directory', build_dir)
264 264
265 # The way android builders on tryserver.chromium.perf are archived is 265 # The way android builders on tryserver.chromium.perf are archived is
266 # different from builders on chromium.perf. In order to support both 266 # different from builders on chromium.perf. In order to support both
(...skipping 22 matching lines...) Expand all
289 shutil.move(sys.argv[1], sys.argv[2]) 289 shutil.move(sys.argv[1], sys.argv[2])
290 """, 290 """,
291 args=[zip_dir, build_dir]) 291 args=[zip_dir, build_dir])
292 else: 292 else:
293 self.m.chromium_tests.download_and_unzip_build( 293 self.m.chromium_tests.download_and_unzip_build(
294 mastername, buildername, update_step, bot_db, 294 mastername, buildername, update_step, bot_db,
295 build_archive_url=build_archive_url, 295 build_archive_url=build_archive_url,
296 build_revision=test_config_params['parent_got_revision'], 296 build_revision=test_config_params['parent_got_revision'],
297 override_bot_type='tester') 297 override_bot_type='tester')
298 298
299 tests = [self.m.chromium_tests.steps.BisectTest(test_config_params)] 299 tests = [
300 self.m.chromium_tests.steps.BisectTest(
301 test_config_params, **kwargs)]
300 302
301 if not tests: # pragma: no cover 303 if not tests: # pragma: no cover
302 return 304 return
303 self.m.chromium_swarming.configure_swarming( 305 self.m.chromium_swarming.configure_swarming(
304 'chromium', precommit=False, mastername=mastername) 306 'chromium', precommit=False, mastername=mastername)
305 test_runner = self.m.chromium_tests.create_test_runner(self.m, tests) 307 test_runner = self.m.chromium_tests.create_test_runner(self.m, tests)
306 308
307 bot_config_object = self.m.chromium_tests.create_bot_config_object( 309 bot_config_object = self.m.chromium_tests.create_bot_config_object(
308 mastername, buildername) 310 mastername, buildername)
309 with self.m.chromium_tests.wrap_chromium_tests(bot_config_object, tests): 311 with self.m.chromium_tests.wrap_chromium_tests(bot_config_object, tests):
310 if self.m.chromium.c.TARGET_PLATFORM == 'android' and not skip_download: 312 if self.m.chromium.c.TARGET_PLATFORM == 'android' and not skip_download:
311 deploy_apks = [] 313 deploy_apks = []
312 deploy_args = [] 314 deploy_args = []
313 if self.internal_bisect: # pragma: no cover 315 if self.internal_bisect: # pragma: no cover
314 deploy_args = list(bot_config['deploy_args']) 316 deploy_args = list(bot_config['deploy_args'])
315 deploy_apks = bot_config.get('deploy_apks') 317 deploy_apks = bot_config.get('deploy_apks')
316 if deploy_apks: 318 if deploy_apks:
317 deploy_args.extend([ 319 deploy_args.extend([
318 '--apks', 320 '--apks',
319 ','.join(str(self.m.chromium_android.apk_path(apk)) 321 ','.join(str(self.m.chromium_android.apk_path(apk))
320 for apk in deploy_apks)]) 322 for apk in deploy_apks)])
321 else: 323 else:
322 if bot_config.get('webview'): 324 if bot_config.get('webview'):
323 deploy_apks = ['SystemWebView.apk', 'SystemWebViewShell.apk'] 325 deploy_apks = ['SystemWebView.apk', 'SystemWebViewShell.apk']
324 else: 326 else:
325 deploy_apks = ['ChromePublic.apk'] 327 deploy_apks = ['ChromePublic.apk']
326 self.deploy_apk_on_device( 328 self.deploy_apk_on_device(
327 self.full_deploy_script, deploy_apks, deploy_args) 329 self.full_deploy_script, deploy_apks, deploy_args)
328 test_runner() 330 test_runner()
331 return tests[0].run_results
329 332
330 def deploy_apk_on_device(self, deploy_script, deploy_apks, deploy_args): 333 def deploy_apk_on_device(self, deploy_script, deploy_apks, deploy_args):
331 """Installs apk on the android device.""" 334 """Installs apk on the android device."""
332 if deploy_script: # pragma: no cover 335 if deploy_script: # pragma: no cover
333 self.full_deploy_on_device(deploy_script, deploy_args) 336 self.full_deploy_on_device(deploy_script, deploy_args)
334 else: 337 else:
335 for apk in deploy_apks: 338 for apk in deploy_apks:
336 self.m.chromium_android.adb_install_apk(apk) 339 self.m.chromium_android.adb_install_apk(apk)
337 340
338 def full_deploy_on_device(self, deploy_script, args=None): # pragma: no cover 341 def full_deploy_on_device(self, deploy_script, args=None): # pragma: no cover
(...skipping 29 matching lines...) Expand all
368 api: The recipe api object. 371 api: The recipe api object.
369 update_step: Extra update_step to, used for some job types. 372 update_step: Extra update_step to, used for some job types.
370 bot_db: A BotConfigAndTestDB object, used for some job types. 373 bot_db: A BotConfigAndTestDB object, used for some job types.
371 kwargs: Args to use only for legacy bisect. 374 kwargs: Args to use only for legacy bisect.
372 """ 375 """
373 flags = {} 376 flags = {}
374 if kwargs.get('do_not_nest_wait_for_revision'): 377 if kwargs.get('do_not_nest_wait_for_revision'):
375 flags['do_not_nest_wait_for_revision'] = kwargs.pop( 378 flags['do_not_nest_wait_for_revision'] = kwargs.pop(
376 'do_not_nest_wait_for_revision') 379 'do_not_nest_wait_for_revision')
377 if bot_db is None: # pragma: no cover 380 if bot_db is None: # pragma: no cover
378 self.bot_db = api.chromium_tests.create_bot_db_from_master_dict( 381 self.bot_db = api.chromium_tests.create_bot_db_from_master_dict('', None)
379 '', None, None)
380 else: 382 else:
381 self.bot_db = bot_db 383 self.bot_db = bot_db
382 384
383 context = {} 385 context = {}
384 if self.working_dir: 386 if self.working_dir:
385 context['cwd'] = self.working_dir 387 context['cwd'] = self.working_dir
386 388
387 with api.step.context(context): 389 with api.step.context(context):
388 affected_files = self.m.tryserver.get_files_affected_by_patch() 390 affected_files = self.m.tryserver.get_files_affected_by_patch()
389 # Skip device setup for internal bisect as it is taken care in 391 # Skip device setup for internal bisect as it is taken care in
(...skipping 24 matching lines...) Expand all
414 affected_files, update_step, self.bot_db) 416 affected_files, update_step, self.bot_db)
415 finally: 417 finally:
416 if api.chromium.c.TARGET_PLATFORM == 'android': 418 if api.chromium.c.TARGET_PLATFORM == 'android':
417 if self.internal_bisect: # pragma: no cover 419 if self.internal_bisect: # pragma: no cover
418 api.chromium_android.init_and_sync( 420 api.chromium_android.init_and_sync(
419 gclient_config=api.chromium_android.c.internal_dir_name, 421 gclient_config=api.chromium_android.c.internal_dir_name,
420 use_bot_update=True) 422 use_bot_update=True)
421 else: 423 else:
422 self.ensure_checkout() 424 self.ensure_checkout()
423 api.chromium_android.common_tests_final_steps() 425 api.chromium_android.common_tests_final_steps()
426
427 def stat_compare(self, values_a, values_b, metric,
428 output_format='chartjson', **kwargs):
429 """Compares samples using catapult's statistics implementation.
430
431 Args:
432 values_a, values_b: lists of paths to the json files containing the values
433 produced by the test.
434 metric: the name of the metric as sent by dashboard.
435 output_format: either 'chartjson' or 'valueset'
436
437 Returns:
438 a dict containing 'result' which may be True, False or 'needMoreData', as
439 well as details about each sample ('debug_values', 'mean' and 'std_dev').
440
441 """
442 args = [','.join(map(str, values_a)),
443 ','.join(map(str, values_b)),
444 metric,
445 '--' + output_format]
446
447 script = self.m.path['catapult'].join(
448 'tracing', 'bin', 'compare_samples')
449 return self.m.python(
450 'Compare samples',
451 script=script,
452 args=args,
453 stdout=self.m.json.output(),
454 **kwargs).stdout
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698