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

Side by Side Diff: tools/run-deopt-fuzzer.py

Issue 19931005: Add deopt fuzzer tool. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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 | « test/mjsunit/mjsunit.status ('k') | tools/run-tests.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 2012 the V8 project authors. All rights reserved. 3 # Copyright 2012 the V8 project authors. All rights reserved.
4 # Redistribution and use in source and binary forms, with or without 4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are 5 # modification, are permitted provided that the following conditions are
6 # met: 6 # met:
7 # 7 #
8 # * Redistributions of source code must retain the above copyright 8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer. 9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above 10 # * Redistributions in binary form must reproduce the above
(...skipping 10 matching lines...) Expand all
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 29
30 30
31 import json
32 import math
31 import multiprocessing 33 import multiprocessing
32 import optparse 34 import optparse
33 import os 35 import os
34 from os.path import join 36 from os.path import join
37 import random
35 import shlex 38 import shlex
36 import subprocess 39 import subprocess
37 import sys 40 import sys
38 import time 41 import time
39 42
40 from testrunner.local import execution 43 from testrunner.local import execution
41 from testrunner.local import progress 44 from testrunner.local import progress
42 from testrunner.local import testsuite 45 from testrunner.local import testsuite
43 from testrunner.local import utils 46 from testrunner.local import utils
44 from testrunner.local import verbose 47 from testrunner.local import verbose
45 from testrunner.network import network_execution
46 from testrunner.objects import context 48 from testrunner.objects import context
47 49
48 50
49 ARCH_GUESS = utils.DefaultArch() 51 ARCH_GUESS = utils.DefaultArch()
50 DEFAULT_TESTS = ["mjsunit", "cctest", "message", "preparser"] 52 DEFAULT_TESTS = ["mjsunit"]
51 TIMEOUT_DEFAULT = 60 53 TIMEOUT_DEFAULT = 60
52 TIMEOUT_SCALEFACTOR = {"debug" : 4, 54 TIMEOUT_SCALEFACTOR = {"debug" : 4,
53 "release" : 1 } 55 "release" : 1 }
54 56
55 # Use this to run several variants of the tests.
56 VARIANT_FLAGS = [[],
57 ["--stress-opt", "--always-opt"],
58 ["--nocrankshaft"]]
59 MODE_FLAGS = { 57 MODE_FLAGS = {
60 "debug" : ["--nobreak-on-abort", "--nodead-code-elimination", 58 "debug" : ["--nobreak-on-abort", "--nodead-code-elimination",
61 "--nofold-constants", "--enable-slow-asserts", 59 "--nofold-constants", "--enable-slow-asserts",
62 "--debug-code", "--verify-heap"], 60 "--debug-code", "--verify-heap",
61 "--noparallel-recompilation"],
63 "release" : ["--nobreak-on-abort", "--nodead-code-elimination", 62 "release" : ["--nobreak-on-abort", "--nodead-code-elimination",
64 "--nofold-constants"]} 63 "--nofold-constants", "--noparallel-recompilation"]}
65 64
66 SUPPORTED_ARCHS = ["android_arm", 65 SUPPORTED_ARCHS = ["android_arm",
67 "android_ia32", 66 "android_ia32",
68 "arm", 67 "arm",
69 "ia32", 68 "ia32",
70 "mipsel", 69 "mipsel",
71 "nacl_ia32", 70 "nacl_ia32",
72 "nacl_x64", 71 "nacl_x64",
73 "x64"] 72 "x64"]
74 # Double the timeout for these: 73 # Double the timeout for these:
75 SLOW_ARCHS = ["android_arm", 74 SLOW_ARCHS = ["android_arm",
76 "android_ia32", 75 "android_ia32",
77 "arm", 76 "arm",
78 "mipsel", 77 "mipsel",
79 "nacl_ia32", 78 "nacl_ia32",
80 "nacl_x64"] 79 "nacl_x64"]
80 MAX_DEOPT = 1000000000
81 DISTRIBUTION_MODES = ["smooth", "random"]
82
83
84 class RandomDistribution:
85 def __init__(self, seed=None):
86 seed = seed or random.randint(1, sys.maxint)
87 print "Using random distribution with seed %d" % seed
88 self._random = random.Random(seed)
89
90 def Distribute(self, n, m):
91 if n > m:
92 n = m
93 return self._random.sample(xrange(1, m + 1), n)
94
95
96 class SmoothDistribution:
97 """Distribute n numbers into the interval [1:m].
98 F1: Factor of the first derivation of the distribution function.
99 F2: Factor of the second derivation of the distribution function.
100 With F1 and F2 set to 0, the distribution will be equal.
101 """
102 def __init__(self, factor1=2.0, factor2=0.2):
103 self._factor1 = factor1
104 self._factor2 = factor2
105
106 def Distribute(self, n, m):
107 if n > m:
108 n = m
109 if n <= 1:
110 return [ 1 ]
111
112 result = []
113 x = 0.0
114 dx = 1.0
115 ddx = self._factor1
116 dddx = self._factor2
117 for i in range(0, n):
118 result += [ x ]
119 x += dx
120 dx += ddx
121 ddx += dddx
122
123 # Project the distribution into the interval [0:M].
124 result = [ x * m / result[-1] for x in result ]
125
126 # Equalize by n. The closer n is to m, the more equal will be the
127 # distribution.
128 for (i, x) in enumerate(result):
129 # The value of x if it was equally distributed.
130 equal_x = i / float(n - 1) * float(m - 1) + 1
131
132 # Difference factor between actual and equal distribution.
133 diff = 1 - (x / equal_x)
134
135 # Equalize x dependent on the number of values to distribute.
136 result[i] = int(x + (i + 1) * diff)
137 return result
138
139
140 def Distribution(options):
141 if options.distribution_mode == "random":
142 return RandomDistribution(options.seed)
143 if options.distribution_mode == "smooth":
144 return SmoothDistribution(options.distribution_factor1,
145 options.distribution_factor2)
81 146
82 147
83 def BuildOptions(): 148 def BuildOptions():
84 result = optparse.OptionParser() 149 result = optparse.OptionParser()
85 result.add_option("--arch", 150 result.add_option("--arch",
86 help=("The architecture to run tests for, " 151 help=("The architecture to run tests for, "
87 "'auto' or 'native' for auto-detect"), 152 "'auto' or 'native' for auto-detect"),
88 default="ia32,x64,arm") 153 default="ia32,x64,arm")
89 result.add_option("--arch-and-mode", 154 result.add_option("--arch-and-mode",
90 help="Architecture and mode in the format 'arch.mode'", 155 help="Architecture and mode in the format 'arch.mode'",
91 default=None) 156 default=None)
92 result.add_option("--buildbot", 157 result.add_option("--buildbot",
93 help="Adapt to path structure used on buildbots", 158 help="Adapt to path structure used on buildbots",
94 default=False, action="store_true") 159 default=False, action="store_true")
95 result.add_option("--cat", help="Print the source of the tests",
96 default=False, action="store_true")
97 result.add_option("--command-prefix", 160 result.add_option("--command-prefix",
98 help="Prepended to each shell command used to run a test", 161 help="Prepended to each shell command used to run a test",
99 default="") 162 default="")
163 result.add_option("--coverage", help=("Exponential test coverage "
164 "(range 0.0, 1.0) -- 0.0: one test, 1.0 all tests (slow)"),
165 default=0.4, type="float")
166 result.add_option("--coverage-lift", help=("Lifts test coverage for tests "
167 "with a small number of deopt points (range 0, inf)"),
168 default=20, type="int")
100 result.add_option("--download-data", help="Download missing test suite data", 169 result.add_option("--download-data", help="Download missing test suite data",
101 default=False, action="store_true") 170 default=False, action="store_true")
171 result.add_option("--distribution-factor1", help=("Factor of the first "
172 "derivation of the distribution function"), default=2.0,
173 type="float")
174 result.add_option("--distribution-factor2", help=("Factor of the second "
175 "derivation of the distribution function"), default=0.7,
176 type="float")
177 result.add_option("--distribution-mode", help=("How to select deopt points "
178 "for a given test (smooth|random)"),
179 default="smooth")
180 result.add_option("--dump-results-file", help=("Dump maximum number of "
181 "deopt points per test to a file"))
102 result.add_option("--extra-flags", 182 result.add_option("--extra-flags",
103 help="Additional flags to pass to each test command", 183 help="Additional flags to pass to each test command",
104 default="") 184 default="")
105 result.add_option("--isolates", help="Whether to test isolates", 185 result.add_option("--isolates", help="Whether to test isolates",
106 default=False, action="store_true") 186 default=False, action="store_true")
107 result.add_option("-j", help="The number of parallel tasks to run", 187 result.add_option("-j", help="The number of parallel tasks to run",
108 default=0, type="int") 188 default=0, type="int")
109 result.add_option("-m", "--mode", 189 result.add_option("-m", "--mode",
110 help="The test modes in which to run (comma-separated)", 190 help="The test modes in which to run (comma-separated)",
111 default="release,debug") 191 default="release,debug")
112 result.add_option("--no-network", "--nonetwork",
113 help="Don't distribute tests on the network",
114 default=(utils.GuessOS() != "linux"),
115 dest="no_network", action="store_true")
116 result.add_option("--no-presubmit", "--nopresubmit",
117 help='Skip presubmit checks',
118 default=False, dest="no_presubmit", action="store_true")
119 result.add_option("--no-stress", "--nostress",
120 help="Don't run crankshaft --always-opt --stress-op test",
121 default=False, dest="no_stress", action="store_true")
122 result.add_option("--outdir", help="Base directory with compile output", 192 result.add_option("--outdir", help="Base directory with compile output",
123 default="out") 193 default="out")
124 result.add_option("-p", "--progress", 194 result.add_option("-p", "--progress",
125 help=("The style of progress indicator" 195 help=("The style of progress indicator"
126 " (verbose, dots, color, mono)"), 196 " (verbose, dots, color, mono)"),
127 choices=progress.PROGRESS_INDICATORS.keys(), default="mono") 197 choices=progress.PROGRESS_INDICATORS.keys(),
128 result.add_option("--report", help="Print a summary of the tests to be run", 198 default="mono")
129 default=False, action="store_true")
130 result.add_option("--shard-count", 199 result.add_option("--shard-count",
131 help="Split testsuites into this number of shards", 200 help="Split testsuites into this number of shards",
132 default=1, type="int") 201 default=1, type="int")
133 result.add_option("--shard-run", 202 result.add_option("--shard-run",
134 help="Run this shard from the split up tests.", 203 help="Run this shard from the split up tests.",
135 default=1, type="int") 204 default=1, type="int")
136 result.add_option("--shell", help="DEPRECATED! use --shell-dir", default="")
137 result.add_option("--shell-dir", help="Directory containing executables", 205 result.add_option("--shell-dir", help="Directory containing executables",
138 default="") 206 default="")
139 result.add_option("--stress-only", 207 result.add_option("--seed", help="The seed for the random distribution",
140 help="Only run tests with --always-opt --stress-opt", 208 type="int")
141 default=False, action="store_true")
142 result.add_option("--time", help="Print timing information after running",
143 default=False, action="store_true")
144 result.add_option("-t", "--timeout", help="Timeout in seconds", 209 result.add_option("-t", "--timeout", help="Timeout in seconds",
145 default= -1, type="int") 210 default= -1, type="int")
146 result.add_option("-v", "--verbose", help="Verbose output", 211 result.add_option("-v", "--verbose", help="Verbose output",
147 default=False, action="store_true") 212 default=False, action="store_true")
148 result.add_option("--valgrind", help="Run tests through valgrind",
149 default=False, action="store_true")
150 result.add_option("--warn-unused", help="Report unused rules",
151 default=False, action="store_true")
152 result.add_option("--junitout", help="File name of the JUnit output")
153 result.add_option("--junittestsuite",
154 help="The testsuite name in the JUnit output file",
155 default="v8tests")
156 return result 213 return result
157 214
158 215
159 def ProcessOptions(options): 216 def ProcessOptions(options):
160 global VARIANT_FLAGS 217 global VARIANT_FLAGS
161 218
162 # Architecture and mode related stuff. 219 # Architecture and mode related stuff.
163 if options.arch_and_mode: 220 if options.arch_and_mode:
164 tokens = options.arch_and_mode.split(".") 221 tokens = options.arch_and_mode.split(".")
165 options.arch = tokens[0] 222 options.arch = tokens[0]
166 options.mode = tokens[1] 223 options.mode = tokens[1]
167 options.mode = options.mode.split(",") 224 options.mode = options.mode.split(",")
168 for mode in options.mode: 225 for mode in options.mode:
169 if not mode.lower() in ["debug", "release"]: 226 if not mode.lower() in ["debug", "release"]:
170 print "Unknown mode %s" % mode 227 print "Unknown mode %s" % mode
171 return False 228 return False
172 if options.arch in ["auto", "native"]: 229 if options.arch in ["auto", "native"]:
173 options.arch = ARCH_GUESS 230 options.arch = ARCH_GUESS
174 options.arch = options.arch.split(",") 231 options.arch = options.arch.split(",")
175 for arch in options.arch: 232 for arch in options.arch:
176 if not arch in SUPPORTED_ARCHS: 233 if not arch in SUPPORTED_ARCHS:
177 print "Unknown architecture %s" % arch 234 print "Unknown architecture %s" % arch
178 return False 235 return False
179 236
180 # Special processing of other options, sorted alphabetically. 237 # Special processing of other options, sorted alphabetically.
181
182 if options.buildbot:
183 # Buildbots run presubmit tests as a separate step.
184 options.no_presubmit = True
185 options.no_network = True
186 if options.command_prefix:
187 print("Specifying --command-prefix disables network distribution, "
188 "running tests locally.")
189 options.no_network = True
190 options.command_prefix = shlex.split(options.command_prefix) 238 options.command_prefix = shlex.split(options.command_prefix)
191 options.extra_flags = shlex.split(options.extra_flags) 239 options.extra_flags = shlex.split(options.extra_flags)
192 if options.j == 0: 240 if options.j == 0:
193 options.j = multiprocessing.cpu_count() 241 options.j = multiprocessing.cpu_count()
194 if options.no_stress: 242 if not options.distribution_mode in DISTRIBUTION_MODES:
195 VARIANT_FLAGS = [[], ["--nocrankshaft"]] 243 print "Unknown distribution mode %s" % options.distribution_mode
196 if not options.shell_dir: 244 return False
197 if options.shell: 245 if options.distribution_factor1 < 0.0:
198 print "Warning: --shell is deprecated, use --shell-dir instead." 246 options.distribution_factor1 = 0.0
Jakob Kummerow 2013/07/23 15:13:43 might want to print a warning here too: "Invalid -
199 options.shell_dir = os.path.dirname(options.shell) 247 if options.distribution_factor2 < 0.0:
200 if options.stress_only: 248 options.distribution_factor2 = 0.0
201 VARIANT_FLAGS = [["--stress-opt", "--always-opt"]] 249 if options.coverage < 0.0 or options.coverage > 1.0:
202 if options.valgrind: 250 options.coverage = 0.4
203 run_valgrind = os.path.join("tools", "run-valgrind.py") 251 if options.coverage_lift < 0:
204 # This is OK for distributed running, so we don't need to set no_network. 252 options.coverage_lift = 0
205 options.command_prefix = (["python", "-u", run_valgrind] +
206 options.command_prefix)
207 return True 253 return True
208 254
209 255
210 def ShardTests(tests, shard_count, shard_run): 256 def ShardTests(tests, shard_count, shard_run):
211 if shard_count < 2: 257 if shard_count < 2:
212 return tests 258 return tests
213 if shard_run < 1 or shard_run > shard_count: 259 if shard_run < 1 or shard_run > shard_count:
214 print "shard-run not a valid number, should be in [1:shard-count]" 260 print "shard-run not a valid number, should be in [1:shard-count]"
215 print "defaulting back to running all tests" 261 print "defaulting back to running all tests"
216 return tests 262 return tests
217 count = 0 263 count = 0
218 shard = [] 264 shard = []
219 for test in tests: 265 for test in tests:
220 if count % shard_count == shard_run - 1: 266 if count % shard_count == shard_run - 1:
221 shard.append(test) 267 shard.append(test)
222 count += 1 268 count += 1
223 return shard 269 return shard
224 270
225 271
226 def Main(): 272 def Main():
227 parser = BuildOptions() 273 parser = BuildOptions()
228 (options, args) = parser.parse_args() 274 (options, args) = parser.parse_args()
229 if not ProcessOptions(options): 275 if not ProcessOptions(options):
230 parser.print_help() 276 parser.print_help()
231 return 1 277 return 1
232 278
233 exit_code = 0 279 exit_code = 0
234 workspace = os.path.abspath(join(os.path.dirname(sys.argv[0]), "..")) 280 workspace = os.path.abspath(join(os.path.dirname(sys.argv[0]), ".."))
235 if not options.no_presubmit:
236 print ">>> running presubmit tests"
237 code = subprocess.call(
238 [sys.executable, join(workspace, "tools", "presubmit.py")])
239 exit_code = code
240 281
241 suite_paths = utils.GetSuitePaths(join(workspace, "test")) 282 suite_paths = utils.GetSuitePaths(join(workspace, "test"))
242 283
243 if len(args) == 0: 284 if len(args) == 0:
244 suite_paths = [ s for s in suite_paths if s in DEFAULT_TESTS ] 285 suite_paths = [ s for s in suite_paths if s in DEFAULT_TESTS ]
245 else: 286 else:
246 args_suites = set() 287 args_suites = set()
247 for arg in args: 288 for arg in args:
248 suite = arg.split(os.path.sep)[0] 289 suite = arg.split(os.path.sep)[0]
249 if not suite in args_suites: 290 if not suite in args_suites:
(...skipping 11 matching lines...) Expand all
261 for s in suites: 302 for s in suites:
262 s.DownloadData() 303 s.DownloadData()
263 304
264 for mode in options.mode: 305 for mode in options.mode:
265 for arch in options.arch: 306 for arch in options.arch:
266 code = Execute(arch, mode, args, options, suites, workspace) 307 code = Execute(arch, mode, args, options, suites, workspace)
267 exit_code = exit_code or code 308 exit_code = exit_code or code
268 return exit_code 309 return exit_code
269 310
270 311
312 def CalculateNTests(m, options):
313 """Calculates the number of tests from m deopt points with exponential
314 coverage.
315 The coverage is expected to be between 0.0 and 1.0.
316 The 'coverage lift' lifts the coverage for tests with smaller m values.
317 """
318 c = float(options.coverage)
319 l = float(options.coverage_lift)
320 return int(math.pow(float(m), (float(m) * c + l) / (float(m) + l)))
Jakob Kummerow 2013/07/23 15:13:43 I think you can s/float(m)/m/ three times here.
321
322
271 def Execute(arch, mode, args, options, suites, workspace): 323 def Execute(arch, mode, args, options, suites, workspace):
272 print(">>> Running tests for %s.%s" % (arch, mode)) 324 print(">>> Running tests for %s.%s" % (arch, mode))
273 325
326 dist = Distribution(options)
327
274 shell_dir = options.shell_dir 328 shell_dir = options.shell_dir
275 if not shell_dir: 329 if not shell_dir:
276 if options.buildbot: 330 if options.buildbot:
277 shell_dir = os.path.join(workspace, options.outdir, mode) 331 shell_dir = os.path.join(workspace, options.outdir, mode)
278 mode = mode.lower() 332 mode = mode.lower()
279 else: 333 else:
280 shell_dir = os.path.join(workspace, options.outdir, 334 shell_dir = os.path.join(workspace, options.outdir,
281 "%s.%s" % (arch, mode)) 335 "%s.%s" % (arch, mode))
282 shell_dir = os.path.relpath(shell_dir) 336 shell_dir = os.path.relpath(shell_dir)
283 337
(...skipping 12 matching lines...) Expand all
296 mode_flags, options.verbose, 350 mode_flags, options.verbose,
297 timeout, options.isolates, 351 timeout, options.isolates,
298 options.command_prefix, 352 options.command_prefix,
299 options.extra_flags) 353 options.extra_flags)
300 354
301 # Find available test suites and read test cases from them. 355 # Find available test suites and read test cases from them.
302 variables = { 356 variables = {
303 "mode": mode, 357 "mode": mode,
304 "arch": arch, 358 "arch": arch,
305 "system": utils.GuessOS(), 359 "system": utils.GuessOS(),
306 "isolates": options.isolates 360 "isolates": options.isolates,
361 "deopt_fuzzer": True,
307 } 362 }
308 all_tests = [] 363 all_tests = []
309 num_tests = 0 364 num_tests = 0
310 test_id = 0 365 test_id = 0
366
367 # Remember test case prototypes for the fuzzing phase.
368 test_backup = dict((s, []) for s in suites)
369
311 for s in suites: 370 for s in suites:
312 s.ReadStatusFile(variables) 371 s.ReadStatusFile(variables)
313 s.ReadTestCases(ctx) 372 s.ReadTestCases(ctx)
314 if len(args) > 0: 373 if len(args) > 0:
315 s.FilterTestCasesByArgs(args) 374 s.FilterTestCasesByArgs(args)
316 all_tests += s.tests 375 all_tests += s.tests
317 s.FilterTestCasesByStatus(options.warn_unused) 376 s.FilterTestCasesByStatus(False)
318 if options.cat: 377 test_backup[s] = s.tests
319 verbose.PrintTestSource(s.tests) 378 analysis_flags = [
Jakob Kummerow 2013/07/23 15:13:43 couple nits here: (1) use proper string formatting
320 continue 379 '--deopt-every-n-times',
321 variant_flags = s.VariantFlags() or VARIANT_FLAGS 380 str(MAX_DEOPT),
322 s.tests = [ t.CopyAddingFlags(v) for t in s.tests for v in variant_flags ] 381 '--print-deopt-stress',
323 s.tests = ShardTests(s.tests, options.shard_count, options.shard_run) 382 ]
383 s.tests = [ t.CopyAddingFlags(analysis_flags) for t in s.tests ]
324 num_tests += len(s.tests) 384 num_tests += len(s.tests)
325 for t in s.tests: 385 for t in s.tests:
326 t.id = test_id 386 t.id = test_id
327 test_id += 1 387 test_id += 1
328 388
329 if options.cat: 389 if num_tests == 0:
330 return 0 # We're done here. 390 print "No tests to run."
391 return 0
331 392
332 if options.report: 393 try:
333 verbose.PrintReport(all_tests) 394 print(">>> Collection phase")
395 progress_indicator = progress.PROGRESS_INDICATORS[options.progress]()
396 runner = execution.Runner(suites, progress_indicator, ctx)
397
398 exit_code = runner.Run(options.j)
399 if runner.terminate:
400 return exit_code
401
402 except KeyboardInterrupt:
403 return 1
404
405 print(">>> Analysis phase")
406 num_tests = 0
407 test_id = 0
408 for s in suites:
409 test_results = {}
410 for t in s.tests:
411 for line in t.output.stdout.splitlines():
412 if line.startswith('=== Stress deopt counter: '):
Jakob Kummerow 2013/07/23 15:13:43 nit: ""
413 test_results[t.path] = MAX_DEOPT - int(line.split(' ')[-1])
414 for t in s.tests:
415 if t.path not in test_results:
416 print "Missing results for " + t.path
Jakob Kummerow 2013/07/23 15:13:43 print "... %s" % t.path
417 if options.dump_results_file:
418 results_dict = dict((t.path, n) for (t, n) in test_results.iteritems())
419 with file(dump_results_file + "." + str(time.time()), 'w') as f:
Jakob Kummerow 2013/07/23 15:13:43 file("%s.%d.txt" % (dump_results_file, time.time()
420 f.write(json.dumps(results_dict))
421
422 # Reset tests and redistribute the prototypes from the collection phase.
423 s.tests = []
424 if options.verbose:
425 print "Test distributions:"
426 for t in test_backup[s]:
427 max_deopt = test_results.get(t.path, 0)
428 if max_deopt == 0:
429 continue
430 n_deopt = CalculateNTests(max_deopt, options)
431 distribution = dist.Distribute(n_deopt, max_deopt)
432 if options.verbose:
433 print t.path + " " + str(distribution)
Jakob Kummerow 2013/07/23 15:13:43 print "%s %s" % (t.path, distribution)
434 for i in distribution:
435 fuzzing_flags = ['--deopt-every-n-times', str(i)]
Jakob Kummerow 2013/07/23 15:13:43 nit: "" (and ideally: "%d" % i)
436 s.tests.append(t.CopyAddingFlags(fuzzing_flags))
437 num_tests += len(s.tests)
438 for t in s.tests:
439 t.id = test_id
440 test_id += 1
334 441
335 if num_tests == 0: 442 if num_tests == 0:
336 print "No tests to run." 443 print "No tests to run."
337 return 0 444 return 0
338 445
339 # Run the tests, either locally or distributed on the network.
340 try: 446 try:
341 start_time = time.time() 447 print(">>> Deopt fuzzing phase (%d test cases)" % num_tests)
342 progress_indicator = progress.PROGRESS_INDICATORS[options.progress]() 448 progress_indicator = progress.PROGRESS_INDICATORS[options.progress]()
343 if options.junitout: 449 runner = execution.Runner(suites, progress_indicator, ctx)
344 progress_indicator = progress.JUnitTestProgressIndicator(
345 progress_indicator, options.junitout, options.junittestsuite)
346
347 run_networked = not options.no_network
348 if not run_networked:
349 print("Network distribution disabled, running tests locally.")
350 elif utils.GuessOS() != "linux":
351 print("Network distribution is only supported on Linux, sorry!")
352 run_networked = False
353 peers = []
354 if run_networked:
355 peers = network_execution.GetPeers()
356 if not peers:
357 print("No connection to distribution server; running tests locally.")
358 run_networked = False
359 elif len(peers) == 1:
360 print("No other peers on the network; running tests locally.")
361 run_networked = False
362 elif num_tests <= 100:
363 print("Less than 100 tests, running them locally.")
364 run_networked = False
365
366 if run_networked:
367 runner = network_execution.NetworkedRunner(suites, progress_indicator,
368 ctx, peers, workspace)
369 else:
370 runner = execution.Runner(suites, progress_indicator, ctx)
371 450
372 exit_code = runner.Run(options.j) 451 exit_code = runner.Run(options.j)
373 if runner.terminate: 452 if runner.terminate:
374 return exit_code 453 return exit_code
375 overall_duration = time.time() - start_time 454
376 except KeyboardInterrupt: 455 except KeyboardInterrupt:
377 return 1 456 return 1
378 457
379 if options.time:
380 verbose.PrintTestDurations(suites, overall_duration)
381 return exit_code 458 return exit_code
382 459
383 460
384 if __name__ == "__main__": 461 if __name__ == "__main__":
385 sys.exit(Main()) 462 sys.exit(Main())
OLDNEW
« no previous file with comments | « test/mjsunit/mjsunit.status ('k') | tools/run-tests.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698