Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1324)

Side by Side Diff: scripts/slave/recipe_modules/auto_bisect/local_bisect.py

Issue 2247373002: Refactor stages 1, 2 and test_api overhaul. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/build.git@master
Patch Set: Addressing all early feedback. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 base64 5 import base64
6 import collections 6 import collections
7 import json 7 import json
8 8
9 from auto_bisect import bisect_exceptions
9 10
10 def perform_bisect(api, **flags): 11 def perform_bisect(api, **flags):
11 # Try catch all the exceptions thrown in bisection so that recipe can 12 # Try catch all the exceptions thrown in bisection so that recipe can
12 # post the failed job result to dashboard 13 # post the failed job result to dashboard
13 try: 14 try:
14 bisect_attempts = [] 15 bisect_attempts = []
15 if api.m.chromium.c.TARGET_PLATFORM != 'android': 16 if api.m.chromium.c.TARGET_PLATFORM != 'android':
16 _perform_single_bisect(api, bisect_attempts, **flags) 17 _perform_single_bisect(api, bisect_attempts, **flags)
17 else: 18 else:
18 # pick an available device if targe platform is android 19 # pick an available device if targe platform is android
19 connected_devices = _get_connected_devices(api) 20 connected_devices = _get_connected_devices(api)
20 if not connected_devices: 21 if not connected_devices:
21 raise api.m.step.StepFailure( 22 raise api.m.step.StepFailure(
22 'No Android test devices are available') 23 'No Android test devices are available')
23 for device in connected_devices: 24 for device in connected_devices:
24 api.m.bisect_tester.device_to_test = device 25 api.m.bisect_tester.device_to_test = device
25 try: 26 try:
26 _perform_single_bisect(api, bisect_attempts, **flags) 27 _perform_single_bisect(api, bisect_attempts, **flags)
27 break 28 break
28 except api.m.step.StepFailure: 29 except api.m.step.StepFailure:
29 # Redo the bisect job if target platform is android and bisect 30 # Redo the bisect job if target platform is android and bisect
30 # failed because the test device disconnected 31 # failed because the test device disconnected
31 current_connected_devices = _get_connected_devices(api) 32 current_connected_devices = _get_connected_devices(api)
32 if (api.m.bisect_tester.device_to_test not in 33 if (api.m.bisect_tester.device_to_test not in
33 current_connected_devices): 34 current_connected_devices):
34 continue 35 continue
35 else: 36 else:
36 raise 37 raise
37 except: # pylint: disable=bare-except 38 except bisect_exceptions.InconclusiveBisectException:
38 if bisect_attempts: 39 if bisect_attempts:
39 bisect_attempts[-1].post_result(halt_on_failure=True) 40 bisect_attempts[-1].post_result()
41 raise api.m.step.StepFailure('Bisect cannot identify a culprit')
42 except Exception: # pylint: disable=bare-except
43 if bisect_attempts:
44 bisect_attempts[-1].post_result()
40 raise 45 raise
41 46
42 def _perform_single_bisect(api, bisect_attempts, **flags): 47 def _perform_single_bisect(api, bisect_attempts, **flags):
43 bisect_config = dict(api.m.properties.get('bisect_config')) 48 bisect_config = dict(api.m.properties.get('bisect_config'))
44 if bisect_attempts: 49 if bisect_attempts:
45 bisect_config['good_revision'] = bisect_attempts[-1].lkgr.commit_hash 50 bisect_config['good_revision'] = bisect_attempts[-1].lkgr.commit_hash
46 bisect_config['bad_revision'] = bisect_attempts[-1].fkbr.commit_hash 51 bisect_config['bad_revision'] = bisect_attempts[-1].fkbr.commit_hash
47 bisector = api.create_bisector(bisect_config, **flags) 52 bisector = api.create_bisector(bisect_config, **flags)
48 bisect_attempts.append(bisector) 53 bisect_attempts.append(bisector)
49 with api.m.step.nest('Gathering reference values'): 54 with api.m.step.nest('Gathering reference values'):
50 _gather_reference_range(api, bisector) 55 _gather_reference_range(bisector)
51 if (not bisector.failed and bisector.check_improvement_direction() and 56 if (not bisector.failed and bisector.check_improvement_direction() and
52 bisector.check_initial_confidence()): 57 bisector.check_initial_confidence()):
58 bisector.compute_relative_change()
53 if bisector.check_reach_adjacent_revision( 59 if bisector.check_reach_adjacent_revision(
54 bisector.good_rev): # pragma: no cover 60 bisector.good_rev): # pragma: no cover
55 # Only show this step if bisect has reached adjacent revisions. 61 # Only show this step if bisect has reached adjacent revisions.
56 with api.m.step.nest(str('Check bisect finished on revision ' + 62 with api.m.step.nest(str('Check bisect finished on revision ' +
57 bisector.good_rev.revision_string())): 63 bisector.good_rev.revision_string())):
58 if bisector.check_bisect_finished(bisector.good_rev): 64 if bisector.check_bisect_finished(bisector.good_rev):
59 bisector.bisect_over = True 65 bisector.bisect_over = True
60 if not bisector.bisect_over: 66 if not bisector.bisect_over:
61 _bisect_main_loop(bisector) 67 _bisect_main_loop(bisector)
62 else: 68 else:
63 bisector.bisect_over = True 69 bisector.bisect_over = True
64 bisector.print_result_debug_info() 70 bisector.print_result_debug_info()
65 bisector.post_result(halt_on_failure=True) 71 bisector.post_result(halt_on_failure=True)
66 72
67 def _get_connected_devices(api): 73 def _get_connected_devices(api):
68 api.m.chromium_android.device_status() 74 api.m.chromium_android.device_status()
69 return api.m.chromium_android.devices 75 return api.m.chromium_android.devices
70 76
71 def _gather_reference_range(api, bisector): # pragma: no cover 77 def _gather_reference_range(bisector): # pragma: no cover
72 bisector.good_rev.start_job() 78 bisector.good_rev.start_job()
73 bisector.bad_rev.start_job() 79 bisector.bad_rev.start_job()
74 bisector.wait_for_all([bisector.good_rev, bisector.bad_rev])
75 if bisector.good_rev.failed: 80 if bisector.good_rev.failed:
76 bisector.surface_result('REF_RANGE_FAIL') 81 bisector.surface_result('REF_RANGE_FAIL')
77 api.m.halt('Testing the "good" revision failed')
78 bisector.failed = True 82 bisector.failed = True
83 raise bisect_exceptions.InconclusiveBisectException(
84 'Testing the "good" revision failed')
79 elif bisector.bad_rev.failed: 85 elif bisector.bad_rev.failed:
80 bisector.surface_result('REF_RANGE_FAIL') 86 bisector.surface_result('REF_RANGE_FAIL')
81 api.m.halt('Testing the "bad" revision failed')
82 bisector.failed = True 87 bisector.failed = True
83 api.m.halt('Testing the "good" revision failed') 88 raise bisect_exceptions.InconclusiveBisectException(
84 else: 89 'Testing the "bad" revision failed')
85 bisector.compute_relative_change()
86
87 90
88 def _bisect_main_loop(bisector): # pragma: no cover 91 def _bisect_main_loop(bisector): # pragma: no cover
89 """This is the main bisect loop. 92 """This is the main bisect loop.
90 93
91 It gets an evenly distributed number of revisions in the candidate range, 94 It gets an evenly distributed number of revisions in the candidate range,
92 then it starts them in parallel and waits for them to finish. 95 then it starts them in parallel and waits for them to finish.
93 """ 96 """
94 while not bisector.bisect_over: 97 while not bisector.bisect_over:
95 revision_to_check = bisector.get_revision_to_eval() 98 revision_to_check = bisector.get_revision_to_eval()
96 if not revision_to_check: 99 if not revision_to_check:
97 bisector.bisect_over = True 100 bisector.bisect_over = True
98 break 101 break
99 102
100 with bisector.api.m.step.nest(str('Working on revision ' + 103 with bisector.api.m.step.nest(str('Working on revision ' +
101 revision_to_check.revision_string())): 104 revision_to_check.revision_string())):
102 bisector.post_result(halt_on_failure=False) 105 bisector.post_result(halt_on_failure=False)
103 revision_to_check.start_job() 106 revision_to_check.start_job()
104 bisector.wait_for(revision_to_check)
105 107
106 if bisector.check_reach_adjacent_revision(revision_to_check): 108 if bisector.check_reach_adjacent_revision(revision_to_check):
107 # Only show this step if bisect has reached adjacent revisions. 109 # Only show this step if bisect has reached adjacent revisions.
108 with bisector.api.m.step.nest( 110 with bisector.api.m.step.nest(
109 str('Check bisect finished on revision ' + 111 str('Check bisect finished on revision ' +
110 revision_to_check.revision_string())): 112 revision_to_check.revision_string())):
111 if bisector.check_bisect_finished(revision_to_check): 113 if bisector.check_bisect_finished(revision_to_check):
112 bisector.bisect_over = True 114 bisector.bisect_over = True
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698