OLD | NEW |
---|---|
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 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 DEPS = [ | 5 DEPS = [ |
6 'bot_update', | 6 'bot_update', |
7 'chromium', | 7 'chromium', |
8 'gclient', | 8 'gclient', |
9 'isolate', | 9 'isolate', |
10 'itertools', | 10 'itertools', |
11 'json', | 11 'json', |
12 'path', | 12 'path', |
13 'platform', | 13 'platform', |
14 'properties', | 14 'properties', |
15 'python', | 15 'python', |
16 'raw_io', | 16 'raw_io', |
17 'step', | 17 'step', |
18 'step_history', | 18 'step_history', |
19 'swarming', | |
19 'test_utils', | 20 'test_utils', |
20 'tryserver', | 21 'tryserver', |
21 ] | 22 ] |
22 | 23 |
23 | 24 |
24 BUILDERS = { | 25 BUILDERS = { |
25 'tryserver.chromium': { | 26 'tryserver.chromium': { |
26 'builders': { | 27 'builders': { |
27 'linux_arm_cross_compile': { | 28 'linux_arm_cross_compile': { |
28 'GYP_DEFINES': { | 29 'GYP_DEFINES': { |
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
333 'compile_only': False, | 334 'compile_only': False, |
334 'testing': { | 335 'testing': { |
335 'platform': 'win', | 336 'platform': 'win', |
336 }, | 337 }, |
337 }, | 338 }, |
338 }, | 339 }, |
339 }, | 340 }, |
340 } | 341 } |
341 | 342 |
342 | 343 |
344 def add_swarming_builder(original, swarming, server='tryserver.chromium'): | |
345 """Duplicates builder config on |server|, adding 'enable_swarming: True'.""" | |
346 assert server in BUILDERS | |
347 assert original in BUILDERS[server]['builders'] | |
348 assert swarming not in BUILDERS[server]['builders'] | |
349 conf = BUILDERS[server]['builders'][original].copy() | |
350 conf['enable_swarming'] = True | |
351 BUILDERS[server]['builders'][swarming] = conf | |
352 | |
353 | |
354 add_swarming_builder('linux_chromium_rel', 'linux_chromium_rel_swarming') | |
355 add_swarming_builder('win_chromium_rel', 'win_chromium_rel_swarming') | |
356 add_swarming_builder('mac_chromium_rel', 'mac_chromium_rel_swarming') | |
357 | |
358 | |
343 def GenSteps(api): | 359 def GenSteps(api): |
344 class CheckdepsTest(api.test_utils.Test): # pylint: disable=W0232 | 360 class CheckdepsTest(api.test_utils.Test): # pylint: disable=W0232 |
345 name = 'checkdeps' | 361 name = 'checkdeps' |
346 | 362 |
347 @staticmethod | 363 @staticmethod |
348 def compile_targets(): | 364 def compile_targets(): |
349 return [] | 365 return [] |
350 | 366 |
351 @staticmethod | 367 @staticmethod |
352 def run(suffix): | 368 def run(suffix): |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
430 step_test_data=lambda: api.json.test_api.canned_gtest_output(True)) | 446 step_test_data=lambda: api.json.test_api.canned_gtest_output(True)) |
431 | 447 |
432 def has_valid_results(self, suffix): | 448 def has_valid_results(self, suffix): |
433 step_name = self._step_name(suffix) | 449 step_name = self._step_name(suffix) |
434 gtest_results = api.step_history[step_name].json.gtest_results | 450 gtest_results = api.step_history[step_name].json.gtest_results |
435 if not gtest_results.valid: # pragma: no cover | 451 if not gtest_results.valid: # pragma: no cover |
436 return False | 452 return False |
437 global_tags = gtest_results.raw.get('global_tags', []) | 453 global_tags = gtest_results.raw.get('global_tags', []) |
438 return 'UNRELIABLE_RESULTS' not in global_tags | 454 return 'UNRELIABLE_RESULTS' not in global_tags |
439 | 455 |
440 | |
441 def failures(self, suffix): | 456 def failures(self, suffix): |
442 step_name = self._step_name(suffix) | 457 step_name = self._step_name(suffix) |
443 return api.step_history[step_name].json.gtest_results.failures | 458 return api.step_history[step_name].json.gtest_results.failures |
444 | 459 |
445 | 460 |
461 class SwarmingGTestTest(api.test_utils.Test): | |
462 # This test is using 'trigger' and 'collect' instead of 'run'. | |
463 async = True | |
464 | |
465 def __init__(self, name, args=None): | |
466 api.test_utils.Test.__init__(self) | |
467 self._name = name | |
468 self._args = args or [] | |
469 self._tasks = {} | |
470 self._results = {} | |
471 | |
472 @property | |
473 def name(self): | |
474 return self._name | |
475 | |
476 def compile_targets(self): | |
477 # <X>_run target depends on <X>, and then isolates it invoking isolate.py. | |
478 # It is a convention, not a hard coded rule. | |
479 return [self._name + '_run'] | |
480 | |
481 def trigger(self, suffix): | |
482 assert suffix not in self._tasks, ( | |
483 'Test %s was already triggered' % self._step_name(suffix)) | |
484 | |
485 # *.isolated may be missing if *_run target is misconfigured. It a error | |
Paweł Hajdan Jr.
2014/06/10 08:36:56
nit: "It a error" -> "It's an error"
Vadim Sh.
2014/06/12 01:00:08
Done.
| |
486 # in gyp, not a recipe failure. So carry on with recipe execution. | |
487 isolated_hash = api.isolate.isolated_tests.get(self._name) | |
488 if not isolated_hash: | |
489 return api.python.inline( | |
490 '[error] %s' % self._step_name(suffix), | |
491 r""" | |
492 import sys | |
493 print '*.isolated file for target %s is missing' % sys.argv[1] | |
494 sys.exit(1) | |
495 """, | |
496 args=[self._name], | |
497 always_run=True) | |
498 | |
499 # If rerunning without a patch, run only tests that failed. | |
500 args = self._args[:] | |
501 if suffix == 'without patch': | |
502 failed_tests = sorted(self.failures('with patch')) | |
503 args.append('--gtest_filter=%s' % ':'.join(failed_tests)) | |
504 | |
505 # Trigger the test on swarming. | |
506 self._tasks[suffix] = api.swarming.gtest_task( | |
507 title=self._step_name(suffix), | |
508 isolated_hash=isolated_hash, | |
509 test_launcher_summary_output=api.json.gtest_results( | |
510 add_json_log=False), | |
511 extra_args=args) | |
512 return api.swarming.trigger([self._tasks[suffix]], always_run=True) | |
513 | |
514 def collect(self, suffix): | |
515 assert suffix not in self._results, ( | |
516 'Results of %s were already collected' % self._step_name(suffix)) | |
517 | |
518 # Emit error if test wasn't triggered. This happens if *.isolated is not | |
519 # found. (The build is already red by this moment anyway). | |
520 if suffix not in self._tasks: | |
521 return api.python.inline( | |
522 '[collect error] %s' % self._step_name(suffix), | |
523 r""" | |
524 import sys | |
525 print '%s wasn\'t triggered' % sys.argv[1] | |
526 sys.exit(1) | |
527 """, | |
528 args=[self._name], | |
529 always_run=True) | |
530 | |
531 # Update step presentation, store step results in self._results. | |
532 def followup_fn(step_result): | |
533 r = step_result.json.gtest_results | |
534 p = step_result.presentation | |
535 if r.valid: | |
536 p.step_text += api.test_utils.format_step_text([ | |
537 ['failures:', r.failures] | |
538 ]) | |
539 self._results[suffix] = r | |
540 | |
541 # Wait for test on swarming to finish. | |
542 return api.swarming.collect( | |
543 [self._tasks[suffix]], | |
544 always_run=True, | |
545 can_fail_build=False, | |
546 followup_fn=followup_fn) | |
547 | |
548 def has_valid_results(self, suffix): | |
549 # Test wasn't triggered or wasn't collected. | |
550 if suffix not in self._tasks or not suffix in self._results: | |
551 return False | |
552 # Test ran, but failed to produce valid *.json. | |
553 gtest_results = self._results[suffix] | |
554 if not gtest_results.valid: # pragma: no cover | |
555 return False | |
556 global_tags = gtest_results.raw.get('global_tags', []) | |
557 return 'UNRELIABLE_RESULTS' not in global_tags | |
558 | |
559 def failures(self, suffix): | |
560 assert self.has_valid_results(suffix) | |
561 return self._results[suffix].failures | |
562 | |
563 | |
446 class NaclIntegrationTest(api.test_utils.Test): # pylint: disable=W0232 | 564 class NaclIntegrationTest(api.test_utils.Test): # pylint: disable=W0232 |
447 name = 'nacl_integration' | 565 name = 'nacl_integration' |
448 | 566 |
449 @staticmethod | 567 @staticmethod |
450 def compile_targets(): | 568 def compile_targets(): |
451 return ['chrome'] | 569 return ['chrome'] |
452 | 570 |
453 def run(self, suffix): | 571 def run(self, suffix): |
454 args = [ | 572 args = [ |
455 '--mode', api.chromium.c.build_config_fs, | 573 '--mode', api.chromium.c.build_config_fs, |
456 '--json_build_results_output_file', api.json.output(), | 574 '--json_build_results_output_file', api.json.output(), |
457 ] | 575 ] |
458 return api.python( | 576 return api.python( |
459 self._step_name(suffix), | 577 self._step_name(suffix), |
460 api.path['checkout'].join('chrome', | 578 api.path['checkout'].join('chrome', |
461 'test', | 579 'test', |
462 'nacl_test_injection', | 580 'nacl_test_injection', |
463 'buildbot_nacl_integration.py'), | 581 'buildbot_nacl_integration.py'), |
464 args, | 582 args, |
465 can_fail_build=False, | 583 can_fail_build=False, |
466 step_test_data=lambda: api.m.json.test_api.output([])) | 584 step_test_data=lambda: api.m.json.test_api.output([])) |
467 | 585 |
468 def has_valid_results(self, suffix): | 586 def has_valid_results(self, suffix): |
469 return api.step_history[self._step_name(suffix)].json.output is not None | 587 return api.step_history[self._step_name(suffix)].json.output is not None |
470 | 588 |
471 def failures(self, suffix): | 589 def failures(self, suffix): |
472 failures = api.step_history[self._step_name(suffix)].json.output | 590 failures = api.step_history[self._step_name(suffix)].json.output |
473 return [f['raw_name'] for f in failures] | 591 return [f['raw_name'] for f in failures] |
474 | 592 |
593 | |
594 def parse_test_spec(test_spec, enable_swarming, should_use_test): | |
595 """Returns a list of tests to run and additional targets to compile. | |
596 | |
597 Uses 'should_use_test' callback to figure out what tests should be skipped. | |
598 | |
599 Returns triple (compile_targets, gtest_tests, swarming_tests) where | |
600 gtest_tests is a list of GTestTest | |
601 swarming_tests is a list of SwarmingGTestTest. | |
602 """ | |
603 compile_targets = [] | |
604 gtest_tests_spec = [] | |
605 if isinstance(test_spec, dict): | |
606 compile_targets = test_spec.get('compile_targets', []) | |
607 gtest_tests_spec = test_spec.get('gtest_tests', []) | |
608 else: | |
609 # TODO(nodir): Remove this after | |
610 # https://codereview.chromium.org/297303012/#ps50001 | |
611 # lands. | |
612 gtest_tests_spec = test_spec | |
613 | |
614 gtest_tests = [] | |
615 swarming_tests = [] | |
616 for test in gtest_tests_spec: | |
617 test_name = None | |
618 test_dict = None | |
619 | |
620 # Read test_dict for the test, it defines where test can run. | |
621 if isinstance(test, unicode): | |
622 test_name = test.encode('utf-8') | |
623 test_dict = {} | |
624 elif isinstance(test, dict): | |
625 if 'test' not in test: # pragma: no cover | |
626 raise ValueError('Invalid entry in test spec: %r' % test) | |
627 test_name = test['test'].encode('utf-8') | |
628 test_dict = test | |
629 else: # pragma: no cover | |
630 raise ValueError('Unrecognized entry in test spec: %r' % test) | |
631 | |
632 # Should skip it completely? | |
633 if not test_name or not should_use_test(test_dict): | |
634 continue | |
635 | |
636 # If test can run on swarming, test_dict has a section that defines when | |
637 # swarming should be used, in same format as main test dict. | |
638 use_swarming = False | |
639 if enable_swarming: | |
640 swarming_spec = test_dict.get('swarming', False) | |
Paweł Hajdan Jr.
2014/06/10 08:36:56
nit: Could you rename this to "can_use_swarming_if
Vadim Sh.
2014/06/12 01:00:08
No, because in general it's not a boolean field, b
| |
641 if isinstance(swarming_spec, bool): | |
642 use_swarming = swarming_spec | |
643 swarming_spec = {} | |
644 elif isinstance(swarming_spec, dict): | |
Paweł Hajdan Jr.
2014/06/10 08:36:56
We have isinstance for other parts of the spec for
Vadim Sh.
2014/06/12 01:00:08
Always dict now.
| |
645 if not swarming_spec: # pragma: no cover | |
646 raise ValueError('Empty \'swarming\' section in test spec for %s ' | |
647 'is ambiguous. Use true or false.' % test_name) | |
648 use_swarming = should_use_test(swarming_spec) | |
649 else: # pragma: no cover | |
650 raise ValueError( | |
651 'Unrecognized swarming entry in test spec: %r' % test) | |
652 | |
653 test_args = test_dict.get('args') | |
654 if isinstance(test_args, basestring): | |
655 test_args = [test_args] | |
656 | |
657 if use_swarming: | |
658 swarming_tests.append(SwarmingGTestTest(test_name, test_args)) | |
659 else: | |
660 gtest_tests.append(GTestTest(test_name, test_args)) | |
661 | |
662 return compile_targets, gtest_tests, swarming_tests | |
663 | |
664 | |
475 mastername = api.properties.get('mastername') | 665 mastername = api.properties.get('mastername') |
476 buildername = api.properties.get('buildername') | 666 buildername = api.properties.get('buildername') |
477 master_dict = BUILDERS.get(mastername, {}) | 667 master_dict = BUILDERS.get(mastername, {}) |
478 bot_config = master_dict.get('builders', {}).get(buildername) | 668 bot_config = master_dict.get('builders', {}).get(buildername) |
479 assert bot_config, ( | 669 assert bot_config, ( |
480 'Unrecognized builder name %r for master %r.' % ( | 670 'Unrecognized builder name %r for master %r.' % ( |
481 buildername, mastername)) | 671 buildername, mastername)) |
482 | 672 |
483 # Make sure tests and the recipe specify correct and matching platform. | 673 # Make sure tests and the recipe specify correct and matching platform. |
484 assert api.platform.name == bot_config.get('testing', {}).get('platform') | 674 assert api.platform.name == bot_config.get('testing', {}).get('platform') |
485 | 675 |
486 api.chromium.set_config(bot_config['chromium_config'], | 676 api.chromium.set_config(bot_config['chromium_config'], |
487 **bot_config.get('chromium_config_kwargs', {})) | 677 **bot_config.get('chromium_config_kwargs', {})) |
488 # Settings GYP_DEFINES explicitly because chromium config constructor does | 678 # Settings GYP_DEFINES explicitly because chromium config constructor does |
489 # not support that. | 679 # not support that. |
490 api.chromium.c.gyp_env.GYP_DEFINES.update(bot_config.get('GYP_DEFINES', {})) | 680 api.chromium.c.gyp_env.GYP_DEFINES.update(bot_config.get('GYP_DEFINES', {})) |
491 if bot_config.get('use_isolate'): | |
492 api.isolate.set_isolate_environment(api.chromium.c) | |
493 api.chromium.apply_config('trybot_flavor') | 681 api.chromium.apply_config('trybot_flavor') |
494 api.gclient.set_config('chromium') | 682 api.gclient.set_config('chromium') |
495 api.step.auto_resolve_conflicts = True | 683 api.step.auto_resolve_conflicts = True |
496 | 684 |
497 yield api.bot_update.ensure_checkout() | 685 yield api.bot_update.ensure_checkout() |
498 # The first time we run bot update, remember if bot_update mode is on or off. | 686 # The first time we run bot update, remember if bot_update mode is on or off. |
499 bot_update_mode = api.step_history.last_step().json.output['did_run'] | 687 bot_update_mode = api.step_history.last_step().json.output['did_run'] |
500 if not bot_update_mode: | 688 if not bot_update_mode: |
501 yield api.gclient.checkout( | 689 yield api.gclient.checkout( |
502 revert=True, can_fail_build=False, abort_on_failure=False) | 690 revert=True, can_fail_build=False, abort_on_failure=False) |
(...skipping 30 matching lines...) Expand all Loading... | |
533 'args': ['--test-launcher-print-test-stdio=always'], | 721 'args': ['--test-launcher-print-test-stdio=always'], |
534 }, | 722 }, |
535 { | 723 { |
536 'test': 'browser_tests', | 724 'test': 'browser_tests', |
537 'exclude_builders': ['tryserver.chromium:win_chromium_x64_rel'], | 725 'exclude_builders': ['tryserver.chromium:win_chromium_x64_rel'], |
538 }, | 726 }, |
539 ]), | 727 ]), |
540 followup_fn=test_spec_followup_fn, | 728 followup_fn=test_spec_followup_fn, |
541 ) | 729 ) |
542 | 730 |
731 def should_use_test(test): | |
732 """Given a test dict from test spec returns True or False.""" | |
733 if 'platforms' in test: | |
734 if api.platform.name not in test['platforms']: | |
735 return False | |
736 if 'chromium_configs' in test: | |
737 if bot_config['chromium_config'] not in test['chromium_configs']: | |
738 return False | |
739 if 'exclude_builders' in test: | |
740 if '%s:%s' % (mastername, buildername) in test['exclude_builders']: | |
741 return False | |
742 return True | |
743 | |
744 # Parse test spec file into list of Test instances. | |
745 compile_targets, gtest_tests, swarming_tests = parse_test_spec( | |
746 api.step_history['read test spec'].json.output, | |
747 bot_config.get('enable_swarming'), | |
748 should_use_test) | |
749 | |
750 # Swarming uses Isolate to transfer files to swarming bots. | |
751 # set_isolate_environment modifies GYP_DEFINES to enable test isolation. | |
752 use_isolate = swarming_tests or bot_config.get('use_isolate') | |
753 if use_isolate: | |
754 api.isolate.set_isolate_environment(api.chromium.c) | |
755 | |
543 runhooks_env = bot_config.get('runhooks_env', {}) | 756 runhooks_env = bot_config.get('runhooks_env', {}) |
544 | 757 |
545 yield api.chromium.runhooks(env=runhooks_env, abort_on_failure=False, | 758 yield api.chromium.runhooks(env=runhooks_env, abort_on_failure=False, |
546 can_fail_build=False) | 759 can_fail_build=False) |
547 if api.step_history.last_step().retcode != 0: | 760 if api.step_history.last_step().retcode != 0: |
548 # Before removing the checkout directory try just using LKCR. | 761 # Before removing the checkout directory try just using LKCR. |
549 api.gclient.set_config('chromium_lkcr') | 762 api.gclient.set_config('chromium_lkcr') |
550 | 763 |
551 # Since we're likely to switch to an earlier revision, revert the patch, | 764 # Since we're likely to switch to an earlier revision, revert the patch, |
552 # sync with the new config, and apply issue again. | 765 # sync with the new config, and apply issue again. |
(...skipping 10 matching lines...) Expand all Loading... | |
563 if api.step_history.last_step().retcode != 0: | 776 if api.step_history.last_step().retcode != 0: |
564 if api.platform.is_win: | 777 if api.platform.is_win: |
565 yield api.chromium.taskkill() | 778 yield api.chromium.taskkill() |
566 yield ( | 779 yield ( |
567 api.path.rmcontents('slave build directory', api.path['slave_build']), | 780 api.path.rmcontents('slave build directory', api.path['slave_build']), |
568 api.gclient.checkout(revert=False), | 781 api.gclient.checkout(revert=False), |
569 api.tryserver.maybe_apply_issue(), | 782 api.tryserver.maybe_apply_issue(), |
570 api.chromium.runhooks(env=runhooks_env) | 783 api.chromium.runhooks(env=runhooks_env) |
571 ) | 784 ) |
572 | 785 |
573 gtest_tests = [] | 786 # If going to use swarming_client (pinned in src/DEPS), ensure it is |
574 compile_targets = [] | 787 # compatible with what recipes expect. |
575 test_spec = api.step_history['read test spec'].json.output | 788 if swarming_tests: |
576 | 789 yield api.swarming.check_client_version() |
577 if isinstance(test_spec, dict): | |
578 compile_targets = test_spec.get('compile_targets', []) | |
579 gtest_tests_spec = test_spec.get('gtest_tests', []) | |
580 else: | |
581 # TODO (nodir): Remove this after | |
582 # https://codereview.chromium.org/297303012/#ps50001 | |
583 # lands. | |
584 gtest_tests_spec = test_spec | |
585 | |
586 for test in gtest_tests_spec: | |
587 test_name = None | |
588 test_args = None | |
589 | |
590 if isinstance(test, unicode): | |
591 test_name = test.encode('utf-8') | |
592 elif isinstance(test, dict): | |
593 if 'platforms' in test: | |
594 if api.platform.name not in test['platforms']: | |
595 continue | |
596 | |
597 if 'chromium_configs' in test: | |
598 if bot_config['chromium_config'] not in test['chromium_configs']: | |
599 continue | |
600 | |
601 if 'exclude_builders' in test: | |
602 if '%s:%s' % (mastername, buildername) in test['exclude_builders']: | |
603 continue | |
604 | |
605 test_args = test.get('args') | |
606 if isinstance(test_args, basestring): | |
607 test_args = [test_args] | |
608 | |
609 if 'test' not in test: # pragma: no cover | |
610 raise ValueError('Invalid entry in test spec: %r' % test) | |
611 | |
612 test_name = test['test'].encode('utf-8') | |
613 else: # pragma: no cover | |
614 raise ValueError('Unrecognized entry in test spec: %r' % test) | |
615 | |
616 if test_name: | |
617 gtest_tests.append(GTestTest(test_name, test_args)) | |
618 | 790 |
619 tests = [] | 791 tests = [] |
620 tests.append(CheckdepsTest()) | 792 tests.append(CheckdepsTest()) |
621 tests.append(Deps2GitTest()) | 793 tests.append(Deps2GitTest()) |
622 for test in gtest_tests: | 794 tests.extend(gtest_tests) |
623 tests.append(test) | 795 tests.extend(swarming_tests) |
624 tests.append(NaclIntegrationTest()) | 796 tests.append(NaclIntegrationTest()) |
625 | 797 |
626 compile_targets.extend(bot_config.get('compile_targets', [])) | 798 compile_targets.extend(bot_config.get('compile_targets', [])) |
627 compile_targets.extend(api.itertools.chain( | 799 compile_targets.extend(api.itertools.chain( |
628 *[t.compile_targets() for t in tests])) | 800 *[t.compile_targets() for t in tests])) |
629 # TODO(phajdan.jr): Also compile 'all' on win, http://crbug.com/368831 . | 801 # TODO(phajdan.jr): Also compile 'all' on win, http://crbug.com/368831 . |
630 # Disabled for now because it takes too long and/or fails on Windows. | 802 # Disabled for now because it takes too long and/or fails on Windows. |
631 if not api.platform.is_win and not bot_config.get('exclude_compile_all'): | 803 if not api.platform.is_win and not bot_config.get('exclude_compile_all'): |
632 compile_targets = ['all'] + compile_targets | 804 compile_targets = ['all'] + compile_targets |
633 yield api.chromium.compile(compile_targets, | 805 yield api.chromium.compile(compile_targets, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
667 yield api.chromium.runhooks() | 839 yield api.chromium.runhooks() |
668 yield api.chromium.compile(compile_targets, | 840 yield api.chromium.compile(compile_targets, |
669 name='compile ' | 841 name='compile ' |
670 '(with patch, lkcr, clobber, nuke)', | 842 '(with patch, lkcr, clobber, nuke)', |
671 force_clobber=True) | 843 force_clobber=True) |
672 | 844 |
673 # Do not run tests if the build is already in a failed state. | 845 # Do not run tests if the build is already in a failed state. |
674 if api.step_history.failed: | 846 if api.step_history.failed: |
675 return | 847 return |
676 | 848 |
677 if bot_config.get('use_isolate'): | 849 # Collect *.isolated hashes for all isolated targets, used when triggering |
850 # tests on swarming. | |
851 if use_isolate: | |
678 yield api.isolate.find_isolated_tests(api.chromium.output_dir) | 852 yield api.isolate.find_isolated_tests(api.chromium.output_dir) |
679 | 853 |
680 if bot_config['compile_only']: | 854 if bot_config['compile_only']: |
681 return | 855 return |
682 | 856 |
683 if bot_config['chromium_config'] not in ['chromium_chromeos', | 857 if bot_config['chromium_config'] not in ['chromium_chromeos', |
684 'chromium_chromeos_clang']: | 858 'chromium_chromeos_clang']: |
685 # TODO(phajdan.jr): Make it possible to retry telemetry tests (add JSON). | 859 # TODO(phajdan.jr): Make it possible to retry telemetry tests (add JSON). |
860 # TODO(vadimsh): Trigger swarming tests before telemetry tests. | |
686 yield ( | 861 yield ( |
687 api.chromium.run_telemetry_unittests(), | 862 api.chromium.run_telemetry_unittests(), |
688 api.chromium.run_telemetry_perf_unittests(), | 863 api.chromium.run_telemetry_perf_unittests(), |
689 ) | 864 ) |
690 | 865 |
691 def deapply_patch_fn(failing_tests): | 866 def deapply_patch_fn(failing_tests): |
692 if api.platform.is_win: | 867 if api.platform.is_win: |
693 yield api.chromium.taskkill() | 868 yield api.chromium.taskkill() |
694 if bot_update_mode: | 869 if bot_update_mode: |
695 yield api.bot_update.ensure_checkout(patch=False, | 870 yield api.bot_update.ensure_checkout(patch=False, |
696 always_run=True, | 871 always_run=True, |
697 update_presentation=False) | 872 update_presentation=False) |
698 else: | 873 else: |
699 yield api.gclient.checkout(revert=True, always_run=True), | 874 yield api.gclient.checkout(revert=True, always_run=True), |
700 yield api.chromium.runhooks(always_run=True), | 875 yield api.chromium.runhooks(always_run=True), |
701 compile_targets = list(api.itertools.chain( | 876 compile_targets = list(api.itertools.chain( |
702 *[t.compile_targets() for t in failing_tests])) | 877 *[t.compile_targets() for t in failing_tests])) |
703 if compile_targets: | 878 if compile_targets: |
704 yield api.chromium.compile(compile_targets, | 879 yield api.chromium.compile(compile_targets, |
705 name='compile (without patch)', | 880 name='compile (without patch)', |
706 abort_on_failure=False, | 881 abort_on_failure=False, |
707 can_fail_build=False, | 882 can_fail_build=False, |
708 always_run=True) | 883 always_run=True) |
709 if api.step_history['compile (without patch)'].retcode != 0: | 884 if api.step_history['compile (without patch)'].retcode != 0: |
710 yield api.chromium.compile(compile_targets, | 885 yield api.chromium.compile(compile_targets, |
711 name='compile (without patch, clobber)', | 886 name='compile (without patch, clobber)', |
712 force_clobber=True, | 887 force_clobber=True, |
713 always_run=True) | 888 always_run=True) |
889 if use_isolate: | |
890 yield api.isolate.find_isolated_tests(api.chromium.output_dir, | |
891 always_run=True) | |
714 | 892 |
715 yield api.test_utils.determine_new_failures(tests, deapply_patch_fn) | 893 yield api.test_utils.determine_new_failures(tests, deapply_patch_fn) |
716 | 894 |
717 | 895 |
718 def _sanitize_nonalpha(text): | 896 def _sanitize_nonalpha(text): |
719 return ''.join(c if c.isalnum() else '_' for c in text) | 897 return ''.join(c if c.isalnum() else '_' for c in text) |
720 | 898 |
721 | 899 |
722 def GenTests(api): | 900 def GenTests(api): |
723 canned_checkdeps = { | 901 canned_checkdeps = { |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
908 'test': 'browser_tests', | 1086 'test': 'browser_tests', |
909 'args': '--gtest-filter: *NaCl*', | 1087 'args': '--gtest-filter: *NaCl*', |
910 }, { | 1088 }, { |
911 'test': 'base_tests', | 1089 'test': 'base_tests', |
912 'args': ['--gtest-filter: *NaCl*'], | 1090 'args': ['--gtest-filter: *NaCl*'], |
913 }, | 1091 }, |
914 ], | 1092 ], |
915 }) | 1093 }) |
916 ) | 1094 ) |
917 ) | 1095 ) |
1096 | |
1097 # Successfully compiling, isolating and running two targets on swarming. | |
1098 # Check both 'swarming: True' and 'swarming: {dict}' test spec definitions. | |
1099 yield ( | |
1100 api.test('swarming_basic') + | |
1101 props(buildername='linux_chromium_rel_swarming') + | |
1102 api.platform.name('linux') + | |
1103 api.override_step_data('read test spec', api.json.output({ | |
1104 'gtest_tests': [ | |
1105 { | |
1106 'test': 'base_unittests', | |
1107 'swarming': True, | |
1108 }, | |
1109 { | |
1110 'test': 'browser_tests', | |
1111 'swarming': { | |
1112 'platforms': ['linux'], | |
1113 }, | |
1114 }, | |
1115 ], | |
1116 }) | |
1117 ) + | |
1118 api.override_step_data( | |
1119 'find isolated tests', | |
1120 api.isolate.output_json(['base_unittests', 'browser_tests'])) | |
1121 ) | |
1122 | |
1123 # One target (browser_tests) failed to produce *.isolated file. | |
1124 yield ( | |
1125 api.test('swarming_missing_isolated') + | |
1126 props(buildername='linux_chromium_rel_swarming') + | |
1127 api.platform.name('linux') + | |
1128 api.override_step_data('read test spec', api.json.output({ | |
1129 'gtest_tests': [ | |
1130 { | |
1131 'test': 'base_unittests', | |
1132 'swarming': True, | |
1133 }, | |
1134 { | |
1135 'test': 'browser_tests', | |
1136 'swarming': True, | |
1137 }, | |
1138 ], | |
1139 }) | |
1140 ) + | |
1141 api.override_step_data( | |
1142 'find isolated tests', | |
1143 api.isolate.output_json(['base_unittests'])) | |
1144 ) | |
1145 | |
1146 # One test (base_unittest) failed on swarming. It is retried with | |
1147 # deapplied patch. | |
1148 yield ( | |
1149 api.test('swarming_deapply_patch') + | |
1150 props(buildername='linux_chromium_rel_swarming') + | |
1151 api.platform.name('linux') + | |
1152 api.override_step_data('read test spec', api.json.output({ | |
1153 'gtest_tests': [ | |
1154 { | |
1155 'test': 'base_unittests', | |
1156 'swarming': True, | |
1157 }, | |
1158 { | |
1159 'test': 'browser_tests', | |
1160 'swarming': True, | |
1161 }, | |
1162 ], | |
1163 }) | |
1164 ) + | |
1165 api.override_step_data( | |
1166 'find isolated tests', | |
1167 api.isolate.output_json(['base_unittests', 'browser_tests'])) + | |
1168 api.override_step_data('[swarming] base_unittests (with patch)', | |
1169 canned_test(passing=False)) + | |
1170 api.override_step_data( | |
1171 'find isolated tests (2)', | |
1172 api.isolate.output_json(['base_unittests'])) | |
1173 ) | |
OLD | NEW |