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

Side by Side Diff: scripts/slave/recipe_modules/auto_bisect/example.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: Removing debug prints. Created 4 years, 4 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 json 5 import json
6 6
7 DEPS = [ 7 DEPS = [
8 'auto_bisect', 8 'auto_bisect',
9 'chromium',
9 'chromium_tests', 10 'chromium_tests',
10 'recipe_engine/json', 11 'recipe_engine/json',
12 'depot_tools/gclient',
11 'recipe_engine/path', 13 'recipe_engine/path',
12 'recipe_engine/properties', 14 'recipe_engine/properties',
13 'recipe_engine/raw_io', 15 'recipe_engine/raw_io',
14 'recipe_engine/step', 16 'recipe_engine/step',
15 ] 17 ]
16 18
17 """This file is a recipe demonstrating the auto_bisect recipe module. 19 """This file is a recipe demonstrating the auto_bisect recipe module.
18 20
19 For more information about recipes, see: https://goo.gl/xKnjz6 21 For more information about recipes, see: https://goo.gl/xKnjz6
20 """ 22 """
21 23
22 24
23 def RunSteps(api): 25 def RunSteps(api):
24 fake_checkout_path = api.path.mkdtemp('fake_checkout') 26 # Dupe of bisection/desktop_bisect recipe.
25 api.path['checkout'] = fake_checkout_path 27 mastername = api.properties.get('mastername')
26 bisector = api.auto_bisect.create_bisector(api.properties['bisect_config'], 28 buildername = api.properties.get('buildername')
27 do_not_nest_wait_for_revision=True) 29 bot_config = api.chromium_tests.create_bot_config_object(mastername,
28 30 buildername)
29 # Request builds and tests for initial range and wait. 31 api.chromium_tests.configure_build(bot_config)
30 bisector.good_rev.start_job() 32 api.gclient.apply_config('perf')
31 bisector.bad_rev.start_job() 33 api.gclient.c.got_revision_mapping.pop('catapult', None)
32 bisector.wait_for_all([bisector.good_rev, bisector.bad_rev]) 34 update_step, bot_db = api.chromium_tests.prepare_checkout(bot_config)
33 35 api.path.c.dynamic_paths['catapult'] = api.auto_bisect.working_dir.join(
34 if bisector.good_rev.failed or bisector.bad_rev.failed: 36 'catapult')
35 return 37 api.auto_bisect.start_try_job(api, update_step=update_step, bot_db=bot_db,
36 38 do_not_nest_wait_for_revision=True)
37 assert bisector.check_improvement_direction()
38 assert bisector.check_initial_confidence()
39 revision_to_check = bisector.get_revision_to_eval()
40 revision_to_check.start_job()
41 bisector.wait_for(revision_to_check)
42 bisector.check_bisect_finished(revision_to_check)
43
44 # Evaluate inserted DEPS-modified revisions.
45 revision_to_check = bisector.get_revision_to_eval()
46 if revision_to_check:
47 revision_to_check.start_job()
48 # Only added for coverage.
49 revision_to_check.read_deps(bisector.get_perf_tester_name())
50 api.auto_bisect.query_revision_info(revision_to_check)
51 else:
52 raise api.step.StepFailure('Expected revision to check.')
53 # TODO(robertocn): Add examples for the following operations:
54 # Abort unnecessary jobs
55 # Print results (may be done in a unit test)
56
57 # Test runner for classic bisect script; calls bisect script in recipe
58 # wrapper with extra_src and path_to_config to override default behavior for
59 # android-chrome bisect jobs.
60 if api.properties.get('mastername'):
61 # TODO(akuegel): Load the config explicitly instead of relying on the
62 # builders.py entries in chromium_tests.
63 mastername = api.properties.get('mastername')
64 buildername = api.properties.get('buildername')
65 bot_config = api.chromium_tests.create_bot_config_object(
66 mastername, buildername)
67 api.chromium_tests.configure_build(bot_config)
68 api.chromium_tests.prepare_checkout(bot_config)
69 kwargs = {
70 'extra_src': 'dummy_extra_src',
71 'path_to_config': '/dummy/path/',
72 }
73 api.auto_bisect.run_bisect_script(**kwargs)
74
75 39
76 def GenTests(api): 40 def GenTests(api):
77 dummy_gs_location = ('gs://chrome-perf/bisect-results/' 41 yield (
78 'a6298e4afedbf2cd461755ea6f45b0ad64222222-test.results') 42 api.test('basic_linux_bisect')
79 basic_test = _make_test(api, _get_basic_test_data(), 'basic') 43 + api.properties(
80 yield basic_test 44 mastername='tryserver.chromium.perf',
81 45 buildername='linux_perf_bisect',
82 invalid_config_test = api.test('invalid_config') 46 slavename='dummyslave',
83 invalid_config_test += api.properties( 47 bisect_config={
84 bisect_config=_get_config({'good_revision': 'not a valid revision'})) 48 'test_type': 'perf',
85 yield invalid_config_test 49 'command':
86 50 ('src/tools/perf/run_benchmark -v --browser=release '
87 failed_build_test = _make_test( 51 '--output-format=valueset smoothness.tough_scrolling_cases'),
88 api, _get_ref_range_only_test_data(), 'failed_build_test', 52 'good_revision': '314015',
89 extra_config={'dummy_builds': None}) 53 'bad_revision': '314017',
90 failed_build_test += api.step_data('gsutil ls', retcode=1) 54 'metric': 'mean_input_event_latency/mean_input_event_latency',
91 failed_build_test += api.step_data('gsutil ls (2)' , retcode=1) 55 'bug_id': '-1',
92 failed_build_test += api.step_data('gsutil ls (3)' , retcode=1) 56 'gs_bucket': 'chrome-perf',
93 failed_build_test += api.step_data( 57 'dummy_builds': 'True',
94 'fetch builder state', 58 'dummy_tests': 'True',
95 api.raw_io.output(json.dumps({'cachedBuilds': ['2106']}))) 59 'dummy_job_names': 'True',
96 failed_build_test += api.step_data( 60 'bypass_stats_check': 'True',
97 'fetch build details', 61 'skip_gclient_ops': 'True',
98 api.raw_io.output(json.dumps({ 62 'recipe_tester_name': 'linux_perf_tester'
99 'results': 2, 63 })
100 'properties': [('build_archive_url', 64 + api.auto_bisect([
101 ('gs://chrome-perf/Linux Builder/full-build-linux_' 65 {
102 'a6298e4afedbf2cd461755ea6f45b0ad64222222.zip'))] 66 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222',
103 }))) 67 'commit_pos': '314015',
104 yield failed_build_test 68 'parsed_values': [19, 20, 21, 22, 23],
105 69 'test_results': 5 * [{'stdout': 'benchmark text', 'retcode': 0}],
106 70 },
107 delayed_build_test = _make_test( 71 {
108 api, _get_ref_range_only_test_data(), 'delayed_build_test', 72 'hash': 'dcdcdc0ff1122212323134879ddceeb1240b0988',
109 extra_config={'dummy_builds': None}) 73 'commit_pos': '314016',
110 delayed_build_test += api.step_data('gsutil ls', retcode=1) 74 'parsed_values': [12, 13, 14, 15, 16],
111 delayed_build_test += api.step_data('gsutil ls (2)', retcode=1) 75 'test_results': 5 * [{'stdout': 'benchmark text', 'retcode': 0}],
112 delayed_build_test += api.step_data('gsutil ls (3)', retcode=1) 76 'cl_info': {
113 delayed_build_test += api.step_data('gsutil ls (4)', retcode=1) 77 'author': 'DummyAuthor',
114 delayed_build_test += api.step_data('gsutil ls (5)', retcode=1) 78 'email': 'dummy@nowhere.com',
115 delayed_build_test += api.step_data('gsutil ls (6)', retcode=1) 79 'subject': 'Some random CL',
116 delayed_build_test += api.step_data( 80 'date': '01/01/2015',
117 'fetch builder state', 81 'body': ('A long description for a CL.\n'
118 api.raw_io.output(json.dumps({'cachedBuilds': []}))) 82 'Containing multiple lines'),
119 delayed_build_test += api.step_data(
120 'fetch builder state (2)',
121 api.raw_io.output(json.dumps({'cachedBuilds': ['2106']})))
122 delayed_build_test += api.step_data(
123 'fetch build details',
124 api.raw_io.output(json.dumps({
125 'properties': [('build_archive_url',
126 ('gs://chrome-perf/Linux Builder/full-build-linux_'
127 'a6298e4afedbf2cd461755ea6f45b0ad64222222.zip'))]
128 })))
129 delayed_build_test += api.step_data(
130 'fetch build details (2)',
131 api.raw_io.output(json.dumps({
132 'results': 2,
133 'properties': [('build_archive_url',
134 ('gs://chrome-perf/Linux Builder/full-build-linux_'
135 'a6298e4afedbf2cd461755ea6f45b0ad64222222.zip'))]
136 })))
137 yield delayed_build_test
138
139 missing_metric_test = _make_test(
140 api, _get_ref_range_only_missing_metric_test_data(),
141 'missing_metric_test')
142 yield missing_metric_test
143
144 windows_test = _make_test(
145 api, _get_basic_test_data(), 'windows_bisector', platform='windows')
146 yield windows_test
147
148 winx64_test = _make_test(
149 api, _get_basic_test_data(), 'windows_x64_bisector', platform='win_x64')
150 yield winx64_test
151
152 mac_test = _make_test(
153 api, _get_basic_test_data(), 'mac_bisector', platform='mac')
154 yield mac_test
155
156 android_test = _make_test(
157 api, _get_basic_test_data(), 'android_bisector', platform='android')
158 yield android_test
159
160 android_arm64_test = _make_test(
161 api, _get_basic_test_data(), 'android_arm64_bisector',
162 platform='android_arm64')
163 yield android_arm64_test
164
165 failed_data = _get_basic_test_data()
166 failed_data[0].pop('DEPS')
167 failed_data[1]['test_results']['results']['errors'] = ['Dummy error.']
168 failed_data[1].pop('DEPS_change')
169 failed_data[1].pop('DEPS')
170 failed_data[1].pop('DEPS_interval')
171 failed_data[0].pop('git_diff')
172 failed_data[0].pop('cl_info')
173 yield _make_test(api, failed_data, 'failed_test')
174
175 yield _make_test(api, _get_reversed_basic_test_data(), 'reversed_basic')
176
177 bad_git_hash_data = _get_basic_test_data()
178 bad_git_hash_data[1]['interned_hashes'] = {'003': '12345', '002': 'Bad Hash'}
179
180 bisect_script_test = _make_test(
181 api, _get_basic_test_data(), 'basic_bisect_script')
182
183 yield bisect_script_test
184
185
186 def _get_ref_range_only_test_data():
187 return [
188 {
189 'refrange': True,
190 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222',
191 'commit_pos': '314015',
192 'fail_to_build': True,
193 },
194 {
195 'refrange': True,
196 'hash': '00316c9ddfb9d7b4e1ed2fff9fe6d964d2111111',
197 'commit_pos': '314017',
198 },
199 ]
200
201
202 def _get_ref_range_only_missing_metric_test_data():
203 return [
204 {
205 'refrange': True,
206 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222',
207 'commit_pos': '314015',
208 'test_results': {
209 'results': {
210 'values': [],
211 }, 83 },
212 'retcodes': [0], 84 },
213 } 85 {
214 }, 86 'hash': '00316c9ddfb9d7b4e1ed2fff9fe6d964d2111111',
215 { 87 'commit_pos': '314017',
216 'refrange': True, 88 'parsed_values': [12, 13, 14, 15, 16],
217 'hash': '00316c9ddfb9d7b4e1ed2fff9fe6d964d2111111', 89 'test_results': 5 * [{'stdout': 'benchmark text', 'retcode': 0}],
218 'commit_pos': '314017', 90 }]))
219 'test_results': { 91 yield (
220 'results': { 92 api.test('v8_roll_bisect')
221 'values': [], 93 + api.properties(
94 mastername='tryserver.chromium.perf',
95 buildername='linux_perf_bisect',
96 slavename='dummyslave',
97 bisect_config={
98 'test_type': 'perf',
99 'command':
100 ('src/tools/perf/run_benchmark -v --browser=release '
101 '--output-format=valueset smoothness.tough_scrolling_cases'),
102 'good_revision': '314015',
103 'bad_revision': '314017',
104 'metric': 'mean_input_event_latency/mean_input_event_latency',
105 'bug_id': '-1',
106 'gs_bucket': 'chrome-perf',
107 'dummy_builds': 'True',
108 'dummy_tests': 'True',
109 'dummy_job_names': 'True',
110 'bypass_stats_check': 'True',
111 'skip_gclient_ops': 'True',
112 'recipe_tester_name': 'linux_perf_tester'
113 })
114 + api.auto_bisect([
115 {
116 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222',
117 'commit_pos': '314015',
118 'parsed_values': [19, 20, 21, 22, 23],
119 'test_results': 5 * [{'stdout': 'benchmark text', 'retcode': 0}],
120 "DEPS": ("vars={'v8_revision': '001'};"
121 "deps = {'src/v8': 'v8.git@' + Var('v8_revision'),"
122 "'src/third_party/WebKit': 'webkit.git@010'}"),
123 },
124 {
125 'depot':'v8',
126 'hash': '002',
127 'parsed_values': [12, 13, 14, 15, 16],
128 'test_results': 5 * [{'stdout': 'benchmark text', 'retcode': 0}],
129 'cl_info': {
130 'author': 'DummyAuthor',
131 'email': 'dummy@nowhere.com',
132 'subject': 'Some random CL',
133 'date': '01/01/2015',
134 'body': ('A long description for a CL.\n'
135 'Containing multiple lines'),
222 }, 136 },
223 'retcodes': [0],
224 }
225 },
226 ]
227
228
229 def _get_basic_test_data():
230 return [
231 {
232 'refrange': True,
233 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222',
234 'commit_pos': '314015',
235 'test_results': {
236 'results':{
237 'values': [19, 20, 21, 22, 23],
238 },
239 'retcodes': [0],
240 }, 137 },
241 "DEPS": ("vars={'v8_revision': '001'};" 138 {
242 "deps = {'src/v8': 'v8.git@' + Var('v8_revision')," 139 'depot':'v8',
243 "'src/third_party/WebKit': 'webkit.git@010'}"), 140 'hash': '003',
244 'git_diff': { 141 'parsed_values': [12, 13, 14, 15, 16],
245 '002': 'Dummy .diff contents 001 - 002', 142 'test_results': 5 * [{'stdout': 'benchmark text', 'retcode': 0}],
246 '003': 'Dummy .diff contents 001 - 003',
247 }, 143 },
248 'cl_info': { 144 {
249 'author': 'DummyAuthor', 145 'hash': 'dcdcdc0ff1122212323134879ddceeb1240b0988',
250 'email': 'dummy@nowhere.com', 146 'commit_pos': '314016',
251 'subject': 'Some random CL', 147 'parsed_values': [12, 13, 14, 15, 16],
252 'date': '01/01/2015', 148 'test_results': 5 * [{'stdout': 'benchmark text', 'retcode': 0}],
253 'body': ('A long description for a CL.\n' 149 'DEPS_change': 'True',
254 'Containing multiple lines'), 150 "DEPS": ("vars={'v8_revision': '004'};"
151 "deps = {'src/v8': 'v8.git@' + Var('v8_revision'),"
152 "'src/third_party/WebKit': 'webkit.git@010'}"),
153 'DEPS_interval': {'v8': '002 003 004'.split()},
255 }, 154 },
256 }, 155 {
257 { 156 'hash': '00316c9ddfb9d7b4e1ed2fff9fe6d964d2111111',
258 'hash': 'dcdcdc0ff1122212323134879ddceeb1240b0988', 157 'commit_pos': '314017',
259 'commit_pos': '314016', 158 'parsed_values': [12, 13, 14, 15, 16],
260 'test_results': { 159 'test_results': 5 * [{'stdout': 'benchmark text', 'retcode': 0}],
261 'results': { 160 }]))
262 'values': [12, 13, 14, 15, 16],
263 },
264 'retcodes': [0],
265 },
266 'DEPS_change': 'True',
267 "DEPS": ("vars={'v8_revision': '004'};"
268 "deps = {'src/v8': 'v8.git@' + Var('v8_revision'),"
269 "'src/third_party/WebKit': 'webkit.git@010'}"),
270 'DEPS_interval': {'v8': '002 003 004'.split()},
271 },
272 {
273 'refrange': True,
274 'hash': '00316c9ddfb9d7b4e1ed2fff9fe6d964d2111111',
275 'commit_pos': '314017',
276 'test_results': {
277 'results': {
278 'values': [12, 13, 14, 15, 16],
279 },
280 'retcodes': [0],
281 }
282 },
283 ]
284
285
286 def _get_reversed_basic_test_data():
287 return [
288 {
289 'refrange': True,
290 'hash': '00316c9ddfb9d7b4e1ed2fff9fe6d964d2111111',
291 'commit_pos': '314015',
292 'test_results': {
293 'results': {
294 'values': [19, 20, 21, 22, 23],
295 },
296 'retcodes': [0],
297 },
298 'cl_info': {
299 'author': 'DummyAuthor',
300 'email': 'dummy@nowhere.com',
301 'subject': 'Some random CL',
302 'date': '01/01/2015',
303 'body': ('A long description for a CL.\n'
304 'Containing multiple lines'),
305 },
306 },
307 {
308 'hash': 'a6298e4afedbf2cd461755ea6f45b0ad64222222',
309 'commit_pos': '314016',
310 'test_results': {
311 'results': {
312 'values': [19, 20, 21, 22, 23],
313 },
314 'retcodes': [0],
315 },
316 "DEPS": ("vars={'v8_revision': '001'};"
317 "deps = {'src/v8': 'v8.git@' + Var('v8_revision'),"
318 "'src/third_party/WebKit': 'webkit.git@010'}"),
319 'git_diff': {
320 '002': 'Dummy .diff contents 001 - 002',
321 '003': 'Dummy .diff contents 001 - 003',
322 },
323 },
324 {
325 'refrange': True,
326 'hash': 'dcdcdc0ff1122212323134879ddceeb1240b0988',
327 'commit_pos': '314017',
328 'test_results': {
329 'results': {
330 'values': [12, 13, 14, 15, 16],
331 },
332 'retcodes': [0],
333 },
334 'DEPS_change': 'True',
335 "DEPS": ("vars={'v8_revision': '004'};"
336 "deps = {'src/v8': 'v8.git@' + Var('v8_revision'),"
337 "'src/third_party/WebKit': 'webkit.git@010'}"),
338 'DEPS_interval': {'v8': '002 003 004'.split()},
339 },
340 ]
341
342
343 def _make_test(api, test_data, test_name, platform='linux', extra_config=None):
344 basic_test = api.test(test_name)
345 basic_test += api.properties(mastername='tryserver.chromium.perf',
346 buildername='linux_perf_bisect',
347 slavename='dummyslave')
348 basic_test += _get_revision_range_step_data(api, test_data)
349 for revision_data in test_data:
350 for step_data in _get_step_data_for_revision(api, revision_data):
351 basic_test += step_data
352 if 'win_x64' in platform:
353 basic_test += api.properties(bisect_config=_get_config({
354 'command': ('src/tools/perf/run_benchmark -v --browser=release_x64'
355 ' smoothness.tough_scrolling_cases'),
356 'recipe_tester_name': 'chromium_rel_win7_x64'}))
357 elif 'win' in platform:
358 basic_test += api.properties(bisect_config=_get_config(
359 {'recipe_tester_name': 'chromium_rel_win7'}))
360 elif 'mac' in platform:
361 basic_test += api.properties(bisect_config=_get_config(
362 {'recipe_tester_name': 'chromium_rel_mac'}))
363 elif 'android_arm64' in platform:
364 basic_test += api.properties(bisect_config=_get_config({
365 'command': ('src/tools/perf/run_benchmark -v --browser=android-chromium'
366 ' smoothness.tough_scrolling_cases'),
367 'recipe_tester_name': 'android-nexus9'}))
368 elif 'android' in platform:
369 basic_test += api.properties(bisect_config=_get_config({
370 'command': ('src/tools/perf/run_benchmark -v --browser=android-chromium'
371 ' smoothness.tough_scrolling_cases'),
372 'recipe_tester_name': 'android-nexus7'}))
373 else:
374 basic_test += api.properties(bisect_config=_get_config(extra_config))
375 basic_test += api.properties(
376 buildbotURL= 'https://build.chromium.org/p/tryserver.chromium.perf')
377 return basic_test
378
379
380 def _get_revision_range_step_data(api, range_data):
381 """Adds canned output for fetch_intervening_revisions.py."""
382 min_rev = range_data[0]['hash']
383 max_rev = range_data[-1]['hash']
384 output = [[r['hash'], 'ignored'] for r in range_data[1:-1]]
385 step_name = ('Expanding revision range.for revisions %s:%s' %
386 (min_rev, max_rev))
387 return api.step_data(step_name, stdout=api.json.output(output))
388
389
390 def _get_config(params=None):
391 """Returns a sample bisect config dict with some fields overridden."""
392 example_config = {
393 'test_type': 'perf',
394 'command': (
395 'src/tools/perf/run_benchmark -v --browser=release smoothness.'
396 'tough_scrolling_cases'),
397 'good_revision': '314015',
398 'bad_revision': '314017',
399 'metric': 'mean_input_event_latency/mean_input_event_latency',
400 'repeat_count': '2',
401 'bug_id': '-1',
402 'max_time_minutes': '5',
403 'gs_bucket': 'chrome-perf',
404 'builder_host': 'master4.golo.chromium.org',
405 'builder_port': '8341',
406 'dummy_builds': 'True',
407 'dummy_tests': 'True',
408 'dummy_job_names': 'True',
409 'bypass_stats_check': 'True',
410 'skip_gclient_ops': 'True',
411 'recipe_tester_name': 'linux_perf_tester',
412 }
413 if params:
414 example_config.update(params)
415 return example_config
416
417
418 def _get_step_data_for_revision(api, revision_data, include_build_steps=True):
419 """Generator that produces step patches for fake results."""
420 commit_pos_number = revision_data['commit_pos']
421 commit_hash = revision_data['hash']
422 test_results = revision_data.get('test_results')
423
424 if 'refrange' in revision_data:
425 parent_step = 'Resolving reference range.'
426 commit_pos = 'refs/heads/master@{#%s}' % commit_pos_number
427 step_name = parent_step + 'crrev get commit hash for ' + commit_pos
428 yield api.step_data(
429 step_name,
430 stdout=api.json.output({'git_sha': commit_hash}))
431
432 if include_build_steps:
433 if test_results:
434 step_name = ('gsutil Get test results for build %s') % commit_hash
435 yield api.step_data(step_name, stdout=api.json.output(test_results))
436
437 if revision_data.get('DEPS', False):
438 step_name = 'fetch file %s:DEPS' % commit_hash
439 yield api.step_data(step_name, stdout=api.raw_io.output(
440 revision_data['DEPS']))
441
442 if 'git_diff' in revision_data:
443 for deps_rev, diff_file in revision_data['git_diff'].iteritems():
444 step_name = 'Generating patch for %s:DEPS to %s'
445 step_name %= (commit_hash, deps_rev)
446 yield api.step_data(step_name, stdout=api.raw_io.output(diff_file))
447
448 if 'DEPS_change' in revision_data:
449 step_name = 'Checking DEPS for ' + commit_hash
450 yield api.step_data(step_name, stdout=api.raw_io.output('DEPS'))
451
452 if 'DEPS_interval' in revision_data:
453 for depot_name, interval in revision_data['DEPS_interval'].iteritems():
454 for item in reversed(interval[:-1]):
455 step_name = 'Hashing modified DEPS file with revision ' + item
456 file_hash = 'f412e8458'
457 yield api.step_data(step_name, stdout=api.raw_io.output(file_hash))
458 step_name = 'Expanding revision range for revision %s on depot %s'
459 step_name %= (interval[-1], depot_name)
460 stdout = api.json.output([(r, 0) for r in interval[:-1]])
461 yield api.step_data(step_name, stdout=stdout)
462
463 if 'cl_info' in revision_data:
464 step_name = 'Reading culprit cl information.'
465 stdout = api.json.output(revision_data['cl_info'])
466 yield api.step_data(step_name, stdout=stdout)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698