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

Side by Side Diff: tools/bots/bot.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
OLDNEW
(Empty)
1 #!/usr/bin/python
2
3 # Copyright (c) 2012 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 """
8 Shared code for use in the buildbot scripts.
9 """
10
11 import optparse
12 import os
13 from os.path import abspath
14 from os.path import dirname
15 import subprocess
16 import sys
17
18 DART_PATH = dirname(dirname(dirname(abspath(__file__))))
19
20 NO_COLOR_ENV = dict(os.environ)
21 NO_COLOR_ENV['TERM'] = 'nocolor'
22
23 BUILDER_NAME = 'BUILDBOT_BUILDERNAME'
24 BUILDER_CLOBBER = 'BUILDBOT_CLOBBER'
25
26
27 class BuildInfo(object):
28 """
29 Encapsulation of build information.
30
31 - compiler: None, 'dart2dart', 'dart2js' or 'dartc'.
32 - runtime: 'd8', 'ie', 'ff', 'safari', 'chrome', 'opera', or None.
33 - mode: 'debug' or 'release'.
34 - system: 'linux', 'mac', or 'win7'.
35 - checked: True if we should run in checked mode, otherwise False.
36 - host_checked: True if we should run in host checked mode, otherwise False.
37 - shard_index: The shard we are running, None when not specified.
38 - total_shards: The total number of shards, None when not specified.
39 - is_buildbot: True if we are on a buildbot (or emulating it).
40 - test_set: Specification of a non standard test set or None.
41 """
42 def __init__(self, compiler, runtime, mode, system, checked=False,
43 host_checked=False, shard_index=None, total_shards=None,
44 is_buildbot=False, test_set=None):
45 self.compiler = compiler
46 self.runtime = runtime
47 self.mode = mode
48 self.system = system
49 self.checked = checked
50 self.host_checked = host_checked
51 self.shard_index = shard_index
52 self.total_shards = total_shards
53 self.is_buildbot = is_buildbot
54 self.test_set = test_set
55
56 def PrintBuildInfo(self):
57 shard_description = ""
58 if self.shard_index:
59 shard_description = " shard %s of %s" % (self.shard_index,
60 self.total_shards)
61 print ("compiler: %s, runtime: %s mode: %s, system: %s,"
62 " checked: %s, host-checked: %s, test-set: %s%s"
63 ) % (self.compiler, self.runtime, self.mode, self.system,
64 self.checked, self.host_checked, self.test_set,
65 shard_description)
66
67
68 class BuildStep(object):
69 """
70 A context manager for handling build steps.
71
72 When the context manager is entered, it prints the "@@@BUILD_STEP __@@@"
73 message. If it exits from an error being raised it displays the
74 "@@@STEP_FAILURE@@@" message.
75
76 If swallow_error is True, then this will catch and discard any OSError that
77 is thrown. This lets you run later BuildSteps if the current one fails.
78 """
79 def __init__(self, name, swallow_error=False):
80 self.name = name
81 self.swallow_error = swallow_error
82
83 def __enter__(self):
84 print '@@@BUILD_STEP %s@@@' % self.name
85
86 def __exit__(self, type, value, traceback):
87 if value:
88 print '@@@STEP_FAILURE@@@'
89 if self.swallow_error and isinstance(value, OSError):
90 return True
91
92
93 def RunBot(parse_name, custom_steps):
94 """
95 The main function for running a buildbot.
96
97 A buildbot script should invoke this once. The parse_name function will be
98 called with the name of the buildbot and should return an instance of
99 BuildInfo. This function will then set up the bot, build the SDK etc. When
100 that's done, it will call custom_steps, passing in the BuildInfo object.
101
102 In that, you can perform any bot-specific build steps.
103
104 This function will not return. It will call sys.exit() with an appropriate
105 exit code.
106 """
107 if len(sys.argv) == 0:
108 print 'Script pathname not known, giving up.'
109 sys.exit(1)
110
111 name, is_buildbot = GetBotName()
112 build_info = parse_name(name, is_buildbot)
113 if not build_info:
114 print 'Could not handle unfamiliar bot name "%s".' % name
115 sys.exit(1)
116
117 # Print out the buildinfo for easy debugging.
118 build_info.PrintBuildInfo()
119
120 # Make sure we are in the dart directory
121 os.chdir(DART_PATH)
122
123 try:
124 Clobber(build_info.mode)
125 BuildSDK(build_info.mode, build_info.system)
126
127 custom_steps(build_info)
128 except OSError as e:
129 sys.exit(e.errno)
130
131 sys.exit(0)
132
133
134 def GetBotName():
135 """
136 Gets the name of the current buildbot.
137
138 Returns a tuple of the buildbot name and a flag to indicate if we are actually
139 a buildbot (True), or just a user pretending to be one (False).
140 """
141 # For testing the bot locally, allow the user to pass in a buildbot name.
142 parser = optparse.OptionParser()
143 parser.add_option('-n', '--name', dest='name', help='The name of the build'
144 'bot you would like to emulate (ex: vm-mac-debug)', default=None)
145 args, _ = parser.parse_args()
146
147 if args.name:
148 return args.name, False
149
150 name = os.environ.get(BUILDER_NAME)
151 if not name:
152 print 'Use -n $BUILDBOT_NAME for the bot you would like to emulate.'
153 sys.exit(1)
154
155 return name, True
156
157
158 def Clobber(mode):
159 """
160 Clobbers the builder before we do the build, if appropriate.
161
162 - mode: either 'debug' or 'release'
163 """
164 if os.environ.get(BUILDER_CLOBBER) != "1":
165 return
166
167 with BuildStep('Clobber'):
168 cmd = [sys.executable,
169 './tools/clean_output_directory.py',
170 '--mode=' + mode]
171 print 'Clobbering %s' % (' '.join(cmd))
172 RunProcess(cmd)
173
174
175 def BuildSDK(mode, system):
176 """
177 Builds the SDK.
178
179 - mode: either 'debug' or 'release'
180 - system: either 'linux', 'mac', or 'win7'
181 """
182 with BuildStep('Build SDK'):
183 args = [sys.executable, './tools/build.py', '--mode=' + mode, 'create_sdk']
184 print 'Building SDK: %s' % (' '.join(args))
185 RunProcess(args)
186
187
188 def RunTest(name, build_info, targets, flags=None):
189 """
190 Runs test.py with the given settings.
191 """
192 if not flags:
193 flags = []
194
195 step_name = GetStepName(name, flags)
196 with BuildStep(step_name):
197 sys.stdout.flush()
198
199 cmd = [
200 sys.executable, os.path.join(os.curdir, 'tools', 'test.py'),
201 '--step_name=' + step_name,
202 '--mode=' + build_info.mode,
203 '--compiler=' + build_info.compiler,
204 '--runtime=' + build_info.runtime,
205 '--progress=buildbot',
206 '-v', '--time', '--use-sdk', '--report'
207 ]
208
209 if build_info.checked:
210 cmd.append('--checked')
211
212 cmd.extend(flags)
213 cmd.extend(targets)
214
215 print 'Running: %s' % (' '.join(cmd))
216 RunProcess(cmd)
217
218
219 def RunProcess(command):
220 """
221 Runs command.
222
223 If a non-zero exit code is returned, raises an OSError with errno as the exit
224 code.
225 """
226 exit_code = subprocess.call(command, env=NO_COLOR_ENV)
227 if exit_code != 0:
228 raise OSError(exit_code)
229
230
231 def GetStepName(name, flags):
232 """
233 Filters out flags with '=' as this breaks the /stats feature of the buildbot.
234 """
235 flags = [x for x in flags if not '=' in x]
236 return ('%s tests %s' % (name, ' '.join(flags))).strip()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698