| # Copyright 2016 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from google.protobuf import struct_pb2, json_format |
| |
| from recipe_engine import recipe_api |
| |
| from recipe_engine.post_process import ( |
| DoesNotRunRE, |
| DropExpectation, |
| MustRun, |
| StatusException, |
| StatusFailure, |
| StatusSuccess, |
| ) |
| |
| from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2 |
| |
| from PB.recipes.dart.dart.gclient import Gclient |
| |
| PROPERTIES = Gclient |
| |
| DEPS = [ |
| 'bisect_build', |
| 'dart', |
| 'depot_tools/gitiles', |
| 'depot_tools/osx_sdk', |
| 'recipe_engine/buildbucket', |
| 'recipe_engine/context', |
| 'recipe_engine/path', |
| 'recipe_engine/properties', |
| 'recipe_engine/raw_io', |
| 'recipe_engine/step', |
| ] |
| |
| |
| TEST_MATRIX = { |
| "filesets": { |
| "fileset1": "[]", |
| "nameoffileset": "[]" |
| }, |
| "global": { |
| "chrome": "66.0.3359.139", |
| "firefox": "60.0.1" |
| }, |
| "builder_configurations": [ |
| { |
| "builders": [ |
| "dart2js-win-debug-x64-firefox", |
| ], |
| "meta": {}, |
| "steps": [{ |
| "name": "Build", |
| "script": "tools/build.py", |
| "arguments": ["foo", "--bar"], |
| "shards": 1 |
| }, { |
| "name": "Test-step 1", |
| "script": "tools/test.py", |
| "arguments": ["foo", "--bar", "-e co19", "language_2"], |
| }, { |
| "name": "Test-step 2", |
| "arguments": ["foo", "--bar", "-mdebug", |
| "-n${runtime}-foo-${mode}-${arch}-bar"], |
| }] |
| } |
| ] |
| } |
| |
| |
| def _is_infra_failure(api, failure): |
| return (isinstance(failure, api.step.InfraFailure) or |
| api.dart.has_infra_failure(failure)) |
| |
| |
| def _compute_failure_reason(api, failure): |
| assert not failure or not _is_infra_failure(api, failure) |
| return failure.reason if failure else api.bisect_build.REASON_SUCCESS |
| |
| |
| def _schedule_bisection(api, failure=None): |
| if not api.bisect_build.is_enabled: |
| # This builder is not configured to use bisection. |
| return |
| if _is_infra_failure(api, failure): |
| # TODO(karlklose): fan out on infra failures during bisection and consider |
| # starting a bisection for some kinds of infra failures. |
| return |
| elif api.bisect_build.is_bisecting() or failure: |
| reason = _compute_failure_reason(api, failure) |
| api.bisect_build.schedule("https://dart.googlesource.com/sdk", reason) |
| |
| |
| def RunSteps(api, properties): |
| # Override analyzer cache location to make analyzer runs hermetic. |
| env = {'ANALYZER_STATE_LOCATION_OVERRIDE': |
| api.path['cleanup'].join('analysis-cache')} |
| try: |
| with api.osx_sdk('mac'), api.context(env=env): |
| _run_steps_impl(api, properties) |
| except api.step.StepFailure as failure: |
| _schedule_bisection(api, failure) |
| raise |
| _schedule_bisection(api) |
| |
| |
| def _run_steps_impl(api, properties): |
| clobber = api.properties.get('clobber', False) |
| api.dart.checkout( |
| clobber=clobber, |
| custom_vars=json_format.MessageToDict(properties.custom_vars)) |
| api.dart.kill_tasks() |
| |
| try: |
| api.dart.test(test_data=TEST_MATRIX) |
| finally: |
| api.dart.kill_tasks() |
| |
| |
| RESULT_DATA = ( |
| '{"name":"test_foo"' |
| ',"configuration":"config_bar","suite":"suite_baz",' |
| '"test_name":"Language/Classes/Abstract_Instance_Members/inherited_t01",' |
| '"time_ms":451,"result":"CompileTimeError","expected":"CompileTimeError",' |
| '"matches":true,"commit_time":1551185312,' |
| '"commit_hash":"f0042a32250a8a6193e6d07e2b6508b13f43c864",' |
| '"build_number":"2404","builder_name":"vm-kernel-linux-product-x64",' |
| '"bot_name":"trusty-dart-68765ebb-us-central1-b-2ls0","flaky":false,' |
| '"previous_flaky":false,"previous_result":"CompileTimeError",' |
| '"previous_commit_hash":"f0042a32250a8a6193e6d07e2b6508b13f43c864",' |
| '"previous_commit_time":1551185312,"previous_build_number":2403,' |
| '"changed":false}\n') |
| |
| TESTED_REVISION = '1a2b3c4d' |
| |
| |
| def GenTests(api): |
| yield api.test( |
| 'builders/dart2js-win-debug-x64-firefox-try', |
| api.buildbucket.try_build( |
| builder='dart2js-win-debug-x64-firefox-try', |
| git_repo='https://dart.googlesource.com/sdk', |
| project='dart'), |
| api.properties( |
| Gclient( |
| custom_vars=json_format.ParseDict({ |
| 'download_firefox': True, |
| }, struct_pb2.Struct()))), |
| api.step_data('add fields to result records', |
| api.raw_io.output_text(RESULT_DATA)), |
| ) |
| |
| yield api.test( |
| 'successful-build-does-not-start-bisection', |
| api.buildbucket.ci_build( |
| builder='dart2js-win-debug-x64-firefox', |
| git_repo='https://dart.googlesource.com/sdk', |
| project='dart', |
| revision=TESTED_REVISION), |
| api.properties(bisection_enabled=True), |
| api.step_data('add fields to result records', |
| api.raw_io.output_text(RESULT_DATA)), |
| api.post_process(DoesNotRunRE, 'schedule bisect (.*)'), |
| api.post_process(StatusSuccess), |
| ) |
| |
| yield api.test( |
| 'infra-failure-does-not-start-bisection', |
| api.buildbucket.ci_build( |
| builder='dart2js-win-debug-x64-firefox', |
| git_repo='https://dart.googlesource.com/sdk', |
| project='dart', |
| revision=TESTED_REVISION), |
| api.properties(bisection_enabled=True), |
| api.step_data('add fields to result records', |
| api.raw_io.output_text(RESULT_DATA)), |
| # Create an infra-failure in the test results step |
| api.step_data('test results', retcode=2), |
| api.post_process(DoesNotRunRE, 'schedule bisect (.*)'), |
| api.post_process(StatusException), |
| ) |
| |
| yield api.test( |
| 'toplevel-infra-failure-does-not-start-bisection', |
| api.buildbucket.ci_build( |
| # Specifies a builder that is not in the test matrix: |
| builder='undefined-builder-name', |
| git_repo='https://dart.googlesource.com/sdk', |
| project='dart', |
| revision=TESTED_REVISION), |
| api.properties(bisection_enabled=True), |
| api.post_process(DoesNotRunRE, 'schedule bisect (.*)'), |
| api.post_process(StatusException), |
| ) |
| |
| yield api.test( |
| 'failing-test-step-starts-bisection', |
| api.buildbucket.ci_build( |
| builder='dart2js-win-debug-x64-firefox', |
| git_repo='https://dart.googlesource.com/sdk', |
| project='dart', |
| build_number=4711, |
| revision=TESTED_REVISION), |
| api.properties(bisection_enabled=True), |
| api.step_data('add fields to result records', |
| api.raw_io.output_text(RESULT_DATA)), |
| # Create a successful base build for the bisection |
| # (see bisect_build/test_api.py) |
| api.bisect_build.fetch_previous_builds(api, [ |
| api.bisect_build.build(api, 'foo', 4710, |
| '2d72510e447ab60a9728aeea2362d8be2cbd7789') |
| ]) + |
| # Create a fake gitiles log for the bisection algorithm (see gitiles/test_api.py) |
| api.step_data( |
| 'gitiles log: 2d72510e447ab60a9728aeea2362d8be2cbd7789..%s' % |
| TESTED_REVISION, api.gitiles.make_log_test_data('master')), |
| # Make test step fail by failing the 'test results' step |
| api.step_data('test results', retcode=1), |
| api.post_process( |
| MustRun, |
| 'schedule bisect (f4d35da881f8fd329a4d3e01dd78b66a502d5c49)'), |
| api.post_process(StatusFailure), |
| ) |
| |
| yield api.test( |
| 'different-failure-in-bisection-schedules-two-bisection-builds', |
| api.buildbucket.ci_build( |
| builder='dart2js-win-debug-x64-firefox', |
| git_repo='https://dart.googlesource.com/sdk', |
| project='dart', |
| revision=TESTED_REVISION), |
| api.properties( |
| bisection_enabled=True, |
| bisect_newer=['a', 'b', 'c'], |
| bisect_older=['c', 'd', 'e'], |
| bisect_base_build=4711, |
| bisect_reason="Step('Build') (retcode: 1)", |
| ), |
| # Make build step fail by failing the 'test results' step |
| api.step_data('test results', retcode=1), |
| api.post_process(MustRun, 'schedule bisect (b)'), |
| api.post_process(MustRun, 'schedule bisect (d)'), |
| api.post_process(StatusFailure), |
| api.post_process(DropExpectation), |
| ) |