| OLD | NEW |
| (Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import json |
| 6 |
| 7 from recipe_engine.config import List |
| 8 from recipe_engine.recipe_api import Property |
| 9 |
| 10 |
| 11 DEPS = [ |
| 12 'chromium', |
| 13 'chromium_tests', |
| 14 'gclient', |
| 15 'json', |
| 16 'path', |
| 17 'properties', |
| 18 'python', |
| 19 'step', |
| 20 ] |
| 21 |
| 22 |
| 23 PROPERTIES = { |
| 24 'target_mastername': Property( |
| 25 kind=str, help='The target master to match compile config to.'), |
| 26 'target_buildername': Property( |
| 27 kind=str, help='The target builder to match compile config to.'), |
| 28 'root_solution_revisions': Property( |
| 29 kind=List(basestring), |
| 30 help='The Chromium revisions to be tested for compile failure, ' |
| 31 'ordered from older revisions to newer revisions.'), |
| 32 'requested_compile_targets': Property( |
| 33 kind=List(basestring), default=None, param_name='compile_targets', |
| 34 help='The failed compile targets, eg: browser_tests'), |
| 35 } |
| 36 |
| 37 |
| 38 class CompileResult(object): |
| 39 SKIPPED = 'skipped' # No compile is needed. |
| 40 PASSED = 'passed' # Compile passed. |
| 41 FAILED = 'failed' # Compile failed. |
| 42 |
| 43 |
| 44 def _run_compile_at_revision(api, target_mastername, target_buildername, |
| 45 revision, compile_targets): |
| 46 with api.step.nest('test %s' % str(revision)): |
| 47 # Checkout code at the given revision to recompile. |
| 48 bot_update_step, master_dict, test_spec = \ |
| 49 api.chromium_tests.prepare_checkout( |
| 50 target_mastername, |
| 51 target_buildername, |
| 52 root_solution_revision=revision) |
| 53 |
| 54 # TODO(http://crbug.com/560991): if compile targets are provided, check |
| 55 # whether they exist and then use analyze to compile the impacted ones by |
| 56 # the given revision. |
| 57 compile_targets = sorted(set(compile_targets or [])) |
| 58 if not compile_targets: |
| 59 compile_targets, _ = api.chromium_tests.get_compile_targets_and_tests( |
| 60 target_mastername, |
| 61 target_buildername, |
| 62 master_dict, |
| 63 test_spec, |
| 64 override_bot_type='builder_tester') |
| 65 |
| 66 try: |
| 67 api.chromium_tests.compile_specific_targets( |
| 68 target_mastername, |
| 69 target_buildername, |
| 70 bot_update_step, |
| 71 master_dict, |
| 72 compile_targets, |
| 73 tests_including_triggered=[], |
| 74 mb_mastername=target_mastername, |
| 75 mb_buildername=target_buildername, |
| 76 override_bot_type='builder_tester') |
| 77 return CompileResult.PASSED |
| 78 except api.step.InfraFailure: |
| 79 raise |
| 80 except api.step.StepFailure: |
| 81 return CompileResult.FAILED |
| 82 |
| 83 |
| 84 def RunSteps(api, target_mastername, target_buildername, |
| 85 root_solution_revisions, requested_compile_targets): |
| 86 api.chromium_tests.configure_build( |
| 87 target_mastername, target_buildername, override_bot_type='builder_tester') |
| 88 |
| 89 results = [] |
| 90 try: |
| 91 for current_revision in root_solution_revisions: |
| 92 compile_result = _run_compile_at_revision( |
| 93 api, target_mastername, target_buildername, |
| 94 current_revision, requested_compile_targets) |
| 95 |
| 96 results.append([current_revision, compile_result]) |
| 97 if compile_result == CompileResult.FAILED: |
| 98 # TODO(http://crbug.com/560991): if compile targets are specified, |
| 99 # compile may fail because those targets are added in a later revision. |
| 100 break # Found the culprit, no need to check later revisions. |
| 101 finally: |
| 102 # Report the result. |
| 103 # TODO(http://crbug.com/563807): use api.python.succeeding_step instead. |
| 104 step_result = api.python.inline( |
| 105 'report', 'import sys; sys.exit(0)', add_python_log=False) |
| 106 if (not requested_compile_targets and |
| 107 results and results[-1][1] == CompileResult.FAILED): |
| 108 step_result.presentation.step_text = '<br/>Culprit: %s' % results[-1][0] |
| 109 step_result.presentation.logs.setdefault('result', []).append( |
| 110 json.dumps(results, indent=2)) |
| 111 |
| 112 # Set the result as a build property too, so that it will be reported back |
| 113 # to Buildbucket and Findit will pull from there instead of buildbot master. |
| 114 step_result.presentation.properties['result'] = results |
| 115 |
| 116 return results |
| 117 |
| 118 |
| 119 def GenTests(api): |
| 120 def props(compile_targets=None): |
| 121 properties = { |
| 122 'mastername': 'tryserver.chromium.linux', |
| 123 'buildername': 'linux_variable', |
| 124 'slavename': 'build1-a1', |
| 125 'buildnumber': '1', |
| 126 'target_mastername': 'chromium.linux', |
| 127 'target_buildername': 'Linux Builder', |
| 128 'root_solution_revisions': ['r1'], |
| 129 } |
| 130 if compile_targets: |
| 131 properties['compile_targets'] = compile_targets |
| 132 return api.properties(**properties) |
| 133 |
| 134 yield ( |
| 135 api.test('compile_specified_targets') + |
| 136 props(compile_targets=['target_name']) |
| 137 ) |
| 138 |
| 139 yield ( |
| 140 api.test('compile_default_targets') + |
| 141 props() + |
| 142 api.override_step_data('test r1.read test spec', |
| 143 api.json.output({ |
| 144 'Linux Builder': { |
| 145 'additional_compile_targets': [ |
| 146 'base_unittests', |
| 147 ], |
| 148 } |
| 149 })) |
| 150 ) |
| 151 |
| 152 yield ( |
| 153 api.test('compile_succeeded') + |
| 154 props() + |
| 155 api.override_step_data('test r1.compile', retcode=1) |
| 156 ) |
| 157 |
| 158 yield ( |
| 159 api.test('compile_failed') + |
| 160 props() + |
| 161 api.override_step_data('test r1.compile', retcode=1) |
| 162 ) |
| 163 |
| 164 yield ( |
| 165 api.test('failed_compile_upon_infra_failure') + |
| 166 props(compile_targets=['target_name']) + |
| 167 api.override_step_data( |
| 168 'test r1.compile', |
| 169 api.json.output({ |
| 170 'notice': [ |
| 171 { |
| 172 'infra_status': { |
| 173 'ping_status_code': 408, |
| 174 }, |
| 175 }, |
| 176 ], |
| 177 }), |
| 178 retcode=1) |
| 179 ) |
| OLD | NEW |