Chromium Code Reviews| 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 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 430 step_test_data=lambda: api.json.test_api.canned_gtest_output(True)) | 431 step_test_data=lambda: api.json.test_api.canned_gtest_output(True)) |
| 431 | 432 |
| 432 def has_valid_results(self, suffix): | 433 def has_valid_results(self, suffix): |
| 433 step_name = self._step_name(suffix) | 434 step_name = self._step_name(suffix) |
| 434 gtest_results = api.step_history[step_name].json.gtest_results | 435 gtest_results = api.step_history[step_name].json.gtest_results |
| 435 if not gtest_results.valid: # pragma: no cover | 436 if not gtest_results.valid: # pragma: no cover |
| 436 return False | 437 return False |
| 437 global_tags = gtest_results.raw.get('global_tags', []) | 438 global_tags = gtest_results.raw.get('global_tags', []) |
| 438 return 'UNRELIABLE_RESULTS' not in global_tags | 439 return 'UNRELIABLE_RESULTS' not in global_tags |
| 439 | 440 |
| 440 | |
| 441 def failures(self, suffix): | 441 def failures(self, suffix): |
| 442 step_name = self._step_name(suffix) | 442 step_name = self._step_name(suffix) |
| 443 return api.step_history[step_name].json.gtest_results.failures | 443 return api.step_history[step_name].json.gtest_results.failures |
| 444 | 444 |
| 445 | 445 |
| 446 class SwarmingGTestTest(api.test_utils.Test): | |
| 447 # This test is using 'trigger' and 'collect' instead of 'run'. | |
| 448 async = True | |
| 449 | |
| 450 def __init__(self, name, args=None): | |
| 451 api.test_utils.Test.__init__(self) | |
| 452 self._name = name | |
| 453 self._args = args or [] | |
| 454 self._tasks = {} | |
| 455 self._results = {} | |
| 456 | |
| 457 @property | |
| 458 def name(self): | |
| 459 return self._name | |
| 460 | |
| 461 def compile_targets(self): | |
| 462 # <X>_run target depends on <X>, and then isolates it invoking isolate.py. | |
| 463 # It is a convention, not a hard coded rule. | |
| 464 return [self._name + '_run'] | |
| 465 | |
| 466 def trigger(self, suffix): | |
| 467 assert suffix not in self._tasks, ( | |
| 468 'Test %s was already triggered' % self._step_name(suffix)) | |
| 469 | |
| 470 # *.isolated may be missing if *_run target is misconfigured. It a error | |
| 471 # in gyp, not a recipe failure. So carry on with recipe execution. | |
| 472 isolated_hash = api.isolate.isolated_tests.get(self._name) | |
| 473 if not isolated_hash: | |
| 474 return api.python.inline( | |
| 475 '[error] %s' % self._step_name(suffix), | |
| 476 r""" | |
| 477 import sys | |
| 478 print '*.isolated file for target %s is missing' % sys.argv[1] | |
| 479 sys.exit(1) | |
| 480 """, | |
| 481 args=[self._name], | |
| 482 always_run=True) | |
| 483 | |
| 484 # If rerunning without a patch, run only tests that failed. | |
| 485 args = self._args[:] | |
| 486 if suffix == 'without patch': | |
| 487 assert self.has_valid_results('with patch') | |
| 488 failed_tests = sorted(self.failures('with patch')) | |
| 489 args.append('--gtest_filter=%s' % ':'.join(failed_tests)) | |
|
Vadim Sh.
2014/06/04 00:03:56
Local tests are using a temp file with gtest filte
| |
| 490 | |
| 491 # Trigger the test on swarming. | |
| 492 self._tasks[suffix] = api.swarming.gtest_task( | |
| 493 title=self._step_name(suffix), | |
| 494 isolated_hash=isolated_hash, | |
| 495 test_launcher_summary_output=api.json.gtest_results( | |
| 496 add_json_log=False), | |
| 497 extra_args=args) | |
| 498 return api.swarming.trigger([self._tasks[suffix]], always_run=True) | |
| 499 | |
| 500 def collect(self, suffix): | |
| 501 assert suffix not in self._results, ( | |
| 502 'Results of %s were already collected' % self._step_name(suffix)) | |
| 503 | |
| 504 # Do nothing if test wasn't triggered. This happens if *.isolated is not | |
| 505 # found. The build is already red by this moment. | |
| 506 if suffix not in self._tasks: | |
| 507 return [] | |
| 508 | |
| 509 # Update step presentation, store step results in self._results. | |
| 510 def followup_fn(step_result): | |
| 511 r = step_result.json.gtest_results | |
| 512 p = step_result.presentation | |
| 513 if r.valid: | |
| 514 p.step_text += api.test_utils.format_step_text([ | |
| 515 ['failures:', r.failures] | |
| 516 ]) | |
| 517 self._results[suffix] = r | |
| 518 | |
| 519 # Wait for test on swarming to finish. | |
| 520 return api.swarming.collect( | |
| 521 [self._tasks[suffix]], | |
| 522 always_run=True, | |
| 523 can_fail_build=False, | |
| 524 followup_fn=followup_fn) | |
| 525 | |
| 526 def has_valid_results(self, suffix): | |
| 527 gtest_results = self._results.get(suffix) | |
| 528 if not gtest_results or not gtest_results.valid: # pragma: no cover | |
| 529 return False | |
| 530 global_tags = gtest_results.raw.get('global_tags', []) | |
| 531 return 'UNRELIABLE_RESULTS' not in global_tags | |
| 532 | |
| 533 def failures(self, suffix): | |
| 534 assert suffix in self._results, ( | |
| 535 'Test %s wasn\'t collected yet' % self._step_name(suffix)) | |
| 536 return self._results[suffix].failures | |
| 537 | |
| 538 | |
| 446 class NaclIntegrationTest(api.test_utils.Test): # pylint: disable=W0232 | 539 class NaclIntegrationTest(api.test_utils.Test): # pylint: disable=W0232 |
| 447 name = 'nacl_integration' | 540 name = 'nacl_integration' |
| 448 | 541 |
| 449 @staticmethod | 542 @staticmethod |
| 450 def compile_targets(): | 543 def compile_targets(): |
| 451 return ['chrome'] | 544 return ['chrome'] |
| 452 | 545 |
| 453 def run(self, suffix): | 546 def run(self, suffix): |
| 454 args = [ | 547 args = [ |
| 455 '--mode', api.chromium.c.build_config_fs, | 548 '--mode', api.chromium.c.build_config_fs, |
| 456 '--json_build_results_output_file', api.json.output(), | 549 '--json_build_results_output_file', api.json.output(), |
| 457 ] | 550 ] |
| 458 return api.python( | 551 return api.python( |
| 459 self._step_name(suffix), | 552 self._step_name(suffix), |
| 460 api.path['checkout'].join('chrome', | 553 api.path['checkout'].join('chrome', |
| 461 'test', | 554 'test', |
| 462 'nacl_test_injection', | 555 'nacl_test_injection', |
| 463 'buildbot_nacl_integration.py'), | 556 'buildbot_nacl_integration.py'), |
| 464 args, | 557 args, |
| 465 can_fail_build=False, | 558 can_fail_build=False, |
| 466 step_test_data=lambda: api.m.json.test_api.output([])) | 559 step_test_data=lambda: api.m.json.test_api.output([])) |
| 467 | 560 |
| 468 def has_valid_results(self, suffix): | 561 def has_valid_results(self, suffix): |
| 469 return api.step_history[self._step_name(suffix)].json.output is not None | 562 return api.step_history[self._step_name(suffix)].json.output is not None |
| 470 | 563 |
| 471 def failures(self, suffix): | 564 def failures(self, suffix): |
| 472 failures = api.step_history[self._step_name(suffix)].json.output | 565 failures = api.step_history[self._step_name(suffix)].json.output |
| 473 return [f['raw_name'] for f in failures] | 566 return [f['raw_name'] for f in failures] |
| 474 | 567 |
| 568 | |
|
M-A Ruel
2014/06/04 00:52:53
remove one empty line
Vadim Sh.
2014/06/04 02:58:27
Hmm.. I'm not sure. It marks the end of local clas
| |
| 569 def parse_test_spec(test_spec, should_use_test): | |
| 570 """Returns a list of tests to run and additional targets to compile. | |
|
Vadim Sh.
2014/06/04 00:03:56
This is refactoring of spec parsing code into a se
| |
| 571 | |
| 572 Uses 'should_use_test' callback to figure out what tests should be skipped. | |
| 573 | |
| 574 Returns triple (compile_targets, gtest_tests, swarming_tests) where | |
| 575 gtest_tests is a list of GTestTest | |
| 576 swarming_tests is a list of SwarmingGTestTest. | |
| 577 """ | |
| 578 compile_targets = [] | |
| 579 gtest_tests_spec = [] | |
| 580 if isinstance(test_spec, dict): | |
| 581 compile_targets = test_spec.get('compile_targets', []) | |
| 582 gtest_tests_spec = test_spec.get('gtest_tests', []) | |
| 583 else: | |
| 584 # TODO (nodir): Remove this after | |
|
M-A Ruel
2014/06/04 00:52:53
TODO(nodir):
We never put a space in between.
Vadim Sh.
2014/06/04 02:58:27
Done. (I've just copy-pasted it from where it was
| |
| 585 # https://codereview.chromium.org/297303012/#ps50001 | |
| 586 # lands. | |
| 587 gtest_tests_spec = test_spec | |
| 588 | |
| 589 gtest_tests = [] | |
| 590 swarming_tests = [] | |
| 591 for test in gtest_tests_spec: | |
| 592 test_name = None | |
| 593 test_dict = None | |
| 594 | |
| 595 # Read test_dict for the test, it defines where test can run. | |
| 596 if isinstance(test, unicode): | |
| 597 test_name = test.encode('utf-8') | |
| 598 test_dict = {} | |
| 599 elif isinstance(test, dict): | |
| 600 if 'test' not in test: # pragma: no cover | |
| 601 raise ValueError('Invalid entry in test spec: %r' % test) | |
| 602 test_name = test['test'].encode('utf-8') | |
| 603 test_dict = test | |
| 604 else: # pragma: no cover | |
| 605 raise ValueError('Unrecognized entry in test spec: %r' % test) | |
| 606 | |
| 607 # Should skip it completely? | |
| 608 if not test_name or not should_use_test(test_dict): | |
| 609 continue | |
| 610 | |
| 611 # If test can run on swarming, test_dict has a section that defines when | |
| 612 # swarming should be used, in same format as main test dict. | |
| 613 use_swarming = False | |
| 614 swarming_spec = test_dict.get('swarming', False) | |
| 615 if isinstance(swarming_spec, bool): | |
| 616 use_swarming = swarming_spec | |
| 617 swarming_spec = {} | |
| 618 elif isinstance(swarming_spec, dict): | |
| 619 if not swarming_spec: # pragma: no cover | |
| 620 raise ValueError('Empty \'swarming\' section in test spec for %s ' | |
| 621 'is ambiguous. Use false or true.' % test_name) | |
|
M-A Ruel
2014/06/04 00:52:53
True or False ?
Vadim Sh.
2014/06/04 02:58:27
It's originally in *.json file. So boolean literal
| |
| 622 use_swarming = should_use_test(swarming_spec) | |
| 623 else: # pragma: no cover | |
| 624 raise ValueError('Unrecognized swarming entry in test spec: %r' % test) | |
| 625 | |
| 626 test_args = test_dict.get('args') | |
| 627 if isinstance(test_args, basestring): | |
|
M-A Ruel
2014/06/04 00:52:53
I'm not familiar with this code but the isinstance
Vadim Sh.
2014/06/04 02:58:27
I didn't change this logic, it was here previously
| |
| 628 test_args = [test_args] | |
| 629 | |
| 630 if use_swarming: | |
| 631 swarming_tests.append(SwarmingGTestTest(test_name, test_args)) | |
| 632 else: | |
| 633 gtest_tests.append(GTestTest(test_name, test_args)) | |
| 634 | |
| 635 return compile_targets, gtest_tests, swarming_tests | |
| 636 | |
| 637 | |
| 475 mastername = api.properties.get('mastername') | 638 mastername = api.properties.get('mastername') |
| 476 buildername = api.properties.get('buildername') | 639 buildername = api.properties.get('buildername') |
| 477 master_dict = BUILDERS.get(mastername, {}) | 640 master_dict = BUILDERS.get(mastername, {}) |
| 478 bot_config = master_dict.get('builders', {}).get(buildername) | 641 bot_config = master_dict.get('builders', {}).get(buildername) |
| 479 assert bot_config, ( | 642 assert bot_config, ( |
| 480 'Unrecognized builder name %r for master %r.' % ( | 643 'Unrecognized builder name %r for master %r.' % ( |
| 481 buildername, mastername)) | 644 buildername, mastername)) |
| 482 | 645 |
| 483 # Make sure tests and the recipe specify correct and matching platform. | 646 # Make sure tests and the recipe specify correct and matching platform. |
| 484 assert api.platform.name == bot_config.get('testing', {}).get('platform') | 647 assert api.platform.name == bot_config.get('testing', {}).get('platform') |
| 485 | 648 |
| 486 api.chromium.set_config(bot_config['chromium_config'], | 649 api.chromium.set_config(bot_config['chromium_config'], |
| 487 **bot_config.get('chromium_config_kwargs', {})) | 650 **bot_config.get('chromium_config_kwargs', {})) |
| 488 # Settings GYP_DEFINES explicitly because chromium config constructor does | 651 # Settings GYP_DEFINES explicitly because chromium config constructor does |
| 489 # not support that. | 652 # not support that. |
| 490 api.chromium.c.gyp_env.GYP_DEFINES.update(bot_config.get('GYP_DEFINES', {})) | 653 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') | 654 api.chromium.apply_config('trybot_flavor') |
| 494 api.gclient.set_config('chromium') | 655 api.gclient.set_config('chromium') |
| 495 api.step.auto_resolve_conflicts = True | 656 api.step.auto_resolve_conflicts = True |
| 496 | 657 |
| 497 yield api.bot_update.ensure_checkout() | 658 yield api.bot_update.ensure_checkout() |
| 498 # The first time we run bot update, remember if bot_update mode is on or off. | 659 # 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'] | 660 bot_update_mode = api.step_history.last_step().json.output['did_run'] |
| 500 if not bot_update_mode: | 661 if not bot_update_mode: |
| 501 yield api.gclient.checkout( | 662 yield api.gclient.checkout( |
| 502 revert=True, can_fail_build=False, abort_on_failure=False) | 663 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'], | 694 'args': ['--test-launcher-print-test-stdio=always'], |
| 534 }, | 695 }, |
| 535 { | 696 { |
| 536 'test': 'browser_tests', | 697 'test': 'browser_tests', |
| 537 'exclude_builders': ['tryserver.chromium:win_chromium_x64_rel'], | 698 'exclude_builders': ['tryserver.chromium:win_chromium_x64_rel'], |
| 538 }, | 699 }, |
| 539 ]), | 700 ]), |
| 540 followup_fn=test_spec_followup_fn, | 701 followup_fn=test_spec_followup_fn, |
| 541 ) | 702 ) |
| 542 | 703 |
| 704 def should_use_test(test): | |
| 705 """Given a test dict from test spec returns True or False.""" | |
| 706 if 'platforms' in test: | |
|
Vadim Sh.
2014/06/04 00:03:56
No new logic here.
| |
| 707 if api.platform.name not in test['platforms']: | |
| 708 return False | |
| 709 if 'chromium_configs' in test: | |
| 710 if bot_config['chromium_config'] not in test['chromium_configs']: | |
| 711 return False | |
| 712 if 'exclude_builders' in test: | |
| 713 if '%s:%s' % (mastername, buildername) in test['exclude_builders']: | |
| 714 return False | |
| 715 return True | |
| 716 | |
| 717 # Parse test spec file into list of Test instances. | |
| 718 compile_targets, gtest_tests, swarming_tests = parse_test_spec( | |
| 719 api.step_history['read test spec'].json.output, | |
| 720 should_use_test) | |
| 721 | |
| 722 # Swarming uses Isolate to transfer files to swarming bots. | |
| 723 # set_isolate_environment modifies GYP_DEFINES to enable test isolation. | |
| 724 use_isolate = swarming_tests or bot_config.get('use_isolate') | |
| 725 if use_isolate: | |
| 726 api.isolate.set_isolate_environment(api.chromium.c) | |
| 727 | |
| 543 runhooks_env = bot_config.get('runhooks_env', {}) | 728 runhooks_env = bot_config.get('runhooks_env', {}) |
| 544 | 729 |
| 545 yield api.chromium.runhooks(env=runhooks_env, abort_on_failure=False, | 730 yield api.chromium.runhooks(env=runhooks_env, abort_on_failure=False, |
| 546 can_fail_build=False) | 731 can_fail_build=False) |
| 547 if api.step_history.last_step().retcode != 0: | 732 if api.step_history.last_step().retcode != 0: |
| 548 # Before removing the checkout directory try just using LKCR. | 733 # Before removing the checkout directory try just using LKCR. |
| 549 api.gclient.set_config('chromium_lkcr') | 734 api.gclient.set_config('chromium_lkcr') |
| 550 | 735 |
| 551 # Since we're likely to switch to an earlier revision, revert the patch, | 736 # Since we're likely to switch to an earlier revision, revert the patch, |
| 552 # sync with the new config, and apply issue again. | 737 # 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: | 748 if api.step_history.last_step().retcode != 0: |
| 564 if api.platform.is_win: | 749 if api.platform.is_win: |
| 565 yield api.chromium.taskkill() | 750 yield api.chromium.taskkill() |
| 566 yield ( | 751 yield ( |
| 567 api.path.rmcontents('slave build directory', api.path['slave_build']), | 752 api.path.rmcontents('slave build directory', api.path['slave_build']), |
| 568 api.gclient.checkout(revert=False), | 753 api.gclient.checkout(revert=False), |
| 569 api.tryserver.maybe_apply_issue(), | 754 api.tryserver.maybe_apply_issue(), |
| 570 api.chromium.runhooks(env=runhooks_env) | 755 api.chromium.runhooks(env=runhooks_env) |
| 571 ) | 756 ) |
| 572 | 757 |
| 573 gtest_tests = [] | 758 # If going to use swarming_client (pinned in src/DEPS), ensure it is |
| 574 compile_targets = [] | 759 # compatible with what recipes expect. |
| 575 test_spec = api.step_history['read test spec'].json.output | 760 if swarming_tests: |
| 576 | 761 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 | 762 |
| 619 tests = [] | 763 tests = [] |
| 620 tests.append(CheckdepsTest()) | 764 tests.append(CheckdepsTest()) |
| 621 tests.append(Deps2GitTest()) | 765 tests.append(Deps2GitTest()) |
| 622 for test in gtest_tests: | 766 tests.extend(gtest_tests) |
| 623 tests.append(test) | 767 tests.extend(swarming_tests) |
| 624 tests.append(NaclIntegrationTest()) | 768 tests.append(NaclIntegrationTest()) |
| 625 | 769 |
| 626 compile_targets.extend(bot_config.get('compile_targets', [])) | 770 compile_targets.extend(bot_config.get('compile_targets', [])) |
| 627 compile_targets.extend(api.itertools.chain( | 771 compile_targets.extend(api.itertools.chain( |
| 628 *[t.compile_targets() for t in tests])) | 772 *[t.compile_targets() for t in tests])) |
| 629 # TODO(phajdan.jr): Also compile 'all' on win, http://crbug.com/368831 . | 773 # 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. | 774 # 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'): | 775 if not api.platform.is_win and not bot_config.get('exclude_compile_all'): |
| 632 compile_targets = ['all'] + compile_targets | 776 compile_targets = ['all'] + compile_targets |
| 633 yield api.chromium.compile(compile_targets, | 777 yield api.chromium.compile(compile_targets, |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 667 yield api.chromium.runhooks() | 811 yield api.chromium.runhooks() |
| 668 yield api.chromium.compile(compile_targets, | 812 yield api.chromium.compile(compile_targets, |
| 669 name='compile ' | 813 name='compile ' |
| 670 '(with patch, lkcr, clobber, nuke)', | 814 '(with patch, lkcr, clobber, nuke)', |
| 671 force_clobber=True) | 815 force_clobber=True) |
| 672 | 816 |
| 673 # Do not run tests if the build is already in a failed state. | 817 # Do not run tests if the build is already in a failed state. |
| 674 if api.step_history.failed: | 818 if api.step_history.failed: |
| 675 return | 819 return |
| 676 | 820 |
| 677 if bot_config.get('use_isolate'): | 821 # Collect *.isolated hashes for all isolated targets, used when triggering |
| 822 # tests on swarming. | |
| 823 if use_isolate: | |
| 678 yield api.isolate.find_isolated_tests(api.chromium.output_dir) | 824 yield api.isolate.find_isolated_tests(api.chromium.output_dir) |
| 679 | 825 |
| 680 if bot_config['compile_only']: | 826 if bot_config['compile_only']: |
| 681 return | 827 return |
| 682 | 828 |
| 683 if bot_config['chromium_config'] not in ['chromium_chromeos', | 829 if bot_config['chromium_config'] not in ['chromium_chromeos', |
| 684 'chromium_chromeos_clang']: | 830 'chromium_chromeos_clang']: |
| 685 # TODO(phajdan.jr): Make it possible to retry telemetry tests (add JSON). | 831 # TODO(phajdan.jr): Make it possible to retry telemetry tests (add JSON). |
| 832 # TODO(vadimsh): Trigger swarming tests before telemetry tests. | |
| 686 yield ( | 833 yield ( |
| 687 api.chromium.run_telemetry_unittests(), | 834 api.chromium.run_telemetry_unittests(), |
| 688 api.chromium.run_telemetry_perf_unittests(), | 835 api.chromium.run_telemetry_perf_unittests(), |
| 689 ) | 836 ) |
| 690 | 837 |
| 691 def deapply_patch_fn(failing_tests): | 838 def deapply_patch_fn(failing_tests): |
| 692 if api.platform.is_win: | 839 if api.platform.is_win: |
| 693 yield api.chromium.taskkill() | 840 yield api.chromium.taskkill() |
| 694 if bot_update_mode: | 841 if bot_update_mode: |
| 695 yield api.bot_update.ensure_checkout(patch=False, | 842 yield api.bot_update.ensure_checkout(patch=False, |
| 696 always_run=True, | 843 always_run=True, |
| 697 update_presentation=False) | 844 update_presentation=False) |
| 698 else: | 845 else: |
| 699 yield api.gclient.checkout(revert=True, always_run=True), | 846 yield api.gclient.checkout(revert=True, always_run=True), |
| 700 yield api.chromium.runhooks(always_run=True), | 847 yield api.chromium.runhooks(always_run=True), |
| 701 compile_targets = list(api.itertools.chain( | 848 compile_targets = list(api.itertools.chain( |
| 702 *[t.compile_targets() for t in failing_tests])) | 849 *[t.compile_targets() for t in failing_tests])) |
| 703 if compile_targets: | 850 if compile_targets: |
| 704 yield api.chromium.compile(compile_targets, | 851 yield api.chromium.compile(compile_targets, |
| 705 name='compile (without patch)', | 852 name='compile (without patch)', |
| 706 abort_on_failure=False, | 853 abort_on_failure=False, |
| 707 can_fail_build=False, | 854 can_fail_build=False, |
| 708 always_run=True) | 855 always_run=True) |
| 709 if api.step_history['compile (without patch)'].retcode != 0: | 856 if api.step_history['compile (without patch)'].retcode != 0: |
| 710 yield api.chromium.compile(compile_targets, | 857 yield api.chromium.compile(compile_targets, |
| 711 name='compile (without patch, clobber)', | 858 name='compile (without patch, clobber)', |
| 712 force_clobber=True, | 859 force_clobber=True, |
| 713 always_run=True) | 860 always_run=True) |
| 861 if use_isolate: | |
| 862 yield api.isolate.find_isolated_tests(api.chromium.output_dir, | |
| 863 always_run=True) | |
| 714 | 864 |
| 715 yield api.test_utils.determine_new_failures(tests, deapply_patch_fn) | 865 yield api.test_utils.determine_new_failures(tests, deapply_patch_fn) |
| 716 | 866 |
| 717 | 867 |
| 718 def _sanitize_nonalpha(text): | 868 def _sanitize_nonalpha(text): |
| 719 return ''.join(c if c.isalnum() else '_' for c in text) | 869 return ''.join(c if c.isalnum() else '_' for c in text) |
| 720 | 870 |
| 721 | 871 |
| 722 def GenTests(api): | 872 def GenTests(api): |
| 723 canned_checkdeps = { | 873 canned_checkdeps = { |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 908 'test': 'browser_tests', | 1058 'test': 'browser_tests', |
| 909 'args': '--gtest-filter: *NaCl*', | 1059 'args': '--gtest-filter: *NaCl*', |
| 910 }, { | 1060 }, { |
| 911 'test': 'base_tests', | 1061 'test': 'base_tests', |
| 912 'args': ['--gtest-filter: *NaCl*'], | 1062 'args': ['--gtest-filter: *NaCl*'], |
| 913 }, | 1063 }, |
| 914 ], | 1064 ], |
| 915 }) | 1065 }) |
| 916 ) | 1066 ) |
| 917 ) | 1067 ) |
| 1068 | |
| 1069 yield ( | |
|
M-A Ruel
2014/06/04 00:52:53
I think a comment about why it's done this way wou
Vadim Sh.
2014/06/04 02:58:27
Added comments describing what code flow paths are
| |
| 1070 api.test('swarming_basic') + | |
| 1071 props() + | |
| 1072 api.platform.name('linux') + | |
| 1073 api.override_step_data('read test spec', api.json.output({ | |
| 1074 'gtest_tests': [ | |
| 1075 { | |
| 1076 'test': 'base_unittests', | |
| 1077 'swarming': True, | |
|
M-A Ruel
2014/06/04 00:52:53
I don't understand why you do not use a dict with
Vadim Sh.
2014/06/04 02:58:27
It's for code coverage of 'if isinstance(swarming_
| |
| 1078 }, | |
| 1079 { | |
| 1080 'test': 'browser_tests', | |
| 1081 'swarming': { | |
| 1082 'platforms': ['linux'], | |
| 1083 }, | |
| 1084 }, | |
| 1085 ], | |
| 1086 }) | |
| 1087 ) + | |
| 1088 api.override_step_data( | |
| 1089 'find isolated tests', | |
| 1090 api.isolate.output_json(['base_unittests', 'browser_tests'])) | |
| 1091 ) | |
| 1092 | |
| 1093 yield ( | |
| 1094 api.test('swarming_missing_isolated') + | |
| 1095 props() + | |
| 1096 api.platform.name('linux') + | |
| 1097 api.override_step_data('read test spec', api.json.output({ | |
| 1098 'gtest_tests': [ | |
| 1099 { | |
| 1100 'test': 'base_unittests', | |
| 1101 'swarming': True, | |
| 1102 }, | |
| 1103 { | |
| 1104 'test': 'browser_tests', | |
| 1105 'swarming': { | |
| 1106 'platforms': ['linux'], | |
| 1107 }, | |
| 1108 }, | |
| 1109 ], | |
| 1110 }) | |
| 1111 ) + | |
| 1112 api.override_step_data( | |
| 1113 'find isolated tests', | |
| 1114 api.isolate.output_json(['base_unittests'])) | |
| 1115 ) | |
| 1116 | |
| 1117 yield ( | |
| 1118 api.test('swarming_deapply_patch') + | |
| 1119 props() + | |
| 1120 api.platform.name('linux') + | |
| 1121 api.override_step_data('read test spec', api.json.output({ | |
| 1122 'gtest_tests': [ | |
| 1123 { | |
| 1124 'test': 'base_unittests', | |
| 1125 'swarming': True, | |
| 1126 }, | |
| 1127 { | |
| 1128 'test': 'browser_tests', | |
| 1129 'swarming': { | |
| 1130 'platforms': ['linux'], | |
| 1131 }, | |
| 1132 }, | |
| 1133 ], | |
| 1134 }) | |
| 1135 ) + | |
| 1136 api.override_step_data( | |
| 1137 'find isolated tests', | |
| 1138 api.isolate.output_json(['base_unittests', 'browser_tests'])) + | |
| 1139 api.override_step_data('[swarming] base_unittests (with patch)', | |
| 1140 canned_test(passing=False)) + | |
| 1141 api.override_step_data( | |
| 1142 'find isolated tests (2)', | |
| 1143 api.isolate.output_json(['base_unittests', 'browser_tests'])) | |
| 1144 ) | |
| OLD | NEW |