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

Side by Side Diff: build/android/buildbot/bb_run_bot.py

Issue 17114007: [Android] Refactor the buildbot scripts to prepare for downstream usage. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address second round of comments Created 7 years, 5 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
« no previous file with comments | « build/android/buildbot/bb_host_steps.py ('k') | build/android/buildbot/bb_utils.py » ('j') | 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 # 2 #
3 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 3 # Copyright (c) 2013 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 import collections 7 import collections
8 import copy 8 import copy
9 import json 9 import json
10 import os 10 import os
11 import pipes 11 import pipes
12 import re 12 import re
13 import subprocess 13 import subprocess
14 import sys 14 import sys
15 15
16 import bb_utils 16 import bb_utils
17 17
18 BotConfig = collections.namedtuple( 18 _BotConfig = collections.namedtuple(
19 'BotConfig', ['bot_id', 'host_obj', 'test_obj']) 19 'BotConfig', ['bot_id', 'host_obj', 'test_obj'])
20 20
21 HostConfig = collections.namedtuple( 21 HostConfig = collections.namedtuple(
22 'HostConfig', 22 'HostConfig',
23 ['host_steps', 'extra_args', 'extra_gyp_defines', 'target_arch']) 23 ['script', 'host_steps', 'extra_args', 'extra_gyp_defines', 'target_arch'])
24 24
25 TestConfig = collections.namedtuple('Tests', ['tests', 'extra_args']) 25 TestConfig = collections.namedtuple('Tests', ['script', 'tests', 'extra_args'])
26
27
28 def BotConfig(bot_id, host_object, test_object=None):
29 return _BotConfig(bot_id, host_object, test_object)
26 30
27 31
28 def DictDiff(d1, d2): 32 def DictDiff(d1, d2):
29 diff = [] 33 diff = []
30 for key in sorted(set(d1.keys() + d2.keys())): 34 for key in sorted(set(d1.keys() + d2.keys())):
31 if key in d1 and d1[key] != d2.get(key): 35 if key in d1 and d1[key] != d2.get(key):
32 diff.append('- %s=%s' % (key, pipes.quote(d1[key]))) 36 diff.append('- %s=%s' % (key, pipes.quote(d1[key])))
33 if key in d2 and d2[key] != d1.get(key): 37 if key in d2 and d2[key] != d1.get(key):
34 diff.append('+ %s=%s' % (key, pipes.quote(d2[key]))) 38 diff.append('+ %s=%s' % (key, pipes.quote(d2[key])))
35 return '\n'.join(diff) 39 return '\n'.join(diff)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 71
68 # Bots checkout chrome in /b/build/slave/<name>/build/src 72 # Bots checkout chrome in /b/build/slave/<name>/build/src
69 build_internal_android = os.path.abspath(os.path.join( 73 build_internal_android = os.path.abspath(os.path.join(
70 bb_utils.CHROME_SRC, '..', '..', '..', '..', '..', 'build_internal', 74 bb_utils.CHROME_SRC, '..', '..', '..', '..', '..', 'build_internal',
71 'scripts', 'slave', 'android')) 75 'scripts', 'slave', 'android'))
72 if os.path.exists(build_internal_android): 76 if os.path.exists(build_internal_android):
73 env['PATH'] = os.pathsep.join([build_internal_android, env['PATH']]) 77 env['PATH'] = os.pathsep.join([build_internal_android, env['PATH']])
74 return env 78 return env
75 79
76 80
77 def GetCommands(options, bot_config): 81 def GetCommands(options, bot_config, host_step_script, device_step_script):
78 """Get a formatted list of commands. 82 """Get a formatted list of commands.
79 83
80 Args: 84 Args:
81 options: Options object. 85 options: Options object.
82 bot_config: A BotConfig named tuple. 86 bot_config: A BotConfig named tuple.
87 host_step_script: Host step script.
88 device_step_script: Device step script.
83 Returns: 89 Returns:
84 list of Command objects. 90 list of Command objects.
85 """ 91 """
86 property_args = bb_utils.EncodeProperties(options) 92 property_args = bb_utils.EncodeProperties(options)
87 commands = [['build/android/buildbot/bb_host_steps.py'] + 93 commands = [[host_step_script,
88 ['--steps=%s' % ','.join(bot_config.host_obj.host_steps)] + 94 '--steps=%s' % ','.join(bot_config.host_obj.host_steps)] +
89 property_args + (bot_config.host_obj.extra_args or [])] 95 property_args + (bot_config.host_obj.extra_args or [])]
90 96
91 test_obj = bot_config.test_obj 97 test_obj = bot_config.test_obj
92 if test_obj: 98 if test_obj:
93 run_test_cmd = [ 99 run_test_cmd = [device_step_script, '--reboot'] + property_args
94 'build/android/buildbot/bb_device_steps.py', '--reboot'] + property_args
95 for test in test_obj.tests: 100 for test in test_obj.tests:
96 run_test_cmd.extend(['-f', test]) 101 run_test_cmd.extend(['-f', test])
97 if test_obj.extra_args: 102 if test_obj.extra_args:
98 run_test_cmd.extend(test_obj.extra_args) 103 run_test_cmd.extend(test_obj.extra_args)
99 commands.append(run_test_cmd) 104 commands.append(run_test_cmd)
100 return commands 105 return commands
101 106
102 107
103 def GetBotStepMap(): 108 def GetBotStepMap():
104 compile_step = ['compile'] 109 compile_step = ['compile']
105 std_host_tests = ['check_webview_licenses', 'findbugs'] 110 std_host_tests = ['check_webview_licenses', 'findbugs']
106 std_build_steps = ['compile', 'zip_build'] 111 std_build_steps = ['compile', 'zip_build']
107 std_test_steps = ['extract_build'] 112 std_test_steps = ['extract_build']
108 std_tests = ['ui', 'unit'] 113 std_tests = ['ui', 'unit']
109 flakiness_server = '--upload-to-flakiness-server' 114 flakiness_server = '--upload-to-flakiness-server'
110 115
111 def B(bot_id, host_object, test_object=None): 116 B = BotConfig
112 return BotConfig(bot_id, host_object, test_object) 117 H = (lambda steps, extra_args=None, extra_gyp=None, target_arch=None :
113 118 HostConfig('build/android/buildbot/bb_host_steps.py', steps, extra_args,
114 def T(tests, extra_args=None): 119 extra_gyp, target_arch))
115 return TestConfig(tests, extra_args) 120 T = (lambda tests, extra_args=None :
116 121 TestConfig('build/android/buildbot/bb_device_steps.py', tests,
117 def H(host_steps, extra_args=None, extra_gyp=None, target_arch=None): 122 extra_args))
118 return HostConfig(host_steps, extra_args, extra_gyp, target_arch)
119 123
120 bot_configs = [ 124 bot_configs = [
121 # Main builders 125 # Main builders
122 B('main-builder-dbg', H(std_build_steps + std_host_tests)), 126 B('main-builder-dbg', H(std_build_steps + std_host_tests)),
123 B('main-builder-rel', H(std_build_steps)), 127 B('main-builder-rel', H(std_build_steps)),
124 B('main-clang-builder', 128 B('main-clang-builder',
125 H(compile_step, extra_gyp='clang=1 component=shared_library')), 129 H(compile_step, extra_gyp='clang=1 component=shared_library')),
126 B('main-clobber', H(compile_step)), 130 B('main-clobber', H(compile_step)),
127 B('main-tests', H(std_test_steps), T(std_tests, [flakiness_server])), 131 B('main-tests', H(std_test_steps), T(std_tests, [flakiness_server])),
128 132
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 # Trybots do not upload to flakiness dashboard. They should be otherwise 178 # Trybots do not upload to flakiness dashboard. They should be otherwise
175 # identical in configuration to their trunk building counterparts. 179 # identical in configuration to their trunk building counterparts.
176 test_obj = bot_map[to_id].test_obj 180 test_obj = bot_map[to_id].test_obj
177 if to_id.startswith('try') and test_obj: 181 if to_id.startswith('try') and test_obj:
178 extra_args = test_obj.extra_args 182 extra_args = test_obj.extra_args
179 if extra_args and flakiness_server in extra_args: 183 if extra_args and flakiness_server in extra_args:
180 extra_args.remove(flakiness_server) 184 extra_args.remove(flakiness_server)
181 return bot_map 185 return bot_map
182 186
183 187
184 def main(argv): 188 # Return an object from the map, looking first for an exact id match.
189 # If this fails, look for an id which is a substring of the specified id.
190 # Choose the longest of all substring matches.
191 # pylint: disable=W0622
192 def GetBestMatch(id_map, id):
193 config = id_map.get(id)
194 if not config:
195 substring_matches = filter(lambda x: x in id, id_map.iterkeys())
196 if substring_matches:
197 max_id = max(substring_matches, key=len)
198 print 'Using config from id="%s" (substring match).' % max_id
199 config = id_map[max_id]
200 return config
201
202
203 def GetRunBotOptParser():
185 parser = bb_utils.GetParser() 204 parser = bb_utils.GetParser()
186 parser.add_option('--bot-id', help='Specify bot id directly.') 205 parser.add_option('--bot-id', help='Specify bot id directly.')
187 parser.add_option('--testing', action='store_true', 206 parser.add_option('--testing', action='store_true',
188 help='For testing: print, but do not run commands') 207 help='For testing: print, but do not run commands')
208
209 return parser
210
211
212 def main(argv):
213 parser = GetRunBotOptParser()
189 options, args = parser.parse_args(argv[1:]) 214 options, args = parser.parse_args(argv[1:])
190 if args: 215 if args:
191 parser.error('Unused args: %s' % args) 216 parser.error('Unused args: %s' % args)
192 217
193 bot_id = options.bot_id or options.factory_properties.get('android_bot_id') 218 bot_id = options.bot_id or options.factory_properties.get('android_bot_id')
194 if not bot_id: 219 if not bot_id:
195 parser.error('A bot id must be specified through option or factory_props.') 220 parser.error('A bot id must be specified through option or factory_props.')
196 221
197 # Get a BotConfig object looking first for an exact bot-id match. If no exact 222 bot_config = GetBestMatch(GetBotStepMap(), bot_id)
198 # match, look for a bot-id which is a substring of the specified id.
199 # This allows similar bots to have unique IDs, but to share config.
200 # If multiple substring matches exist, pick the longest one.
201 bot_map = GetBotStepMap()
202 bot_config = bot_map.get(bot_id)
203 if not bot_config:
204 substring_matches = filter(lambda x: x in bot_id, bot_map.iterkeys())
205 if substring_matches:
206 max_id = max(substring_matches, key=len)
207 print 'Using config from id="%s" (substring match).' % max_id
208 bot_config = bot_map[max_id]
209 if not bot_config: 223 if not bot_config:
210 print 'Error: config for id="%s" cannot be inferred.' % bot_id 224 print 'Error: config for id="%s" cannot be inferred.' % bot_id
211 return 1 225 return 1
212 226
213 print 'Using config:', bot_config 227 print 'Using config:', bot_config
214 228
215 commands = GetCommands(options, bot_config) 229 commands = GetCommands(
230 options, bot_config,
231 'build/android/buildbot/bb_host_steps.py',
232 'build/android/buildbot/bb_device_steps.py')
216 for command in commands: 233 for command in commands:
217 print 'Will run: ', bb_utils.CommandToString(command) 234 print 'Will run: ', bb_utils.CommandToString(command)
218 print 235 print
219 236
220 env = GetEnvironment(bot_config.host_obj, options.testing) 237 env = GetEnvironment(bot_config.host_obj, options.testing)
221 print 'Environment changes:' 238 print 'Environment changes:'
222 print DictDiff(dict(os.environ), env) 239 print DictDiff(dict(os.environ), env)
223 240
224 for command in commands: 241 for command in commands:
225 print bb_utils.CommandToString(command) 242 print bb_utils.CommandToString(command)
226 sys.stdout.flush() 243 sys.stdout.flush()
227 if options.testing: 244 if options.testing:
228 env['BUILDBOT_TESTING'] = '1' 245 env['BUILDBOT_TESTING'] = '1'
229 return_code = subprocess.call(command, cwd=bb_utils.CHROME_SRC, env=env) 246 return_code = subprocess.call(command, cwd=bb_utils.CHROME_SRC, env=env)
230 if return_code != 0: 247 if return_code != 0:
231 return return_code 248 return return_code
232 249
233 250
234 if __name__ == '__main__': 251 if __name__ == '__main__':
235 sys.exit(main(sys.argv)) 252 sys.exit(main(sys.argv))
OLDNEW
« no previous file with comments | « build/android/buildbot/bb_host_steps.py ('k') | build/android/buildbot/bb_utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698