blob: c09e9c14df2f70544cab62afdb7737504639f155 [file] [log] [blame]
# Copyright 2013 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 recipe_engine.post_process import Filter
DEPS = [
'archive',
'chromium',
'depot_tools/gclient',
'depot_tools/infra_paths',
'recipe_engine/context',
'recipe_engine/json',
'recipe_engine/path',
'recipe_engine/platform',
'recipe_engine/properties',
'recipe_engine/raw_io',
'recipe_engine/runtime',
'recipe_engine/step',
'recipe_engine/url',
'swarming_client',
'recipe_engine/time',
'depot_tools/tryserver',
'v8',
]
def RunSteps(api):
v8 = api.v8
v8.apply_bot_config(v8.BUILDERS)
additional_trigger_properties = {}
test_spec = {}
tests = v8.create_tests()
tests += v8.extra_tests_from_properties()
if v8.is_pure_swarming_tester(tests):
api.swarming_client.checkout()
# Simulate a v8 update on slim swarming testers. The revision
# property is mandatory. The commit position is required by gatekeeper.
api.step.active_result.presentation.properties['got_revision'] = (
api.properties['revision'])
api.step.active_result.presentation.properties['got_revision_cp'] = (
api.properties.get('parent_got_revision_cp'))
v8.set_up_swarming()
else:
# Make sure we don't run a non-pure swarming tester on a subdir slave.
# Subdir slaves have the name pattern 'slaveN-c3#M'.
assert '#' not in api.properties.get('bot_id', ''), (
'Can only use pure swarming testers on subdir slaves.')
if api.platform.is_win:
api.chromium.taskkill()
if v8.generate_sanitizer_coverage:
# When collecting code coverage, we need to sync to the revision that
# fits to the patch for the line numbers to match.
revision = v8.calculate_patch_base_gerrit()
update_step = v8.checkout(revision=revision, suffix='with patch base')
else:
update_step = v8.checkout()
update_properties = update_step.json.output['properties']
if update_properties.get('got_swarming_client_revision'):
additional_trigger_properties['parent_got_swarming_client_revision'] = (
update_properties['got_swarming_client_revision'])
v8.set_up_swarming()
v8.runhooks()
if v8.generate_gcov_coverage:
v8.init_gcov_coverage()
test_spec = v8.read_test_spec()
tests += v8.extra_tests_from_test_spec(test_spec)
if v8.should_build:
v8.compile(test_spec)
if v8.should_upload_build:
v8.upload_build()
v8.maybe_create_clusterfuzz_archive(update_step)
if v8.should_download_build:
v8.download_build()
if v8.should_test:
test_results = v8.runtests(tests)
v8.maybe_bisect(test_results)
if not api.tryserver.is_tryserver and test_results.is_negative:
# Let the overall build fail for failures and flakes.
raise api.step.StepFailure('Failures or flakes in build.')
if api.tryserver.is_tryserver and test_results.has_failures:
# Let tryjobs fail for failures only.
raise api.step.StepFailure('Failures in tryjob.')
if v8.generate_gcov_coverage:
v8.upload_gcov_coverage_report()
v8.maybe_trigger(test_spec=test_spec, **additional_trigger_properties)
def GenTests(api):
for mastername, _, buildername, _ in api.v8.iter_builders('v8'):
yield api.v8.test(mastername, buildername)
yield (
api.v8.test(
'client.v8.branches',
'V8 Linux - beta branch',
'branch_sync_failure',
) +
api.step_data('bot_update', retcode=1)
)
yield (
api.v8.test(
'client.v8',
'V8 Linux',
'swarming_collect_failure',
) +
api.step_data('Check', retcode=1)
)
# Simulate a tryjob triggered by the CQ for setting up different swarming
# default tags.
yield (
api.v8.test(
'tryserver.v8',
'v8_linux_rel_ng_triggered',
'triggered_by_cq',
requester='commit-bot@chromium.org',
patch_project='v8',
blamelist=['dude@chromium.org'],
)
)
# Simulate a tryjob triggered by the tryserver for setting up different
# swarming default tags.
yield (
api.v8.test(
'tryserver.v8',
'v8_linux_rel_ng_triggered',
'triggered_by_ts',
requester='dude@chromium.org',
patch_project='v8',
blamelist=['dude@chromium.org'],
)
)
# Test usage of test filters. They're used when the buildbucket
# job gets a property 'testfilter', which is expected to be a json list of
# test-filter strings.
yield (
api.v8.test(
'tryserver.v8',
'v8_linux_rel_ng_triggered',
'test_filter',
) +
api.properties(
testfilter=['mjsunit/regression/*', 'test262/foo', 'test262/bar'],
extra_flags='--trace_gc --turbo_stats',
)
)
# Test extra properties on a builder bot to ensure it triggers the tester
# with the right properties.
yield (
api.v8.test(
'tryserver.v8',
'v8_win64_rel_ng',
'test_filter_builder',
) +
api.properties(
testfilter=['mjsunit/regression/*', 'test262/foo', 'test262/bar'],
extra_flags='--trace_gc --turbo_stats',
) +
api.post_process(Filter('trigger'))
)
# Test triggered builds when running on LUCI.
yield (
api.v8.test(
'tryserver.v8',
'v8_win64_rel_ng',
'test_triggered_build_luci',
) +
api.properties(buildbucket={'build': {'bucket': 'luci.v8.try'}}) +
api.runtime(is_luci=True, is_experimental=False) +
api.post_process(Filter('trigger'))
)
# Test using extra flags with a bot that already uses some extra flags as
# positional argument.
yield (
api.v8.test(
'tryserver.v8',
'v8_linux_rel_ng_triggered',
'positional_extra_flags',
) +
api.properties(
extra_flags=['--trace_gc', '--turbo_stats'],
)
)
yield (
api.v8.test(
'tryserver.v8',
'v8_linux_rel_ng_triggered',
'failures',
) +
api.override_step_data(
'Check', api.v8.output_json(has_failures=True))
)
yield (
api.v8.test(
'tryserver.v8',
'v8_linux_rel_ng_triggered',
'flakes',
) +
api.override_step_data(
'Check', api.v8.output_json(has_failures=True, flakes=True))
)
def TestFailures(wrong_results, flakes):
results_suffix = "_wrong_results" if wrong_results else ""
flakes_suffix = "_flakes" if flakes else ""
return (
api.v8.test(
'client.v8',
'V8 Linux64 - internal snapshot',
'test_failures%s%s' % (results_suffix, flakes_suffix),
) +
api.override_step_data(
'Check', api.v8.output_json(
has_failures=True, wrong_results=wrong_results, flakes=flakes))
)
yield TestFailures(wrong_results=False, flakes=False)
yield TestFailures(wrong_results=False, flakes=True)
yield (
TestFailures(wrong_results=True, flakes=False) +
api.expect_exception('AssertionError')
)
yield (
api.v8.test(
'client.v8',
'V8 Linux64 - internal snapshot',
'empty_json',
) +
api.override_step_data('Check', api.json.output([])) +
api.expect_exception('AssertionError')
)
yield (
api.v8.test(
'client.v8',
'V8 Linux64 - internal snapshot',
'one_failure',
) +
api.override_step_data('Check', api.v8.one_failure())
)
yield (
api.v8.test(
'client.v8',
'V8 Linux64',
'one_failure_build_env_not_supported',
) +
api.override_step_data('Check', api.v8.one_failure()) +
api.properties(parent_build_environment=None)
)
yield (
api.v8.test(
'client.v8',
'V8 Fuzzer',
'fuzz_archive',
) +
api.step_data('Fuzz', retcode=1)
)
# Bisect over range a1, a2, a3. Assume a2 is the culprit. Steps:
# Bisect a0 -> no failures.
# Bisect a2 -> failures.
# Bisect a1 -> no failures.
# Report culprit a2.
yield (
api.v8.test(
'client.v8',
'V8 Linux - predictable',
'bisect',
) +
api.v8.fail('Check - d8') +
api.v8.fail('Bisect a2.Retry') +
api.time.step(120)
)
# The same as above, but overriding changes.
yield (
api.v8.test(
'client.v8',
'V8 Linux - predictable',
'bisect_override_changes',
) +
api.properties(
override_changes=[
{'revision': 'a1'},
{'revision': 'a2'},
{'revision': 'a3'},
],
) +
api.v8.fail('Check - d8') +
api.v8.fail('Bisect a2.Retry') +
api.time.step(120)
)
# Disable bisection, because the failing test is too long compared to the
# overall test time.
yield (
api.v8.test(
'client.v8',
'V8 Linux - predictable',
'bisect_tests_too_long',
) +
api.v8.fail('Check - d8') +
api.time.step(7)
)
# Bisect over range a1, a2, a3. Assume a2 is the culprit.
# Same as above with a swarming builder_tester.
yield (
api.v8.test(
'client.v8',
'V8 Linux - shared',
'bisect_swarming',
) +
api.v8.fail('Check') +
api.v8.fail('Bisect a2.Retry') +
api.time.step(120)
)
# Bisect over range a1, a2, a3. Assume a3 is the culprit. This is a tester
# and the build for a2 is not available. Steps:
# Bisect a0 -> no failures.
# Bisect a1 -> no failures.
# Report a2 and a3 as possible culprits.
yield (
api.v8.test(
'client.v8',
'V8 Linux64',
'bisect_tester_swarming',
) +
api.v8.fail('Check') +
api.time.step(120)
)
# Same as above with a slim swarming tester.
yield (
api.v8.test(
'client.v8',
'V8 Linux64 - custom snapshot - debug',
'slim_bisect_tester_swarming',
) +
api.v8.fail('Mjsunit') +
api.override_step_data(
'Bisect a0.gsutil download isolated json',
api.json.output({'mjsunit': '[dummy hash for bisection]'}),
) +
api.override_step_data(
'Bisect a1.gsutil download isolated json',
api.json.output({'mjsunit': '[dummy hash for bisection]'}),
) +
api.time.step(120)
)
# Same as above with a windows bot. Regression test making sure that
# the swarming hashes are searched in a windows bucket.
f = Filter()
f = f.include_re(r'.*check build.*')
yield (
api.v8.test(
'client.v8',
'V8 Win32',
'bisect',
) +
api.v8.fail('Check') +
api.post_process(f) +
api.time.step(120)
)
# Disable bisection due to a recurring failure. Steps:
# Bisect a0 -> failures.
yield (
api.v8.test(
'client.v8',
'V8 Linux - predictable',
'bisect_recurring_failure',
) +
api.v8.fail('Check - d8') +
api.v8.fail('Bisect a0.Retry') +
api.time.step(120)
)
# Disable bisection due to less than two changes.
yield (
api.v8.test(
'client.v8',
'V8 Linux - predictable',
'bisect_one_change',
) +
api.v8.fail('Check - d8') +
api.url.json(
'Bisect.Fetch changes', api.v8.example_one_buildbot_change()) +
api.override_step_data(
'Bisect.Get change range',
api.v8.example_bisection_range_one_change(),
) +
api.time.step(120)
)
# Explicitly highlight slow tests not marked as slow.
yield (
api.v8.test(
'tryserver.v8',
'v8_linux_rel_ng_triggered',
'slow_tests',
requester='commit-bot@chromium.org',
patch_project='v8',
blamelist=['dude@chromium.org'],
) +
api.override_step_data(
'Check', api.v8.output_json(unmarked_slow_test=True))
)
# Test tryjob with named cache.
yield (
api.v8.test(
'tryserver.v8',
'v8_linux_rel_ng',
'with_cache',
requester='commit-bot@chromium.org',
blamelist=['dude@chromium.org'],
path_config='generic',
)
)
# Test using build_id (replaces buildnumber in LUCI world).
yield (
api.v8.test(
'tryserver.v8',
'v8_linux_rel_ng',
'with_build_id',
build_id='buildbucket/cr-buildbucket.appspot.com/1234567890',
)
)
# Test reading a pyl test-spec from the V8 repository. The additional test
# targets should be isolated and the tests should be executed.
f = Filter()
f = f.include('read test spec')
f = f.include('isolate tests')
f = f.include_re(r'.*Mjsunit.*')
yield (
api.v8.test(
'client.v8',
'V8 Mac64',
'with_test_spec',
) +
api.path.exists(api.path['checkout'].join(
'infra', 'testing', 'client.v8.pyl')) +
api.override_step_data(
'read test spec',
api.v8.example_test_spec(
'V8 Mac64',
'[{"name": "mjsunit", "variant": "sweet", "shards": 2}]',
),
) +
api.post_process(f)
)
# As above but on a builder. The additional test targets should be isolated
# and the tests should be passed as properties to the triggered testers in
# the trigger step.
yield (
api.v8.test(
'client.v8',
'V8 Linux - nosnap builder',
'with_test_spec',
) +
api.path.exists(api.path['checkout'].join(
'infra', 'testing', 'client.v8.pyl')) +
api.override_step_data(
'read test spec',
api.v8.example_test_spec(
'V8 Linux - nosnap',
'[{"name": "mjsunit", "variant": "sweet", "shards": 2}]',
),
) +
api.post_process(Filter(
'read test spec',
'isolate tests',
'trigger',
))
)
# As above but on a tester. The additional tests passed as property from the
# builder should be executed.
f = Filter()
f = f.include_re(r'.*Mjsunit.*')
yield (
api.v8.test(
'client.v8',
'V8 Linux - nosnap',
'with_test_spec',
parent_test_spec=[["mjsunit", 2, "sweet"]],
) +
api.post_process(f)
)