blob: 132947e2f4bb3bc9a905f3f3bc2609be59976014 [file] [log] [blame]
# 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 = 'clobber' in api.properties
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',
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 buildbucket/test_api.py)
api.buildbucket.simulated_search_results(
[
api.buildbucket.ci_build_message(
status='SUCCESS', build_number=4711),
],
step_name='fetch previous build'),
# 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),
)