Title: [160016] trunk/Tools
Revision
160016
Author
mhahnenb...@apple.com
Date
2013-12-03 10:51:12 -0800 (Tue, 03 Dec 2013)

Log Message

run-jsc-stress-tests only supports host environments that have make installed
https://bugs.webkit.org/show_bug.cgi?id=124550

Reviewed by Darin Adler.

This might not be the case for all hosts, so this patch implements an alternate "backend" 
for run-jsc-stress-tests to use normal shell commands rather than Makefiles. To remain at 
least somewhat competitive with the make-based test runner, the shell backend uses subshells
run in the background to allow tests to run in parallel. Since the concurrency primitives 
in shell scripting are rather coarse, the overhead of this parallelism is higher than that 
of the make-based runner.

* Scripts/jsc-stress-test-helpers/shell-runner.sh: Added. This is the runner that is copied into
the bundle and controls all of the parallel aspects of the shell-based test runner.
* Scripts/run-jsc-stress-tests:

Modified Paths

Added Paths

Diff

Modified: trunk/Tools/ChangeLog (160015 => 160016)


--- trunk/Tools/ChangeLog	2013-12-03 18:44:32 UTC (rev 160015)
+++ trunk/Tools/ChangeLog	2013-12-03 18:51:12 UTC (rev 160016)
@@ -1,3 +1,21 @@
+2013-12-03  Mark Hahnenberg  <mhahnenb...@apple.com>
+
+        run-jsc-stress-tests only supports host environments that have make installed
+        https://bugs.webkit.org/show_bug.cgi?id=124550
+
+        Reviewed by Darin Adler.
+
+        This might not be the case for all hosts, so this patch implements an alternate "backend" 
+        for run-jsc-stress-tests to use normal shell commands rather than Makefiles. To remain at 
+        least somewhat competitive with the make-based test runner, the shell backend uses subshells
+        run in the background to allow tests to run in parallel. Since the concurrency primitives 
+        in shell scripting are rather coarse, the overhead of this parallelism is higher than that 
+        of the make-based runner.
+
+        * Scripts/jsc-stress-test-helpers/shell-runner.sh: Added. This is the runner that is copied into
+        the bundle and controls all of the parallel aspects of the shell-based test runner.
+        * Scripts/run-jsc-stress-tests:
+
 2013-12-03  Tamas Gergely  <tgergely.u-sze...@partner.samsung.com>
 
         Remove function from TextChecker

Added: trunk/Tools/Scripts/jsc-stress-test-helpers/shell-runner.sh (0 => 160016)


--- trunk/Tools/Scripts/jsc-stress-test-helpers/shell-runner.sh	                        (rev 0)
+++ trunk/Tools/Scripts/jsc-stress-test-helpers/shell-runner.sh	2013-12-03 18:51:12 UTC (rev 160016)
@@ -0,0 +1,76 @@
+# Copyright (C) 2013 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.  Redistributions of source code must retain the above copyright
+#     notice, this list of conditions and the following disclaimer. 
+# 2.  Redistributions in binary form must reproduce the above copyright
+#     notice, this list of conditions and the following disclaimer in the
+#     documentation and/or other materials provided with the distribution. 
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+numProcs=`sysctl -n hw.activecpu`
+if [ $? -gt 0 ]
+then
+    numProcs=`nproc --all 2>/dev/null`
+    if [ $? -gt 0 ]
+    then
+        numProcs=1
+    fi
+fi
+
+indexFile=".index"
+testList=".all_tests.txt"
+tempFile=".temp.txt"
+lockDir=".lock_dir"
+
+trap "kill -9 0" SIGINT
+
+echo 0 > ${indexFile}
+ls test_script_* > ${testList}
+
+function lock_test_list() {
+    until mkdir ${lockDir} 2> /dev/null; do sleep 0; done
+}
+
+function unlock_test_list() {
+    rmdir ${lockDir}
+}
+
+total=`wc -l < "${testList}" | sed 's/ //g'`
+for proc in `seq ${numProcs}`
+do
+    (
+        lock_test_list
+        while [ -s ${testList} ]
+        do
+            index=`cat ${indexFile}`
+            index=$((index + 1))
+            echo "${index}" > ${indexFile}
+            printf "\r ${index}/${total}"
+
+            nextTest=`tail -n 1 ${testList}`
+            sed '$d' < ${testList} > ${tempFile}
+            mv ${tempFile} ${testList}
+            unlock_test_list
+
+            sh ${nextTest} > /dev/null
+
+            lock_test_list
+        done
+        unlock_test_list
+    )&
+done
+wait

Modified: trunk/Tools/Scripts/run-jsc-stress-tests (160015 => 160016)


--- trunk/Tools/Scripts/run-jsc-stress-tests	2013-12-03 18:44:32 UTC (rev 160015)
+++ trunk/Tools/Scripts/run-jsc-stress-tests	2013-12-03 18:51:12 UTC (rev 160016)
@@ -68,7 +68,7 @@
 end
 
 def mysys(*cmd)
-    printCommandArray(*cmd)
+    printCommandArray(*cmd) if $verbosity >= 1
     raise "Command failed: #{$?.inspect}" unless system(*cmd)
 end
 
@@ -92,6 +92,7 @@
 $bundle = nil
 $tarball = false
 $copyVM = false
+$testRunnerType = :make
 
 def usage
     puts "run-jsc-stress-tests -j <shell path> <collections path> [<collections path> ...]"
@@ -102,6 +103,8 @@
     puts "--verbose            (-v)   Print more things while running."
     puts "--run-bundle                Runs a bundle previously created by run-jsc-stress-tests."
     puts "--tarball                   Creates a tarball of the final bundle."
+    puts "--shell-runner              Uses the shell-based test runner instead of the default make-based runner."
+    puts "                            In general the shell runner is slower than the make runner."
     puts "--help               (-h)   Print this message."
     exit 1
 end
@@ -113,6 +116,7 @@
                ['--run-bundle', GetoptLong::REQUIRED_ARGUMENT],
                ['--tarball', GetoptLong::NO_ARGUMENT],
                ['--force-vm-copy', GetoptLong::NO_ARGUMENT],
+               ['--shell-runner', GetoptLong::NO_ARGUMENT],
                ['--verbose', '-v', GetoptLong::NO_ARGUMENT]).each {
     | opt, arg |
     case opt
@@ -133,6 +137,8 @@
         $copyVM = true
     when '--force-vm-copy'
         $copyVM = true
+    when '--shell-runner'
+        $testRunnerType = :shell
     end
 }
 
@@ -381,7 +387,7 @@
     end
     
     def reproScriptCommand
-        # We have to find our way back to the .parallel directory since that's where all of the relative
+        # We have to find our way back to the .runner directory since that's where all of the relative
         # paths assume they start out from.
         script = "CURRENT_DIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\n"
         script += "cd $CURRENT_DIR\n"
@@ -389,7 +395,7 @@
             | pathComponent |
             script += "cd ..\n"
         }
-        script += "cd .parallel\n"
+        script += "cd .runner\n"
 
         script += "export DYLD_FRAMEWORK_PATH=$(cd ../#{$frameworkPath.dirname}; pwd)\n"
         IMPORTANT_ENVS.each {
@@ -916,13 +922,54 @@
     end
 end
 
-def prepareParallelTestRunner
+def prepareTestRunner
+    raise if $bundle
+
+    $runlist.each_with_index {
+        | plan, index |
+        plan.index = index
+    }
+
+    Dir.mkdir($runnerDir) unless $runnerDir.directory?
+    toDelete = []
+    Dir.foreach($runnerDir) {
+        | filename |
+        if filename =~ /^test_/
+            toDelete << filename
+        end
+    }
+    
+    toDelete.each {
+        | filename |
+        File.unlink($runnerDir + filename)
+    }
+
+    $runlist.each {
+        | plan |
+        plan.writeRunScript($runnerDir + "test_script_#{plan.index}")
+    }
+
+    case $testRunnerType
+    when :make
+        prepareMakeTestRunner
+    when :shell
+        prepareShellTestRunner
+    else
+        raise "Unknown test runner type: #{$testRunnerType.to_s}"
+    end
+end
+
+def prepareShellTestRunner
+    FileUtils.cp SCRIPTS_PATH + "jsc-stress-test-helpers" + "shell-runner.sh", $runnerDir + "runscript"
+end
+
+def prepareMakeTestRunner
     # 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/.parallel") in which we create a dummy
+    # 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
@@ -945,40 +992,19 @@
     # continue past that failure and complete all the tests anyway.
     #
     # In the end, this script collects all of the failures by searching for
-    # files in the .parallel directory whose name matches /^test_fail_/, where
+    # files in the .runner directory whose name matches /^test_fail_/, where
     # the thing after the 'fail_' is the test index. Those are the files that
     # would be created by the test scripts if they detect failure. We're
     # 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 = []
-    $runlist.each_with_index {
-        | plan, index |
-        runIndices << index
-        plan.index = index
-    }
-    
-    Dir.mkdir($parallelDir) unless $parallelDir.directory?
-    toDelete = []
-    Dir.foreach($parallelDir) {
-        | filename |
-        if filename =~ /^test_/
-            toDelete << filename
-        end
-    }
-    
-    toDelete.each {
-        | filename |
-        File.unlink($parallelDir + filename)
-    }
-
     $runlist.each {
         | plan |
-        plan.writeRunScript($parallelDir + "test_script_#{plan.index}")
+        runIndices << plan.index
     }
     
-    File.open($parallelDir + "Makefile", "w") {
+    File.open($runnerDir + "Makefile", "w") {
         | outp |
         outp.puts("all: " + runIndices.map{|v| "test_done_#{v}"}.join(' '))
         runIndices.each {
@@ -1004,17 +1030,34 @@
     
 puts
 
-def cleanParallelDirectory
+def cleanRunnerDirectory
     raise unless $bundle
-    Dir.foreach($parallelDir) {
+    Dir.foreach($runnerDir) {
         | filename |
         next unless filename =~ /^test_fail/
-        FileUtils.rm_f $parallelDir + filename
+        FileUtils.rm_f $runnerDir + filename
     }
 end
 
-def runParallelTestRunner
-    Dir.chdir($parallelDir) {
+def runTestRunner
+    case $testRunnerType
+    when :shell
+        runShellTestRunner
+    when :make
+        runMakeTestRunner
+    else
+        raise "Unknown test runner type: #{$testRunnerType.to_s}"
+    end
+end
+
+def runShellTestRunner
+    Dir.chdir($runnerDir) {
+        mysys("sh", "runscript")
+    }
+end
+
+def runMakeTestRunner
+    Dir.chdir($runnerDir) {
         # -1 for the Makefile, and -2 for '..' and '.'
         numberOfTests = Dir.entries(".").count - 3
         unless $progressMeter
@@ -1083,7 +1126,7 @@
 def detectFailures
     raise if $bundle
 
-    Dir.foreach($parallelDir) {
+    Dir.foreach($runnerDir) {
         | filename |
         next unless filename =~ /test_fail_/
         appendFailure($runlist[$~.post_match.to_i])
@@ -1105,13 +1148,16 @@
 end
 
 $outputDir = $outputDir.realpath
-$parallelDir = $outputDir + ".parallel"
+$runnerDir = $outputDir + ".runner"
 
 prepareBundle unless $bundle
-prepareParallelTestRunner unless $bundle
-cleanParallelDirectory if $bundle
+
+puts " "
+
+prepareTestRunner unless $bundle
+cleanRunnerDirectory if $bundle
 cleanOldResults if $bundle
-runParallelTestRunner
+runTestRunner
 cleanEmptyResultFiles
 detectFailures unless $bundle
 compressBundle if $tarball
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to