Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Performance Test Bisect Tool | 6 """Performance Test Bisect Tool |
| 7 | 7 |
| 8 This script bisects a series of changelists using binary search. It starts at | 8 This script bisects a series of changelists using binary search. It starts at |
| 9 a bad revision where a performance metric has regressed, and asks for a last | 9 a bad revision where a performance metric has regressed, and asks for a last |
| 10 known-good revision. It will then binary search across this revision range by | 10 known-good revision. It will then binary search across this revision range by |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 69 # svn: Needed for git workflow to resolve hashes to svn revisions. | 69 # svn: Needed for git workflow to resolve hashes to svn revisions. |
| 70 # from: Parent depot that must be bisected before this is bisected. | 70 # from: Parent depot that must be bisected before this is bisected. |
| 71 # deps_var: Key name in vars varible in DEPS file that has revision information. | 71 # deps_var: Key name in vars varible in DEPS file that has revision information. |
| 72 DEPOT_DEPS_NAME = { | 72 DEPOT_DEPS_NAME = { |
| 73 'chromium' : { | 73 'chromium' : { |
| 74 "src" : "src", | 74 "src" : "src", |
| 75 "recurse" : True, | 75 "recurse" : True, |
| 76 "depends" : None, | 76 "depends" : None, |
| 77 "from" : ['cros', 'android-chrome'], | 77 "from" : ['cros', 'android-chrome'], |
| 78 'viewvc': 'http://src.chromium.org/viewvc/chrome?view=revision&revision=', | 78 'viewvc': 'http://src.chromium.org/viewvc/chrome?view=revision&revision=', |
| 79 'deps_var': None | 79 'deps_var': 'chromium_rev' |
| 80 }, | 80 }, |
| 81 'webkit' : { | 81 'webkit' : { |
| 82 "src" : "src/third_party/WebKit", | 82 "src" : "src/third_party/WebKit", |
| 83 "recurse" : True, | 83 "recurse" : True, |
| 84 "depends" : None, | 84 "depends" : None, |
| 85 "from" : ['chromium'], | 85 "from" : ['chromium'], |
| 86 'viewvc': 'http://src.chromium.org/viewvc/blink?view=revision&revision=', | 86 'viewvc': 'http://src.chromium.org/viewvc/blink?view=revision&revision=', |
| 87 'deps_var': 'webkit_revision' | 87 'deps_var': 'webkit_revision' |
| 88 }, | 88 }, |
| 89 'angle' : { | 89 'angle' : { |
| (...skipping 1270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1360 | 1360 |
| 1361 bleeding_edge_revision = None | 1361 bleeding_edge_revision = None |
| 1362 | 1362 |
| 1363 for c in commits: | 1363 for c in commits: |
| 1364 bleeding_edge_revision = self._GetV8BleedingEdgeFromV8TrunkIfMappable(c) | 1364 bleeding_edge_revision = self._GetV8BleedingEdgeFromV8TrunkIfMappable(c) |
| 1365 if bleeding_edge_revision: | 1365 if bleeding_edge_revision: |
| 1366 break | 1366 break |
| 1367 | 1367 |
| 1368 return bleeding_edge_revision | 1368 return bleeding_edge_revision |
| 1369 | 1369 |
| 1370 def Get3rdPartyRevisionsFromCurrentRevision(self, depot, revision): | 1370 def _ParseRevisionsFromDEPSFileManually(self, depot): |
| 1371 """Parses the DEPS file to determine WebKit/v8/etc... versions. | 1371 """Manually parses the vars section of the DEPS file to determine |
| 1372 chromium/blink/etc... revisions. | |
| 1373 | |
| 1374 Args: | |
| 1375 depot: Depot being bisected. | |
| 1372 | 1376 |
| 1373 Returns: | 1377 Returns: |
| 1374 A dict in the format {depot:revision} if successful, otherwise None. | 1378 A dict in the format {depot:revision} if successful, otherwise None. |
| 1375 """ | 1379 """ |
| 1376 cwd = os.getcwd() | 1380 # We'll parse the "vars" section of the DEPS file. |
| 1377 self.ChangeToDepotWorkingDirectory(depot) | 1381 rxp = re.compile("vars = {(?P<vars_body>[^}]+)", re.MULTILINE) |
| 1382 re_results = rxp.search(ReadStringFromFile(bisect_utils.FILE_DEPS_GIT)) | |
| 1383 locals = {} | |
| 1378 | 1384 |
| 1379 results = {} | 1385 if not re_results: |
| 1386 return None | |
| 1380 | 1387 |
| 1381 if depot == 'chromium' or depot == 'android-chrome': | 1388 for current_line in re_results.group("vars_body").splitlines(): |
| 1389 try: | |
| 1390 # We should be left with a series of entries in the vars component of | |
| 1391 # the DEPS file with the following format: | |
| 1392 # 'depot_name': 'revision', | |
|
qyearsley
2014/04/25 18:11:18
I think this might not work for some .DEPS.git fil
shatch
2014/04/25 20:24:16
True, changed it to use a regex to match up name/r
| |
| 1393 depot_name = current_line.split("'")[1].split("'")[0] | |
| 1394 depot_revision = current_line.split(": '")[1].split("'")[0] | |
| 1395 for current_name, current_data in DEPOT_DEPS_NAME.iteritems(): | |
| 1396 if (current_data.has_key('deps_var') and | |
| 1397 current_data['deps_var'] == depot_name): | |
| 1398 src_name = current_name | |
| 1399 locals[src_name] = depot_revision | |
| 1400 break | |
| 1401 except IndexError: | |
| 1402 pass | |
| 1403 return locals | |
| 1404 | |
| 1405 def _ParseRevisionsFromDEPSFile(self, depot): | |
| 1406 """Parses the local DEPS file to determine blink/skia/v8 revisions which may | |
| 1407 be needed if the bisect recurses into those depots later. | |
| 1408 | |
| 1409 Args: | |
| 1410 depot: Depot being bisected. | |
| 1411 | |
| 1412 Returns: | |
| 1413 A dict in the format {depot:revision} if successful, otherwise None. | |
| 1414 """ | |
| 1415 try: | |
| 1382 locals = {'Var': lambda _: locals["vars"][_], | 1416 locals = {'Var': lambda _: locals["vars"][_], |
| 1383 'From': lambda *args: None} | 1417 'From': lambda *args: None} |
| 1384 execfile(bisect_utils.FILE_DEPS_GIT, {}, locals) | 1418 execfile(bisect_utils.FILE_DEPS_GIT, {}, locals) |
| 1385 | 1419 locals = locals['deps'] |
| 1386 os.chdir(cwd) | 1420 results = {} |
| 1387 | 1421 |
| 1388 rxp = re.compile(".git@(?P<revision>[a-fA-F0-9]+)") | 1422 rxp = re.compile(".git@(?P<revision>[a-fA-F0-9]+)") |
| 1389 | 1423 |
| 1390 for d in DEPOT_NAMES: | 1424 for d in DEPOT_NAMES: |
| 1391 if DEPOT_DEPS_NAME[d].has_key('platform'): | 1425 if DEPOT_DEPS_NAME[d].has_key('platform'): |
| 1392 if DEPOT_DEPS_NAME[d]['platform'] != os.name: | 1426 if DEPOT_DEPS_NAME[d]['platform'] != os.name: |
| 1393 continue | 1427 continue |
| 1394 | 1428 |
| 1395 if (DEPOT_DEPS_NAME[d]['recurse'] and | 1429 if (DEPOT_DEPS_NAME[d]['recurse'] and |
| 1396 depot in DEPOT_DEPS_NAME[d]['from']): | 1430 depot in DEPOT_DEPS_NAME[d]['from']): |
| 1397 if (locals['deps'].has_key(DEPOT_DEPS_NAME[d]['src']) or | 1431 if (locals.has_key(DEPOT_DEPS_NAME[d]['src']) or |
| 1398 locals['deps'].has_key(DEPOT_DEPS_NAME[d]['src_old'])): | 1432 locals.has_key(DEPOT_DEPS_NAME[d]['src_old'])): |
| 1399 if locals['deps'].has_key(DEPOT_DEPS_NAME[d]['src']): | 1433 if locals.has_key(DEPOT_DEPS_NAME[d]['src']): |
| 1400 re_results = rxp.search(locals['deps'][DEPOT_DEPS_NAME[d]['src']]) | 1434 re_results = rxp.search(locals[DEPOT_DEPS_NAME[d]['src']]) |
| 1401 self.depot_cwd[d] = \ | 1435 self.depot_cwd[d] = \ |
| 1402 os.path.join(self.src_cwd, DEPOT_DEPS_NAME[d]['src'][4:]) | 1436 os.path.join(self.src_cwd, DEPOT_DEPS_NAME[d]['src'][4:]) |
| 1403 elif locals['deps'].has_key(DEPOT_DEPS_NAME[d]['src_old']): | 1437 elif (DEPOT_DEPS_NAME[d].has_key('src_old') and |
| 1438 locals.has_key(DEPOT_DEPS_NAME[d]['src_old'])): | |
| 1404 re_results = \ | 1439 re_results = \ |
| 1405 rxp.search(locals['deps'][DEPOT_DEPS_NAME[d]['src_old']]) | 1440 rxp.search(locals[DEPOT_DEPS_NAME[d]['src_old']]) |
| 1406 self.depot_cwd[d] = \ | 1441 self.depot_cwd[d] = \ |
| 1407 os.path.join(self.src_cwd, DEPOT_DEPS_NAME[d]['src_old'][4:]) | 1442 os.path.join(self.src_cwd, DEPOT_DEPS_NAME[d]['src_old'][4:]) |
| 1408 | 1443 |
| 1409 if re_results: | 1444 if re_results: |
| 1410 results[d] = re_results.group('revision') | 1445 results[d] = re_results.group('revision') |
| 1411 else: | 1446 else: |
| 1412 print 'Couldn\'t parse revision for %s.' % d | 1447 warning_text = ('Couldn\'t parse revision for %s while bisecting ' |
| 1413 print | 1448 '%s' % (d, depot)) |
| 1414 return None | 1449 if not warningText in self.warnings: |
| 1450 self.warnings.append(warningText) | |
| 1415 else: | 1451 else: |
| 1416 print 'Couldn\'t find %s while parsing .DEPS.git.' % d | 1452 print 'Couldn\'t find %s while parsing .DEPS.git.' % d |
| 1417 print | 1453 print |
| 1418 return None | 1454 return None |
| 1455 return results | |
| 1456 except ImportError: | |
| 1457 return self._ParseRevisionsFromDEPSFileManually(depot) | |
| 1458 | |
| 1459 def Get3rdPartyRevisionsFromCurrentRevision(self, depot, revision): | |
| 1460 """Parses the DEPS file to determine WebKit/v8/etc... versions. | |
| 1461 | |
| 1462 Returns: | |
| 1463 A dict in the format {depot:revision} if successful, otherwise None. | |
| 1464 """ | |
| 1465 cwd = os.getcwd() | |
| 1466 self.ChangeToDepotWorkingDirectory(depot) | |
| 1467 | |
| 1468 results = {} | |
| 1469 | |
| 1470 if depot == 'chromium' or depot == 'android-chrome': | |
| 1471 results = self._ParseRevisionsFromDEPSFile(depot) | |
| 1472 os.chdir(cwd) | |
| 1419 elif depot == 'cros': | 1473 elif depot == 'cros': |
| 1420 cmd = [CROS_SDK_PATH, '--', 'portageq-%s' % self.opts.cros_board, | 1474 cmd = [CROS_SDK_PATH, '--', 'portageq-%s' % self.opts.cros_board, |
| 1421 'best_visible', '/build/%s' % self.opts.cros_board, 'ebuild', | 1475 'best_visible', '/build/%s' % self.opts.cros_board, 'ebuild', |
| 1422 CROS_CHROMEOS_PATTERN] | 1476 CROS_CHROMEOS_PATTERN] |
| 1423 (output, return_code) = RunProcessAndRetrieveOutput(cmd) | 1477 (output, return_code) = RunProcessAndRetrieveOutput(cmd) |
| 1424 | 1478 |
| 1425 assert not return_code, 'An error occurred while running' \ | 1479 assert not return_code, 'An error occurred while running' \ |
| 1426 ' "%s"' % ' '.join(cmd) | 1480 ' "%s"' % ' '.join(cmd) |
| 1427 | 1481 |
| 1428 if len(output) > CROS_CHROMEOS_PATTERN: | 1482 if len(output) > CROS_CHROMEOS_PATTERN: |
| (...skipping 2290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3719 # The perf dashboard scrapes the "results" step in order to comment on | 3773 # The perf dashboard scrapes the "results" step in order to comment on |
| 3720 # bugs. If you change this, please update the perf dashboard as well. | 3774 # bugs. If you change this, please update the perf dashboard as well. |
| 3721 bisect_utils.OutputAnnotationStepStart('Results') | 3775 bisect_utils.OutputAnnotationStepStart('Results') |
| 3722 print 'Error: %s' % e.message | 3776 print 'Error: %s' % e.message |
| 3723 if opts.output_buildbot_annotations: | 3777 if opts.output_buildbot_annotations: |
| 3724 bisect_utils.OutputAnnotationStepClosed() | 3778 bisect_utils.OutputAnnotationStepClosed() |
| 3725 return 1 | 3779 return 1 |
| 3726 | 3780 |
| 3727 if __name__ == '__main__': | 3781 if __name__ == '__main__': |
| 3728 sys.exit(main()) | 3782 sys.exit(main()) |
| OLD | NEW |