Modified: trunk/Tools/ChangeLog (271178 => 271179)
--- trunk/Tools/ChangeLog 2021-01-05 23:02:40 UTC (rev 271178)
+++ trunk/Tools/ChangeLog 2021-01-05 23:14:21 UTC (rev 271179)
@@ -1,3 +1,21 @@
+2021-01-05 Angelos Oikonomopoulos <[email protected]>
+
+ [JSC] allow stress tests to opt out of parallel execution
+ https://bugs.webkit.org/show_bug.cgi?id=213373
+
+ Reviewed by Yusuke Suzuki.
+
+ On memory-limited devices, some JSC stress tests may intermittently OOM when
+ they get scheduled along with another heavy JSC stress test. However, the tests
+ might be able to complete if run on their own.
+
+ This patch adds a serial! directive that causes a JSC stress test to only ever
+ be scheduled to run by itself. It's currently unused and needs to be enabled on
+ a test-by-test basis.
+
+ * Scripts/run-jsc-stress-tests:
+ * Scripts/webkitruby/jsc-stress-test-writer-default.rb:
+
2021-01-05 Ryan Haddad <[email protected]>
Unreviewed, reverting r271169.
Modified: trunk/Tools/Scripts/run-jsc-stress-tests (271178 => 271179)
--- trunk/Tools/Scripts/run-jsc-stress-tests 2021-01-05 23:02:40 UTC (rev 271178)
+++ trunk/Tools/Scripts/run-jsc-stress-tests 2021-01-05 23:14:21 UTC (rev 271179)
@@ -551,6 +551,7 @@
COLLECT_CONTINUOUSLY_OPTIONS = shouldCollectContinuously? ? ["--collectContinuously=true", "--useGenerationalGC=false"] : []
+$serialRunlist = []
$runlist = []
def frameworkFromJSCPath(jscPath)
@@ -618,6 +619,14 @@
$benchmarkDirectory, command, "#{$collectionName}/#{$benchmark}", name, outputHandler,
errorHandler)
plan.additionalEnv.push(*additionalEnv)
+ if $runCommandOptions[:serial]
+ # Add this to the list of tests to be run on their own, so
+ # that we can treat them specially when scheduling, but keep
+ # it in the $runlist for code that dosn't care about
+ # scheduling.
+ $serialRunlist << plan
+ end
+
if $numChildProcesses > 1 and $runCommandOptions[:isSlow]
$runlist.unshift plan
else
@@ -669,6 +678,10 @@
$runCommandOptions[:crashOK] = true
end
+def serial!
+ $runCommandOptions[:serial] = true
+end
+
def requireOptions(*options)
$testSpecificRequiredOptions += options
end
@@ -2389,19 +2402,29 @@
detectFailures
end
-def prepareGnuParallelTestRunner
- path = $runnerDir + "parallel-tests"
+def prepareGnuParallelRunnerJobs(name, runlist, exclude)
+ path = $runnerDir + name
FileUtils.mkdir_p($runnerDir)
File.open(path, "w") {
| outp |
- $runlist.each {
+ runlist.each {
| plan |
+ if exclude.has_key?(plan)
+ next
+ end
outp.puts("./test_script_#{plan.index}")
}
}
end
+def prepareGnuParallelTestRunner
+ serialTests = {}
+ $serialRunlist.each { |p| serialTests[p] = nil }
+ prepareGnuParallelRunnerJobs("parallel-tests", $runlist, serialTests)
+ prepareGnuParallelRunnerJobs("serial-tests", $serialRunlist, {})
+end
+
def withGnuParallelSshWrapper(&blk)
Tempfile.open('ssh-wrapper', $runnerDir) {
| wrapper |
@@ -2461,21 +2484,24 @@
}
end
-def runGnuParallelRunner
- inputs = $runnerDir + "parallel-tests"
+def runGnuParallelRunner(inputs, options={})
timeout = 300
if ENV["JSCTEST_timeout"]
timeout = ENV["JSCTEST_timeout"].to_f.ceil.to_i
end
+ # We add 1 to make sure we always have waiting jobs and
+ # don't run into stalls due to ssh latency. However, we
+ # want to respect numChildProcesses, so we don't just use
+ # the -j +1 GNU parallel idiom.
+ parallelJobsOnEachHost = $numChildProcesses + 1
+ if options[:parallelJobsOnEachHost]
+ parallelJobsOnEachHost = options[:parallelJobsOnEachHost]
+ end
withGnuParallelSshLoginFile {
| slf |
cmd = [
"parallel",
- # We add 1 to make sure we always have waiting jobs and
- # don't run into stalls due to ssh latency. However, we
- # want to respect numChildProcesses, so we don't just use
- # the -j +1 GNU parallel idiom.
- "-j", "#{$numChildProcesses + 1}",
+ "-j", "#{parallelJobsOnEachHost}",
"--retries 5",
"--line-buffer", # we know our output is line-oriented
"--slf", slf,
@@ -2508,7 +2534,9 @@
if $remoteHosts.size == 0
raise "All remote hosts failed, giving up"
end
- runGnuParallelRunner
+ runGnuParallelRunner($runnerDir + "serial-tests",
+ { :parallelJobsOnEachHost => 1})
+ runGnuParallelRunner($runnerDir + "parallel-tests")
detectFailures
end
Modified: trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-default.rb (271178 => 271179)
--- trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-default.rb 2021-01-05 23:02:40 UTC (rev 271178)
+++ trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-default.rb 2021-01-05 23:14:21 UTC (rev 271179)
@@ -305,17 +305,27 @@
FileUtils.cp SCRIPTS_PATH + "jsc-stress-test-helpers" + "shell-runner.sh", $runnerDir + "runscript"
end
+def output_target(outp, plan, prereqs)
+ index = plan.index
+ target = "test_done_#{index}"
+ outp.puts "#{target}: #{prereqs.join(" ")}"
+ outp.puts "\tsh test_script_#{index}"
+ target
+end
+
def prepareMakeTestRunner(remoteIndex)
# The goals of our parallel test runner are scalability and simplicity. The
# simplicity part is particularly important. We don't want to have to have
# a full-time contributor just philosophising about parallel testing.
#
- # As such, we just pass off all of the hard work to 'make'. This creates a
- # dummy directory ("$outputDir/.runner") in which we create a dummy
- # Makefile. The Makefile has an 'all' rule that depends on all of the tests.
- # That is, for each test we know we will run, there is a rule in the
- # Makefile and 'all' depends on it. Running 'make -j <whatever>' on this
- # Makefile results in 'make' doing all of the hard work:
+ # As such, we just pass off all of the hard work to 'make'. This
+ # creates a dummy directory ("$outputDir/.runner") in which we
+ # create a dummy Makefile. The Makefile has a 'parallel' rule that
+ # depends all tests, other than the ones marked 'serial'. The
+ # serial tests are arranged in a chain; the last target in the
+ # serial chain depends on 'parallel' and 'all' depends on the head
+ # of the chain. Running 'make -j <whatever>' on this Makefile
+ # results in 'make' doing all of the hard work:
#
# - Load balancing just works. Most systems have a great load balancer in
# 'make'. If your system doesn't then just install a real 'make'.
@@ -340,23 +350,39 @@
# basically using the filesystem as a concurrent database of test failures.
# Even if two tests fail at the same time, since they're touching different
# files we won't miss any failures.
- runIndices = []
+ serialPlans = {}
+ $serialRunlist.each { |p| serialPlans[p] = nil }
+ runPlans = []
+ serialRunPlans = []
$runlist.each {
| plan |
if !$remote or plan.index % $remoteHosts.length == remoteIndex
- runIndices << plan.index
+ if serialPlans.has_key?(plan)
+ serialRunPlans << plan
+ else
+ runPlans << plan
+ end
end
}
-
+
File.open($runnerDir + "Makefile.#{remoteIndex}", "w") {
| outp |
- outp.puts("all: " + runIndices.map{|v| "test_done_#{v}"}.join(' '))
- runIndices.each {
- | index |
- plan = $runlist[index]
- outp.puts "test_done_#{index}:"
- outp.puts "\tsh test_script_#{plan.index}"
+ if serialRunPlans.empty?
+ outp.puts("all: parallel")
+ else
+ serialPrereq = "test_done_#{serialRunPlans[-1].index}"
+ outp.puts("all: #{serialPrereq}")
+ prev_target = "parallel"
+ serialRunPlans.each {
+ | plan |
+ prev_target = output_target(outp, plan, [prev_target])
+ }
+ end
+ parallelTargets = runPlans.collect {
+ | plan |
+ output_target(outp, plan, [])
}
+ outp.puts("parallel: " + parallelTargets.join(" "))
}
end