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

Side by Side Diff: master/skia_master_scripts/utils.py

Issue 13861012: Change builder names (Closed) Base URL: http://skia.googlecode.com/svn/buildbot/
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « master/skia_master_scripts/factory.py ('k') | master/slaves.cfg » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2013 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 5
6 """Miscellaneous utilities needed by the Skia buildbot master.""" 6 """Miscellaneous utilities needed by the Skia buildbot master."""
7 7
8 8
9 import httplib2 9 import httplib2
10 import re 10 import re
11 11
12 # requires Google APIs client library for Python; see 12 # requires Google APIs client library for Python; see
13 # https://code.google.com/p/google-api-python-client/wiki/Installation 13 # https://code.google.com/p/google-api-python-client/wiki/Installation
14 from apiclient.discovery import build 14 from apiclient.discovery import build
15 from buildbot.scheduler import AnyBranchScheduler 15 from buildbot.scheduler import AnyBranchScheduler
16 from buildbot.schedulers import timed 16 from buildbot.schedulers import timed
17 from buildbot.schedulers.filter import ChangeFilter 17 from buildbot.schedulers.filter import ChangeFilter
18 from buildbot.util import NotABranch 18 from buildbot.util import NotABranch
19 from config_private import TRY_SVN_BASEURL 19 from config_private import TRY_SVN_BASEURL
20 from master import master_config 20 from master import master_config
21 from master import try_job_svn 21 from master import try_job_svn
22 from master import try_job_rietveld 22 from master import try_job_rietveld
23 from master.builders_pools import BuildersPools 23 from master.builders_pools import BuildersPools
24 from oauth2client.client import SignedJwtAssertionCredentials 24 from oauth2client.client import SignedJwtAssertionCredentials
25 25
26 from skia_master_scripts import android_factory
27 from skia_master_scripts import chromeos_factory
28 from skia_master_scripts import factory as skia_factory
29 from skia_master_scripts import housekeeping_percommit_factory, \
30 housekeeping_periodic_factory
31 from skia_master_scripts import ios_factory
32 from skia_master_scripts import nacl_factory
33
34 import config_private 26 import config_private
35 27
36 28
37 CATEGORY_BUILD = ' Build' 29 BUILDER_NAME_SEP = '-'
38 TRYBOT_NAME_SUFFIX = '_Trybot' 30
31 # Patterns for creating builder names, based on the role of the builder.
32 # TODO(borenet): Extract these into a separate file (JSON?) so that they can be
33 # read by other users.
34 BUILDER_ROLE_COMPILE = 'Build'
35 BUILDER_ROLE_PERF = 'Perf'
36 BUILDER_ROLE_TEST = 'Test'
37 BUILDER_ROLE_HOUSEKEEPER = 'Housekeeper'
38 BUILDER_NAME_DEFAULT_ATTRS = ['os', 'model', 'gpu', 'arch', 'configuration']
39 BUILDER_NAME_SCHEMA = {
40 BUILDER_ROLE_COMPILE: ['os', 'compiler', 'target_arch', 'configuration'],
41 BUILDER_ROLE_TEST: BUILDER_NAME_DEFAULT_ATTRS,
42 BUILDER_ROLE_PERF: BUILDER_NAME_DEFAULT_ATTRS,
43 BUILDER_ROLE_HOUSEKEEPER: ['frequency'],
44 }
45
46 TRYBOT_NAME_SUFFIX = 'Trybot'
39 TRY_SCHEDULER_SVN = 'skia_try_svn' 47 TRY_SCHEDULER_SVN = 'skia_try_svn'
40 TRY_SCHEDULER_RIETVELD = 'skia_try_rietveld' 48 TRY_SCHEDULER_RIETVELD = 'skia_try_rietveld'
41 TRY_SCHEDULERS = [TRY_SCHEDULER_SVN, TRY_SCHEDULER_RIETVELD] 49 TRY_SCHEDULERS = [TRY_SCHEDULER_SVN, TRY_SCHEDULER_RIETVELD]
42 TRY_SCHEDULERS_STR = '|'.join(TRY_SCHEDULERS) 50 TRY_SCHEDULERS_STR = '|'.join(TRY_SCHEDULERS)
43 51
44 52
45 def IsTrybot(builder_name): 53 def IsTrybot(builder_name):
46 return builder_name.endswith(TRYBOT_NAME_SUFFIX) 54 return builder_name.endswith(TRYBOT_NAME_SUFFIX)
47 55
48 56
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 # Skip buildbot runs of a CL if its commit log message contains the following 204 # Skip buildbot runs of a CL if its commit log message contains the following
197 # substring. 205 # substring.
198 SKIP_BUILDBOT_SUBSTRING = '(SkipBuildbotRuns)' 206 SKIP_BUILDBOT_SUBSTRING = '(SkipBuildbotRuns)'
199 207
200 # If the below regex is found in a CL's commit log message, only run the 208 # If the below regex is found in a CL's commit log message, only run the
201 # builders specified therein. 209 # builders specified therein.
202 RUN_BUILDERS_REGEX = '\(RunBuilders:(.+)\)' 210 RUN_BUILDERS_REGEX = '\(RunBuilders:(.+)\)'
203 RUN_BUILDERS_RE_COMPILED = re.compile(RUN_BUILDERS_REGEX) 211 RUN_BUILDERS_RE_COMPILED = re.compile(RUN_BUILDERS_REGEX)
204 212
205 213
214 def AndroidModelToDevice(android_model):
215 name_parts = []
216 for part in re.split('(\d+)', android_model):
217 if re.match('(\d+)', part):
218 name_parts.append(part)
219 else:
220 name_parts.extend(re.findall('[A-Z][a-z]*', part))
221 return '_'.join([part.lower() for part in name_parts])
222
223
206 # Since we can't modify the existing Helper class, we subclass it here, 224 # Since we can't modify the existing Helper class, we subclass it here,
207 # overriding the necessary parts to get things working as we want. 225 # overriding the necessary parts to get things working as we want.
208 # Specifically, the Helper class hardcodes each registered scheduler to be 226 # Specifically, the Helper class hardcodes each registered scheduler to be
209 # instantiated as a 'Scheduler,' which aliases 'SingleBranchScheduler.' We add 227 # instantiated as a 'Scheduler,' which aliases 'SingleBranchScheduler.' We add
210 # an 'AnyBranchScheduler' method and change the implementation of Update() to 228 # an 'AnyBranchScheduler' method and change the implementation of Update() to
211 # instantiate the proper type. 229 # instantiate the proper type.
212 230
213 # TODO(borenet): modify this code upstream so that we don't need this override. 231 # TODO(borenet): modify this code upstream so that we don't need this override.
214 # BUG: http://code.google.com/p/skia/issues/detail?id=761 232 # BUG: http://code.google.com/p/skia/issues/detail?id=761
215 class SkiaHelper(master_config.Helper): 233 class SkiaHelper(master_config.Helper):
216 234
217 def Builder(self, name, factory, gatekeeper=None, scheduler=None, 235 def Builder(self, name, factory, gatekeeper=None, scheduler=None,
218 builddir=None, auto_reboot=False, notify_on_missing=False, 236 builddir=None, auto_reboot=False, notify_on_missing=False):
219 override_category=None):
220 if override_category:
221 old_category = self._defaults.get('category')
222 self._defaults['category'] = override_category
223 super(SkiaHelper, self).Builder(name=name, factory=factory, 237 super(SkiaHelper, self).Builder(name=name, factory=factory,
224 gatekeeper=gatekeeper, scheduler=scheduler, 238 gatekeeper=gatekeeper, scheduler=scheduler,
225 builddir=builddir, auto_reboot=auto_reboot, 239 builddir=builddir, auto_reboot=auto_reboot,
226 notify_on_missing=notify_on_missing) 240 notify_on_missing=notify_on_missing)
227 if override_category:
228 self._defaults['category'] = old_category
229 241
230 def AnyBranchScheduler(self, name, branches, treeStableTimer=60, 242 def AnyBranchScheduler(self, name, branches, treeStableTimer=60,
231 categories=None): 243 categories=None):
232 if name in self._schedulers: 244 if name in self._schedulers:
233 raise ValueError('Scheduler %s already exist' % name) 245 raise ValueError('Scheduler %s already exist' % name)
234 self._schedulers[name] = {'type': 'AnyBranchScheduler', 246 self._schedulers[name] = {'type': 'AnyBranchScheduler',
235 'branches': branches, 247 'branches': branches,
236 'treeStableTimer': treeStableTimer, 248 'treeStableTimer': treeStableTimer,
237 'builders': [], 249 'builders': [],
238 'categories': categories} 250 'categories': categories}
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 # been defined. 372 # been defined.
361 # pylint: disable=W0601 373 # pylint: disable=W0601
362 global skia_all_subdirs 374 global skia_all_subdirs
363 try: 375 try:
364 if skia_all_subdirs: 376 if skia_all_subdirs:
365 raise Exception('skia_all_subdirs has already been defined!') 377 raise Exception('skia_all_subdirs has already been defined!')
366 except NameError: 378 except NameError:
367 skia_all_subdirs = all_subdirs 379 skia_all_subdirs = all_subdirs
368 380
369 381
370 def MakeBuilderName(builder_base_name, config): 382 def MakeBuilderName(role, extra_config=None, is_trybot=False, **kwargs):
371 """ Inserts config into builder_base_name at '%s', or if builder_base_name 383 schema = BUILDER_NAME_SCHEMA.get(role)
372 does not contain '%s', appends config to the end of builder_base_name, 384 if not schema:
373 separated by an underscore. """ 385 raise ValueError('%s is not a recognized role.' % role)
374 try: 386 for k, v in kwargs.iteritems():
375 return builder_base_name % config 387 if BUILDER_NAME_SEP in v:
376 except TypeError: 388 raise ValueError('%s not allowed in %s.' % (v, BUILDER_NAME_SEP))
377 # If builder_base_name does not contain '%s' 389 if not k in schema:
378 return '%s_%s' % (builder_base_name, config) 390 raise ValueError('Schema does not contain "%s": %s' %(k, schema))
391 if extra_config and BUILDER_NAME_SEP in extra_config:
392 raise ValueError('%s not allowed in %s.' % (extra_config,
393 BUILDER_NAME_SEP))
394 name_parts = [role]
395 name_parts.extend([kwargs[attribute] for attribute in schema])
396 if extra_config:
397 name_parts.append(extra_config)
398 if is_trybot:
399 name_parts.append(TRYBOT_NAME_SUFFIX)
400 print BUILDER_NAME_SEP.join(name_parts)
401 return BUILDER_NAME_SEP.join(name_parts)
379 402
380 403
381 def MakeCompileBuilderName(builder_base_name, release=False): 404 def _MakeBuilder(helper, role, os, model, gpu, configuration, arch,
382 if release: 405 gm_image_subdir, factory_type, extra_config=None,
383 compile_name = 'Compile_Release' 406 perf_output_basedir=None, extra_branches=None, is_trybot=False,
384 else: 407 **kwargs):
385 compile_name = 'Compile_Debug' 408 """ Creates a builder and scheduler. """
386 return MakeBuilderName(builder_base_name, compile_name)
387
388
389 def MakeDebugBuilderName(builder_base_name):
390 return MakeBuilderName(builder_base_name, skia_factory.CONFIG_DEBUG)
391
392
393 def MakeReleaseBuilderName(builder_base_name):
394 return MakeBuilderName(builder_base_name, skia_factory.CONFIG_RELEASE)
395
396
397 def MakeBenchBuilderName(builder_base_name):
398 return MakeBuilderName(builder_base_name, skia_factory.CONFIG_BENCH)
399
400
401 def MakeSchedulerName(builder_base_name):
402 return MakeBuilderName(builder_base_name, 'Scheduler')
403
404
405 def _MakeBuilderSet(helper, builder_base_name, gm_image_subdir,
406 perf_output_basedir=None, extra_branches=None,
407 factory_type=None, do_compile=True, do_debug=True,
408 do_release=True, do_bench=True, try_schedulers=None,
409 compile_bot_warnings_as_errors=True,
410 **kwargs):
411 """ Creates a trio of builders for a given platform:
412 1. Debug mode builder which runs all steps
413 2. Release mode builder which runs all steps EXCEPT benchmarks
414 3. Release mode builder which runs ONLY benchmarks.
415 """
416 B = helper.Builder 409 B = helper.Builder
417 F = helper.Factory 410 F = helper.Factory
418 411
419 if not extra_branches: 412 if not extra_branches:
420 extra_branches = [] 413 extra_branches = []
421 subdirs_to_checkout = set(extra_branches) 414 subdirs_to_checkout = set(extra_branches)
422 if gm_image_subdir: 415 if gm_image_subdir:
423 gm_image_branch = 'gm-expected/%s' % gm_image_subdir 416 gm_image_branch = 'gm-expected/%s' % gm_image_subdir
424 subdirs_to_checkout.add(gm_image_branch) 417 subdirs_to_checkout.add(gm_image_branch)
425 418
426 if try_schedulers: 419 builder_name = MakeBuilderName(
427 scheduler_name = '|'.join(try_schedulers) 420 role=role,
428 builder_base_name = builder_base_name + TRYBOT_NAME_SUFFIX 421 os=os,
422 model=model,
423 gpu=gpu,
424 configuration=configuration,
425 arch=arch,
426 extra_config=extra_config,
427 is_trybot=is_trybot)
428
429 if is_trybot:
430 scheduler_name = TRY_SCHEDULERS_STR
429 else: 431 else:
430 scheduler_name = MakeSchedulerName(builder_base_name) 432 scheduler_name = builder_name + BUILDER_NAME_SEP + 'Scheduler'
431 branches = list(subdirs_to_checkout.union(SKIA_PRIMARY_SUBDIRS)) 433 branches = list(subdirs_to_checkout.union(SKIA_PRIMARY_SUBDIRS))
432 helper.AnyBranchScheduler(scheduler_name, branches=branches) 434 helper.AnyBranchScheduler(scheduler_name, branches=branches)
433 435
434 if do_compile: 436 B(builder_name, 'f_%s' % builder_name, scheduler=scheduler_name)
435 compile_debug_builder_name = MakeCompileBuilderName(builder_base_name, 437 F('f_%s' % builder_name, factory_type(
436 release=False) 438 builder_name=builder_name,
437 B(compile_debug_builder_name, 'f_%s' % compile_debug_builder_name, 439 other_subdirs=subdirs_to_checkout,
438 # Do not add gatekeeper for trybots. 440 configuration=configuration,
439 gatekeeper='GateKeeper' if try_schedulers is None else None, 441 gm_image_subdir=gm_image_subdir,
440 scheduler=scheduler_name, override_category=CATEGORY_BUILD) 442 do_patch_step=is_trybot,
441 F('f_%s' % compile_debug_builder_name, factory_type( 443 perf_output_basedir=perf_output_basedir,
442 builder_name=compile_debug_builder_name, 444 **kwargs
443 other_subdirs=subdirs_to_checkout, 445 ).Build(role=role))
444 configuration=skia_factory.CONFIG_DEBUG,
445 gm_image_subdir=gm_image_subdir,
446 do_patch_step=(try_schedulers is not None),
447 perf_output_basedir=None,
448 compile_warnings_as_errors=compile_bot_warnings_as_errors,
449 **kwargs
450 ).BuildCompileOnly())
451 compile_release_builder_name = MakeCompileBuilderName(builder_base_name,
452 release=True)
453 B(compile_release_builder_name, 'f_%s' % compile_release_builder_name,
454 # Do not add gatekeeper for trybots.
455 gatekeeper='GateKeeper' if try_schedulers is None else None,
456 scheduler=scheduler_name, override_category=CATEGORY_BUILD)
457 F('f_%s' % compile_release_builder_name, factory_type(
458 builder_name=compile_release_builder_name,
459 other_subdirs=subdirs_to_checkout,
460 configuration=skia_factory.CONFIG_RELEASE,
461 gm_image_subdir=gm_image_subdir,
462 do_patch_step=(try_schedulers is not None),
463 perf_output_basedir=None,
464 compile_warnings_as_errors=compile_bot_warnings_as_errors,
465 **kwargs
466 ).BuildCompileOnly())
467
468 if do_debug:
469 debug_builder_name = MakeDebugBuilderName(builder_base_name)
470 B(debug_builder_name, 'f_%s' % debug_builder_name,
471 scheduler=scheduler_name)
472 F('f_%s' % debug_builder_name, factory_type(
473 builder_name=debug_builder_name,
474 other_subdirs=subdirs_to_checkout,
475 configuration=skia_factory.CONFIG_DEBUG,
476 gm_image_subdir=gm_image_subdir,
477 do_patch_step=(try_schedulers is not None),
478 perf_output_basedir=None,
479 compile_warnings_as_errors=False,
480 **kwargs
481 ).Build())
482
483 if do_release:
484 no_perf_builder_name = MakeReleaseBuilderName(builder_base_name)
485 B(no_perf_builder_name, 'f_%s' % no_perf_builder_name,
486 scheduler=scheduler_name)
487 F('f_%s' % no_perf_builder_name, factory_type(
488 builder_name=no_perf_builder_name,
489 other_subdirs=subdirs_to_checkout,
490 configuration=skia_factory.CONFIG_RELEASE,
491 gm_image_subdir=gm_image_subdir,
492 do_patch_step=(try_schedulers is not None),
493 perf_output_basedir=None,
494 compile_warnings_as_errors=False,
495 **kwargs
496 ).BuildNoPerf())
497
498 if do_bench:
499 perf_builder_name = MakeBenchBuilderName(builder_base_name)
500 B(perf_builder_name, 'f_%s' % perf_builder_name,
501 scheduler=scheduler_name)
502 F('f_%s' % perf_builder_name, factory_type(
503 builder_name=perf_builder_name,
504 other_subdirs=subdirs_to_checkout,
505 configuration=skia_factory.CONFIG_RELEASE,
506 gm_image_subdir=gm_image_subdir,
507 do_patch_step=(try_schedulers is not None),
508 perf_output_basedir=perf_output_basedir,
509 compile_warnings_as_errors=False,
510 **kwargs
511 ).BuildPerfOnly())
512 446
513 447
514 def _MakeBuilderAndMaybeTrybotSet(do_trybots=True, **kwargs): 448 def _MakeBuilderAndMaybeTrybotSet(do_trybots=True, **kwargs):
515 _MakeBuilderSet(try_schedulers=None, **kwargs) 449 _MakeBuilder(**kwargs)
516 if do_trybots: 450 if do_trybots:
517 _MakeBuilderSet(try_schedulers=TRY_SCHEDULERS, **kwargs) 451 _MakeBuilder(is_trybot=True, **kwargs)
518 452
519 453
520 def MakeBuilderSet(**kwargs): 454 def MakeBuilderSet(**kwargs):
521 _MakeBuilderAndMaybeTrybotSet(factory_type=skia_factory.SkiaFactory, **kwargs) 455 _MakeBuilderAndMaybeTrybotSet(**kwargs)
522 456
523 457
524 def MakeHousekeeperBuilderSet(helper, do_trybots, do_upload_results): 458 def _MakeCompileBuilder(helper, scheduler, os, compiler, configuration,
525 B = helper.Builder 459 target_arch, factory_type, is_trybot,
526 F = helper.Factory 460 extra_config=None, **kwargs):
527 461 builder_name = MakeBuilderName(role=BUILDER_ROLE_COMPILE,
528 builder_factory_scheduler = [ 462 os=os,
529 # The Percommit housekeeper 463 compiler=compiler,
530 ('Skia_PerCommit_House_Keeping', 464 configuration=configuration,
531 housekeeping_percommit_factory.HouseKeepingPerCommitFactory, 465 target_arch=target_arch,
532 'skia_rel'), 466 extra_config=extra_config,
533 # The Periodic housekeeper 467 is_trybot=is_trybot)
534 ('Skia_Periodic_House_Keeping', 468 helper.Builder(builder_name, 'f_%s' % builder_name,
535 housekeeping_periodic_factory.HouseKeepingPeriodicFactory, 469 # Do not add gatekeeper for trybots.
536 'skia_periodic'), 470 gatekeeper='GateKeeper' if is_trybot else None,
537 ] 471 scheduler=scheduler)
538 if do_trybots: 472 helper.Factory('f_%s' % builder_name, factory_type(
539 # Add the corresponding trybot builders to the above list. 473 builder_name=builder_name,
540 builder_factory_scheduler.extend([ 474 do_patch_step=is_trybot,
541 (builder + TRYBOT_NAME_SUFFIX, factory, TRY_SCHEDULERS_STR) 475 configuration=configuration,
542 for (builder, factory, _scheduler) in builder_factory_scheduler]) 476 **kwargs
543 477 ).Build(role=BUILDER_ROLE_COMPILE))
544 for (builder_name, factory, scheduler) in builder_factory_scheduler: 478 return builder_name
545 B(builder_name, 'f_%s' % builder_name, scheduler=scheduler)
546 F('f_%s' % builder_name,
547 factory(
548 do_upload_results=do_upload_results,
549 target_platform=skia_factory.TARGET_PLATFORM_LINUX,
550 builder_name=builder_name,
551 do_patch_step=(scheduler == TRY_SCHEDULERS_STR),
552 ).Build())
553 479
554 480
555 def MakeAndroidBuilderSet(extra_branches=None, **kwargs): 481 def MakeCompileBuilderSet(scheduler, do_trybots=True, **kwargs):
556 if not extra_branches: 482 if do_trybots:
557 extra_branches = [] 483 _MakeCompileBuilder(scheduler=scheduler, is_trybot=True, **kwargs)
558 extra_branches.append('android') 484 _MakeCompileBuilder(scheduler=TRY_SCHEDULERS_STR, is_trybot=False, **kwargs)
559 _MakeBuilderAndMaybeTrybotSet(factory_type=android_factory.AndroidFactory,
560 extra_branches=extra_branches,
561 **kwargs)
562
563
564 def MakeChromeOSBuilderSet(**kwargs):
565 _MakeBuilderAndMaybeTrybotSet(factory_type=chromeos_factory.ChromeOSFactory,
566 **kwargs)
567
568
569 def MakeIOSBuilderSet(**kwargs):
570 _MakeBuilderAndMaybeTrybotSet(factory_type=ios_factory.iOSFactory, **kwargs)
571
572
573 def MakeNaClBuilderSet(**kwargs):
574 _MakeBuilderAndMaybeTrybotSet(factory_type=nacl_factory.NaClFactory, **kwargs)
575 485
576 486
577 def CanMergeBuildRequests(req1, req2): 487 def CanMergeBuildRequests(req1, req2):
578 """ Determine whether or not two BuildRequests can be merged. Note that the 488 """ Determine whether or not two BuildRequests can be merged. Note that the
579 call to buildbot.sourcestamp.SourceStamp.canBeMergedWith() is conspicuously 489 call to buildbot.sourcestamp.SourceStamp.canBeMergedWith() is conspicuously
580 missing. This is because that method verifies that: 490 missing. This is because that method verifies that:
581 1. req1.source.repository == req2.source.repository 491 1. req1.source.repository == req2.source.repository
582 2. req1.source.project == req2.source.project 492 2. req1.source.project == req2.source.project
583 3. req1.source.branch == req2.source.branch 493 3. req1.source.branch == req2.source.branch
584 4. req1.patch == None and req2.patch = None 494 4. req1.patch == None and req2.patch = None
(...skipping 29 matching lines...) Expand all
614 # request is associated with a change but the revisions match (#5 above). 524 # request is associated with a change but the revisions match (#5 above).
615 if req1.source.changes and not req2.source.changes: 525 if req1.source.changes and not req2.source.changes:
616 return False 526 return False
617 if not req1.source.changes and req2.source.changes: 527 if not req1.source.changes and req2.source.changes:
618 return False 528 return False
619 if not (req1.source.changes and req2.source.changes): 529 if not (req1.source.changes and req2.source.changes):
620 if req1.source.revision != req2.source.revision: 530 if req1.source.revision != req2.source.revision:
621 return False 531 return False
622 532
623 return True 533 return True
OLDNEW
« no previous file with comments | « master/skia_master_scripts/factory.py ('k') | master/slaves.cfg » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698