| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import json | 5 import json |
| 6 | 6 |
| 7 DEPS = [ | 7 DEPS = [ |
| 8 'auto_bisect', | 8 'auto_bisect', |
| 9 'chromium_tests', | 9 'chromium_tests', |
| 10 'json', |
| 10 'path', | 11 'path', |
| 11 'properties', | 12 'properties', |
| 12 'raw_io', | 13 'raw_io', |
| 13 'step', | 14 'step', |
| 14 ] | 15 ] |
| 15 | 16 |
| 16 | 17 |
| 17 # This file is just a recipe showing how one would use this module. | 18 # This file is just a recipe showing how one would use this module. |
| 18 # | 19 # |
| 19 # The RunSteps and GenTests functions define the required interface for a | 20 # The RunSteps and GenTests functions define the required interface for a |
| (...skipping 11 matching lines...) Expand all Loading... |
| 31 def RunSteps(api): | 32 def RunSteps(api): |
| 32 fake_checkout_path = api.path.mkdtemp('fake_checkout') | 33 fake_checkout_path = api.path.mkdtemp('fake_checkout') |
| 33 api.path['checkout'] = fake_checkout_path | 34 api.path['checkout'] = fake_checkout_path |
| 34 bisector = api.auto_bisect.create_bisector(api.properties['bisect_config']) | 35 bisector = api.auto_bisect.create_bisector(api.properties['bisect_config']) |
| 35 | 36 |
| 36 # Request builds/tests for initial range and wait | 37 # Request builds/tests for initial range and wait |
| 37 bisector.good_rev.start_job() | 38 bisector.good_rev.start_job() |
| 38 bisector.bad_rev.start_job() | 39 bisector.bad_rev.start_job() |
| 39 bisector.wait_for_all([bisector.good_rev, bisector.bad_rev]) | 40 bisector.wait_for_all([bisector.good_rev, bisector.bad_rev]) |
| 40 | 41 |
| 42 if bisector.good_rev.failed or bisector.bad_rev.failed: |
| 43 return |
| 44 |
| 41 assert bisector.check_improvement_direction() | 45 assert bisector.check_improvement_direction() |
| 42 assert bisector.check_initial_confidence() | 46 assert bisector.check_initial_confidence() |
| 43 revisions_to_check = bisector.get_revisions_to_eval(1) | 47 revisions_to_check = bisector.get_revisions_to_eval(1) |
| 44 assert len(revisions_to_check) == 1 | 48 assert len(revisions_to_check) == 1 |
| 45 revisions_to_check[0].start_job() | 49 revisions_to_check[0].start_job() |
| 46 bisector.wait_for_any(revisions_to_check) | 50 bisector.wait_for_any(revisions_to_check) |
| 47 bisector.check_bisect_finished(revisions_to_check[0]) | 51 bisector.check_bisect_finished(revisions_to_check[0]) |
| 48 | 52 |
| 49 # Evaluate inserted DEPS-modified revisions | 53 # Evaluate inserted DEPS-modified revisions |
| 50 revisions_to_check = bisector.get_revisions_to_eval(2) | 54 revisions_to_check = bisector.get_revisions_to_eval(2) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 63 if api.properties.get('mastername'): | 67 if api.properties.get('mastername'): |
| 64 # TODO(akuegel): Load the config explicitly instead of relying on the | 68 # TODO(akuegel): Load the config explicitly instead of relying on the |
| 65 # builders.py entries in chromium_tests. | 69 # builders.py entries in chromium_tests. |
| 66 mastername = api.properties.get('mastername') | 70 mastername = api.properties.get('mastername') |
| 67 buildername = api.properties.get('buildername') | 71 buildername = api.properties.get('buildername') |
| 68 api.chromium_tests.configure_build(mastername, buildername) | 72 api.chromium_tests.configure_build(mastername, buildername) |
| 69 api.chromium_tests.prepare_checkout(mastername, buildername) | 73 api.chromium_tests.prepare_checkout(mastername, buildername) |
| 70 api.auto_bisect.run_bisect_script('dummy_extra_src', '/dummy/path/') | 74 api.auto_bisect.run_bisect_script('dummy_extra_src', '/dummy/path/') |
| 71 | 75 |
| 72 def GenTests(api): | 76 def GenTests(api): |
| 73 wait_for_any_output = ( | 77 dummy_gs_location = ('gs://chrome-perf/bisect-results/' |
| 74 'Build finished: gs://chrome-perf/bisect-results/' | 78 'a6298e4afedbf2cd461755ea6f45b0ad64222222-test.results') |
| 75 'a6298e4afedbf2cd461755ea6f45b0ad64222222-test.results') | 79 wait_for_any_output = { |
| 80 'completed': [ |
| 81 { |
| 82 'type': 'gs', |
| 83 'location': dummy_gs_location |
| 84 } |
| 85 ] |
| 86 } |
| 87 |
| 76 basic_data = _get_basic_test_data() | 88 basic_data = _get_basic_test_data() |
| 77 basic_test = _make_test(api, basic_data, 'basic') | 89 basic_test = _make_test(api, basic_data, 'basic') |
| 78 basic_test += api.step_data( | 90 basic_test += api.step_data( |
| 79 'Waiting for revision 314015 and 1 other revision(s). (2)', | 91 'Waiting for revision 314015 and 1 other revision(s). (2)', |
| 80 stdout=api.raw_io.output(wait_for_any_output)) | 92 stdout=api.json.output(wait_for_any_output)) |
| 81 | 93 |
| 82 yield basic_test | 94 yield basic_test |
| 83 | 95 |
| 96 failed_build_test_data = _get_ref_range_only_test_data() |
| 97 failed_build_test = _make_test( |
| 98 api, failed_build_test_data, 'failed_build_test') |
| 99 failed_build_test_step_data = { |
| 100 'failed': |
| 101 [{ |
| 102 'builder': 'linux_perf_tester', |
| 103 'job_name': 'a6298e4afedbf2cd461755ea6f45b0ad64222222-test', |
| 104 'master': 'tryserver.chromium.perf', |
| 105 'type': 'buildbot', |
| 106 'job_url': 'http://tempuri.org/log', |
| 107 }], |
| 108 } |
| 109 failed_build_test += api.step_data( |
| 110 'Waiting for revision 314015 and 1 other revision(s). (2)', |
| 111 stdout=api.json.output(failed_build_test_step_data), retcode=1) |
| 112 |
| 113 yield failed_build_test |
| 114 |
| 84 basic_data = _get_basic_test_data() | 115 basic_data = _get_basic_test_data() |
| 85 windows_test = _make_test( | 116 windows_test = _make_test( |
| 86 api, basic_data, 'windows_bisector', platform='windows') | 117 api, basic_data, 'windows_bisector', platform='windows') |
| 87 windows_test += api.step_data( | 118 windows_test += api.step_data( |
| 88 'Waiting for revision 314015 and 1 other revision(s). (2)', | 119 'Waiting for revision 314015 and 1 other revision(s). (2)', |
| 89 stdout=api.raw_io.output(wait_for_any_output)) | 120 stdout=api.json.output(wait_for_any_output)) |
| 90 | 121 |
| 91 yield windows_test | 122 yield windows_test |
| 92 | 123 |
| 93 basic_data = _get_basic_test_data() | 124 basic_data = _get_basic_test_data() |
| 94 winx64_test = _make_test( | 125 winx64_test = _make_test( |
| 95 api, basic_data, 'windows_x64_bisector', platform='win_x64') | 126 api, basic_data, 'windows_x64_bisector', platform='win_x64') |
| 96 winx64_test += api.step_data( | 127 winx64_test += api.step_data( |
| 97 'Waiting for revision 314015 and 1 other revision(s). (2)', | 128 'Waiting for revision 314015 and 1 other revision(s). (2)', |
| 98 stdout=api.raw_io.output(wait_for_any_output)) | 129 stdout=api.json.output(wait_for_any_output)) |
| 99 | 130 |
| 100 yield winx64_test | 131 yield winx64_test |
| 101 | 132 |
| 102 basic_data = _get_basic_test_data() | 133 basic_data = _get_basic_test_data() |
| 103 mac_test = _make_test(api, basic_data, 'mac_bisector', platform='mac') | 134 mac_test = _make_test(api, basic_data, 'mac_bisector', platform='mac') |
| 104 mac_test += api.step_data( | 135 mac_test += api.step_data( |
| 105 'Waiting for revision 314015 and 1 other revision(s). (2)', | 136 'Waiting for revision 314015 and 1 other revision(s). (2)', |
| 106 stdout=api.raw_io.output(wait_for_any_output)) | 137 stdout=api.json.output(wait_for_any_output)) |
| 107 | 138 |
| 108 yield mac_test | 139 yield mac_test |
| 109 | 140 |
| 110 basic_data = _get_basic_test_data() | 141 basic_data = _get_basic_test_data() |
| 111 android_test = _make_test( | 142 android_test = _make_test( |
| 112 api, basic_data, 'android_bisector', platform='android') | 143 api, basic_data, 'android_bisector', platform='android') |
| 113 android_test += api.step_data( | 144 android_test += api.step_data( |
| 114 'Waiting for revision 314015 and 1 other revision(s). (2)', | 145 'Waiting for revision 314015 and 1 other revision(s). (2)', |
| 115 stdout=api.raw_io.output(wait_for_any_output)) | 146 stdout=api.json.output(wait_for_any_output)) |
| 116 | 147 |
| 117 yield android_test | 148 yield android_test |
| 118 | 149 |
| 119 basic_data = _get_basic_test_data() | 150 basic_data = _get_basic_test_data() |
| 120 android_arm64_test = _make_test( | 151 android_arm64_test = _make_test( |
| 121 api, basic_data, 'android_arm64_bisector', platform='android_arm64') | 152 api, basic_data, 'android_arm64_bisector', platform='android_arm64') |
| 122 android_arm64_test += api.step_data( | 153 android_arm64_test += api.step_data( |
| 123 'Waiting for revision 314015 and 1 other revision(s). (2)', | 154 'Waiting for revision 314015 and 1 other revision(s). (2)', |
| 124 stdout=api.raw_io.output(wait_for_any_output)) | 155 stdout=api.json.output(wait_for_any_output)) |
| 125 | 156 |
| 126 yield android_arm64_test | 157 yield android_arm64_test |
| 127 | 158 |
| 128 failed_data = _get_basic_test_data() | 159 failed_data = _get_basic_test_data() |
| 129 failed_data[0].pop('DEPS') | 160 failed_data[0].pop('DEPS') |
| 130 failed_data[1]['test_results']['results']['error'] = 'Dummy error.' | 161 failed_data[1]['test_results']['results']['error'] = 'Dummy error.' |
| 131 failed_data[1]['test_results']['results'].pop('mean') | 162 failed_data[1]['test_results']['results'].pop('mean') |
| 132 failed_data[1]['test_results']['results'].pop('std_err') | 163 failed_data[1]['test_results']['results'].pop('std_err') |
| 133 failed_data[1].pop('DEPS_change') | 164 failed_data[1].pop('DEPS_change') |
| 134 failed_data[1].pop('DEPS') | 165 failed_data[1].pop('DEPS') |
| (...skipping 24 matching lines...) Expand all Loading... |
| 159 | 190 |
| 160 bad_deps_syntax_data = _get_basic_test_data() | 191 bad_deps_syntax_data = _get_basic_test_data() |
| 161 bad_deps_syntax_data[1]['DEPS']='raise RuntimeError("")' | 192 bad_deps_syntax_data[1]['DEPS']='raise RuntimeError("")' |
| 162 yield _make_test(api, bad_deps_syntax_data, 'bad_deps_syntax') | 193 yield _make_test(api, bad_deps_syntax_data, 'bad_deps_syntax') |
| 163 | 194 |
| 164 | 195 |
| 165 basic__data = _get_basic_test_data() | 196 basic__data = _get_basic_test_data() |
| 166 bisect_script_test = _make_test(api, basic_data, 'basic_bisect_script') | 197 bisect_script_test = _make_test(api, basic_data, 'basic_bisect_script') |
| 167 bisect_script_test += api.step_data( | 198 bisect_script_test += api.step_data( |
| 168 'Waiting for revision 314015 and 1 other revision(s). (2)', | 199 'Waiting for revision 314015 and 1 other revision(s). (2)', |
| 169 stdout=api.raw_io.output(wait_for_any_output)) | 200 stdout=api.json.output(wait_for_any_output)) |
| 170 | 201 |
| 171 bisect_script_test += api.properties(mastername='tryserver.chromium.perf', | 202 bisect_script_test += api.properties(mastername='tryserver.chromium.perf', |
| 172 buildername='linux_perf_bisect', | 203 buildername='linux_perf_bisect', |
| 173 slavename='dummyslave') | 204 slavename='dummyslave') |
| 174 yield bisect_script_test | 205 yield bisect_script_test |
| 175 | 206 |
| 176 | 207 |
| 208 def _get_ref_range_only_test_data(): |
| 209 return [ |
| 210 { |
| 211 'refrange': True, |
| 212 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222', |
| 213 'commit_pos': '314015', |
| 214 }, |
| 215 { |
| 216 'refrange': True, |
| 217 'hash': '00316c9ddfb9d7b4e1ed2fff9fe6d964d2111111', |
| 218 'commit_pos': '314017', |
| 219 'test_results': { |
| 220 'results':{ |
| 221 'mean': 15, |
| 222 'std_err': 1, |
| 223 'values': [14, 15, 16], |
| 224 }, |
| 225 'retcodes': [0], |
| 226 } |
| 227 }, |
| 228 ] |
| 229 |
| 230 |
| 177 def _get_basic_test_data(): | 231 def _get_basic_test_data(): |
| 178 return [ | 232 return [ |
| 179 { | 233 { |
| 180 'refrange': True, | 234 'refrange': True, |
| 181 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222', | 235 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222', |
| 182 'commit_pos': '314015', | 236 'commit_pos': '314015', |
| 183 'test_results': { | 237 'test_results': { |
| 184 'results':{ | 238 'results':{ |
| 185 'mean': 20, | 239 'mean': 20, |
| 186 'std_err': 1, | 240 'std_err': 1, |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 359 'recipe_tester_name': 'linux_perf_tester' | 413 'recipe_tester_name': 'linux_perf_tester' |
| 360 } | 414 } |
| 361 example_config.update(params) | 415 example_config.update(params) |
| 362 return example_config | 416 return example_config |
| 363 | 417 |
| 364 | 418 |
| 365 def _get_step_data_for_revision(api, revision_data, include_build_steps=True): | 419 def _get_step_data_for_revision(api, revision_data, include_build_steps=True): |
| 366 """Generator that produces step patches for fake results.""" | 420 """Generator that produces step patches for fake results.""" |
| 367 commit_pos = revision_data['commit_pos'] | 421 commit_pos = revision_data['commit_pos'] |
| 368 commit_hash = revision_data['hash'] | 422 commit_hash = revision_data['hash'] |
| 369 test_results = revision_data['test_results'] | 423 test_results = revision_data.get('test_results') |
| 370 | 424 |
| 371 if 'refrange' in revision_data: | 425 if 'refrange' in revision_data: |
| 372 parent_step = 'Resolving reference range.' | 426 parent_step = 'Resolving reference range.' |
| 373 else: | 427 else: |
| 374 parent_step = 'Expanding revision range.' | 428 parent_step = 'Expanding revision range.' |
| 375 step_name = parent_step + 'resolving commit_pos ' + commit_pos | 429 step_name = parent_step + 'resolving commit_pos ' + commit_pos |
| 376 yield api.step_data(step_name, stdout=api.raw_io.output('hash:' + | 430 yield api.step_data(step_name, stdout=api.raw_io.output('hash:' + |
| 377 commit_hash)) | 431 commit_hash)) |
| 378 | 432 |
| 379 step_name = parent_step + 'resolving hash ' + commit_hash | 433 step_name = parent_step + 'resolving hash ' + commit_hash |
| 380 commit_pos_str = 'refs/heads/master@{#%s}' % commit_pos | 434 commit_pos_str = 'refs/heads/master@{#%s}' % commit_pos |
| 381 yield api.step_data(step_name, stdout=api.raw_io.output(commit_pos_str)) | 435 yield api.step_data(step_name, stdout=api.raw_io.output(commit_pos_str)) |
| 382 | 436 |
| 383 if include_build_steps: | 437 if include_build_steps: |
| 384 step_name = 'gsutil Get test results for build ' + commit_hash | 438 if test_results: |
| 385 yield api.step_data(step_name, stdout=api.raw_io.output(json.dumps( | 439 step_name = 'gsutil Get test results for build ' + commit_hash |
| 386 test_results))) | 440 yield api.step_data(step_name, stdout=api.json.output(test_results)) |
| 387 | 441 |
| 388 if revision_data.get('DEPS', False): | 442 if revision_data.get('DEPS', False): |
| 389 step_name = 'git cat-file %s:DEPS' % commit_hash | 443 step_name = 'git cat-file %s:DEPS' % commit_hash |
| 390 yield api.step_data(step_name, stdout=api.raw_io.output( | 444 yield api.step_data(step_name, stdout=api.raw_io.output( |
| 391 revision_data['DEPS'])) | 445 revision_data['DEPS'])) |
| 392 | 446 |
| 393 if 'git_diff' in revision_data: | 447 if 'git_diff' in revision_data: |
| 394 for deps_rev, diff_file in revision_data['git_diff'].iteritems(): | 448 for deps_rev, diff_file in revision_data['git_diff'].iteritems(): |
| 395 step_name = 'Generating patch for %s:DEPS to %s' | 449 step_name = 'Generating patch for %s:DEPS to %s' |
| 396 step_name %= (commit_hash, deps_rev) | 450 step_name %= (commit_hash, deps_rev) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 411 step_name = 'Expanding revision range for revision %s on depot %s' | 465 step_name = 'Expanding revision range for revision %s on depot %s' |
| 412 step_name %= (interval[0], depot_name) | 466 step_name %= (interval[0], depot_name) |
| 413 stdout = api.raw_io.output('\n'.join(interval)) | 467 stdout = api.raw_io.output('\n'.join(interval)) |
| 414 yield api.step_data(step_name, stdout=stdout) | 468 yield api.step_data(step_name, stdout=stdout) |
| 415 | 469 |
| 416 if 'cl_info' in revision_data: | 470 if 'cl_info' in revision_data: |
| 417 step_name = 'Reading culprit cl information.' | 471 step_name = 'Reading culprit cl information.' |
| 418 stdout = api.raw_io.output(revision_data['cl_info']) | 472 stdout = api.raw_io.output(revision_data['cl_info']) |
| 419 yield api.step_data(step_name, stdout=stdout) | 473 yield api.step_data(step_name, stdout=stdout) |
| 420 | 474 |
| OLD | NEW |