run-jsc-stress-tests can only run locally
https://bugs.webkit.org/show_bug.cgi?id=124551

Reviewed by Filip Pizlo.

* Scripts/jsc-stress-test-helpers/shell-runner.sh: Fixed a couple issues. One was if the script was
killed before the lock directory was removed, future executions wouldn't make any progress. Also
added a couple more signals to handle gracefully at shutdown.
* Scripts/run-javascriptcore-tests: Pass through the --remote argument to run-jsc-stress-tests.
* Scripts/run-jsc-stress-tests: Added support for the --remote flag. It accepts a hostname, user, and port.
The script then generates the test bundle, tars it up, and copies it to the remote host via ssh where
it then untars the bundle and executes the shell-based test runner. Also refactored some of the logic
toward the end of the script to make it easier to tell which of the various modes do what.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@160108 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index dc89fed..da00175 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,19 @@
+2013-12-04  Mark Hahnenberg  <mhahnenberg@apple.com>
+
+        run-jsc-stress-tests can only run locally
+        https://bugs.webkit.org/show_bug.cgi?id=124551
+
+        Reviewed by Filip Pizlo.
+
+        * Scripts/jsc-stress-test-helpers/shell-runner.sh: Fixed a couple issues. One was if the script was
+        killed before the lock directory was removed, future executions wouldn't make any progress. Also 
+        added a couple more signals to handle gracefully at shutdown. 
+        * Scripts/run-javascriptcore-tests: Pass through the --remote argument to run-jsc-stress-tests.
+        * Scripts/run-jsc-stress-tests: Added support for the --remote flag. It accepts a hostname, user, and port.
+        The script then generates the test bundle, tars it up, and copies it to the remote host via ssh where
+        it then untars the bundle and executes the shell-based test runner. Also refactored some of the logic
+        toward the end of the script to make it easier to tell which of the various modes do what.
+
 2013-12-04  Csaba Osztrogonác  <ossy@webkit.org>
 
         [EFL][WK2] Buildfix after r160104
diff --git a/Tools/Scripts/jsc-stress-test-helpers/shell-runner.sh b/Tools/Scripts/jsc-stress-test-helpers/shell-runner.sh
index ce0cc5f..86a9755 100644
--- a/Tools/Scripts/jsc-stress-test-helpers/shell-runner.sh
+++ b/Tools/Scripts/jsc-stress-test-helpers/shell-runner.sh
@@ -36,7 +36,7 @@
 tempFile=".temp.txt"
 lockDir=".lock_dir"
 
-trap "kill -9 0" SIGINT
+trap "kill -9 0" SIGINT SIGHUP SIGTERM
 
 echo 0 > ${indexFile}
 ls test_script_* > ${testList}
@@ -49,6 +49,11 @@
     rmdir ${lockDir}
 }
 
+if [ -d ${lockDir} ]
+then
+    rmdir ${lockDir}
+fi
+
 total=`wc -l < "${testList}" | sed 's/ //g'`
 for proc in `seq ${numProcs}`
 do
diff --git a/Tools/Scripts/run-javascriptcore-tests b/Tools/Scripts/run-javascriptcore-tests
index e6ba809..d07b8c5 100755
--- a/Tools/Scripts/run-javascriptcore-tests
+++ b/Tools/Scripts/run-javascriptcore-tests
@@ -80,6 +80,7 @@
 my $enableFTL = 0;
 
 my $createTarball = 0;
+my $remoteHost = 0;
 
 my $programName = basename($0);
 my $buildJSCDefault = $buildJSC ? "will check" : "will not check";
@@ -97,6 +98,7 @@
   --[no-]testapi                Run (or don't run) testapi (default: $testapiDefault)
   --[no-]jsc-stress             Run (or don't run) the JSC stress tests (default: $jscStressDefault)
   --tarball                     Create a tarball of the bundle produced by running the JSC stress tests.
+  --remote=                     Run the JSC stress tests on the specified remote host. Implies --tarball.
 EOF
 
 GetOptions(
@@ -108,6 +110,7 @@
     'testapi!' => \$runTestAPI,
     'jsc-stress!' => \$runJSCStress,
     'tarball!' => \$createTarball,
+    'remote=s' => \$remoteHost,
     'help' => \$showHelp
 );
 
@@ -246,6 +249,10 @@
     if ($createTarball) {
         push(@jscStressDriverCmd, "--tarball");
     }
+    if ($remoteHost) {
+        push(@jscStressDriverCmd, "--remote");
+        push(@jscStressDriverCmd, $remoteHost);
+    }
     if (defined($extraTests)) {
         push(@jscStressDriverCmd, $extraTests);
     }
diff --git a/Tools/Scripts/run-jsc-stress-tests b/Tools/Scripts/run-jsc-stress-tests
index 7fcb8c3..83f88ac 100755
--- a/Tools/Scripts/run-jsc-stress-tests
+++ b/Tools/Scripts/run-jsc-stress-tests
@@ -26,6 +26,7 @@
 require 'fileutils'
 require 'getoptlong'
 require 'pathname'
+require 'uri'
 require 'yaml'
 
 THIS_SCRIPT_PATH = Pathname.new(__FILE__).realpath
@@ -93,6 +94,10 @@
 $tarball = false
 $copyVM = false
 $testRunnerType = :make
+$remoteUser = nil
+$remoteHost = nil
+$remotePort = nil
+$remoteDirectory = nil
 
 def usage
     puts "run-jsc-stress-tests -j <shell path> <collections path> [<collections path> ...]"
@@ -105,6 +110,7 @@
     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 "--remote                    Specify a remote host on which to run tests."
     puts "--help               (-h)   Print this message."
     exit 1
 end
@@ -117,6 +123,7 @@
                ['--tarball', GetoptLong::NO_ARGUMENT],
                ['--force-vm-copy', GetoptLong::NO_ARGUMENT],
                ['--shell-runner', GetoptLong::NO_ARGUMENT],
+               ['--remote', GetoptLong::REQUIRED_ARGUMENT],
                ['--verbose', '-v', GetoptLong::NO_ARGUMENT]).each {
     | opt, arg |
     case opt
@@ -139,6 +146,13 @@
         $copyVM = true
     when '--shell-runner'
         $testRunnerType = :shell
+    when '--remote'
+        $copyVM = true
+        $testRunnerType = :shell
+        $tarball = true
+        $remote = true
+        uri = URI("ftp://" + arg)
+        $remoteUser, $remoteHost, $remotePort = uri.user, uri.host, uri.port
     end
 }
 
@@ -161,15 +175,11 @@
 $runlist = []
 
 def frameworkFromJSCPath(jscPath)
-    if jscPath.dirname.basename.to_s == "Resources" and jscPath.dirname.dirname.basename.to_s == "JavaScriptCore.framework"
-        jscPath.dirname.dirname
-    elsif jscPath.dirname.dirname.basename.to_s == "WebKitBuild"
-        parentDirName = jscPath.dirname.basename.to_s
-        if parentDirName == "Debug" or parentDirName == "Release" 
-            jscPath.dirname + "JavaScriptCore.framework"
-        else
-            raise "Unknown JSC path, cannot copy full framework: #{jscPath}"
-        end
+    parentDirectory = jscPath.dirname
+    if parentDirectory.basename.to_s == "Resources" and parentDirectory.dirname.basename.to_s == "JavaScriptCore.framework"
+        parentDirectory.dirname
+    elsif parentDirectory.basename.to_s =~ /^Debug/ or parentDirectory.basename.to_s =~ /^Release/
+        jscPath.dirname + "JavaScriptCore.framework"
     else
         $stderr.puts "Warning: cannot identify JSC framework, doing generic VM copy."
         nil
@@ -885,6 +895,8 @@
         | collection |
         handleCollection(collection)
     }
+
+    puts
 end
 
 def cleanOldResults
@@ -1050,13 +1062,41 @@
     end
 end
 
-def runShellTestRunner
-    Dir.chdir($runnerDir) {
-        mysys("sh", "runscript")
+def sshRead(cmd)
+    raise unless $remote
+
+    result = ""
+    IO.popen("ssh -p #{$remotePort} #{$remoteUser}@#{$remoteHost} '#{cmd}'", "r") {
+      | inp |
+      inp.each_line {
+        | line |
+        result += line
+      }
     }
+    raise "#{$?}" unless $?.success?
+    result
+end
+
+def runShellTestRunner
+    if $remote
+        $remoteDirectory = JSON::parse(sshRead("cat ~/.bencher"))["tempPath"]
+        mysys("scp", "-P", $remotePort.to_s, ($outputDir.dirname + "payload.tar.gz").to_s, "#{$remoteUser}@#{$remoteHost}:#{$remoteDirectory}")
+        remoteScript = ""
+        remoteScript += "cd #{$remoteDirectory} && "
+        remoteScript += "rm -rf #{$outputDir.basename} && "
+        remoteScript += "tar xzf payload.tar.gz && "
+        remoteScript += "cd #{$outputDir.basename}/.runner && "
+        remoteScript += "DYLD_FRAMEWORK_PATH=$(cd ../#{$frameworkPath.dirname}; pwd) sh runscript" 
+        system("ssh", "-p", $remotePort.to_s, "#{$remoteUser}@#{$remoteHost}", remoteScript)
+    else
+        Dir.chdir($runnerDir) {
+            mysys("sh", "runscript")
+        }
+    end
 end
 
 def runMakeTestRunner
+    raise if $remote
     Dir.chdir($runnerDir) {
         # -1 for the Makefile, and -2 for '..' and '.'
         numberOfTests = Dir.entries(".").count - 3
@@ -1126,11 +1166,20 @@
 def detectFailures
     raise if $bundle
 
-    Dir.foreach($runnerDir) {
-        | filename |
-        next unless filename =~ /test_fail_/
-        appendFailure($runlist[$~.post_match.to_i])
-    }
+    if $remote
+        output = sshRead("cd #{$remoteDirectory}/#{$outputDir.basename}/.runner && (ls test_fail_* 2> /dev/null || true)")
+        output.split(/\n/).each {
+            | line |
+            next unless line =~ /test_fail_/
+            appendFailure($runlist[$~.post_match.to_i])
+        }
+    else
+        Dir.foreach($runnerDir) {
+            | filename |
+            next unless filename =~ /test_fail_/
+            appendFailure($runlist[$~.post_match.to_i])
+        }
+    end
 end
 
 def compressBundle
@@ -1154,14 +1203,49 @@
 $outputDir = $outputDir.realpath
 $runnerDir = $outputDir + ".runner"
 
-prepareBundle unless $bundle
+def runBundle
+    raise unless $bundle
 
-puts
+    cleanRunnerDirectory
+    cleanOldResults
+    runTestRunner
+    cleanEmptyResultFiles
+end
 
-prepareTestRunner unless $bundle
-cleanRunnerDirectory if $bundle
-cleanOldResults if $bundle
-runTestRunner
-cleanEmptyResultFiles
-detectFailures unless $bundle
-compressBundle if $tarball
+def runNormal
+    raise if $bundle or $tarball
+
+    prepareBundle
+    prepareTestRunner
+    runTestRunner
+    cleanEmptyResultFiles
+    detectFailures
+end
+
+def runTarball
+    raise unless $tarball
+
+    prepareBundle 
+    prepareTestRunner
+    compressBundle
+end
+
+def runRemote
+    raise unless $remote
+
+    prepareBundle
+    prepareTestRunner
+    compressBundle
+    runTestRunner
+    detectFailures
+end
+
+if $bundle
+    runBundle
+elsif $remote
+    runRemote
+elsif $tarball
+    runTarball
+else
+    runNormal
+end