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 """Runs all the buildbot steps for ChromeDriver except for update/compile.""" | 6 """Runs all the buildbot steps for ChromeDriver except for update/compile.""" |
| 7 | 7 |
| 8 import bisect | 8 import bisect |
| 9 import csv | 9 import csv |
| 10 import datetime | 10 import datetime |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 util.Unzip(zip_path, chrome_paths.GetBuildDir(['host_forwarder'])) | 89 util.Unzip(zip_path, chrome_paths.GetBuildDir(['host_forwarder'])) |
| 90 | 90 |
| 91 | 91 |
| 92 def _GetTestResultsLog(platform): | 92 def _GetTestResultsLog(platform): |
| 93 """Gets the test results log for the given platform. | 93 """Gets the test results log for the given platform. |
| 94 | 94 |
| 95 Args: | 95 Args: |
| 96 platform: The platform that the test results log is for. | 96 platform: The platform that the test results log is for. |
| 97 | 97 |
| 98 Returns: | 98 Returns: |
| 99 A dictionary where the keys are SVN revisions and the values are booleans | 99 A dictionary where the keys are commit positions and the values are booleans |
| 100 indicating whether the tests passed. | 100 indicating whether the tests passed. |
| 101 """ | 101 """ |
| 102 temp_log = tempfile.mkstemp()[1] | 102 temp_log = tempfile.mkstemp()[1] |
| 103 log_name = TEST_LOG_FORMAT % platform | 103 log_name = TEST_LOG_FORMAT % platform |
| 104 result = slave_utils.GSUtilDownloadFile( | 104 result = slave_utils.GSUtilDownloadFile( |
| 105 '%s/%s' % (GS_CHROMEDRIVER_DATA_BUCKET, log_name), temp_log) | 105 '%s/%s' % (GS_CHROMEDRIVER_DATA_BUCKET, log_name), temp_log) |
| 106 if result: | 106 if result: |
| 107 return {} | 107 return {} |
| 108 with open(temp_log, 'rb') as log_file: | 108 with open(temp_log, 'rb') as log_file: |
| 109 json_dict = json.load(log_file) | 109 json_dict = json.load(log_file) |
| 110 # Workaround for json encoding dictionary keys as strings. | 110 # Workaround for json encoding dictionary keys as strings. |
| 111 return dict([(int(v[0]), v[1]) for v in json_dict.items()]) | 111 return dict([(int(v[0]), v[1]) for v in json_dict.items()]) |
| 112 | 112 |
| 113 | 113 |
| 114 def _PutTestResultsLog(platform, test_results_log): | 114 def _PutTestResultsLog(platform, test_results_log): |
| 115 """Pushes the given test results log to google storage.""" | 115 """Pushes the given test results log to google storage.""" |
| 116 temp_dir = util.MakeTempDir() | 116 temp_dir = util.MakeTempDir() |
| 117 log_name = TEST_LOG_FORMAT % platform | 117 log_name = TEST_LOG_FORMAT % platform |
| 118 log_path = os.path.join(temp_dir, log_name) | 118 log_path = os.path.join(temp_dir, log_name) |
| 119 with open(log_path, 'wb') as log_file: | 119 with open(log_path, 'wb') as log_file: |
| 120 json.dump(test_results_log, log_file) | 120 json.dump(test_results_log, log_file) |
| 121 if slave_utils.GSUtilCopyFile(log_path, GS_CHROMEDRIVER_DATA_BUCKET): | 121 if slave_utils.GSUtilCopyFile(log_path, GS_CHROMEDRIVER_DATA_BUCKET): |
| 122 raise Exception('Failed to upload test results log to google storage') | 122 raise Exception('Failed to upload test results log to google storage') |
| 123 | 123 |
| 124 | 124 |
| 125 def _UpdateTestResultsLog(platform, revision, passed): | 125 def _UpdateTestResultsLog(platform, revision, passed): |
|
stgao
2014/09/30 17:47:11
|revision| -> |commit_position|?
Please update oth
samuong
2014/09/30 18:07:07
Done.
| |
| 126 """Updates the test results log for the given platform. | 126 """Updates the test results log for the given platform. |
| 127 | 127 |
| 128 Args: | 128 Args: |
| 129 platform: The platform name. | 129 platform: The platform name. |
| 130 revision: The SVN revision number. | 130 revision: The commit position number. |
| 131 passed: Boolean indicating whether the tests passed at this revision. | 131 passed: Boolean indicating whether the tests passed at this revision. |
| 132 """ | 132 """ |
| 133 assert isinstance(revision, int), 'The revision must be an integer' | 133 |
| 134 assert revision.isdigit(), 'The commit position must be a number' | |
| 135 revision = int(revision) | |
| 134 log = _GetTestResultsLog(platform) | 136 log = _GetTestResultsLog(platform) |
| 135 if len(log) > 500: | 137 if len(log) > 500: |
| 136 del log[min(log.keys())] | 138 del log[min(log.keys())] |
| 137 assert revision not in log, 'Results already exist for revision %s' % revision | 139 assert revision not in log, 'Results already exist for revision %s' % revision |
| 138 log[revision] = bool(passed) | 140 log[revision] = bool(passed) |
| 139 _PutTestResultsLog(platform, log) | 141 _PutTestResultsLog(platform, log) |
| 140 | 142 |
| 141 | 143 |
| 142 def _GetVersion(): | 144 def _GetVersion(): |
| 143 """Get the current chromedriver version.""" | 145 """Get the current chromedriver version.""" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 157 lines = f.readlines() | 159 lines = f.readlines() |
| 158 chrome_min_version_line = [ | 160 chrome_min_version_line = [ |
| 159 x for x in lines if 'kMinimumSupportedChromeVersion' in x] | 161 x for x in lines if 'kMinimumSupportedChromeVersion' in x] |
| 160 chrome_min_version = chrome_min_version_line[0].split('{')[1].split(',')[0] | 162 chrome_min_version = chrome_min_version_line[0].split('{')[1].split(',')[0] |
| 161 with open(os.path.join(chrome_paths.GetSrc(), 'chrome', 'VERSION'), 'r') as f: | 163 with open(os.path.join(chrome_paths.GetSrc(), 'chrome', 'VERSION'), 'r') as f: |
| 162 chrome_max_version = f.readlines()[0].split('=')[1].strip() | 164 chrome_max_version = f.readlines()[0].split('=')[1].strip() |
| 163 return (chrome_min_version, chrome_max_version) | 165 return (chrome_min_version, chrome_max_version) |
| 164 | 166 |
| 165 | 167 |
| 166 def _RevisionState(test_results_log, revision): | 168 def _RevisionState(test_results_log, revision): |
| 167 """Check the state of tests at a given SVN revision. | 169 """Check the state of tests at a given commit position. |
| 168 | 170 |
| 169 Considers tests as having passed at a revision if they passed at revisons both | 171 Considers tests as having passed at a revision if they passed at revisons both |
| 170 before and after. | 172 before and after. |
| 171 | 173 |
| 172 Args: | 174 Args: |
| 173 test_results_log: A test results log dictionary from _GetTestResultsLog(). | 175 test_results_log: A test results log dictionary from _GetTestResultsLog(). |
| 174 revision: The revision to check at. | 176 revision: The revision to check at. |
| 175 | 177 |
| 176 Returns: | 178 Returns: |
| 177 'passed', 'failed', or 'unknown' | 179 'passed', 'failed', or 'unknown' |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 396 util.PrintAndFlush('URL Error %s' % error.message) | 398 util.PrintAndFlush('URL Error %s' % error.message) |
| 397 return None | 399 return None |
| 398 data = json.loads(response.read()[4:]) | 400 data = json.loads(response.read()[4:]) |
| 399 if 'message' in data: | 401 if 'message' in data: |
| 400 message = data['message'].split('\n') | 402 message = data['message'].split('\n') |
| 401 message = [line for line in message if line.strip()] | 403 message = [line for line in message if line.strip()] |
| 402 search_pattern = re.compile(GS_SEARCH_PATTERN) | 404 search_pattern = re.compile(GS_SEARCH_PATTERN) |
| 403 result = search_pattern.search(message[len(message)-1]) | 405 result = search_pattern.search(message[len(message)-1]) |
| 404 if result: | 406 if result: |
| 405 return result.group(1) | 407 return result.group(1) |
| 406 util.PrintAndFlush('Failed to get svn revision number for %s' % | 408 util.PrintAndFlush('Failed to get commit position number for %s' % |
| 407 snapshot_hashcode) | 409 snapshot_hashcode) |
| 408 return None | 410 return None |
| 409 | 411 |
| 410 | 412 |
| 411 def _GetGitHashFromCommitPosition(commit_position): | 413 def _GetGitHashFromCommitPosition(commit_position): |
| 412 json_url = CR_REV_URL % commit_position | 414 json_url = CR_REV_URL % commit_position |
| 413 try: | 415 try: |
| 414 response = urllib2.urlopen(json_url) | 416 response = urllib2.urlopen(json_url) |
| 415 except urllib2.HTTPError as error: | 417 except urllib2.HTTPError as error: |
| 416 util.PrintAndFlush('HTTP Error %d' % error.getcode()) | 418 util.PrintAndFlush('HTTP Error %d' % error.getcode()) |
| 417 return None | 419 return None |
| 418 except urllib2.URLError as error: | 420 except urllib2.URLError as error: |
| 419 util.PrintAndFlush('URL Error %s' % error.message) | 421 util.PrintAndFlush('URL Error %s' % error.message) |
| 420 return None | 422 return None |
| 421 data = json.loads(response.read()) | 423 data = json.loads(response.read()) |
| 422 if 'git_sha' in data: | 424 if 'git_sha' in data: |
| 423 return data['git_sha'] | 425 return data['git_sha'] |
| 424 util.PrintAndFlush('Failed to get git hash for %s' % commit_position) | 426 util.PrintAndFlush('Failed to get git hash for %s' % commit_position) |
| 425 return None | 427 return None |
| 426 | 428 |
| 427 | 429 |
| 428 def _WaitForLatestSnapshot(revision): | 430 def _WaitForLatestSnapshot(revision): |
| 429 util.MarkBuildStepStart('wait_for_snapshot') | 431 util.MarkBuildStepStart('wait_for_snapshot') |
| 430 def _IsRevisionNumber(revision): | |
| 431 if isinstance(revision, int): | |
| 432 return True | |
| 433 else: | |
| 434 return revision.isdigit() | |
| 435 while True: | 432 while True: |
| 436 snapshot_revision = archive.GetLatestSnapshotVersion() | 433 snapshot_revision = archive.GetLatestSnapshotVersion() |
|
stgao
2014/09/30 17:47:11
Is this one always the commit position now?
Last t
samuong
2014/09/30 18:07:07
Looks like a commit position to me:
http://build.
| |
| 437 if not _IsRevisionNumber(snapshot_revision): | |
| 438 snapshot_revision = _GetCommitPositionFromGitHash(snapshot_revision) | |
| 439 if revision is not None and snapshot_revision is not None: | 434 if revision is not None and snapshot_revision is not None: |
| 440 if int(snapshot_revision) >= int(revision): | 435 if int(snapshot_revision) >= int(revision): |
| 441 break | 436 break |
| 442 util.PrintAndFlush('Waiting for snapshot >= %s, found %s' % | 437 util.PrintAndFlush('Waiting for snapshot >= %s, found %s' % |
| 443 (revision, snapshot_revision)) | 438 (revision, snapshot_revision)) |
| 444 time.sleep(60) | 439 time.sleep(60) |
| 445 util.PrintAndFlush('Got snapshot revision %s' % snapshot_revision) | 440 util.PrintAndFlush('Got snapshot revision %s' % snapshot_revision) |
| 446 | 441 |
| 447 | 442 |
| 448 def _AddToolsToPath(platform_name): | 443 def _AddToolsToPath(platform_name): |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 474 os.environ['PATH'] += os.pathsep + os.pathsep.join(paths) | 469 os.environ['PATH'] += os.pathsep + os.pathsep.join(paths) |
| 475 | 470 |
| 476 | 471 |
| 477 def main(): | 472 def main(): |
| 478 parser = optparse.OptionParser() | 473 parser = optparse.OptionParser() |
| 479 parser.add_option( | 474 parser.add_option( |
| 480 '', '--android-packages', | 475 '', '--android-packages', |
| 481 help=('Comma separated list of application package names, ' | 476 help=('Comma separated list of application package names, ' |
| 482 'if running tests on Android.')) | 477 'if running tests on Android.')) |
| 483 parser.add_option( | 478 parser.add_option( |
| 484 '-r', '--revision', help='Chromium revision') | 479 '-r', '--revision', help='Chromium git revision hash') |
| 485 parser.add_option( | 480 parser.add_option( |
| 486 '', '--update-log', action='store_true', | 481 '', '--update-log', action='store_true', |
| 487 help='Update the test results log (only applicable to Android)') | 482 help='Update the test results log (only applicable to Android)') |
| 488 options, _ = parser.parse_args() | 483 options, _ = parser.parse_args() |
| 489 | 484 |
| 490 bitness = '32' | 485 bitness = '32' |
| 491 if util.IsLinux() and platform_module.architecture()[0] == '64bit': | 486 if util.IsLinux() and platform_module.architecture()[0] == '64bit': |
| 492 bitness = '64' | 487 bitness = '64' |
| 493 platform = '%s%s' % (util.GetPlatformName(), bitness) | 488 platform = '%s%s' % (util.GetPlatformName(), bitness) |
| 494 if options.android_packages: | 489 if options.android_packages: |
| 495 platform = 'android' | 490 platform = 'android' |
| 496 | 491 |
| 497 _CleanTmpDir() | 492 _CleanTmpDir() |
| 498 | 493 |
| 499 if not options.revision: | 494 if not options.revision: |
| 500 commit_position = None | 495 commit_position = None |
| 501 elif options.revision.isdigit(): | |
| 502 commit_position = options.revision | |
| 503 else: | 496 else: |
| 504 commit_position = _GetCommitPositionFromGitHash(options.revision) | 497 commit_position = _GetCommitPositionFromGitHash(options.revision) |
| 505 | 498 |
| 506 if platform == 'android': | 499 if platform == 'android': |
| 507 if not options.revision and options.update_log: | 500 if not options.revision and options.update_log: |
| 508 parser.error('Must supply a --revision with --update-log') | 501 parser.error('Must supply a --revision with --update-log') |
| 509 _DownloadPrebuilts() | 502 _DownloadPrebuilts() |
| 510 else: | 503 else: |
| 511 if not options.revision: | 504 if not options.revision: |
| 512 parser.error('Must supply a --revision') | 505 parser.error('Must supply a --revision') |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 541 util.MarkBuildStepStart('run_all_tests.py') | 534 util.MarkBuildStepStart('run_all_tests.py') |
| 542 util.MarkBuildStepError() | 535 util.MarkBuildStepError() |
| 543 | 536 |
| 544 # Add a "cleanup" step so that errors from runtest.py or bb_device_steps.py | 537 # Add a "cleanup" step so that errors from runtest.py or bb_device_steps.py |
| 545 # (which invoke this script) are kept in thier own build step. | 538 # (which invoke this script) are kept in thier own build step. |
| 546 util.MarkBuildStepStart('cleanup') | 539 util.MarkBuildStepStart('cleanup') |
| 547 | 540 |
| 548 | 541 |
| 549 if __name__ == '__main__': | 542 if __name__ == '__main__': |
| 550 main() | 543 main() |
| OLD | NEW |