Diff
Modified: trunk/Tools/ChangeLog (277317 => 277318)
--- trunk/Tools/ChangeLog 2021-05-11 04:46:49 UTC (rev 277317)
+++ trunk/Tools/ChangeLog 2021-05-11 08:34:07 UTC (rev 277318)
@@ -1,3 +1,35 @@
+2021-05-11 Angelos Oikonomopoulos <[email protected]>
+
+ [JSC] detect infrastructure failure for remote stress tests
+ https://bugs.webkit.org/show_bug.cgi?id=222601
+
+ Reviewed by Mark Lam.
+
+ run-jsc-stress-tests currently detects failures by the absence of
+ a failure file (that is generated by each failing test). This is
+ fragile to begin with, as it assumes that tests that fail to run
+ (e.g. because of an error in the runner script) are successful by
+ default.
+
+ However, the main motivation for this patch is to make execution
+ more robust when using remote hosts. Currently,
+ --gnu-parallel-runner will transparently reschedule jobs on a
+ different host when a remote host goes away. But detectFailures
+ expects to be able to connect to all hosts and fetch the failure
+ files, which fails if a remote host is still down when the run
+ finishes.
+
+ Instead, this patch changes the runners to always generate a status
+ file with the exit code. detectFailures then fetches all status
+ files from all hosts that are live on exit. Tests that failed to
+ run are explicitly accounted for as 'noreport' and are set to
+ ERROR in the final report.
+
+ * Scripts/run-_javascript_core-tests:
+ (runJSCStressTests):
+ * Scripts/run-jsc-stress-tests:
+ * Scripts/webkitruby/jsc-stress-test-writer-default.rb:
+
2021-05-10 Chris Dumez <[email protected]>
Use non-throwing std::filesystem API in TestRunner
Modified: trunk/Tools/Scripts/run-_javascript_core-tests (277317 => 277318)
--- trunk/Tools/Scripts/run-_javascript_core-tests 2021-05-11 04:46:49 UTC (rev 277317)
+++ trunk/Tools/Scripts/run-_javascript_core-tests 2021-05-11 08:34:07 UTC (rev 277318)
@@ -932,9 +932,20 @@
}
print "\n";
+ my @jscStressNoResultList = readAllLines($jscStressResultsDir . "/noresult");
+ my $numJSCStressNoResultTests = @jscStressNoResultList;
+
+ if ($numJSCStressNoResultTests) {
+ $isTestFailed = 1;
+ }
+ foreach my $testNoResult (@jscStressNoResultList) {
+ $reportData{$testNoResult} = {actual => "ERROR"};
+ }
+
print "Results for JSC stress tests:\n";
printThingsFound($numJSCStressFailures, "failure", "failures", "found");
- print " OK.\n" if $numJSCStressFailures == 0;
+ printThingsFound($numJSCStressNoResultTests, "test", "tests", "failed to complete");
+ print " OK.\n" if $numJSCStressFailures == 0 and $numJSCStressNoResultTests == 0;
print "\n";
Modified: trunk/Tools/Scripts/run-jsc-stress-tests (277317 => 277318)
--- trunk/Tools/Scripts/run-jsc-stress-tests 2021-05-11 04:46:49 UTC (rev 277317)
+++ trunk/Tools/Scripts/run-jsc-stress-tests 2021-05-11 08:34:07 UTC (rev 277318)
@@ -57,6 +57,9 @@
raise unless SCRIPTS_PATH.dirname.basename.to_s == "Tools"
HELPERS_PATH = SCRIPTS_PATH + "jsc-stress-test-helpers"
+STATUS_FILE_PREFIX = "test_status_"
+STATUS_FILE_PASS = "P"
+STATUS_FILE_FAIL = "F"
begin
require 'shellwords'
@@ -135,6 +138,7 @@
$ldd = nil
$artifact_exec_wrapper = nil
$numChildProcessesSetByUser = false
+$runUniqueId = Random.new.bytes(16).unpack("H*")[0]
def usage
puts "run-jsc-stress-tests -j <shell path> <collections path> [<collections path> ...]"
@@ -537,9 +541,6 @@
end
end
-$numFailures = 0
-$numPasses = 0
-
# We force all tests to use a smaller (1.5M) stack so that stack overflow tests can run faster.
BASE_OPTIONS = ["--useFTLJIT=false", "--useFunctionDotArguments=true", "--validateExceptionChecks=true", "--useDollarVM=true", "--maxPerThreadStackUsage=1572864"]
EAGER_OPTIONS = ["--thresholdForJITAfterWarmUp=10", "--thresholdForJITSoon=10", "--thresholdForOptimizeAfterWarmUp=20", "--thresholdForOptimizeAfterLongWarmUp=20", "--thresholdForOptimizeSoon=20", "--thresholdForFTLOptimizeAfterWarmUp=20", "--thresholdForFTLOptimizeSoon=20", "--thresholdForOMGOptimizeAfterWarmUp=20", "--thresholdForOMGOptimizeSoon=20", "--maximumEvalCacheableSourceLength=150000", "--useEagerCodeBlockJettisonTiming=true", "--repatchBufferingCountdown=0"]
@@ -1823,7 +1824,6 @@
| outp |
outp.puts plan.name
}
- $numFailures += 1
end
def appendPass(plan)
@@ -1831,9 +1831,15 @@
| outp |
outp.puts plan.name
}
- $numPasses += 1
end
+def appendNoResult(plan)
+ File.open($outputDir + "noresult", "a") {
+ | outp |
+ outp.puts plan.name
+ }
+end
+
def appendResult(plan, didPass)
File.open($outputDir + "results", "a") {
| outp |
@@ -2039,7 +2045,7 @@
}
end
-def sshRead(cmd, remoteIndex=0)
+def sshRead(cmd, remoteIndex=0, options={})
raise unless $remote
remoteHost = $remoteHosts[remoteIndex]
@@ -2052,7 +2058,7 @@
result += line
}
}
- raise "#{$?}" unless $?.success?
+ raise "#{$?}" unless $?.success? or options[:ignoreFailure]
result
end
@@ -2207,52 +2213,110 @@
end
end
-def detectFailures
- raise if $bundle
- failures = []
+def getStatusMap
+ name_re = /^[.]\/#{STATUS_FILE_PREFIX}(\d+)$/
+ map = {}
if $remote
$remoteHosts.each_with_index {
| host, remoteIndex |
- output = sshRead("cd #{host.remoteDirectory}/#{$outputDir.basename}/.runner && find . -maxdepth 1 -name \"test_fail_*\"", remoteIndex)
+ output = sshRead("cd #{host.remoteDirectory}/#{$outputDir.basename}/.runner && find . -maxdepth 1 -name \"#{STATUS_FILE_PREFIX}*\" -exec sh -c \"printf \\\"%s \\\" {}; cat {}\" \\;", remoteIndex, :ignoreFailure => true)
output.split(/\n/).each {
| line |
- next unless line =~ /test_fail_/
- failures << $~.post_match.to_i
+ name, run_id, _, result = line.split(' ')
+ md = name_re.match(name)
+ if md.nil?
+ $stderr.puts("Could not parse name in `#{line}`")
+ exit(1)
+ end
+ if run_id != $runUniqueId
+ # This may conceivably happen if a remote goes
+ # away in the middle of a run and comes back
+ # online in the middle of a different run.
+ $stderr.puts("Ignoring stale status file for #{name} (ID #{run_id} but current ID is #{$runUniqueId})")
+ next
+ end
+ index = md[1].to_i
+ if map.has_key?(index)
+ $stderr.puts("Duplicate state file for #{index}")
+ # One scenario in which this could happen:
+ # Test T runs on remote host A and
+ # 1. the status file reaches A's disk
+ # 2. somehow the gnu parallel runner is not made aware of the test's completion (packet loss?)
+ # 3. A machine crashes
+ # 4. gnu parallel re-schedules the test to run on remote host B, where it runs to completion
+ # 5. B comes back online before the end of the run
+ # 6. we collect the status files from all remotes and end up with two status files for T.
+ prev = map[index]
+ # map[index] holds
+ # - a number, if all results codes we've observed for a test are the same
+ # - an array, if they diverge.
+ if prev.is_a?(Array)
+ prev.push(result)
+ elsif prev != result
+ # If the two results differ, keep them
+ # both. This is simply a way to make note of
+ # the divergence (for later reporting).
+ map[index] = [prev, result]
+ else
+ # Got the same result, no need to do anything.
+ end
+ else
+ map[index] = result
+ end
}
}
else
Dir.foreach($runnerDir) {
| filename |
- next unless filename =~ /test_fail_/
- failures << $~.post_match.to_i
+ md = name_re.match("./#{filename}")
+ next unless md
+ File.open("#{$runnerDir}/#{filename}", "r") { |f|
+ runId, _, result = f.read.chomp.split(' ')
+ if runId != $runUniqueId
+ # We clean the dir before a starting a run.
+ raise "Can't happen"
+ end
+ map[md[1].to_i] = result
+ }
}
end
+ map
+end
- failureSet = {}
+def detectFailures
+ raise if $bundle
+ noresult = 0
+ statusMap = getStatusMap
+ familyMap = {}
- failures.each {
- | failure |
- appendFailure($runlist[failure])
- failureSet[failure] = true
- }
-
- familyMap = {}
$runlist.each_with_index {
| plan, index |
unless familyMap[plan.family]
familyMap[plan.family] = []
end
- if failureSet[index]
- appendResult(plan, false)
- familyMap[plan.family] << {:result => "FAIL", :plan => plan};
+ if not statusMap.has_key?(index) or statusMap[index].is_a?(Array)
+ appendNoResult(plan)
+ noresult += 1
next
+ end
+ result = nil
+ if statusMap[index] == STATUS_FILE_PASS
+ appendPass(plan)
+ result = "PASS"
else
- appendResult(plan, true)
- familyMap[plan.family] << {:result => "PASS", :plan => plan};
+ appendFailure(plan)
+ result = "FAIL"
end
- appendPass(plan)
+ appendResult(plan, statusMap[index] == STATUS_FILE_PASS)
+ familyMap[plan.family] << {:result => result, :plan => plan }
}
+ if noresult > 0
+ $stderr.puts("Could not get the exit status for #{noresult} tests")
+ # We can't change our exit code, as run-_javascript_core-tests
+ # expects 0 even when there are failures.
+ end
+
File.open($outputDir + "resultsByFamily", "w") {
| outp |
first = true
@@ -2263,7 +2327,7 @@
else
outp.puts
end
-
+
outp.print "#{familyName}:"
numPassed = 0
@@ -2301,6 +2365,7 @@
clean($outputDir + "failed")
clean($outputDir + "passed")
+clean($outputDir + "noresult")
clean($outputDir + "results")
clean($outputDir + "resultsByFamily")
clean($outputDir + ".vm")
Modified: trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-default.rb (277317 => 277318)
--- trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-default.rb 2021-05-11 04:46:49 UTC (rev 277317)
+++ trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-default.rb 2021-05-11 08:34:07 UTC (rev 277318)
@@ -37,7 +37,7 @@
def silentOutputHandler
Proc.new {
| name |
- " | " + pipeAndPrefixCommand((Pathname("..") + (name + ".out")).to_s, name)
+ pipeAndPrefixCommand((Pathname("..") + (name + ".out")).to_s, name)
}
end
@@ -45,18 +45,24 @@
def noisyOutputHandler
Proc.new {
| name |
- " | cat > " + Shellwords.shellescape((Pathname("..") + (name + ".out")).to_s)
+ "cat > " + Shellwords.shellescape((Pathname("..") + (name + ".out")).to_s)
}
end
+def getAndTestExitCode(plan, condition)
+ <<-EOF
+ if test "$exitCode" #{condition}
+EOF
+end
+
# Error handler for tests that fail exactly when they return non-zero exit status.
# This is useful when a test is expected to fail.
def simpleErrorHandler
Proc.new {
| outp, plan |
- outp.puts "if test -e #{plan.failFile}"
+ outp.puts getAndTestExitCode(plan, "-ne 0")
outp.puts "then"
- outp.puts " (echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + redirectAndPrefixCommand(plan.name)
+ outp.puts " (echo ERROR: Unexpected exit code: $exitCode) | " + redirectAndPrefixCommand(plan.name)
outp.puts " " + plan.failCommand
outp.puts "else"
outp.puts " " + plan.successCommand
@@ -68,7 +74,7 @@
def expectedFailErrorHandler
Proc.new {
| outp, plan |
- outp.puts "if test -e #{plan.failFile}"
+ outp.puts getAndTestExitCode(plan, "-ne 0")
outp.puts "then"
outp.puts " " + plan.successCommand
outp.puts "else"
@@ -84,10 +90,10 @@
Proc.new {
| outp, plan |
outputFilename = Shellwords.shellescape((Pathname("..") + (plan.name + ".out")).to_s)
-
- outp.puts "if test -e #{plan.failFile}"
+
+ outp.puts getAndTestExitCode(plan, "-ne 0")
outp.puts "then"
- outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + redirectAndPrefixCommand(plan.name)
+ outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: $exitCode) | " + redirectAndPrefixCommand(plan.name)
outp.puts " " + plan.failCommand
outp.puts "else"
outp.puts " " + plan.successCommand
@@ -101,10 +107,10 @@
| outp, plan |
outputFilename = Shellwords.shellescape((Pathname("..") + (plan.name + ".out")).to_s)
diffFilename = Shellwords.shellescape((Pathname("..") + (plan.name + ".diff")).to_s)
-
- outp.puts "if test -e #{plan.failFile}"
+
+ outp.puts getAndTestExitCode(plan, "-ne 0")
outp.puts "then"
- outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + redirectAndPrefixCommand(plan.name)
+ outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: $exitCode) | " + redirectAndPrefixCommand(plan.name)
outp.puts " " + plan.failCommand
outp.puts "elif test -e ../#{Shellwords.shellescape(expectedFilename)}"
outp.puts "then"
@@ -130,9 +136,9 @@
| outp, plan |
outputFilename = Shellwords.shellescape((Pathname("..") + (plan.name + ".out")).to_s)
- outp.puts "if test -e #{plan.failFile}"
+ outp.puts getAndTestExitCode(plan, "-ne 0")
outp.puts "then"
- outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + redirectAndPrefixCommand(plan.name)
+ outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: $exitCode) | " + redirectAndPrefixCommand(plan.name)
outp.puts " " + plan.failCommand
outp.puts "elif grep -i -q failed! #{outputFilename}"
outp.puts "then"
@@ -151,7 +157,7 @@
| outp, plan |
outputFilename = Shellwords.shellescape((Pathname("..") + (plan.name + ".out")).to_s)
- outp.puts "if test -e #{plan.failFile}"
+ outp.puts getAndTestExitCode(plan, "-ne 0")
outp.puts "then"
outp.puts " " + plan.successCommand
outp.puts "elif grep -i -q failed! #{outputFilename}"
@@ -171,9 +177,9 @@
| outp, plan |
outputFilename = Shellwords.shellescape((Pathname("..") + (plan.name + ".out")).to_s)
- outp.puts "if test -e #{plan.failFile}"
+ outp.puts getAndTestExitCode(plan, "-ne 0")
outp.puts "then"
- outp.puts " if [ `cat #{plan.failFile}` -eq 3 ]"
+ outp.puts " if [ \"$exitCode\" -eq 3 ]"
outp.puts " then"
outp.puts " if grep -i -q failed! #{outputFilename}"
outp.puts " then"
@@ -183,7 +189,7 @@
outp.puts " " + plan.successCommand
outp.puts " fi"
outp.puts " else"
- outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + redirectAndPrefixCommand(plan.name)
+ outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: $exitCode) | " + redirectAndPrefixCommand(plan.name)
outp.puts " " + plan.failCommand
outp.puts " fi"
outp.puts "else"
@@ -200,9 +206,9 @@
| outp, plan |
outputFilename = Shellwords.shellescape((Pathname("..") + (plan.name + ".out")).to_s)
- outp.puts "if test -e #{plan.failFile}"
+ outp.puts getAndTestExitCode(plan, "-ne 0")
outp.puts "then"
- outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: `cat #{plan.failFile}`) | " + redirectAndPrefixCommand(plan.name)
+ outp.puts " (cat #{outputFilename} && echo ERROR: Unexpected exit code: $exitCode) | " + redirectAndPrefixCommand(plan.name)
outp.puts " " + plan.failCommand
outp.puts "elif grep -i -q FAILED #{outputFilename}"
outp.puts "then"
@@ -262,25 +268,29 @@
script += "#{shellCommand} || exit 1"
"echo #{Shellwords.shellescape(script)} > #{Shellwords.shellescape((Pathname.new("..") + @name).to_s)}"
end
-
+
+ def statusCommand(status)
+ "echo #{$runUniqueId} $exitCode #{status} > #{statusFile}"
+ end
+
def failCommand
- "echo FAIL: #{Shellwords.shellescape(@name)} ; touch #{failFile} ; " + reproScriptCommand
+ "#{statusCommand(STATUS_FILE_FAIL)}; echo FAIL: #{Shellwords.shellescape(@name)}; " + reproScriptCommand
end
def successCommand
+ command = ""
executionTimeMessage = ""
if $reportExecutionTime
executionTimeMessage = " $(($SECONDS - $START_TIME))s"
end
if $progressMeter or $reportExecutionTime or $verbosity >= 2
- "rm -f #{failFile} ; echo PASS: #{Shellwords.shellescape(@name)}#{executionTimeMessage}"
- else
- "rm -f #{failFile}"
+ command = "echo PASS: #{Shellwords.shellescape(@name)}#{executionTimeMessage}"
end
+ "#{statusCommand(STATUS_FILE_PASS)}; #{command}"
end
- def failFile
- "test_fail_#{@index}"
+ def statusFile
+ "#{STATUS_FILE_PREFIX}#{@index}"
end
def writeRunScript(filename)
@@ -290,8 +300,42 @@
outp.puts "START_TIME=$SECONDS"
end
outp.puts "echo Running #{Shellwords.shellescape(@name)}"
- cmd = "(" + shellCommand + " || (echo $? > #{failFile})) 2>&1 "
- cmd += @outputHandler.call(@name)
+ #
+ # +--------------------------------------------------------------------+
+ # | +-----------------------------------------------+ |
+ # | | +--------------+ +-------------------+ | |
+ # | | | cmd 1 ----> 1|---> |0 --> outH 1 ---> 4|-> 4|---------------> 1|
+ # | | | 2 / | +-------------------+ | +-----------+ |
+ # | | |echo $? 0 -> 3|---------------------------> 1|-> |0 read xs | |
+ # | | +--------------+ | | exit $xs | |
+ # | | | +-----------+ |
+ # | +-----------------------------------------------+ |
+ # +--------------------------------------------------------------------+
+ # From the top down (i.e. reading from the outer _expression_ inwards):
+ #
+ # - Redirect FD 4 to our stdout
+ #
+ # - Build a pipe of two command sequences. The
+ # right-hand-side sequence reads a number from stdin and
+ # exits with it. Since it's the last command in the
+ # pipeline, this will be the value of $? after the
+ # pipeline completes.
+ #
+ # - In the left-hand-side sequence, redirect FD 3 to FD 1.
+ #
+ # - Build a pipe of two commands
+ # - run shellCommand, writing its exit code to FD 3.
+ # - run the outputHandler, with its stdin coming from
+ # the pipe, redirecting its output to FD 4. The
+ # outputHandler needs to be in a command sequence
+ # (i.e. in { cmd; ...}) as it may do its own
+ # redirections.
+ #
+ # We do all this
+ # - to avoid having to use a temporary file for the exit code
+ # - to keep within the bounds of POSIX sh (i.e. can't use
+ # PIPESTATUS)
+ cmd = "{ { { { #{shellCommand} 2>&1; echo $? >&3; } | { #{outputHandler.call(@name)} ;} >&4; } 3>&1; } | { read xs; exit $xs; } } 4>&1\nexitCode=$?\n"
if $verbosity >= 3
outp.puts "echo #{Shellwords.shellescape(cmd)}"
end
Modified: trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-playstation.rb (277317 => 277318)
--- trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-playstation.rb 2021-05-11 04:46:49 UTC (rev 277317)
+++ trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-playstation.rb 2021-05-11 08:34:07 UTC (rev 277318)
@@ -305,10 +305,21 @@
return ""
end
+ def statusCommand(status_code)
+ # May be called in th rescue block, so status is not
+ # guaranteed to be set; if it isn't, set the exit code to
+ # something that's clearly invalid.
+ <<-END_STATUS_COMMAND
+ File.open("#{statusFile}", "w") { |f|
+ f.puts("#{$runUniqueId} \#{status.nil? ? 999999999 : status.exitstatus} #{status_code}")
+ }
+ END_STATUS_COMMAND
+ end
+
def failCommand
<<-END_FAIL_COMMAND
print "FAIL: #{Shellwords.shellescape(@name)}\n"
- FileUtils.touch("#{failFile}")
+ #{statusCommand(STATUS_FILE_FAIL)}
#{reproScriptCommand}
END_FAIL_COMMAND
end
@@ -316,28 +327,18 @@
def successCommand
if $progressMeter or $verbosity >= 2
<<-END_VERBOSE_SUCCESS_COMMAND
- File.unlink("#{failFile}") if File.exists?("#{failFile}")
print "PASS: #{Shellwords.shellescape(@name)}\n"
+ #{statusCommand(STATUS_FILE_PASS)}
END_VERBOSE_SUCCESS_COMMAND
else
- "File.unlink(\"#{failFile}\") if File.exists?(\"#{failFile}\")\n"
+ "#{statusCommand(STATUS_FILE_PASS)}\n"
end
end
- def failFile
- "test_fail_#{@index}"
+ def statusFile
+ "#{STATUS_FILE_PREFIX}#{@index}"
end
- def statusWrite
- <<-END_STATUS_WRITE
- if !success
- File.open("#{failFile}", "w") do |code_file|
- code_file.puts status
- end
- end
- END_STATUS_WRITE
- end
-
def writeRunScript(filename)
jsonfilepart = filename.basename.to_s + ".json"
jsondir = filename.dirname.parent + ".json"
@@ -357,7 +358,6 @@
outputName: @name.gsub(/(\\|\/)/, '_'),
checkScript: filename,
args: @arguments,
- failFile: "#{failFile}"
})
}
@@ -371,8 +371,6 @@
cmd = shellCommand
- cmd += statusWrite
-
cmd += @outputHandler.call(@name)
if $verbosity >= 3
@@ -382,7 +380,7 @@
@errorHandler.call(outp, self)
outp.puts "rescue RuntimeError => e"
outp.puts " print \"FAIL: #{Shellwords.shellescape(@name)}\\n\""
- outp.puts " FileUtils.touch(\"#{failFile}\")"
+ outp.puts " #{statusCommand(STATUS_FILE_FAIL)}"
outp.puts "end"
}
end
Modified: trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-ruby.rb (277317 => 277318)
--- trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-ruby.rb 2021-05-11 04:46:49 UTC (rev 277317)
+++ trunk/Tools/Scripts/webkitruby/jsc-stress-test-writer-ruby.rb 2021-05-11 08:34:07 UTC (rev 277318)
@@ -335,10 +335,21 @@
END_REPRO_SCRIPT_COMMAND
end
+ def statusCommand(status_code)
+ # May be called in th rescue block, so status is not
+ # guaranteed to be set; if it isn't, set the exit code to
+ # something that's clearly invalid.
+ <<-END_STATUS_COMMAND
+ File.open("#{statusFile}", "w") { |f|
+ f.puts("#{$runUniqueId} \#{status.nil? ? 999999999 : status.exitstatus} #{status_code}")
+ }
+ END_STATUS_COMMAND
+ end
+
def failCommand
<<-END_FAIL_COMMAND
print "FAIL: #{Shellwords.shellescape(@name)}\n"
- FileUtils.touch("#{failFile}")
+ #{statusCommand(STATUS_FILE_FAIL)}
#{reproScriptCommand}
END_FAIL_COMMAND
end
@@ -346,28 +357,18 @@
def successCommand
if $progressMeter or $verbosity >= 2
<<-END_VERBOSE_SUCCESS_COMMAND
- File.unlink("#{failFile}") if File.exists?("#{failFile}")
print "PASS: #{Shellwords.shellescape(@name)}\n"
+ #{statusCommand(STATUS_FILE_PASS)}
END_VERBOSE_SUCCESS_COMMAND
else
- "File.unlink(\"#{failFile}\") if File.exists?(\"#{failFile}\")\n"
+ "#{statusCommand(STATUS_FILE_PASS)}\n"
end
end
- def failFile
- "test_fail_#{@index}"
+ def statusFile
+ "#{STATUS_FILE_PREFIX}#{@index}"
end
- def statusWrite
- <<-END_STATUS_WRITE
- if !success(status)
- File.open("#{failFile}", "w") do |code_file|
- code_file.puts status.exitstatus
- end
- end
- END_STATUS_WRITE
- end
-
def writeRunScript(filename)
File.open(filename, "w") {
| outp |
@@ -382,8 +383,6 @@
cmd = shellCommand
- cmd += statusWrite
-
cmd += @outputHandler.call(@name)
if $verbosity >= 3
@@ -393,7 +392,7 @@
@errorHandler.call(outp, self)
outp.puts "rescue"
outp.puts " print \"FAIL: #{Shellwords.shellescape(@name)}\\n\""
- outp.puts " FileUtils.touch(\"#{failFile}\")"
+ outp.puts " #{statusCommand(STATUS_FILE_FAIL)}"
outp.puts "end"
}
end