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

Side by Side Diff: tools/run-tests.py

Issue 10919265: First commit of new tools/run-tests.py (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: s/server.py/test-server.py/ in README Created 8 years, 2 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 | « tools/presubmit.py ('k') | tools/status-file-converter.py » ('j') | 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/env python
2 #
3 # Copyright 2012 the V8 project authors. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following
12 # disclaimer in the documentation and/or other materials provided
13 # with the distribution.
14 # * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived
16 # from this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30
31 import multiprocessing
32 import optparse
33 import os
34 from os.path import join
35 import subprocess
36 import sys
37 import time
38
39 from testrunner.local import execution
40 from testrunner.local import progress
41 from testrunner.local import testsuite
42 from testrunner.local import utils
43 from testrunner.local import verbose
44 from testrunner.network import network_execution
45 from testrunner.objects import context
46
47
48 ARCH_GUESS = utils.DefaultArch()
49 DEFAULT_TESTS = ["mjsunit", "cctest", "message", "preparser"]
50 TIMEOUT_DEFAULT = 60
51 TIMEOUT_SCALEFACTOR = {"debug" : 4,
52 "release" : 1 }
53
54 # Use this to run several variants of the tests.
55 VARIANT_FLAGS = [[],
56 ["--stress-opt", "--always-opt"],
57 ["--nocrankshaft"]]
58 MODE_FLAGS = {
59 "debug" : ["--nobreak-on-abort", "--enable-slow-asserts",
60 "--debug-code", "--verify-heap"],
61 "release" : ["--nobreak-on-abort"]}
62
63
64 def BuildOptions():
65 result = optparse.OptionParser()
66 result.add_option("--arch",
67 help=("The architecture to run tests for, "
68 "'auto' or 'native' for auto-detect"),
69 default="ia32,x64,arm")
70 result.add_option("--arch-and-mode",
71 help="Architecture and mode in the format 'arch.mode'",
72 default=None)
73 result.add_option("--buildbot",
74 help="Adapt to path structure used on buildbots",
75 default=False, action="store_true")
76 result.add_option("--cat", help="Print the source of the tests",
77 default=False, action="store_true")
78 result.add_option("--command-prefix",
79 help="Prepended to each shell command used to run a test",
80 default="")
81 result.add_option("--download-data", help="Download missing test suite data",
82 default=False, action="store_true")
83 result.add_option("--extra-flags",
84 help="Additional flags to pass to each test command",
85 default="")
86 result.add_option("--isolates", help="Whether to test isolates",
87 default=False, action="store_true")
88 result.add_option("-j", help="The number of parallel tasks to run",
89 default=0, type="int")
90 result.add_option("-m", "--mode",
91 help="The test modes in which to run (comma-separated)",
92 default="release,debug")
93 result.add_option("--no-network", "--nonetwork",
94 help="Don't distribute tests on the network",
95 default=(utils.GuessOS() != "linux"),
96 dest="no_network", action="store_true")
97 result.add_option("--no-presubmit", "--nopresubmit",
98 help='Skip presubmit checks',
99 default=False, dest="no_presubmit", action="store_true")
100 result.add_option("--no-stress", "--nostress",
101 help="Don't run crankshaft --always-opt --stress-op test",
102 default=False, dest="no_stress", action="store_true")
103 result.add_option("--outdir", help="Base directory with compile output",
104 default="out")
105 result.add_option("-p", "--progress",
106 help=("The style of progress indicator"
107 " (verbose, dots, color, mono)"),
108 choices=progress.PROGRESS_INDICATORS.keys(), default="mono")
109 result.add_option("--report", help="Print a summary of the tests to be run",
110 default=False, action="store_true")
111 result.add_option("--shard-count",
112 help="Split testsuites into this number of shards",
113 default=1, type="int")
114 result.add_option("--shard-run",
115 help="Run this shard from the split up tests.",
116 default=1, type="int")
117 result.add_option("--shell", help="DEPRECATED! use --shell-dir", default="")
118 result.add_option("--shell-dir", help="Directory containing executables",
119 default="")
120 result.add_option("--stress-only",
121 help="Only run tests with --always-opt --stress-opt",
122 default=False, action="store_true")
123 result.add_option("--time", help="Print timing information after running",
124 default=False, action="store_true")
125 result.add_option("-t", "--timeout", help="Timeout in seconds",
126 default= -1, type="int")
127 result.add_option("-v", "--verbose", help="Verbose output",
128 default=False, action="store_true")
129 result.add_option("--valgrind", help="Run tests through valgrind",
130 default=False, action="store_true")
131 result.add_option("--warn-unused", help="Report unused rules",
132 default=False, action="store_true")
133 return result
134
135
136 def ProcessOptions(options):
137 global VARIANT_FLAGS
138
139 # Architecture and mode related stuff.
140 if options.arch_and_mode:
141 tokens = options.arch_and_mode.split(".")
142 options.arch = tokens[0]
143 options.mode = tokens[1]
144 options.mode = options.mode.split(",")
145 for mode in options.mode:
146 if not mode in ["debug", "release"]:
147 print "Unknown mode %s" % mode
148 return False
149 if options.arch in ["auto", "native"]:
150 options.arch = ARCH_GUESS
151 options.arch = options.arch.split(",")
152 for arch in options.arch:
153 if not arch in ['ia32', 'x64', 'arm', 'mipsel']:
154 print "Unknown architecture %s" % arch
155 return False
156
157 # Special processing of other options, sorted alphabetically.
158
159 if options.buildbot:
160 # Buildbots run presubmit tests as a separate step.
161 options.no_presubmit = True
162 options.no_network = True
163 if options.command_prefix:
164 print("Specifying --command-prefix disables network distribution, "
165 "running tests locally.")
166 options.no_network = True
167 if options.j == 0:
168 options.j = multiprocessing.cpu_count()
169 if options.no_stress:
170 VARIANT_FLAGS = [[], ["--nocrankshaft"]]
171 if not options.shell_dir:
172 if options.shell:
173 print "Warning: --shell is deprecated, use --shell-dir instead."
174 options.shell_dir = os.path.dirname(options.shell)
175 if options.stress_only:
176 VARIANT_FLAGS = [["--stress-opt", "--always-opt"]]
177 # Simulators are slow, therefore allow a longer default timeout.
178 if options.timeout == -1:
179 if options.arch == "arm" or options.arch == "mipsel":
180 options.timeout = 2 * TIMEOUT_DEFAULT;
181 else:
182 options.timeout = TIMEOUT_DEFAULT;
183 if options.valgrind:
184 run_valgrind = os.path.join("tools", "run-valgrind.py")
185 # This is OK for distributed running, so we don't need to set no_network.
186 options.command_prefix = ("python -u " + run_valgrind +
187 options.command_prefix)
188 return True
189
190
191 def ShardTests(tests, shard_count, shard_run):
192 if shard_count < 2:
193 return tests
194 if shard_run < 1 or shard_run > shard_count:
195 print "shard-run not a valid number, should be in [1:shard-count]"
196 print "defaulting back to running all tests"
197 return tests
198 count = 0
199 shard = []
200 for test in tests:
201 if count % shard_count == shard_run - 1:
202 shard.append(test)
203 count += 1
204 return shard
205
206
207 def Main():
208 parser = BuildOptions()
209 (options, args) = parser.parse_args()
210 if not ProcessOptions(options):
211 parser.print_help()
212 return 1
213
214 exit_code = 0
215 workspace = os.path.abspath(join(os.path.dirname(sys.argv[0]), ".."))
216 if not options.no_presubmit:
217 print ">>> running presubmit tests"
218 code = subprocess.call(
219 [sys.executable, join(workspace, "tools", "presubmit.py")])
220 exit_code = code
221
222 suite_paths = utils.GetSuitePaths(join(workspace, "test"))
223 print "all suite_paths:", suite_paths
224
225 if len(args) == 0:
226 suite_paths = [ s for s in suite_paths if s in DEFAULT_TESTS ]
227 else:
228 args_suites = set()
229 for arg in args:
230 suite = arg.split(os.path.sep)[0]
231 if not suite in args_suites:
232 args_suites.add(suite)
233 suite_paths = [ s for s in suite_paths if s in args_suites ]
234
235 suites = []
236 for root in suite_paths:
237 suite = testsuite.TestSuite.LoadTestSuite(
238 os.path.join(workspace, "test", root))
239 if suite:
240 suites.append(suite)
241
242 if options.download_data:
243 for s in suites:
244 s.DownloadData()
245
246 for mode in options.mode:
247 for arch in options.arch:
248 code = Execute(arch, mode, args, options, suites, workspace)
249 exit_code = exit_code or code
250 return exit_code
251
252
253 def Execute(arch, mode, args, options, suites, workspace):
254 print(">>> Running tests for %s.%s" % (arch, mode))
255
256 shell_dir = options.shell_dir
257 if not shell_dir:
258 if options.buildbot:
259 shell_dir = os.path.join(workspace, options.outdir, mode)
260 mode = mode.lower()
261 else:
262 shell_dir = os.path.join(workspace, options.outdir,
263 "%s.%s" % (arch, mode))
264 shell_dir = os.path.relpath(shell_dir)
265
266 # Populate context object.
267 mode_flags = MODE_FLAGS[mode]
268 options.timeout *= TIMEOUT_SCALEFACTOR[mode]
269 ctx = context.Context(arch, mode, shell_dir,
270 mode_flags, options.verbose,
271 options.timeout, options.isolates,
272 options.command_prefix,
273 options.extra_flags)
274
275 # Find available test suites and read test cases from them.
276 variables = {
277 "mode": mode,
278 "arch": arch,
279 "system": utils.GuessOS(),
280 "isolates": options.isolates
281 }
282 all_tests = []
283 num_tests = 0
284 test_id = 0
285 for s in suites:
286 s.ReadStatusFile(variables)
287 s.ReadTestCases(ctx)
288 all_tests += s.tests
289 if len(args) > 0:
290 s.FilterTestCasesByArgs(args)
291 s.FilterTestCasesByStatus(options.warn_unused)
292 if options.cat:
293 verbose.PrintTestSource(s.tests)
294 continue
295 variant_flags = s.VariantFlags() or VARIANT_FLAGS
296 s.tests = [ t.CopyAddingFlags(v) for t in s.tests for v in variant_flags ]
297 s.tests = ShardTests(s.tests, options.shard_count, options.shard_run)
298 num_tests += len(s.tests)
299 for t in s.tests:
300 t.id = test_id
301 test_id += 1
302
303 if options.cat:
304 return 0 # We're done here.
305
306 if options.report:
307 verbose.PrintReport(all_tests)
308
309 if num_tests == 0:
310 print "No tests to run."
311 return 0
312
313 # Run the tests, either locally or distributed on the network.
314 try:
315 start_time = time.time()
316 progress_indicator = progress.PROGRESS_INDICATORS[options.progress]()
317
318 run_networked = not options.no_network
319 if not run_networked:
320 print("Network distribution disabled, running tests locally.")
321 elif utils.GuessOS() != "linux":
322 print("Network distribution is only supported on Linux, sorry!")
323 run_networked = False
324 peers = []
325 if run_networked:
326 peers = network_execution.GetPeers()
327 if not peers:
328 print("No connection to distribution server; running tests locally.")
329 run_networked = False
330 elif len(peers) == 1:
331 print("No other peers on the network; running tests locally.")
332 run_networked = False
333 elif num_tests <= 100:
334 print("Less than 100 tests, running them locally.")
335 run_networked = False
336
337 if run_networked:
338 runner = network_execution.NetworkedRunner(suites, progress_indicator,
339 ctx, peers, workspace)
340 else:
341 runner = execution.Runner(suites, progress_indicator, ctx)
342
343 exit_code = runner.Run(options.j)
344 if runner.terminate:
345 return exit_code
346 overall_duration = time.time() - start_time
347 except KeyboardInterrupt:
348 return 1
349
350 if options.time:
351 verbose.PrintTestDurations(suites, overall_duration)
352 return exit_code
353
354
355 if __name__ == "__main__":
356 sys.exit(Main())
OLDNEW
« no previous file with comments | « tools/presubmit.py ('k') | tools/status-file-converter.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698