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

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

Issue 2278233002: Revert of Use buildbucket to assess build failure. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/build.git@master
Patch Set: 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 """An interface for holding state and result of revisions in a bisect job. 5 """An interface for holding state and result of revisions in a bisect job.
6 6
7 When implementing support for tests other than perf, one should extend this 7 When implementing support for tests other than perf, one should extend this
8 class so that the bisect module and recipe can use it. 8 class so that the bisect module and recipe can use it.
9 9
10 See perf_revision_state for an example. 10 See perf_revision_state for an example.
11 """ 11 """
12 12
13 import hashlib 13 import hashlib
14 import json 14 import json
15 import math 15 import math
16 import os 16 import os
17 import tempfile 17 import tempfile
18 import re 18 import re
19 import uuid 19 import uuid
20 20
21 from . import depot_config 21 from . import depot_config
22 22
23 # These relate to how to increase the number of repetitions during re-test 23 # These relate to how to increase the number of repetitions during re-test
24 MINIMUM_SAMPLE_SIZE = 5 24 MINIMUM_SAMPLE_SIZE = 5
25 INCREASE_FACTOR = 1.5 25 INCREASE_FACTOR = 1.5
26 # Buildbot job result codes.
27 # See http://docs.buildbot.net/current/developer/results.html
28 SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION = range(5)
26 29
27 class RevisionState(object): 30 class RevisionState(object):
28 """Abstracts the state of a single revision on a bisect job.""" 31 """Abstracts the state of a single revision on a bisect job."""
29 32
30 # Possible values for the status attribute of RevisionState: 33 # Possible values for the status attribute of RevisionState:
31 ( 34 (
32 NEW, # A revision_state object that has just been initialized. 35 NEW, # A revision_state object that has just been initialized.
33 BUILDING, # Requested a build for this revision, waiting for it. 36 BUILDING, # Requested a build for this revision, waiting for it.
34 TESTING, # A test job for this revision was triggered, waiting for it. 37 TESTING, # A test job for this revision was triggered, waiting for it.
35 TESTED, # The test job completed with non-failing results. 38 TESTED, # The test job completed with non-failing results.
(...skipping 30 matching lines...) Expand all
66 self.previous_revision = None 69 self.previous_revision = None
67 self.job_name = None 70 self.job_name = None
68 self.patch_file = None 71 self.patch_file = None
69 self.deps_revision = None 72 self.deps_revision = None
70 self.depot_name = depot_name or self.bisector.base_depot 73 self.depot_name = depot_name or self.bisector.base_depot
71 self.depot = depot_config.DEPOT_DEPS_NAME[self.depot_name] 74 self.depot = depot_config.DEPOT_DEPS_NAME[self.depot_name]
72 self.commit_hash = str(commit_hash) 75 self.commit_hash = str(commit_hash)
73 self._rev_str = None 76 self._rev_str = None
74 self.base_revision = base_revision 77 self.base_revision = base_revision
75 self.revision_overrides = {} 78 self.revision_overrides = {}
76 self.build_id = None
77 if self.base_revision: 79 if self.base_revision:
78 assert self.base_revision.deps_file_contents 80 assert self.base_revision.deps_file_contents
79 self.needs_patch = True 81 self.needs_patch = True
80 self.revision_overrides[self.depot['src']] = self.commit_hash 82 self.revision_overrides[self.depot['src']] = self.commit_hash
81 self.deps_patch, self.deps_file_contents = self.bisector.make_deps_patch( 83 self.deps_patch, self.deps_file_contents = self.bisector.make_deps_patch(
82 self.base_revision, self.base_revision.deps_file_contents, 84 self.base_revision, self.base_revision.deps_file_contents,
83 self.depot, self.commit_hash) 85 self.depot, self.commit_hash)
84 self.deps_sha = hashlib.sha1(self.deps_patch).hexdigest() 86 self.deps_sha = hashlib.sha1(self.deps_patch).hexdigest()
85 self.deps_sha_patch = self.bisector.make_deps_sha_file(self.deps_sha) 87 self.deps_sha_patch = self.bisector.make_deps_sha_file(self.deps_sha)
86 self.deps = dict(base_revision.deps) 88 self.deps = dict(base_revision.deps)
87 self.deps[self.depot_name] = self.commit_hash 89 self.deps[self.depot_name] = self.commit_hash
88 else: 90 else:
89 self.needs_patch = False 91 self.needs_patch = False
90 self.build_url = self.bisector.get_platform_gs_prefix() + self._gs_suffix() 92 self.build_url = self.bisector.get_platform_gs_prefix() + self._gs_suffix()
91 self.values = [] 93 self.values = []
92 self.mean_value = None 94 self.mean_value = None
93 self.overall_return_code = None 95 self.overall_return_code = None
94 self.std_dev = None 96 self.std_dev = None
95 self._test_config = None 97 self._test_config = None
98 self.build_number = None
96 99
97 if self.bisector.test_type == 'perf': 100 if self.bisector.test_type == 'perf':
98 self.repeat_count = MINIMUM_SAMPLE_SIZE 101 self.repeat_count = MINIMUM_SAMPLE_SIZE
99 else: 102 else:
100 self.repeat_count = self.bisector.bisect_config.get( 103 self.repeat_count = self.bisector.bisect_config.get(
101 'repeat_count', MINIMUM_SAMPLE_SIZE) 104 'repeat_count', MINIMUM_SAMPLE_SIZE)
102 105
103 @property 106 @property
104 def tested(self): 107 def tested(self):
105 return self.status in (RevisionState.TESTED,) 108 return self.status in (RevisionState.TESTED,)
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 """Checks if the revision is already built and archived.""" 276 """Checks if the revision is already built and archived."""
274 if not self.build_archived: 277 if not self.build_archived:
275 api = self.bisector.api 278 api = self.bisector.api
276 self.build_archived = api.gsutil_file_exists(self.build_url) 279 self.build_archived = api.gsutil_file_exists(self.build_url)
277 280
278 if self.bisector.dummy_builds: 281 if self.bisector.dummy_builds:
279 self.build_archived = self.in_progress 282 self.build_archived = self.in_progress
280 283
281 return self.build_archived 284 return self.build_archived
282 285
286 def _fetch_build_info(self, base_url, build_number):
287 api = self.bisector.api
288 build_url = '%s/builds/%s?as_text=1' % (base_url, build_number)
289 fetch_result = api.m.url.fetch( build_url, step_name='fetch build details')
290 return json.loads(fetch_result or '{}')
291
283 def _is_build_failed(self): 292 def _is_build_failed(self):
284 result = self.bisector.api.m.buildbucket.get_build( 293 api = self.bisector.api
285 self.build_id, 294 current_build = None
286 step_test_data=lambda: self.bisector.api.m.json.test_api.output_stream( 295 path = 'json/builders/' + self.bisector.get_builder_bot_for_this_platform()
287 {'results': [ 296 base_url = api.m.properties.get('buildbotURL', 'http://localhost:8041/')
288 {'build': {'result': 'SUCCESS', 'status': 'COMPLETED'}}]} 297 base_url += path
289 )) 298 if self.build_number is None:
290 return (result.stdout['results'][0]['build']['status'] == 'COMPLETED' and 299 try:
291 result.stdout['results'][0]['build'].get('result') != 'SUCCESS') 300 # Get all the current builds.
301 builder_state_url = base_url + '?as_text=1'
302 builder_state = api.m.url.fetch(
303 builder_state_url, step_name='fetch builder state')
304 builder_state = json.loads(builder_state or '{}')
305 for build_number in builder_state.get('cachedBuilds', []):
306 build = self._fetch_build_info(base_url, build_number)
307 # Properties is a list of triples (key, value, source)
308 build_properties = dict([t[:2] for t in build.get('properties', [])])
309 if build_properties.get('build_archive_url') == self.build_url:
310 self.build_number = build_number
311 current_build = build
312 break
313 except (api.m.step.StepFailure, ValueError): # pragma: no cover
314 # If we cannot get json from buildbot, we cannot determine if a build is
315 # failed, hence we consider it in progress until it times out.
316 return False
317 if self.build_number is None:
318 # The build hasn't started yet, therefore it's not failed.
319 return False
320 if not current_build:
321 current_build = self._fetch_build_info(base_url, self.build_number)
322 return current_build.get('results') in [FAILURE, SKIPPED, EXCEPTION]
292 323
293 def _results_available(self): 324 def _results_available(self):
294 """Checks if the results for the test job have been uploaded.""" 325 """Checks if the results for the test job have been uploaded."""
295 api = self.bisector.api 326 api = self.bisector.api
296 result = api.gsutil_file_exists(self.test_results_url) 327 result = api.gsutil_file_exists(self.test_results_url)
297 if self.bisector.dummy_builds: 328 if self.bisector.dummy_builds:
298 return self.in_progress 329 return self.in_progress
299 return result # pragma: no cover 330 return result # pragma: no cover
300 331
301 def _gs_suffix(self): 332 def _gs_suffix(self):
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 'build_archive_url': self.build_url, 420 'build_archive_url': self.build_url,
390 }, 421 },
391 }, 422 },
392 'client_operation_id': operation_id 423 'client_operation_id': operation_id
393 } 424 }
394 if self.revision_overrides: 425 if self.revision_overrides:
395 build_details['parameters']['properties']['deps_revision_overrides'] = \ 426 build_details['parameters']['properties']['deps_revision_overrides'] = \
396 self.revision_overrides 427 self.revision_overrides
397 428
398 try: 429 try:
399 result = api.m.buildbucket.put( 430 api.m.buildbucket.put([build_details],
400 [build_details], 431 api.m.service_account.get_json_path(
401 api.m.service_account.get_json_path(api.SERVICE_ACCOUNT), 432 api.SERVICE_ACCOUNT))
402 step_test_data=lambda: api.m.json.test_api.output_stream(
403 {'results':[{'build':{'id':'1201331270'}}]}))
404 except api.m.step.StepFailure: # pragma: no cover 433 except api.m.step.StepFailure: # pragma: no cover
405 self.bisector.surface_result('BUILD_FAILURE') 434 self.bisector.surface_result('BUILD_FAILURE')
406 raise 435 raise
407 self.build_id = result.stdout['results'][0]['build']['id']
408 436
409 def _get_bisect_config_for_tester(self): 437 def _get_bisect_config_for_tester(self):
410 """Copies the key-value pairs required by a tester bot to a new dict.""" 438 """Copies the key-value pairs required by a tester bot to a new dict."""
411 result = {} 439 result = {}
412 required_test_properties = { 440 required_test_properties = {
413 'truncate_percent', 441 'truncate_percent',
414 'metric', 442 'metric',
415 'command', 443 'command',
416 'test_type' 444 'test_type'
417 } 445 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 else: 599 else:
572 next_revision_to_test.retest() 600 next_revision_to_test.retest()
573 601
574 def __repr__(self): 602 def __repr__(self):
575 if self.overall_return_code is not None: 603 if self.overall_return_code is not None:
576 return ('RevisionState(rev=%s, values=%r, overall_return_code=%r, ' 604 return ('RevisionState(rev=%s, values=%r, overall_return_code=%r, '
577 'std_dev=%r)') % (self.revision_string(), self.values, 605 'std_dev=%r)') % (self.revision_string(), self.values,
578 self.overall_return_code, self.std_dev) 606 self.overall_return_code, self.std_dev)
579 return ('RevisionState(rev=%s, values=%r, mean_value=%r, std_dev=%r)' % ( 607 return ('RevisionState(rev=%s, values=%r, mean_value=%r, std_dev=%r)' % (
580 self.revision_string(), self.values, self.mean_value, self.std_dev)) 608 self.revision_string(), self.values, self.mean_value, self.std_dev))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698