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

Side by Side Diff: tools/dartium/buildbot_annotated_steps.py

Issue 270663007: Refactor a copy of dartium/buildbot_annotated_steps.py (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: More renaming and moving code. Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2014 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be 4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file. 5 # found in the LICENSE file.
6 6
7 """Chromium buildbot steps 7 """Dartium buildbot steps
8 8
9 Run the Dart layout tests. 9 Archive dartium, content_shell, and chromedriver to the cloud storage bucket
10 gs://dart-archive, and run tests, including the Dart layout tests.
10 """ 11 """
11 12
13 import imp
12 import os 14 import os
13 import platform 15 import platform
14 import re 16 import re
15 import shutil 17 import shutil
16 import socket
17 import subprocess 18 import subprocess
18 import sys 19 import sys
19 import imp
20 20
21 BUILDER_NAME = 'BUILDBOT_BUILDERNAME' 21 import upload_steps
22 REVISION = 'BUILDBOT_REVISION'
23 BUILDER_PATTERN = (r'^dartium-(mac|lucid64|lucid32|win)'
24 r'-(full|inc|debug)(-ninja)?(-(be|dev|stable|integration))?$' )
25
26 if platform.system() == 'Windows':
27 GSUTIL = 'e:/b/build/scripts/slave/gsutil.bat'
28 else:
29 GSUTIL = '/b/build/scripts/slave/gsutil'
30 ACL = 'public-read'
31 GS_SITE = 'gs://'
32 GS_URL = 'https://sandbox.google.com/storage/'
33 GS_DIR = 'dartium-archive'
34 LATEST = 'latest'
35 CONTINUOUS = 'continuous'
36
37 REVISION_FILE = 'chrome/browser/ui/webui/dartvm_revision.h'
38
39 # Add dartium tools and build/util to python path.
40 SRC_PATH = os.path.dirname(os.path.dirname(
41 os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
42 DART_PATH = os.path.join(SRC_PATH, 'dart')
43 TOOLS_PATH = os.path.join(DART_PATH, 'tools', 'dartium')
44 BUILD_UTIL_PATH = os.path.join(SRC_PATH, 'build', 'util')
45 # We limit testing on drt since it takes a long time to run
46 DRT_FILTER = 'html'
47
48
49 sys.path.extend([TOOLS_PATH, BUILD_UTIL_PATH])
50 import archive
51 import utils 22 import utils
52 23
53 bot_utils = imp.load_source('bot_utils', 24 SRC_PATH = os.path.dirname(
ricow1 2014/05/14 17:28:18 I think it makes sense to have the path at where w
Bill Hesse 2014/05/15 10:46:37 Done. Moved to utils and comment added.
54 os.path.join(DART_PATH, 'tools', 'bots', 'bot_utils.py')) 25 os.path.dirname(
26 os.path.dirname(
27 os.path.dirname(os.path.abspath(__file__)))))
28 DART_PATH = os.path.join(SRC_PATH, 'dart')
55 29
56 def DartArchiveFile(local_path, remote_path, create_md5sum=False): 30 # We limit testing on drt since it takes a long time to run.
57 # Copy it to the new unified gs://dart-archive bucket 31 DRT_FILTER = 'html'
ricow1 2014/05/14 17:28:18 I have been meaning to update that to the browser
58 # TODO(kustermann/ricow): Remove all the old archiving code, once everything
59 # points to the new location
60 gsutil = bot_utils.GSUtil()
61 gsutil.upload(local_path, remote_path, public=True)
62 if create_md5sum:
63 # 'local_path' may have a different filename than 'remote_path'. So we need
64 # to make sure the *.md5sum file contains the correct name.
65 assert '/' in remote_path and not remote_path.endswith('/')
66 mangled_filename = remote_path[remote_path.rfind('/') + 1:]
67 local_md5sum = bot_utils.CreateChecksumFile(local_path, mangled_filename)
68 gsutil.upload(local_md5sum, remote_path + '.md5sum', public=True)
69
70 def UploadDartiumVariant(revision, name, channel, arch, mode, zip_file):
71 name = name.replace('drt', 'content_shell')
72 system = sys.platform
73
74 namer = bot_utils.GCSNamer(channel, bot_utils.ReleaseType.RAW)
75 remote_path = namer.dartium_variant_zipfilepath(revision, name, system, arch,
76 mode)
77 DartArchiveFile(zip_file, remote_path, create_md5sum=True)
78 return remote_path
79
80 def ExecuteCommand(cmd):
81 """Execute a command in a subprocess.
82 """
83 print 'Executing: ' + ' '.join(cmd)
84 try:
85 pipe = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
86 (output, error) = pipe.communicate()
87 if pipe.returncode != 0:
88 print 'Execution failed: ' + str(error)
89 return (pipe.returncode, output)
90 except:
91 import traceback
92 print 'Execution raised exception:', traceback.format_exc()
93 return (-1, '')
94
95
96 # TODO: Instead of returning a tuple we should make a class with these fields.
97 def GetBuildInfo():
98 """Returns a tuple (name, dart_revision, version, mode, arch, channel,
99 is_full) where:
100 - name: A name for the build - the buildbot host if a buildbot.
101 - dart_revision: The dart revision.
102 - version: A version string corresponding to this build.
103 - mode: 'Debug' or 'Release'
104 - arch: target architecture
105 - channel: the channel this build is happening on
106 - is_full: True if this is a full build.
107 """
108 os.chdir(SRC_PATH)
109
110 name = None
111 version = None
112 mode = 'Release'
113
114 # Populate via builder environment variables.
115 name = os.environ[BUILDER_NAME]
116
117 # We need to chdir() to src/dart in order to get the correct revision number.
118 with utils.ChangedWorkingDirectory(DART_PATH):
119 dart_tools_utils = imp.load_source('dart_tools_utils',
120 os.path.join('tools', 'utils.py'))
121 dart_revision = dart_tools_utils.GetSVNRevision()
122
123 version = dart_revision + '.0'
124 is_incremental = '-inc' in name
125 is_win_ninja = 'win-inc-ninja' in name
126 is_full = False
127
128 pattern = re.match(BUILDER_PATTERN, name)
129 assert pattern
130 arch = 'x64' if pattern.group(1) == 'lucid64' else 'ia32'
131 if pattern.group(2) == 'debug':
132 mode = 'Debug'
133 is_full = pattern.group(2) == 'full'
134 channel = pattern.group(5)
135 if not channel:
136 channel = 'be'
137
138 # Fall back if not on builder.
139 if not name:
140 name = socket.gethostname().split('.')[0]
141
142 return (name, dart_revision, version, mode, arch, channel, is_full,
143 is_incremental, is_win_ninja)
144
145 32
146 def RunDartTests(mode, component, suite, arch, checked, test_filter=None, 33 def RunDartTests(mode, component, suite, arch, checked, test_filter=None,
147 is_win_ninja=False): 34 is_win_ninja=False):
148 """Runs the Dart WebKit Layout tests. 35 """Runs the Dart WebKit Layout tests.
149 """ 36 """
150 cmd = [sys.executable] 37 cmd = [sys.executable]
151 script = os.path.join(TOOLS_PATH, 'test.py') 38 script = os.path.join(DART_PATH, 'tools', 'dartium', 'test.py')
152 cmd.append(script) 39 cmd.append(script)
153 cmd.append('--buildbot') 40 cmd.append('--buildbot')
154 cmd.append('--mode=' + mode) 41 cmd.append('--mode=' + mode)
155 cmd.append('--component=' + component) 42 cmd.append('--component=' + component)
156 cmd.append('--suite=' + suite) 43 cmd.append('--suite=' + suite)
157 cmd.append('--arch=' + arch) 44 cmd.append('--arch=' + arch)
158 cmd.append('--' + checked) 45 cmd.append('--' + checked)
159 cmd.append('--no-show-results') 46 cmd.append('--no-show-results')
160 47
161 if is_win_ninja: 48 if is_win_ninja:
162 cmd.append('--win-ninja-build') 49 cmd.append('--win-ninja-build')
163 50
164 if test_filter: 51 if test_filter:
165 cmd.append('--test-filter=' + test_filter) 52 cmd.append('--test-filter=' + test_filter)
166 53
167 status = subprocess.call(cmd) 54 status = subprocess.call(cmd)
168 if status != 0: 55 if status != 0:
169 print '@@@STEP_FAILURE@@@' 56 print '@@@STEP_FAILURE@@@'
170 return status 57 return status
171 58
172 59
173 def UploadDartTestsResults(layout_test_results_dir, name, version, 60 def Test(info, component, suite, checked, test_filter=None):
174 component, checked): 61 """Test a particular component (e.g., dartium or content_shell(drt)).
175 """Uploads test results to google storage.
176 """ 62 """
177 print ('@@@BUILD_STEP archive %s_layout_%s_tests results@@@' % 63 print '@@@BUILD_STEP %s_%s_%s_tests@@@' % (component, suite, checked)
178 (component, checked)) 64 sys.stdout.flush()
179 dir_name = os.path.dirname(layout_test_results_dir) 65 layout_test_results_dir = os.path.join(SRC_PATH, 'webkit', info.mode,
180 base_name = os.path.basename(layout_test_results_dir) 66 'layout-test-results')
181 cwd = os.getcwd() 67 shutil.rmtree(layout_test_results_dir, ignore_errors=True)
182 os.chdir(dir_name) 68 status = RunDartTests(info.mode, component, suite, info.arch, checked,
183 69 test_filter=test_filter, is_win_ninja=info.is_win_ninja)
184 archive_name = 'layout_test_results.zip' 70 # Archive test failures
185 archive.ZipDir(archive_name, base_name) 71 if suite == 'layout' and status != 0:
186 72 upload_steps.UploadDartTestsResults(layout_test_results_dir,
187 target = '/'.join([GS_DIR, 'layout-test-results', name, component + '-' + 73 info.name,
188 checked + '-' + version + '.zip']) 74 info.version,
189 status = UploadArchive(os.path.abspath(archive_name), GS_SITE + target) 75 component, checked)
190 os.remove(archive_name)
191 if status == 0:
192 print ('@@@STEP_LINK@download@' + GS_URL + target + '@@@')
193 else:
194 print '@@@STEP_FAILURE@@@'
195 os.chdir(cwd)
196
197
198 def ListArchives(pattern):
199 """List the contents in Google storage matching the file pattern.
200 """
201 cmd = [GSUTIL, 'ls', pattern]
202 (status, output) = ExecuteCommand(cmd)
203 if status != 0:
204 return []
205 return output.split(os.linesep)
206
207
208 def RemoveArchives(archives):
209 """Remove the list of archives in Google storage.
210 """
211 for archive in archives:
212 if archive.find(GS_SITE) == 0:
213 cmd = [GSUTIL, 'rm', archive.rstrip()]
214 (status, _) = ExecuteCommand(cmd)
215 if status != 0:
216 return status
217 return 0
218
219
220 def UploadArchive(source, target):
221 """Upload an archive zip file to Google storage.
222 """
223
224 # Upload file.
225 cmd = [GSUTIL, 'cp', source, target]
226 (status, output) = ExecuteCommand(cmd)
227 if status != 0:
228 return status
229 print 'Uploaded: ' + output
230
231 # Set ACL.
232 if ACL is not None:
233 cmd = [GSUTIL, 'setacl', ACL, target]
234 (status, output) = ExecuteCommand(cmd)
235 return status 76 return status
236 77
237 78
238 def main(): 79 def main():
239 (dartium_bucket, dart_revision, version, mode, arch, channel, 80 # We need to chdir() to src/dart in order to get the correct revision number.
240 is_full, is_incremental, is_win_ninja) = GetBuildInfo() 81 with utils.ChangedWorkingDirectory(DART_PATH):
241 drt_bucket = dartium_bucket.replace('dartium', 'drt') 82 dart_tools_utils = imp.load_source('dart_tools_utils',
242 chromedriver_bucket = dartium_bucket.replace('dartium', 'chromedriver') 83 os.path.join('tools', 'utils.py'))
84 dart_revision = dart_tools_utils.GetSVNRevision()
243 85
244 def archiveAndUpload(archive_latest=False): 86 version = dart_revision + '.0'
245 print '@@@BUILD_STEP dartium_generate_archive@@@' 87 info = upload_steps.BuildInfo(version, dart_revision)
ricow1 2014/05/14 17:28:18 does that function belong somewhere else, the info
Bill Hesse 2014/05/15 10:46:37 I did have the class here, and in multivm-upload,
246 cwd = os.getcwd()
247 dartium_archive = dartium_bucket + '-' + version
248 drt_archive = drt_bucket + '-' + version
249 chromedriver_archive = chromedriver_bucket + '-' + version
250 dartium_zip, drt_zip, chromedriver_zip = \
251 archive.Archive(SRC_PATH, mode, dartium_archive,
252 drt_archive, chromedriver_archive,
253 is_win_ninja=is_win_ninja)
254 status = upload('dartium', dartium_bucket, os.path.abspath(dartium_zip),
255 archive_latest=archive_latest)
256 if status == 0:
257 status = upload('drt', drt_bucket, os.path.abspath(drt_zip),
258 archive_latest=archive_latest)
259 if status == 0:
260 status = upload('chromedriver', chromedriver_bucket,
261 os.path.abspath(chromedriver_zip),
262 archive_latest=archive_latest)
263 os.chdir(cwd)
264 if status != 0:
265 print '@@@STEP_FAILURE@@@'
266 return status
267
268 def upload(module, bucket, zip_file, archive_latest=False):
269 status = 0
270
271 # We archive to the new location on all builders except for -inc builders.
272 if not is_incremental:
273 print '@@@BUILD_STEP %s_upload_archive_new @@@' % module
274 # We archive the full builds to gs://dart-archive/
275 revision = 'latest' if archive_latest else dart_revision
276 remote_path = UploadDartiumVariant(revision, module, channel, arch,
277 mode.lower(), zip_file)
278 print '@@@STEP_LINK@download@' + remote_path + '@@@'
279
280 # We archive to the old locations only for bleeding_edge builders
281 if channel == 'be':
282 _, filename = os.path.split(zip_file)
283 if not archive_latest:
284 target = '/'.join([GS_DIR, bucket, filename])
285 print '@@@BUILD_STEP %s_upload_archive@@@' % module
286 status = UploadArchive(zip_file, GS_SITE + target)
287 print '@@@STEP_LINK@download@' + GS_URL + target + '@@@'
288 else:
289 print '@@@BUILD_STEP %s_upload_latest@@@' % module
290 # Clear latest for this build type.
291 old = '/'.join([GS_DIR, LATEST, bucket + '-*'])
292 old_archives = ListArchives(GS_SITE + old)
293
294 # Upload the new latest and remove unnecessary old ones.
295 target = GS_SITE + '/'.join([GS_DIR, LATEST, filename])
296 status = UploadArchive(zip_file, target)
297 if status == 0:
298 RemoveArchives(
299 [iarch for iarch in old_archives if iarch != target])
300 else:
301 print 'Upload failed'
302
303 # Upload unversioned name to continuous site for incremental
304 # builds.
305 if '-inc' in bucket:
306 continuous_name = bucket[:bucket.find('-inc')]
307 target = GS_SITE + '/'.join([GS_DIR, CONTINUOUS,
308 continuous_name + '.zip'])
309 status = UploadArchive(zip_file, target)
310
311 print ('@@@BUILD_STEP %s_upload_archive is over (status = %s)@@@' %
312 (module, status))
313
314 return status
315
316 def test(component, suite, checked, test_filter=None):
317 """Test a particular component (e.g., dartium or frog).
318 """
319 print '@@@BUILD_STEP %s_%s_%s_tests@@@' % (component, suite, checked)
320 sys.stdout.flush()
321 layout_test_results_dir = os.path.join(SRC_PATH, 'webkit', mode,
322 'layout-test-results')
323 shutil.rmtree(layout_test_results_dir, ignore_errors=True)
324 status = RunDartTests(mode, component, suite, arch, checked,
325 test_filter=test_filter, is_win_ninja=is_win_ninja)
326
327 if suite == 'layout' and status != 0:
328 UploadDartTestsResults(layout_test_results_dir, dartium_bucket, version,
329 component, checked)
330 return status
331 88
332 result = 0 89 result = 0
333 90
334 # Archive to the revision bucket unless integration build 91 # Archive to the revision bucket unless integration build
335 if channel != 'integration': 92 if info.channel != 'integration':
336 result = archiveAndUpload(archive_latest=False) 93 result = upload_steps.ArchiveAndUpload(info, archive_latest=False)
337
338 # On dev/stable we archive to the latest bucket as well 94 # On dev/stable we archive to the latest bucket as well
339 if channel != 'be': 95 if info.channel != 'be':
340 result = archiveAndUpload(archive_latest=True) or result 96 result = (upload_steps.ArchiveAndUpload(info, archive_latest=True)
97 or result)
341 98
342 # Run layout tests 99 # Run layout tests
343 if mode == 'Release' or platform.system() != 'Darwin': 100 if info.mode == 'Release' or platform.system() != 'Darwin':
344 result = test('drt', 'layout', 'unchecked') or result 101 result = Test(info, 'drt', 'layout', 'unchecked') or result
345 result = test('drt', 'layout', 'checked') or result 102 result = Test(info, 'drt', 'layout', 'checked') or result
346 103
347 # Run dartium tests 104 # Run dartium tests
348 result = test('dartium', 'core', 'unchecked') or result 105 result = Test(info, 'dartium', 'core', 'unchecked') or result
349 result = test('dartium', 'core', 'checked') or result 106 result = Test(info, 'dartium', 'core', 'checked') or result
350 107
351 # Run ContentShell tests 108 # Run ContentShell tests
352 # NOTE: We don't run ContentShell tests on dartium-*-inc builders to keep 109 # NOTE: We don't run ContentShell tests on dartium-*-inc builders to keep
353 # cycle times down. 110 # cycle times down.
354 if not is_incremental: 111 if not info.is_incremental:
355 # If we run all checked tests on dartium, we restrict the number of 112 # If we run all checked tests on dartium, we restrict the number of
356 # unchecked tests on drt to DRT_FILTER 113 # unchecked tests on drt to DRT_FILTER
357 result = test('drt', 'core', 'unchecked', test_filter=DRT_FILTER) or result 114 result = Test(info, 'drt', 'core', 'unchecked',
358 result = test('drt', 'core', 'checked') or result 115 test_filter=DRT_FILTER) or result
116 result = Test(info, 'drt', 'core', 'checked') or result
359 117
360 # On the 'be' channel, we only archive to the latest bucket if all tests ran 118 # On the 'be' channel, we only archive to the latest bucket if all tests were
361 # successfull. 119 # successful.
362 if result == 0 and channel == 'be': 120 if result == 0 and info.channel == 'be':
363 result = archiveAndUpload(archive_latest=True) or result 121 result = upload_steps.ArchiveAndUpload(info, archive_latest=True) or result
364 122
365 if __name__ == '__main__': 123 if __name__ == '__main__':
366 sys.exit(main()) 124 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698