⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 271179 in webkit


Ignore:
Timestamp:
Jan 5, 2021, 3:14:21 PM (6 years ago)
Author:
commit-queue@webkit.org
Message:

[JSC] allow stress tests to opt out of parallel execution
https://bugs.webkit.org/show_bug.cgi?id=213373

Patch by Angelos Oikonomopoulos <Angelos Oikonomopoulos> on 2021-01-05
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:
Location:
trunk/Tools
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r271174 r271179  
     12021-01-05  Angelos Oikonomopoulos  <angelos@igalia.com>
     2
     3        [JSC] allow stress tests to opt out of parallel execution
     4        https://bugs.webkit.org/show_bug.cgi?id=213373
     5
     6        Reviewed by Yusuke Suzuki.
     7
     8        On memory-limited devices, some JSC stress tests may intermittently OOM when
     9        they get scheduled along with another heavy JSC stress test. However, the tests
     10        might be able to complete if run on their own.
     11
     12        This patch adds a serial! directive that causes a JSC stress test to only ever
     13        be scheduled to run by itself. It's currently unused and needs to be enabled on
     14        a test-by-test basis.
     15
     16        * Scripts/run-jsc-stress-tests:
     17        * Scripts/webkitruby/jsc-stress-test-writer-default.rb:
     18
    1192021-01-05  Ryan Haddad  <ryanhaddad@apple.com>
    220
  • trunk/Tools/Scripts/run-jsc-stress-tests

    r270827 r271179  
    552552COLLECT_CONTINUOUSLY_OPTIONS = shouldCollectContinuously? ? ["--collectContinuously=true", "--useGenerationalGC=false"] : []
    553553
     554$serialRunlist = []
    554555$runlist = []
    555556
     
    619620        errorHandler)
    620621    plan.additionalEnv.push(*additionalEnv)
     622    if $runCommandOptions[:serial]
     623        # Add this to the list of tests to be run on their own, so
     624        # that we can treat them specially when scheduling, but keep
     625        # it in the $runlist for code that dosn't care about
     626        # scheduling.
     627        $serialRunlist << plan
     628    end
     629
    621630    if $numChildProcesses > 1 and $runCommandOptions[:isSlow]
    622631        $runlist.unshift plan
     
    668677    $testSpecificRequiredOptions += ["-s"]
    669678    $runCommandOptions[:crashOK] = true
     679end
     680
     681def serial!
     682    $runCommandOptions[:serial] = true
    670683end
    671684
     
    23902403end
    23912404
    2392 def prepareGnuParallelTestRunner
    2393     path = $runnerDir + "parallel-tests"
     2405def prepareGnuParallelRunnerJobs(name, runlist, exclude)
     2406    path = $runnerDir + name
    23942407    FileUtils.mkdir_p($runnerDir)
    23952408
    23962409    File.open(path, "w") {
    23972410        | outp |
    2398         $runlist.each {
     2411        runlist.each {
    23992412            | plan |
     2413            if exclude.has_key?(plan)
     2414                next
     2415            end
    24002416            outp.puts("./test_script_#{plan.index}")
    24012417        }
    24022418    }
     2419end
     2420
     2421def prepareGnuParallelTestRunner
     2422    serialTests = {}
     2423    $serialRunlist.each { |p| serialTests[p] = nil }
     2424    prepareGnuParallelRunnerJobs("parallel-tests", $runlist, serialTests)
     2425    prepareGnuParallelRunnerJobs("serial-tests", $serialRunlist, {})
    24032426end
    24042427
     
    24622485end
    24632486
    2464 def runGnuParallelRunner
    2465     inputs = $runnerDir + "parallel-tests"
     2487def runGnuParallelRunner(inputs, options={})
    24662488    timeout = 300
    24672489    if ENV["JSCTEST_timeout"]
    24682490        timeout = ENV["JSCTEST_timeout"].to_f.ceil.to_i
     2491    end
     2492    # We add 1 to make sure we always have waiting jobs and
     2493    # don't run into stalls due to ssh latency. However, we
     2494    # want to respect numChildProcesses, so we don't just use
     2495    # the -j +1 GNU parallel idiom.
     2496    parallelJobsOnEachHost = $numChildProcesses + 1
     2497    if options[:parallelJobsOnEachHost]
     2498      parallelJobsOnEachHost = options[:parallelJobsOnEachHost]
    24692499    end
    24702500    withGnuParallelSshLoginFile {
     
    24722502        cmd = [
    24732503            "parallel",
    2474             # We add 1 to make sure we always have waiting jobs and
    2475             # don't run into stalls due to ssh latency. However, we
    2476             # want to respect numChildProcesses, so we don't just use
    2477             # the -j +1 GNU parallel idiom.
    2478             "-j", "#{$numChildProcesses + 1}",
     2504            "-j", "#{parallelJobsOnEachHost}",
    24792505            "--retries 5",
    24802506            "--line-buffer", # we know our output is line-oriented
     
    25092535        raise "All remote hosts failed, giving up"
    25102536    end
    2511     runGnuParallelRunner
     2537    runGnuParallelRunner($runnerDir + "serial-tests",
     2538                         { :parallelJobsOnEachHost => 1})
     2539    runGnuParallelRunner($runnerDir + "parallel-tests")
    25122540    detectFailures
    25132541end
  • trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-default.rb

    r264391 r271179  
    306306end
    307307
     308def output_target(outp, plan, prereqs)
     309    index = plan.index
     310    target = "test_done_#{index}"
     311    outp.puts "#{target}: #{prereqs.join(" ")}"
     312    outp.puts "\tsh test_script_#{index}"
     313    target
     314end
     315
    308316def prepareMakeTestRunner(remoteIndex)
    309317    # The goals of our parallel test runner are scalability and simplicity. The
     
    311319    # a full-time contributor just philosophising about parallel testing.
    312320    #
    313     # As such, we just pass off all of the hard work to 'make'. This creates a
    314     # dummy directory ("$outputDir/.runner") in which we create a dummy
    315     # Makefile. The Makefile has an 'all' rule that depends on all of the tests.
    316     # That is, for each test we know we will run, there is a rule in the
    317     # Makefile and 'all' depends on it. Running 'make -j <whatever>' on this
    318     # Makefile results in 'make' doing all of the hard work:
     321    # As such, we just pass off all of the hard work to 'make'. This
     322    # creates a dummy directory ("$outputDir/.runner") in which we
     323    # create a dummy Makefile. The Makefile has a 'parallel' rule that
     324    # depends all tests, other than the ones marked 'serial'. The
     325    # serial tests are arranged in a chain; the last target in the
     326    # serial chain depends on 'parallel' and 'all' depends on the head
     327    # of the chain. Running 'make -j <whatever>' on this Makefile
     328    # results in 'make' doing all of the hard work:
    319329    #
    320330    # - Load balancing just works. Most systems have a great load balancer in
     
    341351    # Even if two tests fail at the same time, since they're touching different
    342352    # files we won't miss any failures.
    343     runIndices = []
     353    serialPlans = {}
     354    $serialRunlist.each { |p| serialPlans[p] = nil }
     355    runPlans = []
     356    serialRunPlans = []
    344357    $runlist.each {
    345358        | plan |
    346359        if !$remote or plan.index % $remoteHosts.length == remoteIndex
    347             runIndices << plan.index
     360            if serialPlans.has_key?(plan)
     361                serialRunPlans << plan
     362            else
     363                runPlans << plan
     364            end
    348365        end
    349366    }
    350    
     367
    351368    File.open($runnerDir + "Makefile.#{remoteIndex}", "w") {
    352369        | outp |
    353         outp.puts("all: " + runIndices.map{|v| "test_done_#{v}"}.join(' '))
    354         runIndices.each {
    355             | index |
    356             plan = $runlist[index]
    357             outp.puts "test_done_#{index}:"
    358             outp.puts "\tsh test_script_#{plan.index}"
     370        if serialRunPlans.empty?
     371            outp.puts("all: parallel")
     372        else
     373            serialPrereq = "test_done_#{serialRunPlans[-1].index}"
     374            outp.puts("all: #{serialPrereq}")
     375            prev_target = "parallel"
     376            serialRunPlans.each {
     377                | plan |
     378                prev_target = output_target(outp, plan, [prev_target])
     379            }
     380        end
     381        parallelTargets = runPlans.collect {
     382            | plan |
     383            output_target(outp, plan, [])
    359384        }
     385        outp.puts("parallel: " + parallelTargets.join(" "))
    360386    }
    361387end
Note: See TracChangeset for help on using the changeset viewer.