Chromium Code Reviews| Index: scripts/slave/recipes/findit/chromium/compile.py |
| diff --git a/scripts/slave/recipes/findit/chromium/compile.py b/scripts/slave/recipes/findit/chromium/compile.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..bc45c200ed9134a9694b75949fe8a133b7f4a416 |
| --- /dev/null |
| +++ b/scripts/slave/recipes/findit/chromium/compile.py |
| @@ -0,0 +1,198 @@ |
| +# Copyright 2015 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. |
| + |
| +import json |
| + |
| +from recipe_engine.config import List |
| +from recipe_engine.recipe_api import Property |
| + |
| + |
| +DEPS = [ |
| + 'chromium', |
| + 'chromium_tests', |
| + 'findit', |
| + 'gclient', |
| + 'json', |
| + 'path', |
| + 'properties', |
| + 'python', |
| + 'step', |
| +] |
| + |
| + |
| +PROPERTIES = { |
| + 'target_mastername': Property( |
| + kind=str, help='The target master to match compile config to.'), |
| + 'target_buildername': Property( |
| + kind=str, help='The target builder to match compile config to.'), |
| + 'target_solution': Property( |
| + kind=str, help='The gclient solution, eg: src for chromium.'), |
| + 'target_solution_revisions': Property( |
| + kind=List(basestring), |
| + help='The revisions to be tested for compile failure, ' |
| + 'ordered from older revisions to newer revisions.'), |
| + 'compile_targets': Property( |
| + kind=List(basestring), default=None, param_name='compile_targets', |
|
iannucci
2015/11/18 03:57:54
yay! real types!
Please note that in order for th
stgao
2015/11/19 22:06:34
Yes, it will be a list of strings in the build req
|
| + help='The failed compile targets, eg: browser_tests, a/b.o'), |
|
Dirk Pranke
2015/11/17 22:38:51
nit: it's not clear what "a/b.o" is here; is that
stgao
2015/11/19 22:06:34
Yes, it's supposed to be an arbitrary object file.
|
| +} |
| + |
| + |
| +def RunSteps(api, target_mastername, target_buildername, |
| + target_solution, target_solution_revisions, |
| + compile_targets): |
| + api.chromium_tests.configure_build( |
| + target_mastername, target_buildername, override_bot_type='builder_tester') |
| + |
| + results = [] |
| + try: |
| + for current_revision in target_solution_revisions: |
| + with api.step.nest('test %s' % str(current_revision)): |
| + # Configure the revision to recompile. |
| + cfg = api.gclient.c |
| + if not cfg.revisions: |
| + cfg.revisions = {} |
| + cfg.revisions.update({ |
| + target_solution: current_revision, |
| + }) |
|
iannucci
2015/11/18 03:57:54
This is mutating `api.gclient.c`.
I think a more
stgao
2015/11/19 22:06:34
Yes, it works!
|
| + |
| + bot_update_step, master_dict, test_spec = \ |
| + api.chromium_tests.prepare_checkout( |
| + target_mastername, |
| + target_buildername) |
| + |
| + # If no compile target is provided, use analyze to filter out the |
| + # impacted compile targets by the current revision. |
| + compile_targets = sorted(set(compile_targets or [])) |
| + if not compile_targets: |
| + affected_files = \ |
| + api.findit.get_files_affected_by_revision(current_revision) |
| + |
| + all_compile_targets, _ = \ |
| + api.chromium_tests.get_compile_targets_and_tests( |
| + target_mastername, |
| + target_buildername, |
| + master_dict, |
| + test_spec, |
| + override_bot_type='builder_tester', |
| + override_tests=[]) |
| + |
| + requires_compile, matching_exes, compile_targets = \ |
|
Dirk Pranke
2015/11/17 22:38:51
You should update this logic to the latest version
stgao
2015/11/19 22:06:34
Done.
Also refactored chromium_tests.get_compile_
|
| + api.chromium_tests.analyze( |
| + affected_files, |
| + all_compile_targets, |
| + all_compile_targets, |
| + 'trybot_analyze_config.json') |
| + |
| + |
| + if not requires_compile: |
| + compile_targets = [] |
| + else: |
| + # Note that compile_targets doesn't necessarily include |
| + # matching_exes, and for correctness we need to add them. Otherwise |
| + # it's possible we'd only build foo_unittests but not |
| + # foo_unittests_run. |
| + compile_targets = sorted(set(compile_targets + matching_exes)) |
| + |
| + if not compile_targets: |
| + # No compile target is impacted by the current revision. |
| + results.append([current_revision, 'skip']) |
| + continue |
|
iannucci
2015/11/18 03:57:54
I would maybe pull this loop body into a function
stgao
2015/11/19 22:06:34
Done.
|
| + |
| + try: |
| + api.chromium_tests.compile_specific_targets( |
| + target_mastername, |
| + target_buildername, |
| + bot_update_step, |
| + master_dict, |
| + compile_targets, |
| + [], # Not run any test. |
| + override_bot_type='builder_tester') |
| + results.append([current_revision, 'pass']) |
| + except api.step.InfraFailure: |
| + results.append([current_revision, 'unknown']) |
| + raise |
| + except api.step.StepFailure: |
| + # TODO: if compile targets are specified in the build request, compile |
| + # may fail because those targets are added in a later revision. |
| + results.append([current_revision, 'fail']) |
| + break # Found the culprit, no need to check later revisions. |
| + finally: |
| + # Report the result. |
| + step_result = api.python.inline( |
| + 'report', 'import sys; sys.exit(0)', add_python_log=False) |
| + step_result.presentation.logs.setdefault('result', []).append( |
| + json.dumps(results, indent=2)) |
|
iannucci
2015/11/18 03:57:54
I would consider summarizing the culprit (if we fo
stgao
2015/11/19 22:06:34
Good idea.
Done.
|
| + |
| + return results |
| + |
| + |
| +def GenTests(api): |
| + def props(compile_targets=None): |
| + properties = { |
| + 'mastername': 'tryserver.chromium.linux', |
| + 'buildername': 'linux_variable', |
| + 'slavename': 'build1-a1', |
| + 'buildnumber': '1', |
| + 'target_mastername': 'chromium.linux', |
| + 'target_buildername': 'Linux Builder', |
| + 'target_solution': 'src', |
| + 'target_solution_revisions': ['r1'], |
| + } |
| + if compile_targets: |
| + properties['compile_targets'] = compile_targets |
| + return api.properties(**properties) |
| + |
| + yield ( |
| + api.test('compile_skipped') + |
| + props() + |
| + api.override_step_data( |
| + 'test r1.analyze', |
| + api.json.output({ |
| + 'build_targets': [], |
| + 'status': 'No dependencies', |
| + 'targets': [], |
| + }) |
| + ) |
| + ) |
| + |
| + yield ( |
| + api.test('compile_targets_returned_by_analyze') + |
| + props() + |
| + api.override_step_data( |
| + 'test r1.analyze', |
| + api.json.output({ |
| + 'build_targets': ['test_target'], |
| + 'status': 'Found dependency', |
| + 'targets': ['test_target_run'], |
| + }) |
| + ) |
| + ) |
| + |
| + yield ( |
| + api.test('compile_specified_targets') + |
| + props(compile_targets=['obj/a/b/c.o']) |
| + ) |
| + |
| + yield ( |
| + api.test('compile_failed') + |
| + props(compile_targets=['obj/a/b/c.o']) + |
| + api.override_step_data('test r1.compile', retcode=1) |
| + ) |
| + |
| + yield ( |
| + api.test('compile_failed_infra') + |
| + props(compile_targets=['obj/a/b/c.o']) + |
| + api.override_step_data( |
| + 'test r1.compile', |
| + api.json.output({ |
| + 'notice': [ |
| + { |
| + 'infra_status': { |
| + 'ping_status_code': 408, |
| + }, |
| + }, |
| + ], |
| + }), |
| + retcode=1) |
| + ) |