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

Side by Side Diff: utils/compiler/buildbot.py

Issue 11236012: Add script for pub buildbots. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Respond to review. Created 8 years, 1 month 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
« tools/bots/pub.py ('K') | « tools/bots/pub.py ('k') | 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
(Empty)
1 #!/usr/bin/python
2
3 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style license that can be
5 # found in the LICENSE file.
6
7 """Dart2js buildbot steps
8
9 Runs tests for the dart2js compiler.
10 """
11
12 import platform
13 import optparse
14 import os
15 import re
16 import shutil
17 import subprocess
18 import sys
19
20 BUILDER_NAME = 'BUILDBOT_BUILDERNAME'
21 BUILDER_CLOBBER = 'BUILDBOT_CLOBBER'
22
23
24 DART_PATH = os.path.dirname(
25 os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
26
27 DART2JS_BUILDER = (
28 r'dart2js-(linux|mac|windows)(-(jsshell))?-(debug|release)(-(checked|host-ch ecked))?(-(host-checked))?-?(\d*)-?(\d*)')
29 WEB_BUILDER = (
30 r'dart2js-(ie9|ie10|ff|safari|chrome|opera)-(win7|win8|mac|linux)(-(all|html ))?')
31
32 NO_COLOR_ENV = dict(os.environ)
33 NO_COLOR_ENV['TERM'] = 'nocolor'
34
35 class BuildInfo(object):
36 """ Encapsulation of build information.
37 - compiler: 'dart2js' or None when the builder has an incorrect name
38 - runtime: 'd8', 'ie', 'ff', 'safari', 'chrome', 'opera'
39 - mode: 'debug' or 'release'
40 - system: 'linux', 'mac', or 'win7'
41 - checked: True if we should run in checked mode, otherwise False
42 - host_checked: True if we should run in host checked mode, otherwise False
43 - shard_index: The shard we are running, None when not specified.
44 - total_shards: The total number of shards, None when not specified.
45 - is_buildbot: True if we are on a buildbot (or emulating it).
46 - test_set: Specification of a non standard test set, default None
47 """
48 def __init__(self, compiler, runtime, mode, system, checked=False,
49 host_checked=False, shard_index=None, total_shards=None,
50 is_buildbot=False, test_set=None):
51 self.compiler = compiler
52 self.runtime = runtime
53 self.mode = mode
54 self.system = system
55 self.checked = checked
56 self.host_checked = host_checked
57 self.shard_index = shard_index
58 self.total_shards = total_shards
59 self.is_buildbot = is_buildbot
60 self.test_set = test_set
61
62 def PrintBuildInfo(self):
63 shard_description = ""
64 if self.shard_index:
65 shard_description = " shard %s of %s" % (self.shard_index,
66 self.total_shards)
67 print ("compiler: %s, runtime: %s mode: %s, system: %s,"
68 " checked: %s, host-checked: %s, test-set: %s%s"
69 ) % (self.compiler, self.runtime, self.mode, self.system,
70 self.checked, self.host_checked, self.test_set,
71 shard_description)
72
73
74 def GetBuildInfo():
75 """Returns a BuildInfo object for the current buildbot based on the
76 name of the builder.
77 """
78 parser = optparse.OptionParser()
79 parser.add_option('-n', '--name', dest='name', help='The name of the build'
80 'bot you would like to emulate (ex: web-chrome-win7)', default=None)
81 args, _ = parser.parse_args()
82
83 compiler = None
84 runtime = None
85 mode = None
86 system = None
87 builder_name = os.environ.get(BUILDER_NAME)
88 checked = False
89 host_checked = False
90 shard_index = None
91 total_shards = None
92 is_buildbot = True
93 test_set = None
94
95 if not builder_name:
96 # We are not running on a buildbot.
97 is_buildbot = False
98 if args.name:
99 builder_name = args.name
100 else:
101 print 'Use -n $BUILDBOT_NAME for the bot you would like to emulate.'
102 sys.exit(1)
103
104 if builder_name:
105 dart2js_pattern = re.match(DART2JS_BUILDER, builder_name)
106 web_pattern = re.match(WEB_BUILDER, builder_name)
107
108 if web_pattern:
109 compiler = 'dart2js'
110 runtime = web_pattern.group(1)
111 system = web_pattern.group(2)
112 mode = 'release'
113 test_set = web_pattern.group(4)
114 elif dart2js_pattern:
115 compiler = 'dart2js'
116 system = dart2js_pattern.group(1)
117 runtime = 'd8'
118 if dart2js_pattern.group(3) == 'jsshell':
119 runtime = 'jsshell'
120 mode = dart2js_pattern.group(4)
121 # The valid naming parts for checked and host-checked are:
122 # Empty: checked=False, host_checked=False
123 # -checked: checked=True, host_checked=False
124 # -host-checked: checked=False, host_checked=True
125 # -checked-host-checked: checked=True, host_checked=True
126 if dart2js_pattern.group(6) == 'checked':
127 checked = True
128 if dart2js_pattern.group(6) == 'host-checked':
129 host_checked = True
130 if dart2js_pattern.group(8) == 'host-checked':
131 host_checked = True
132 shard_index = dart2js_pattern.group(9)
133 total_shards = dart2js_pattern.group(10)
134
135 if system == 'windows':
136 system = 'win7'
137
138 if (system == 'win7' and platform.system() != 'Windows') or (
139 system == 'mac' and platform.system() != 'Darwin') or (
140 system == 'linux' and platform.system() != 'Linux'):
141 print ('Error: You cannot emulate a buildbot with a platform different '
142 'from your own.')
143 sys.exit(1)
144 return BuildInfo(compiler, runtime, mode, system, checked, host_checked,
145 shard_index, total_shards, is_buildbot, test_set)
146
147
148 def NeedsXterm(compiler, runtime):
149 return runtime in ['ie', 'chrome', 'safari', 'opera', 'ff', 'drt']
150
151
152 def TestStepName(name, flags):
153 # Filter out flags with '=' as this breaks the /stats feature of the
154 # build bot.
155 flags = [x for x in flags if not '=' in x]
156 return ('%s tests %s' % (name, ' '.join(flags))).strip()
157
158
159 def TestStep(name, mode, system, compiler, runtime, targets, flags):
160 step_name = TestStepName(name, flags)
161 print '@@@BUILD_STEP %s@@@' % step_name
162 sys.stdout.flush()
163 if NeedsXterm(compiler, runtime) and system == 'linux':
164 cmd = ['xvfb-run', '-a']
165 else:
166 cmd = []
167
168 user_test = os.environ.get('USER_TEST', 'no')
169
170 cmd.extend([sys.executable,
171 os.path.join(os.curdir, 'tools', 'test.py'),
172 '--step_name=' + step_name,
173 '--mode=' + mode,
174 '--compiler=' + compiler,
175 '--runtime=' + runtime,
176 '--time',
177 '--use-sdk',
178 '--report'])
179
180 if user_test == 'yes':
181 cmd.append('--progress=color')
182 else:
183 cmd.extend(['--progress=buildbot', '-v'])
184
185 if flags:
186 cmd.extend(flags)
187 cmd.extend(targets)
188
189 print 'running %s' % (' '.join(cmd))
190 exit_code = subprocess.call(cmd, env=NO_COLOR_ENV)
191 if exit_code != 0:
192 print '@@@STEP_FAILURE@@@'
193 return exit_code
194
195
196 def BuildSDK(mode, system):
197 """ build the SDK.
198 Args:
199 - mode: either 'debug' or 'release'
200 - system: either 'linux', 'mac', or 'win7'
201 """
202 os.chdir(DART_PATH)
203
204 args = [sys.executable, './tools/build.py', '--mode=' + mode, 'create_sdk']
205 print 'running %s' % (' '.join(args))
206 return subprocess.call(args, env=NO_COLOR_ENV)
207
208
209 def TestCompiler(runtime, mode, system, flags, is_buildbot, test_set):
210 """ test the compiler.
211 Args:
212 - runtime: either 'd8', 'jsshell', or one of the browsers, see GetBuildInfo
213 - mode: either 'debug' or 'release'
214 - system: either 'linux', 'mac', or 'win7'
215 - flags: extra flags to pass to test.dart
216 - is_buildbot: true if we are running on a real buildbot instead of
217 emulating one.
218 - test_set: Specification of a non standard test set, default None
219 """
220
221 # Make sure we are in the dart directory
222 os.chdir(DART_PATH)
223
224 if system.startswith('win') and runtime == 'ie':
225 # There should not be more than one InternetExplorerDriver instance
226 # running at a time. For details, see
227 # http://code.google.com/p/selenium/wiki/InternetExplorerDriver.
228 flags += ['-j1']
229
230 def GetPath(runtime):
231 """ Helper to get the path to the Chrome or Firefox executable for a
232 particular platform on the buildbot. Throws a KeyError if runtime is not
233 either 'chrome' or 'ff'."""
234 if system == 'mac':
235 partDict = {'chrome': 'Google\\ Chrome', 'ff': 'Firefox'}
236 mac_path = '/Applications/%s.app/Contents/MacOS/%s'
237 path_dict = {'chrome': mac_path % (partDict[runtime], partDict[runtime]),
238 'ff': mac_path % (partDict[runtime], partDict[runtime].lower())}
239 elif system == 'linux':
240 path_dict = {'ff': 'firefox', 'chrome': 'google-chrome'}
241 else:
242 # Windows.
243 path_dict = {'ff': os.path.join('C:/', 'Program Files (x86)',
244 'Mozilla Firefox', 'firefox.exe'),
245 'chrome': os.path.join('C:/', 'Users', 'chrome-bot', 'AppData',
246 'Local', 'Google', 'Chrome', 'Application', 'chrome.exe')}
247 return path_dict[runtime]
248
249 if system == 'linux' and runtime == 'chrome':
250 # TODO(ngeoffray): We should install selenium on the buildbot.
251 runtime = 'drt'
252 elif (runtime == 'ff' or runtime == 'chrome') and is_buildbot:
253 # Print out browser version numbers if we're running on the buildbot (where
254 # we know the paths to these browser installations).
255 version_query_string = '"%s" --version' % GetPath(runtime)
256 if runtime == 'ff' and system == 'win7':
257 version_query_string += '| more'
258 elif runtime == 'chrome' and system == 'win7':
259 version_query_string = ('''reg query "HKCU\\Software\\Microsoft\\''' +
260 '''Windows\\CurrentVersion\\Uninstall\\Google Chrome" /v Version''')
261 p = subprocess.Popen(version_query_string,
262 stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
263 output, stderr = p.communicate()
264 output = output.split()
265 try:
266 print 'Version of %s: %s' % (runtime, output[-1])
267 except IndexError:
268 # Failed to obtain version information. Continue running tests.
269 pass
270
271 if runtime == 'd8':
272 # The dart2js compiler isn't self-hosted (yet) so we run its
273 # unit tests on the VM. We avoid doing this on the builders
274 # that run the browser tests to cut down on the cycle time.
275 TestStep("dart2js_unit", mode, system, 'none', 'vm', ['dart2js'], flags)
276
277 if not (system.startswith('win') and runtime == 'ie'):
278 # Run the default set of test suites.
279 TestStep("dart2js", mode, system, 'dart2js', runtime, [], flags)
280
281 # TODO(kasperl): Consider running peg and css tests too.
282 extras = ['dart2js_extra', 'dart2js_native', 'dart2js_foreign']
283 TestStep("dart2js_extra", mode, system, 'dart2js', runtime, extras, flags)
284 else:
285 # TODO(ricow): Enable standard sharding for IE bots when we have more vms.
286 if test_set == 'html':
287 TestStep("dart2js", mode, system, 'dart2js', runtime, ['html'], flags)
288 elif test_set == 'all':
289 TestStep("dart2js", mode, system, 'dart2js', runtime, ['dartc',
290 'samples', 'standalone', 'corelib', 'co19', 'language', 'isolate',
291 'vm', 'json', 'benchmark_smoke', 'dartdoc', 'utils', 'pub', 'lib'],
292 flags)
293 extras = ['dart2js_extra', 'dart2js_native', 'dart2js_foreign']
294 TestStep("dart2js_extra", mode, system, 'dart2js', runtime, extras,
295 flags)
296
297 return 0
298
299 def _DeleteTempWebdriverProfiles(directory):
300 """Find all the firefox profiles in a particular directory and delete them."""
301 for f in os.listdir(directory):
302 item = os.path.join(directory, f)
303 if os.path.isdir(item) and (f.startswith('tmp') or f.startswith('opera')):
304 subprocess.Popen('rm -rf %s' % item, shell=True)
305
306 def CleanUpTemporaryFiles(system, browser):
307 """For some browser (selenium) tests, the browser creates a temporary profile
308 on each browser session start. On Windows, generally these files are
309 automatically deleted when all python processes complete. However, since our
310 buildbot slave script also runs on python, we never get the opportunity to
311 clear out the temp files, so we do so explicitly here. Our batch browser
312 testing will make this problem occur much less frequently, but will still
313 happen eventually unless we do this.
314
315 This problem also occurs with batch tests in Firefox. For some reason selenium
316 automatically deletes the temporary profiles for Firefox for one browser,
317 but not multiple ones when we have many open batch tasks running. This
318 behavior has not been reproduced outside of the buildbots.
319
320 Args:
321 - system: either 'linux', 'mac', or 'win7'
322 - browser: one of the browsers, see GetBuildInfo
323 """
324 if system == 'win7':
325 shutil.rmtree('C:\\Users\\chrome-bot\\AppData\\Local\\Temp',
326 ignore_errors=True)
327 elif browser == 'ff' or 'opera':
328 # Note: the buildbots run as root, so we can do this without requiring a
329 # password. The command won't actually work on regular machines without
330 # root permissions.
331 _DeleteTempWebdriverProfiles('/tmp')
332 _DeleteTempWebdriverProfiles('/var/tmp')
333
334 def ClobberBuilder(mode):
335 """ Clobber the builder before we do the build.
336 Args:
337 - mode: either 'debug' or 'release'
338 """
339 cmd = [sys.executable,
340 './tools/clean_output_directory.py',
341 '--mode=' + mode]
342 print 'Clobbering %s' % (' '.join(cmd))
343 return subprocess.call(cmd, env=NO_COLOR_ENV)
344
345 def GetShouldClobber():
346 return os.environ.get(BUILDER_CLOBBER) == "1"
347
348 def GetHasHardCodedCheckedMode(build_info):
349 # TODO(ricow): We currently run checked mode tests on chrome on linux and
350 # on the slow (all) IE windows bots. This is a hack and we should use the
351 # normal sharding and checked splitting functionality when we get more
352 # vms for testing this.
353 if (build_info.system == 'linux' and build_info.runtime == 'chrome'):
354 return True
355 if (build_info.system == 'win7' and build_info.runtime == 'ie' and
356 build_info.test_set == 'all'):
357 return True
358 return False
359
360 def main():
361 if len(sys.argv) == 0:
362 print 'Script pathname not known, giving up.'
363 return 1
364
365 build_info = GetBuildInfo()
366
367 # Print out the buildinfo for easy debugging.
368 build_info.PrintBuildInfo()
369
370 if build_info.compiler is None:
371 return 1
372
373 if GetShouldClobber():
374 print '@@@BUILD_STEP Clobber@@@'
375 status = ClobberBuilder(build_info.mode)
376 if status != 0:
377 print '@@@STEP_FAILURE@@@'
378 return status
379
380 print '@@@BUILD_STEP build sdk@@@'
381 status = BuildSDK(build_info.mode, build_info.system)
382 if status != 0:
383 print '@@@STEP_FAILURE@@@'
384 return status
385
386 test_flags = []
387 if build_info.shard_index:
388 test_flags = ['--shards=%s' % build_info.total_shards,
389 '--shard=%s' % build_info.shard_index]
390
391 if build_info.checked: test_flags += ['--checked']
392
393 if build_info.host_checked: test_flags += ['--host-checked']
394
395 status = TestCompiler(build_info.runtime, build_info.mode,
396 build_info.system, list(test_flags),
397 build_info.is_buildbot, build_info.test_set)
398
399 # See comment in GetHasHardCodedCheckedMode, this is a hack.
400 if (status == 0 and GetHasHardCodedCheckedMode(build_info)):
401 status = TestCompiler(build_info.runtime, build_info.mode,
402 build_info.system,
403 test_flags + ['--checked'],
404 build_info.is_buildbot,
405 build_info.test_set)
406
407 if build_info.runtime != 'd8': CleanUpTemporaryFiles(build_info.system,
408 build_info.runtime)
409 if status != 0: print '@@@STEP_FAILURE@@@'
410 return status
411
412 if __name__ == '__main__':
413 sys.exit(main())
OLDNEW
« tools/bots/pub.py ('K') | « tools/bots/pub.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698