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

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

Issue 11666023: Move android buildbot test logic into python (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 12 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
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 import collections
7 import glob
8 import json
9 import optparse
10 import os
11 import pipes
12 import shutil
13 import subprocess
14 import sys
15
16 sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
17 from pylib import buildbot_report
18 from pylib import constants
19
20 TESTING = 'BUILDBOT_TESTING' in os.environ
xusydoc (do not use) 2013/01/04 17:09:21 2 spaces between top-level defines
21 CHROME_SRC = constants.CHROME_DIR
22
23
24 # Describes an instrumation test suite:
25 # test: Name of test we're running.
26 # apk: apk to be installed.
27 # apk_package: package for the apk to be installed.
28 # test_apk: apk to run tests on.
29 # test_data: data folder in format destination:source.
30 I_TEST = collections.namedtuple('InstrumentationTest', [
31 'name', 'apk', 'apk_package', 'test_apk', 'test_data'])
32
33 INSTRUMENTATION_TESTS = dict((suite.name, suite) for suite in [
xusydoc (do not use) 2013/01/04 17:09:21 same
34 I_TEST('ContentShell',
35 'ContentShell.apk',
36 'org.chromium.content_shell',
37 'ContentShellTest',
frankf 2012/12/27 19:57:47 There's a lot of redundancy here. Why can't you de
Isaac (away) 2012/12/27 22:23:03 I am porting bash code to python. If we want to s
38 'content:content/test/data/android/device_files'),
39 I_TEST('ChromiumTestShell',
40 'ChromiumTestShell.apk',
41 'org.chromium.chrome.testshell',
42 'ChromiumTestShellTest',
43 'chrome:chrome/test/data/android/device_files'),
44 I_TEST('AndroidWebView',
45 'AndroidWebView.apk',
46 'org.chromium.android_webview',
47 'AndroidWebViewTest',
48 'webview:android_webview/test/data/device_files'),
49 ])
50
51 VALID_TESTS = set(['ui', 'unit', 'webkit', 'webkit_layout'])
xusydoc (do not use) 2013/01/04 17:09:21 same
52
53
54 def RunCmd(command, flunk_on_failure=True):
55 """Run a command relative to the chrome source root."""
56
57 # Add adb binary to path. In the future, might use build_internal copy.
58 env = dict(os.environ)
59 env['PATH'] = os.pathsep.join([
60 env['PATH'], os.path.join(constants.ANDROID_SDK_ROOT, 'platform-tools')])
61
62 command_str = ' '.join(map(pipes.quote, command))
63 print '>', command_str
64 if not TESTING:
65 code = subprocess.Popen(command, cwd=CHROME_SRC, env=env).wait()
66 else:
67 code = 0
68 print '<', command_str
69 if code != 0:
70 print 'ERROR: non-zero status %d from %s' % (code, command)
71 if flunk_on_failure:
72 buildbot_report.PrintError()
73 else:
74 buildbot_report.PrintWarning()
75 return code
76
77
78 def RunTestSuites(options, suite):
79 """Manages an invocation of run_tests.py.
80
81 Args:
82 options: options object.
83 suite: The suite to pass to run_tests or None to run default suites.
84 """
85 args = ['--verbose']
86 if suite:
87 args.extend(['-s', suite])
88 if options.target == 'Release':
89 args.append('--release')
90 if options.asan:
91 args.append('--tool=asan')
92 RunCmd(['build/android/run_tests.py'] + args)
frankf 2012/12/27 19:57:47 If we're adding the complexity of another wrapper,
Isaac (away) 2012/12/27 22:23:03 This is a pure port - bash -> python. We are not
frankf 2012/12/27 22:33:26 OK, let's keep this CL simple, but it seems we're
93
94
95 def InstallApk(apk, apk_package, target):
96 args = ['--apk', apk, '--apk_package', apk_package]
97 if target == 'Release':
98 args.append('--release')
99
100 RunCmd(['build/android/adb_install_apk.py'] + args)
101
102
103 def RunInstrumentationSuite(options, test):
104 """Manages an invocation of run_instrumentaiton_tests.py.
105
106 Args:
107 options: options object
108 test: An I_TEST namedtuple
109 """
110 buildbot_report.PrintNamedStep('Instrumentation tests for %s' % test.name)
frankf 2012/12/27 19:57:47 Will crbug.com/161993 be addressed in a follow up
Isaac (away) 2012/12/27 22:23:03 That is a separate bug, not directly related to th
frankf 2012/12/27 22:33:26 Let's avoid spaces. I've proposed a convention in
Isaac (away) 2012/12/27 22:55:20 OK, I took a look. I think the word instrumentati
frankf 2012/12/27 23:06:10 It's needed to remove ambiguity in other contexts.
Isaac (away) 2012/12/28 05:31:53 The instrumentation tests use ChromiumTestShell, w
111
112 InstallApk(test.apk, test.apk_package, options.target)
113 args = ['--test-apk', test.test_apk, '--test_data', test.test_data, '-vvv',
114 '-I']
115 if options.target == 'Release':
116 args.append('--release')
117 if options.asan:
118 args.append('--tool=asan')
119
120 RunCmd(['build/android/run_instrumentation_tests.py'] + args)
frankf 2012/12/27 19:57:47 Again, run_instrumentation_tests.py won't produce
Isaac (away) 2012/12/27 22:23:03 See above. Pure port / wrapper changes. It is co
121
122
123 def RunWebkitLint(target):
124 """Lint WebKit's TestExpectation files."""
125 buildbot_report.PrintNamedStep('webkit_lint')
126 RunCmd(['webkit/tools/layout_tests/run_webkit_tests.py',
127 '--lint-test-files',
128 '--chromium',
129 '--target', target])
130
131
132 def RunWebkitLayoutTests(options):
133 """Run layout tests on an actual device."""
134 buildbot_report.PrintNamedStep('webkit_tests')
135 RunCmd(['webkit/tools/layout_tests/run_webkit_tests.py',
136 '--no-show-results',
137 '--no-new-test-results',
138 '--full-results-html',
139 '--clobber-old-results',
140 '--exit-after-n-failures', '5000',
141 '--exit-after-n-crashes-or-timeouts', '100',
142 '--debug-rwt-logging',
143 '--results-directory', '..layout-test-results',
144 '--target', options.target,
145 '--builder-name', options.build_properties.get('buildername', ''),
146 '--build-number', options.build_properties.get('buildnumber', ''),
147 '--master-name', options.build_properties.get('mastername', ''),
148 '--build-name', options.build_properties.get('buildername', ''),
149 '--platform=chromium-android',
150 '--test-results-server',
151 options.factory_properties.get('test_results_server', '')])
152
153
154 def MainTestWrapper(options):
155 if options.install:
156 test_obj = INSTRUMENTATION_TESTS[options.install]
157 InstallApk(test_obj.apk, test_obj.apk_package, options.target)
158
159 if not options.test_filter:
160 return
161
162 # Device check and alert emails
163 RunCmd(['build/android/device_status_check.py'], flunk_on_failure=False)
164
165 # Spawn logcat monitor
166 logcat_dir = os.path.join(CHROME_SRC, 'out/logcat')
167 shutil.rmtree(logcat_dir, ignore_errors=True)
168 if not TESTING:
169 subprocess.Popen(
170 ['build/android/adb_logcat_monitor.py', logcat_dir], cwd=CHROME_SRC)
171
172 if 'unit' in options.test_filter:
173 RunTestSuites(options, None)
174 if 'ui' in options.test_filter:
175 for test in INSTRUMENTATION_TESTS.itervalues():
176 RunInstrumentationSuite(options, test)
177 if 'webkit' in options.test_filter:
178 RunTestSuites(options, 'webkit_unit_tests')
179 RunTestSuites(options, 'TestWebKitAPI')
180 RunWebkitLint(options.target)
181 if 'webkit_layout' in options.test_filter:
182 RunWebkitLayoutTests(options)
183
184 if options.experimental:
185 pass
186
187 # Print logcat, kill logcat monitor
188 buildbot_report.PrintNamedStep('Logcat dump')
189 RunCmd(['build/android/adb_logcat_printer.py', logcat_dir])
190
191 buildbot_report.PrintNamedStep('Test report')
192 for report in glob.glob(
193 os.path.join(CHROME_SRC, 'out', options.target, 'test_logs', '*.log')):
194 subprocess.Popen(['cat', report]).wait()
195 os.remove(report)
196
197
198 def main(argv):
199 parser = optparse.OptionParser()
200
201 def convert_json(option, _, value, parser):
202 setattr(parser.values, option.dest, json.loads(value))
203
204 parser.add_option('--build-properties', action='callback',
205 callback=convert_json, type='string', default={},
206 help='build properties in JSON format')
207 parser.add_option('--factory-properties', action='callback',
208 callback=convert_json, type='string', default={},
209 help='factory properties in JSON format')
210 parser.add_option('--slave-properties', action='callback',
211 callback=convert_json, type='string', default={},
212 help='Properties set by slave script in JSON format')
213 parser.add_option('--experimental', action='store_true',
214 help='Run experiemental tests')
215 parser.add_option('-f', '--test-filter', metavar='<filter>', default=[],
216 action='append',
217 help=('Run a test suite. Test suites: "%s"' %
218 '", "'.join(VALID_TESTS)))
219 parser.add_option('--asan', action='store_true', help='Run tests with asan.')
220 parser.add_option('--install', metavar='<apk name>',
221 help='Install an apk by name')
222 options, args = parser.parse_args(argv[1:])
223
224 def ParserError(msg):
225 """We avoid parser.error because it calls sys.exit."""
226 parser.print_help()
227 print >>sys.stderr, '\nERROR:', msg
228 return 1
229
230 if args:
231 return ParserError('Unused args %s' % args)
232
233 unknown_tests = set(options.test_filter) - VALID_TESTS
234 if unknown_tests:
235 return ParserError('Unknown tests %s' % list(unknown_tests))
236
237 setattr(options, 'target', options.factory_properties.get('target', 'Debug'))
238
239 MainTestWrapper(options)
240
241 if __name__ == '__main__':
xusydoc (do not use) 2013/01/04 17:09:21 same
242 sys.exit(main(sys.argv))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698