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

Side by Side Diff: git_cl.py

Issue 2439293002: git cl try: support multiple bots from different masters without specifying master. (Closed)
Patch Set: Add test 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 | tests/git_cl_test.py » ('j') | tests/git_cl_test.py » ('J')
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) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 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 # Copyright (C) 2008 Evan Martin <martine@danga.com> 6 # Copyright (C) 2008 Evan Martin <martine@danga.com>
7 7
8 """A git-command for integrating reviews on Rietveld and Gerrit.""" 8 """A git-command for integrating reviews on Rietveld and Gerrit."""
9 9
10 from __future__ import print_function 10 from __future__ import print_function
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 default_presubmit=None, 356 default_presubmit=None,
357 project=None, 357 project=None,
358 verbose=options.verbose, 358 verbose=options.verbose,
359 output_stream=sys.stdout) 359 output_stream=sys.stdout)
360 360
361 if masters: 361 if masters:
362 return masters 362 return masters
363 363
364 # Fall back to deprecated method: get try slaves from PRESUBMIT.py 364 # Fall back to deprecated method: get try slaves from PRESUBMIT.py
365 # files. 365 # files.
366 # TODO(qyearsley): Remove this.
366 options.bot = presubmit_support.DoGetTrySlaves( 367 options.bot = presubmit_support.DoGetTrySlaves(
367 change=change, 368 change=change,
368 changed_files=change.LocalPaths(), 369 changed_files=change.LocalPaths(),
369 repository_root=settings.GetRoot(), 370 repository_root=settings.GetRoot(),
370 default_presubmit=None, 371 default_presubmit=None,
371 project=None, 372 project=None,
372 verbose=options.verbose, 373 verbose=options.verbose,
373 output_stream=sys.stdout) 374 output_stream=sys.stdout)
374 375
375 if not options.bot: 376 if not options.bot:
376 return {} 377 return {}
377 378
378 if options.bucket: 379 if options.bucket:
379 return {options.bucket: {b: [] for b in options.bot}} 380 return {options.bucket: {b: [] for b in options.bot}}
380 381
382 if not options.master:
383 master_map, error_message = _get_master_map_for_builders(options.bot)
384 if error_message:
385 option_parser.error(
386 'Tryserver master cannot be found because: %s\n'
387 'Please manually specify the tryserver master, e.g. '
388 '"-m tryserver.chromium.linux".' % error_message)
389 buckets = {}
390 for master, builders in master_map.iteritems():
391 buckets[_prefix_master(master)] = {b: [] for b in builders}
Michael Achenbach 2016/10/26 08:36:40 How about inlining this in the _get_master_map_for
qyearsley 2016/10/26 16:08:47 Makes sense; done
392 return buckets
393
381 builders_and_tests = {} 394 builders_and_tests = {}
382 395
383 # TODO(machenbach): The old style command-line options don't support 396 # TODO(machenbach): The old style command-line options don't support
384 # multiple try masters yet. 397 # multiple try masters yet.
385 old_style = filter(lambda x: isinstance(x, basestring), options.bot) 398 old_style = filter(lambda x: isinstance(x, basestring), options.bot)
386 new_style = filter(lambda x: isinstance(x, tuple), options.bot) 399 new_style = filter(lambda x: isinstance(x, tuple), options.bot)
387 400
388 for bot in old_style: 401 for bot in old_style:
389 if ':' in bot: 402 if ':' in bot:
390 option_parser.error('Specifying testfilter is no longer supported') 403 option_parser.error('Specifying testfilter is no longer supported')
391 elif ',' in bot: 404 elif ',' in bot:
392 option_parser.error('Specify one bot per --bot flag') 405 option_parser.error('Specify one bot per --bot flag')
393 else: 406 else:
394 builders_and_tests.setdefault(bot, []) 407 builders_and_tests.setdefault(bot, [])
395 408
396 for bot, tests in new_style: 409 for bot, tests in new_style:
397 builders_and_tests.setdefault(bot, []).extend(tests) 410 builders_and_tests.setdefault(bot, []).extend(tests)
398 411
399 if not options.master: 412 # Add the "master." prefix to the master name to obtain the bucket name.
400 # TODO(qyearsley): crbug.com/640740 413 bucket = _prefix_master(options.master)
401 options.master, error_message = _get_builder_master(options.bot)
402 if error_message:
403 option_parser.error(
404 'Tryserver master cannot be found because: %s\n'
405 'Please manually specify the tryserver master, e.g. '
406 '"-m tryserver.chromium.linux".' % error_message)
407
408 # Return a master map with one master to be backwards compatible. The
409 # master name defaults to an empty string, which will cause the master
410 # not to be set on rietveld (deprecated).
411 bucket = ''
412 if options.master:
413 # Add the "master." prefix to the master name to obtain the bucket name.
414 bucket = _prefix_master(options.master)
415 return {bucket: builders_and_tests} 414 return {bucket: builders_and_tests}
416 415
417 416
418 def _get_builder_master(bot_list): 417 def _get_master_map_for_builders(builders):
419 """Fetches a master for the given list of builders. 418 """Returns a map of masters to builders for the given builders."""
420
421 Returns a pair (master, error_message), where either master or
422 error_message is None.
423 """
424 map_url = 'https://builders-map.appspot.com/' 419 map_url = 'https://builders-map.appspot.com/'
425 try: 420 try:
426 master_map = json.load(urllib2.urlopen(map_url)) 421 builders_map = json.load(urllib2.urlopen(map_url))
427 except urllib2.URLError as e: 422 except urllib2.URLError as e:
428 return None, ('Failed to fetch builder-to-master map from %s. Error: %s.' % 423 return None, ('Failed to fetch builder-to-master map from %s. Error: %s.' %
429 (map_url, e)) 424 (map_url, e))
430 except ValueError as e: 425 except ValueError as e:
431 return None, ('Invalid json string from %s. Error: %s.' % (map_url, e)) 426 return None, ('Invalid json string from %s. Error: %s.' % (map_url, e))
432 if not master_map: 427 if not builders_map:
433 return None, 'Failed to build master map.' 428 return None, 'Failed to build master map.'
434 429
435 result_master = '' 430 master_map = {}
436 for bot in bot_list: 431 for builder in builders:
437 builder = bot.split(':', 1)[0] 432 builder = builder.split(':', 1)[0]
438 master_list = master_map.get(builder, []) 433 masters = builders_map.get(builder, [])
439 if not master_list: 434 if not masters:
440 return None, ('No matching master for builder %s.' % builder) 435 return None, ('No matching master for builder %s.' % builder)
441 elif len(master_list) > 1: 436 elif len(masters) > 1:
442 return None, ('The builder name %s exists in multiple masters %s.' % 437 return None, ('The builder name %s exists in multiple masters %s.' %
443 (builder, master_list)) 438 (builder, masters))
444 else: 439 else:
Michael Achenbach 2016/10/26 08:36:40 nit: No else after returns required. The code bel
qyearsley 2016/10/26 16:08:47 Done; also, renamed "master_map" to "bucket_map" t
445 cur_master = master_list[0] 440 master = masters[0]
446 if not result_master: 441 master_map.setdefault(master, [])
447 result_master = cur_master 442 master_map[master].append(builder)
448 elif result_master != cur_master: 443
449 return None, 'The builders do not belong to the same master.' 444 return master_map, None
450 return result_master, None
451 445
452 446
453 def _trigger_try_jobs(auth_config, changelist, buckets, options, 447 def _trigger_try_jobs(auth_config, changelist, buckets, options,
454 category='git_cl_try', patchset=None): 448 category='git_cl_try', patchset=None):
455 """Sends a request to Buildbucket to trigger try jobs for a changelist. 449 """Sends a request to Buildbucket to trigger try jobs for a changelist.
456 450
457 Args: 451 Args:
458 auth_config: AuthConfig for Rietveld. 452 auth_config: AuthConfig for Rietveld.
459 changelist: Changelist that the try jobs are associated with. 453 changelist: Changelist that the try jobs are associated with.
460 buckets: A nested dict mapping bucket names to builders to tests. 454 buckets: A nested dict mapping bucket names to builders to tests.
(...skipping 4949 matching lines...) Expand 10 before | Expand all | Expand 10 after
5410 if __name__ == '__main__': 5404 if __name__ == '__main__':
5411 # These affect sys.stdout so do it outside of main() to simplify mocks in 5405 # These affect sys.stdout so do it outside of main() to simplify mocks in
5412 # unit testing. 5406 # unit testing.
5413 fix_encoding.fix_encoding() 5407 fix_encoding.fix_encoding()
5414 setup_color.init() 5408 setup_color.init()
5415 try: 5409 try:
5416 sys.exit(main(sys.argv[1:])) 5410 sys.exit(main(sys.argv[1:]))
5417 except KeyboardInterrupt: 5411 except KeyboardInterrupt:
5418 sys.stderr.write('interrupted\n') 5412 sys.stderr.write('interrupted\n')
5419 sys.exit(1) 5413 sys.exit(1)
OLDNEW
« no previous file with comments | « no previous file | tests/git_cl_test.py » ('j') | tests/git_cl_test.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698