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

Side by Side Diff: chrome/test/chromedriver/run_buildbot_steps.py

Issue 615563003: [chromedriver] Fix git migration issue and remove svn support from run_buildbot_steps.py (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Change "revision" to "commit_position" Created 6 years, 2 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 sys.path.append(SCRIPT_DIR) 45 sys.path.append(SCRIPT_DIR)
46 sys.path.append(SITE_CONFIG_DIR) 46 sys.path.append(SITE_CONFIG_DIR)
47 47
48 import archive 48 import archive
49 import chrome_paths 49 import chrome_paths
50 from slave import gsutil_download 50 from slave import gsutil_download
51 from slave import slave_utils 51 from slave import slave_utils
52 import util 52 import util
53 53
54 54
55 def _ArchivePrebuilts(revision): 55 def _ArchivePrebuilts(commit_position):
56 """Uploads the prebuilts to google storage.""" 56 """Uploads the prebuilts to google storage."""
57 util.MarkBuildStepStart('archive prebuilts') 57 util.MarkBuildStepStart('archive prebuilts')
58 zip_path = util.Zip(os.path.join(chrome_paths.GetBuildDir(['chromedriver']), 58 zip_path = util.Zip(os.path.join(chrome_paths.GetBuildDir(['chromedriver']),
59 'chromedriver')) 59 'chromedriver'))
60 if slave_utils.GSUtilCopy( 60 if slave_utils.GSUtilCopy(
61 zip_path, 61 zip_path,
62 '%s/%s' % (GS_PREBUILTS_URL, 'r%s.zip' % revision)): 62 '%s/%s' % (GS_PREBUILTS_URL, 'r%s.zip' % commit_position)):
63 util.MarkBuildStepError() 63 util.MarkBuildStepError()
64 64
65 65
66 def _ArchiveServerLogs(): 66 def _ArchiveServerLogs():
67 """Uploads chromedriver server logs to google storage.""" 67 """Uploads chromedriver server logs to google storage."""
68 util.MarkBuildStepStart('archive chromedriver server logs') 68 util.MarkBuildStepStart('archive chromedriver server logs')
69 for server_log in glob.glob(os.path.join(tempfile.gettempdir(), 69 for server_log in glob.glob(os.path.join(tempfile.gettempdir(),
70 'chromedriver_*')): 70 'chromedriver_*')):
71 base_name = os.path.basename(server_log) 71 base_name = os.path.basename(server_log)
72 util.AddLink(base_name, '%s/%s' % (SERVER_LOGS_LINK, base_name)) 72 util.AddLink(base_name, '%s/%s' % (SERVER_LOGS_LINK, base_name))
(...skipping 16 matching lines...) Expand all
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, commit_position, passed):
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 commit_position: 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 commit position.
132 """ 132 """
133 assert isinstance(revision, int), 'The revision must be an integer' 133
134 assert commit_position.isdigit(), 'The commit position must be a number'
135 commit_position = int(commit_position)
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 commit_position not in log, \
138 log[revision] = bool(passed) 140 'Results already exist for commit position %s' % commit_position
141 log[commit_position] = bool(passed)
139 _PutTestResultsLog(platform, log) 142 _PutTestResultsLog(platform, log)
140 143
141 144
142 def _GetVersion(): 145 def _GetVersion():
143 """Get the current chromedriver version.""" 146 """Get the current chromedriver version."""
144 with open(os.path.join(_THIS_DIR, 'VERSION'), 'r') as f: 147 with open(os.path.join(_THIS_DIR, 'VERSION'), 'r') as f:
145 return f.read().strip() 148 return f.read().strip()
146 149
147 150
148 def _GetSupportedChromeVersions(): 151 def _GetSupportedChromeVersions():
149 """Get the minimum and maximum supported Chrome versions. 152 """Get the minimum and maximum supported Chrome versions.
150 153
151 Returns: 154 Returns:
152 A tuple of the form (min_version, max_version). 155 A tuple of the form (min_version, max_version).
153 """ 156 """
154 # Minimum supported Chrome version is embedded as: 157 # Minimum supported Chrome version is embedded as:
155 # const int kMinimumSupportedChromeVersion[] = {27, 0, 1453, 0}; 158 # const int kMinimumSupportedChromeVersion[] = {27, 0, 1453, 0};
156 with open(os.path.join(_THIS_DIR, 'chrome', 'version.cc'), 'r') as f: 159 with open(os.path.join(_THIS_DIR, 'chrome', 'version.cc'), 'r') as f:
157 lines = f.readlines() 160 lines = f.readlines()
158 chrome_min_version_line = [ 161 chrome_min_version_line = [
159 x for x in lines if 'kMinimumSupportedChromeVersion' in x] 162 x for x in lines if 'kMinimumSupportedChromeVersion' in x]
160 chrome_min_version = chrome_min_version_line[0].split('{')[1].split(',')[0] 163 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: 164 with open(os.path.join(chrome_paths.GetSrc(), 'chrome', 'VERSION'), 'r') as f:
162 chrome_max_version = f.readlines()[0].split('=')[1].strip() 165 chrome_max_version = f.readlines()[0].split('=')[1].strip()
163 return (chrome_min_version, chrome_max_version) 166 return (chrome_min_version, chrome_max_version)
164 167
165 168
166 def _RevisionState(test_results_log, revision): 169 def _CommitPositionState(test_results_log, commit_position):
167 """Check the state of tests at a given SVN revision. 170 """Check the state of tests at a given commit position.
168 171
169 Considers tests as having passed at a revision if they passed at revisons both 172 Considers tests as having passed at a commit position if they passed at
170 before and after. 173 revisons both before and after.
171 174
172 Args: 175 Args:
173 test_results_log: A test results log dictionary from _GetTestResultsLog(). 176 test_results_log: A test results log dictionary from _GetTestResultsLog().
174 revision: The revision to check at. 177 commit_position: The commit position to check at.
175 178
176 Returns: 179 Returns:
177 'passed', 'failed', or 'unknown' 180 'passed', 'failed', or 'unknown'
178 """ 181 """
179 assert isinstance(revision, int), 'The revision must be an integer' 182 assert isinstance(commit_position, int), 'The commit position must be an int'
180 keys = sorted(test_results_log.keys()) 183 keys = sorted(test_results_log.keys())
181 # Return passed if the exact revision passed on Android. 184 # Return passed if the exact commit position passed on Android.
182 if revision in test_results_log: 185 if commit_position in test_results_log:
183 return 'passed' if test_results_log[revision] else 'failed' 186 return 'passed' if test_results_log[commit_position] else 'failed'
184 # Tests were not run on this exact revision on Android. 187 # Tests were not run on this exact commit position on Android.
185 index = bisect.bisect_right(keys, revision) 188 index = bisect.bisect_right(keys, commit_position)
186 # Tests have not yet run on Android at or above this revision. 189 # Tests have not yet run on Android at or above this commit position.
187 if index == len(test_results_log): 190 if index == len(test_results_log):
188 return 'unknown' 191 return 'unknown'
189 # No log exists for any prior revision, assume it failed. 192 # No log exists for any prior commit position, assume it failed.
190 if index == 0: 193 if index == 0:
191 return 'failed' 194 return 'failed'
192 # Return passed if the revisions on both sides passed. 195 # Return passed if the commit position on both sides passed.
193 if test_results_log[keys[index]] and test_results_log[keys[index - 1]]: 196 if test_results_log[keys[index]] and test_results_log[keys[index - 1]]:
194 return 'passed' 197 return 'passed'
195 return 'failed' 198 return 'failed'
196 199
197 200
198 def _ArchiveGoodBuild(platform, revision): 201 def _ArchiveGoodBuild(platform, commit_position):
199 """Archive chromedriver binary if the build is green.""" 202 """Archive chromedriver binary if the build is green."""
200 assert platform != 'android' 203 assert platform != 'android'
201 util.MarkBuildStepStart('archive build') 204 util.MarkBuildStepStart('archive build')
202 205
203 server_name = 'chromedriver' 206 server_name = 'chromedriver'
204 if util.IsWindows(): 207 if util.IsWindows():
205 server_name += '.exe' 208 server_name += '.exe'
206 zip_path = util.Zip(os.path.join(chrome_paths.GetBuildDir([server_name]), 209 zip_path = util.Zip(os.path.join(chrome_paths.GetBuildDir([server_name]),
207 server_name)) 210 server_name))
208 211
209 build_name = 'chromedriver_%s_%s.%s.zip' % ( 212 build_name = 'chromedriver_%s_%s.%s.zip' % (
210 platform, _GetVersion(), revision) 213 platform, _GetVersion(), commit_position)
211 build_url = '%s/%s' % (GS_CONTINUOUS_URL, build_name) 214 build_url = '%s/%s' % (GS_CONTINUOUS_URL, build_name)
212 if slave_utils.GSUtilCopy(zip_path, build_url): 215 if slave_utils.GSUtilCopy(zip_path, build_url):
213 util.MarkBuildStepError() 216 util.MarkBuildStepError()
214 217
215 (latest_fd, latest_file) = tempfile.mkstemp() 218 (latest_fd, latest_file) = tempfile.mkstemp()
216 os.write(latest_fd, build_name) 219 os.write(latest_fd, build_name)
217 os.close(latest_fd) 220 os.close(latest_fd)
218 latest_url = '%s/latest_%s' % (GS_CONTINUOUS_URL, platform) 221 latest_url = '%s/latest_%s' % (GS_CONTINUOUS_URL, platform)
219 if slave_utils.GSUtilCopy(latest_file, latest_url, mimetype='text/plain'): 222 if slave_utils.GSUtilCopy(latest_file, latest_url, mimetype='text/plain'):
220 util.MarkBuildStepError() 223 util.MarkBuildStepError()
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 result = candidate_pattern.match(line) 258 result = candidate_pattern.match(line)
256 if not result: 259 if not result:
257 print 'Ignored line "%s"' % line 260 print 'Ignored line "%s"' % line
258 continue 261 continue
259 candidates.append(int(result.group(1))) 262 candidates.append(int(result.group(1)))
260 263
261 # Release the latest candidate build that passed Android, if any. 264 # Release the latest candidate build that passed Android, if any.
262 # In this way, if a hot fix is needed, we can delete the release from 265 # In this way, if a hot fix is needed, we can delete the release from
263 # the chromedriver bucket instead of bumping up the release version number. 266 # the chromedriver bucket instead of bumping up the release version number.
264 candidates.sort(reverse=True) 267 candidates.sort(reverse=True)
265 for revision in candidates: 268 for commit_position in candidates:
266 android_result = _RevisionState(android_test_results, revision) 269 android_result = _CommitPositionState(android_test_results, commit_position)
267 if android_result == 'failed': 270 if android_result == 'failed':
268 print 'Android tests did not pass at revision', revision 271 print 'Android tests did not pass at commit position', commit_position
269 elif android_result == 'passed': 272 elif android_result == 'passed':
270 print 'Android tests passed at revision', revision 273 print 'Android tests passed at commit position', commit_position
271 candidate = 'chromedriver_%s_%s.%s.zip' % (platform, version, revision) 274 candidate = 'chromedriver_%s_%s.%s.zip' % (
275 platform, version, commit_position)
272 _Release('%s/%s' % (GS_CONTINUOUS_URL, candidate), version, platform) 276 _Release('%s/%s' % (GS_CONTINUOUS_URL, candidate), version, platform)
273 break 277 break
274 else: 278 else:
275 print 'Android tests have not run at a revision as recent as', revision 279 print 'Android tests have not run at a commit position as recent as', \
280 commit_position
276 281
277 282
278 def _Release(build, version, platform): 283 def _Release(build, version, platform):
279 """Releases the given candidate build.""" 284 """Releases the given candidate build."""
280 release_name = 'chromedriver_%s.zip' % platform 285 release_name = 'chromedriver_%s.zip' % platform
281 util.MarkBuildStepStart('releasing %s' % release_name) 286 util.MarkBuildStepStart('releasing %s' % release_name)
282 temp_dir = util.MakeTempDir() 287 temp_dir = util.MakeTempDir()
283 slave_utils.GSUtilCopy(build, temp_dir) 288 slave_utils.GSUtilCopy(build, temp_dir)
284 zip_path = os.path.join(temp_dir, os.path.basename(build)) 289 zip_path = os.path.join(temp_dir, os.path.basename(build))
285 290
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 util.PrintAndFlush('URL Error %s' % error.message) 401 util.PrintAndFlush('URL Error %s' % error.message)
397 return None 402 return None
398 data = json.loads(response.read()[4:]) 403 data = json.loads(response.read()[4:])
399 if 'message' in data: 404 if 'message' in data:
400 message = data['message'].split('\n') 405 message = data['message'].split('\n')
401 message = [line for line in message if line.strip()] 406 message = [line for line in message if line.strip()]
402 search_pattern = re.compile(GS_SEARCH_PATTERN) 407 search_pattern = re.compile(GS_SEARCH_PATTERN)
403 result = search_pattern.search(message[len(message)-1]) 408 result = search_pattern.search(message[len(message)-1])
404 if result: 409 if result:
405 return result.group(1) 410 return result.group(1)
406 util.PrintAndFlush('Failed to get svn revision number for %s' % 411 util.PrintAndFlush('Failed to get commit position number for %s' %
407 snapshot_hashcode) 412 snapshot_hashcode)
408 return None 413 return None
409 414
410 415
411 def _GetGitHashFromCommitPosition(commit_position): 416 def _GetGitHashFromCommitPosition(commit_position):
412 json_url = CR_REV_URL % commit_position 417 json_url = CR_REV_URL % commit_position
413 try: 418 try:
414 response = urllib2.urlopen(json_url) 419 response = urllib2.urlopen(json_url)
415 except urllib2.HTTPError as error: 420 except urllib2.HTTPError as error:
416 util.PrintAndFlush('HTTP Error %d' % error.getcode()) 421 util.PrintAndFlush('HTTP Error %d' % error.getcode())
417 return None 422 return None
418 except urllib2.URLError as error: 423 except urllib2.URLError as error:
419 util.PrintAndFlush('URL Error %s' % error.message) 424 util.PrintAndFlush('URL Error %s' % error.message)
420 return None 425 return None
421 data = json.loads(response.read()) 426 data = json.loads(response.read())
422 if 'git_sha' in data: 427 if 'git_sha' in data:
423 return data['git_sha'] 428 return data['git_sha']
424 util.PrintAndFlush('Failed to get git hash for %s' % commit_position) 429 util.PrintAndFlush('Failed to get git hash for %s' % commit_position)
425 return None 430 return None
426 431
427 432
428 def _WaitForLatestSnapshot(revision): 433 def _WaitForLatestSnapshot(commit_position):
429 util.MarkBuildStepStart('wait_for_snapshot') 434 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: 435 while True:
436 snapshot_revision = archive.GetLatestSnapshotVersion() 436 snapshot_position = archive.GetLatestSnapshotVersion()
437 if not _IsRevisionNumber(snapshot_revision): 437 if commit_position is not None and snapshot_position is not None:
438 snapshot_revision = _GetCommitPositionFromGitHash(snapshot_revision) 438 if int(snapshot_position) >= int(commit_position):
439 if revision is not None and snapshot_revision is not None:
440 if int(snapshot_revision) >= int(revision):
441 break 439 break
442 util.PrintAndFlush('Waiting for snapshot >= %s, found %s' % 440 util.PrintAndFlush('Waiting for snapshot >= %s, found %s' %
443 (revision, snapshot_revision)) 441 (commit_position, snapshot_position))
444 time.sleep(60) 442 time.sleep(60)
445 util.PrintAndFlush('Got snapshot revision %s' % snapshot_revision) 443 util.PrintAndFlush('Got snapshot commit position %s' % snapshot_position)
446 444
447 445
448 def _AddToolsToPath(platform_name): 446 def _AddToolsToPath(platform_name):
449 """Add some tools like Ant and Java to PATH for testing steps to use.""" 447 """Add some tools like Ant and Java to PATH for testing steps to use."""
450 paths = [] 448 paths = []
451 error_message = '' 449 error_message = ''
452 if platform_name == 'win32': 450 if platform_name == 'win32':
453 paths = [ 451 paths = [
454 # Path to Ant and Java, required for the java acceptance tests. 452 # Path to Ant and Java, required for the java acceptance tests.
455 'C:\\Program Files (x86)\\Java\\ant\\bin', 453 'C:\\Program Files (x86)\\Java\\ant\\bin',
(...skipping 18 matching lines...) Expand all
474 os.environ['PATH'] += os.pathsep + os.pathsep.join(paths) 472 os.environ['PATH'] += os.pathsep + os.pathsep.join(paths)
475 473
476 474
477 def main(): 475 def main():
478 parser = optparse.OptionParser() 476 parser = optparse.OptionParser()
479 parser.add_option( 477 parser.add_option(
480 '', '--android-packages', 478 '', '--android-packages',
481 help=('Comma separated list of application package names, ' 479 help=('Comma separated list of application package names, '
482 'if running tests on Android.')) 480 'if running tests on Android.'))
483 parser.add_option( 481 parser.add_option(
484 '-r', '--revision', help='Chromium revision') 482 '-r', '--revision', help='Chromium git revision hash')
485 parser.add_option( 483 parser.add_option(
486 '', '--update-log', action='store_true', 484 '', '--update-log', action='store_true',
487 help='Update the test results log (only applicable to Android)') 485 help='Update the test results log (only applicable to Android)')
488 options, _ = parser.parse_args() 486 options, _ = parser.parse_args()
489 487
490 bitness = '32' 488 bitness = '32'
491 if util.IsLinux() and platform_module.architecture()[0] == '64bit': 489 if util.IsLinux() and platform_module.architecture()[0] == '64bit':
492 bitness = '64' 490 bitness = '64'
493 platform = '%s%s' % (util.GetPlatformName(), bitness) 491 platform = '%s%s' % (util.GetPlatformName(), bitness)
494 if options.android_packages: 492 if options.android_packages:
495 platform = 'android' 493 platform = 'android'
496 494
497 _CleanTmpDir() 495 _CleanTmpDir()
498 496
499 if not options.revision: 497 if not options.revision:
500 commit_position = None 498 commit_position = None
501 elif options.revision.isdigit():
502 commit_position = options.revision
503 else: 499 else:
504 commit_position = _GetCommitPositionFromGitHash(options.revision) 500 commit_position = _GetCommitPositionFromGitHash(options.revision)
505 501
506 if platform == 'android': 502 if platform == 'android':
507 if not options.revision and options.update_log: 503 if not options.revision and options.update_log:
508 parser.error('Must supply a --revision with --update-log') 504 parser.error('Must supply a --revision with --update-log')
509 _DownloadPrebuilts() 505 _DownloadPrebuilts()
510 else: 506 else:
511 if not options.revision: 507 if not options.revision:
512 parser.error('Must supply a --revision') 508 parser.error('Must supply a --revision')
(...skipping 28 matching lines...) Expand all
541 util.MarkBuildStepStart('run_all_tests.py') 537 util.MarkBuildStepStart('run_all_tests.py')
542 util.MarkBuildStepError() 538 util.MarkBuildStepError()
543 539
544 # Add a "cleanup" step so that errors from runtest.py or bb_device_steps.py 540 # 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. 541 # (which invoke this script) are kept in thier own build step.
546 util.MarkBuildStepStart('cleanup') 542 util.MarkBuildStepStart('cleanup')
547 543
548 544
549 if __name__ == '__main__': 545 if __name__ == '__main__':
550 main() 546 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698