Allow run-javascriptcore-tests to distribute tests between devices
authorguijemont@igalia.com <guijemont@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Oct 2018 00:28:14 +0000 (00:28 +0000)
committerguijemont@igalia.com <guijemont@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 10 Oct 2018 00:28:14 +0000 (00:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190190

Reviewed by Michael Catanzaro.

* Scripts/run-jsc-stress-tests:
* Scripts/webkitruby/jsc-stress-test-writer-default.rb:
* Scripts/webkitruby/jsc-stress-test-writer-ruby.rb:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236993 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Tools/ChangeLog
Tools/Scripts/run-jsc-stress-tests
Tools/Scripts/webkitruby/jsc-stress-test-writer-default.rb
Tools/Scripts/webkitruby/jsc-stress-test-writer-ruby.rb

index 08205c8..e673831 100644 (file)
@@ -1,3 +1,14 @@
+2018-10-09  Guillaume Emont  <guijemont@igalia.com>
+
+        Allow run-javascriptcore-tests to distribute tests between devices
+        https://bugs.webkit.org/show_bug.cgi?id=190190
+
+        Reviewed by Michael Catanzaro.
+
+        * Scripts/run-jsc-stress-tests:
+        * Scripts/webkitruby/jsc-stress-test-writer-default.rb:
+        * Scripts/webkitruby/jsc-stress-test-writer-ruby.rb:
+
 2018-10-09  Dean Jackson  <dino@apple.com>
 
         Update WHLSL to Metal tester with semantics
index b791df8..e4908fe 100755 (executable)
@@ -43,6 +43,8 @@ class String
     end
 end
 
+RemoteHost = Struct.new(:name, :user, :host, :port, :remoteDirectory)
+
 THIS_SCRIPT_PATH = Pathname.new(__FILE__).realpath
 SCRIPTS_PATH = THIS_SCRIPT_PATH.dirname
 WEBKIT_PATH = SCRIPTS_PATH.dirname.dirname
@@ -109,10 +111,7 @@ $tarFileName = "payload.tar.gz"
 $copyVM = false
 $testRunnerType = nil
 $testWriter = "default"
-$remoteUser = nil
-$remoteHost = nil
-$remotePort = nil
-$remoteDirectory = nil
+$remoteHosts = []
 $architecture = nil
 $hostOS = nil
 $filter = nil
@@ -231,7 +230,7 @@ GetoptLong.new(['--help', '-h', GetoptLong::NO_ARGUMENT],
         $tarball = true
         $remote = true
         uri = URI("ssh://" + arg)
-        $remoteUser, $remoteHost, $remotePort = uri.user, uri.host, uri.port
+        $remoteHosts << RemoteHost.new("default-#{$remoteHosts.length}", uri.user, uri.host, uri.port)
     when '--remote-config-file'
         $remoteConfigFile = arg
     when '--child-processes'
@@ -259,16 +258,33 @@ if $remoteConfigFile
     file = File.read($remoteConfigFile)
     config = JSON.parse(file)
 
+    # old style config allowing for only one remote
     if !$remote and config['remote']
         $copyVM = true
         $tarball = true
         $remote = true
         uri = URI("ssh://" + config['remote'])
-        $remoteUser, $remoteHost, $remotePort = uri.user, uri.host, uri.port
+        $remoteHosts = [ RemoteHost.new("default", uri.user, uri.host, uri.port) ]
+        if config['remoteDirectory']
+            $remoteHosts[0].remoteDirectory = config['remoteDirectory']
+        end
     end
 
-    if config['remoteDirectory']
-        $remoteDirectory = config['remoteDirectory']
+    # we can combine --remote and a new style config
+    if config['remotes']
+        $copyVM = true
+        $tarball = true
+        $remote = true
+        $remoteHosts += config['remotes'].map {
+            | remote |
+            uri = URI("ssh://" + remote['address'])
+
+            host = RemoteHost.new(remote['name'], uri.user, uri.host, uri.port)
+            if remote['remoteDirectory']
+                host.remoteDirectory = remote['remoteDirectory']
+            end
+            host
+        }
     end
 end
 
@@ -302,7 +318,7 @@ else
     $jscPath = Pathname.new(jscArg).realpath
 end
 
-$progressMeter = ($verbosity == 0 and $stdout.tty?)
+$progressMeter = ($verbosity == 0 and $stdout.tty? and $remoteHosts.length <= 1)
 
 if $bundle
     $jscPath = $bundle + ".vm" + "JavaScriptCore.framework" + "Resources" + "jsc"
@@ -445,6 +461,10 @@ if !$testRunnerType
     end
 end
 
+if $remoteHosts.length > 1 and $testRunnerType != :make
+    raise "Multiple remote hosts only supported with make runner"
+end
+
 if $testWriter
     if /[^-a-zA-Z0-9_]/.match($testWriter)
         raise "Invalid test writer #{$testWriter} given"
@@ -1711,7 +1731,7 @@ def eachResultFile(startingDir, &block)
     end
 end
 
-def prepareTestRunner
+def prepareTestRunner(remoteIndex=0)
     raise if $bundle
 
     $runlist.each_with_index {
@@ -1740,7 +1760,7 @@ def prepareTestRunner
 
     case $testRunnerType
     when :make
-        prepareMakeTestRunner
+        prepareMakeTestRunner(remoteIndex)
     when :shell
         prepareShellTestRunner
     when :ruby
@@ -1759,11 +1779,13 @@ def cleanRunnerDirectory
     }
 end
 
-def sshRead(cmd)
+def sshRead(cmd, remoteIndex=0)
     raise unless $remote
 
+    remoteHost = $remoteHosts[remoteIndex]
+
     result = ""
-    IO.popen("ssh -p #{$remotePort} #{$remoteUser}@#{$remoteHost} '#{cmd}'", "r") {
+    IO.popen("ssh -p #{remoteHost.port} #{remoteHost.user}@#{remoteHost.host} '#{cmd}'", "r") {
       | inp |
       inp.each_line {
         | line |
@@ -1874,24 +1896,25 @@ def runAndMonitorTestRunnerCommand(*cmd)
     end
 end
 
-def runTestRunner
+def runTestRunner(remoteIndex=0)
     if $remote
-        if !$remoteDirectory
-            $remoteDirectory = JSON::parse(sshRead("cat ~/.bencher"))["tempPath"]
+        remoteHost = $remoteHosts[remoteIndex]
+        if !remoteHost.remoteDirectory
+            remoteHost.remoteDirectory = JSON::parse(sshRead("cat ~/.bencher", remoteIndex))["tempPath"]
         end
-        mysys("ssh", "-p", $remotePort.to_s, "#{$remoteUser}@#{$remoteHost}", "mkdir -p #{$remoteDirectory}")
-        mysys("scp", "-P", $remotePort.to_s, ($outputDir.dirname + $tarFileName).to_s, "#{$remoteUser}@#{$remoteHost}:#{$remoteDirectory}")
+        mysys("ssh", "-p", remoteHost.port.to_s, "#{remoteHost.user}@#{remoteHost.host}", "mkdir -p #{remoteHost.remoteDirectory}")
+        mysys("scp", "-P", remoteHost.port.to_s, ($outputDir.dirname + $tarFileName).to_s, "#{remoteHost.user}@#{remoteHost.host}:#{remoteHost.remoteDirectory}")
         remoteScript = "\""
-        remoteScript += "cd #{$remoteDirectory} && "
+        remoteScript += "cd #{remoteHost.remoteDirectory} && "
         remoteScript += "rm -rf #{$outputDir.basename} && "
         remoteScript += "tar xzf #{$tarFileName} && "
         remoteScript += "cd #{$outputDir.basename}/.runner && "
         remoteScript += "export DYLD_FRAMEWORK_PATH=\\\"\\$(cd #{$testingFrameworkPath.dirname}; pwd)\\\" && "
-        remoteScript += "export LD_LIBRARY_PATH=#{$remoteDirectory}/#{$outputDir.basename}/#{$jscPath.dirname} && "
+        remoteScript += "export LD_LIBRARY_PATH=#{remoteHost.remoteDirectory}/#{$outputDir.basename}/#{$jscPath.dirname} && "
         remoteScript += "export JSCTEST_timeout=#{Shellwords.shellescape(ENV['JSCTEST_timeout'])} && "
         $envVars.each { |var| remoteScript += "export " << var << "\n" }
-        remoteScript += "#{testRunnerCommand}\""
-        runAndMonitorTestRunnerCommand("ssh", "-p", $remotePort.to_s, "#{$remoteUser}@#{$remoteHost}", remoteScript)
+        remoteScript += "#{testRunnerCommand(remoteIndex)}\""
+        runAndMonitorTestRunnerCommand("ssh", "-p", remoteHost.port.to_s, "#{remoteHost.user}@#{remoteHost.host}", remoteScript)
     else
         Dir.chdir($runnerDir) {
             runAndMonitorTestRunnerCommand(testRunnerCommand)
@@ -1905,11 +1928,14 @@ def detectFailures
     failures = []
     
     if $remote
-        output = sshRead("cd #{$remoteDirectory}/#{$outputDir.basename}/.runner && find . -maxdepth 1 -name \"test_fail_*\"")
-        output.split(/\n/).each {
-            | line |
-            next unless line =~ /test_fail_/
-            failures << $~.post_match.to_i
+        $remoteHosts.each_with_index {
+            | host, remoteIndex |
+            output = sshRead("cd #{host.remoteDirectory}/#{$outputDir.basename}/.runner && find . -maxdepth 1 -name \"test_fail_*\"", remoteIndex)
+            output.split(/\n/).each {
+                | line |
+                next unless line =~ /test_fail_/
+                failures << $~.post_match.to_i
+            }
         }
     else
         Dir.foreach($runnerDir) {
@@ -2050,9 +2076,19 @@ def runRemote
     raise unless $remote
 
     prepareBundle
-    prepareTestRunner
+    $remoteHosts.each_index {
+        | index |
+        prepareTestRunner(index)
+    }
     compressBundle
-    runTestRunner
+    threads = []
+    $remoteHosts.each_index {
+        | index |
+        threads << Thread.new {
+            runTestRunner(index)
+        }
+    }
+    threads.each { |thr| thr.join }
     detectFailures
 end
 
index 0553f2e..c174b1a 100644 (file)
@@ -292,7 +292,7 @@ def prepareShellTestRunner
     FileUtils.cp SCRIPTS_PATH + "jsc-stress-test-helpers" + "shell-runner.sh", $runnerDir + "runscript"
 end
 
-def prepareMakeTestRunner
+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.
@@ -330,10 +330,12 @@ def prepareMakeTestRunner
     runIndices = []
     $runlist.each {
         | plan |
-        runIndices << plan.index
+        if !$remote or plan.index % $remoteHosts.length == remoteIndex
+            runIndices << plan.index
+        end
     }
     
-    File.open($runnerDir + "Makefile", "w") {
+    File.open($runnerDir + "Makefile.#{remoteIndex}", "w") {
         | outp |
         outp.puts("all: " + runIndices.map{|v| "test_done_#{v}"}.join(' '))
         runIndices.each {
@@ -355,12 +357,12 @@ def prepareRubyTestRunner
     }
 end
 
-def testRunnerCommand
+def testRunnerCommand(remoteIndex=0)
     case $testRunnerType
     when :shell
         command = "sh runscript"
     when :make
-        command = "make -j #{$numChildProcesses.to_s} -s -f Makefile"
+        command = "make -j #{$numChildProcesses} -s -f Makefile.#{remoteIndex}"
     when :ruby
         command = "ruby runscript"
     else
index 17bff87..6e97e88 100644 (file)
@@ -398,14 +398,16 @@ def prepareShellTestRunner
     `dos2unix #{$runnerDir + "runscript"}`    
 end
 
-def prepareMakeTestRunner
+def prepareMakeTestRunner(remoteIndex)
     runIndices = []
     $runlist.each {
         | plan |
-        runIndices << plan.index
+        if !$remote or plan.index % $remoteHosts.length == remoteIndex
+            runIndices << plan.index
+        end
     }
     
-    File.open($runnerDir + "Makefile", "w") {
+    File.open($runnerDir + "Makefile.#{remoteIndex}", "w") {
         | outp |
         outp.puts("all: " + runIndices.map{|v| "test_done_#{v}"}.join(' '))
         runIndices.each {
@@ -427,12 +429,12 @@ def prepareRubyTestRunner
     }
 end
 
-def testRunnerCommand
+def testRunnerCommand(remoteIndex=0)
     case $testRunnerType
     when :shell
         command = "sh runscript"
     when :make
-        command = "make -j #{$numChildProcesses.to_s} -s -f Makefile"
+        command = "make -j #{$numChildProcesses} -s -f Makefile.#{remoteIndex}"
     when :ruby
         command = "ruby runscript"
     else