зеркало из https://github.com/github/ruby.git
Update to ruby/mspec@dc2eb26
This commit is contained in:
Родитель
f38c6552f9
Коммит
de60139053
|
@ -140,28 +140,44 @@ def ruby_exe(code = :not_given, opts = {})
|
|||
expected_status = opts.fetch(:exit_status, 0)
|
||||
|
||||
begin
|
||||
platform_is_not :opal do
|
||||
command = ruby_cmd(code, opts)
|
||||
output = `#{command}`
|
||||
status = Process.last_status
|
||||
command = ruby_cmd(code, opts)
|
||||
|
||||
exit_status = if status.exited?
|
||||
status.exitstatus
|
||||
elsif status.signaled?
|
||||
signame = Signal.signame status.termsig
|
||||
raise "No signal name?" unless signame
|
||||
:"SIG#{signame}"
|
||||
else
|
||||
raise SpecExpectationNotMetError, "#{exit_status.inspect} is neither exited? nor signaled?"
|
||||
end
|
||||
if exit_status != expected_status
|
||||
formatted_output = output.lines.map { |line| " #{line}" }.join
|
||||
raise SpecExpectationNotMetError,
|
||||
"Expected exit status is #{expected_status.inspect} but actual is #{exit_status.inspect} for command ruby_exe(#{command.inspect})\nOutput:\n#{formatted_output}"
|
||||
end
|
||||
|
||||
output
|
||||
# Try to avoid the extra shell for 2>&1
|
||||
# This is notably useful for TimeoutAction which can then signal the ruby subprocess and not the shell
|
||||
popen_options = []
|
||||
if command.end_with?(' 2>&1')
|
||||
command = command[0...-5]
|
||||
popen_options = [{ err: [:child, :out] }]
|
||||
end
|
||||
|
||||
output = IO.popen(command, *popen_options) do |io|
|
||||
pid = io.pid
|
||||
MSpec.subprocesses << pid
|
||||
begin
|
||||
io.read
|
||||
ensure
|
||||
MSpec.subprocesses.delete(pid)
|
||||
end
|
||||
end
|
||||
|
||||
status = Process.last_status
|
||||
|
||||
exit_status = if status.exited?
|
||||
status.exitstatus
|
||||
elsif status.signaled?
|
||||
signame = Signal.signame status.termsig
|
||||
raise "No signal name?" unless signame
|
||||
:"SIG#{signame}"
|
||||
else
|
||||
raise SpecExpectationNotMetError, "#{exit_status.inspect} is neither exited? nor signaled?"
|
||||
end
|
||||
if exit_status != expected_status
|
||||
formatted_output = output.lines.map { |line| " #{line}" }.join
|
||||
raise SpecExpectationNotMetError,
|
||||
"Expected exit status is #{expected_status.inspect} but actual is #{exit_status.inspect} for command ruby_exe(#{command.inspect})\nOutput:\n#{formatted_output}"
|
||||
end
|
||||
|
||||
output
|
||||
ensure
|
||||
saved_env.each { |key, value| ENV[key] = value }
|
||||
env.keys.each do |key|
|
||||
|
|
|
@ -3,6 +3,8 @@ class TimeoutAction
|
|||
@timeout = timeout
|
||||
@queue = Queue.new
|
||||
@started = now
|
||||
@fail = false
|
||||
@error_message = "took longer than the configured timeout of #{@timeout}s"
|
||||
end
|
||||
|
||||
def register
|
||||
|
@ -37,15 +39,25 @@ class TimeoutAction
|
|||
elapsed = now - @started
|
||||
if elapsed > @timeout
|
||||
if @current_state
|
||||
STDERR.puts "\nExample took longer than the configured timeout of #{@timeout}s:"
|
||||
STDERR.puts "\nExample #{@error_message}:"
|
||||
STDERR.puts "#{@current_state.description}"
|
||||
else
|
||||
STDERR.puts "\nSome code outside an example took longer than the configured timeout of #{@timeout}s"
|
||||
STDERR.puts "\nSome code outside an example #{@error_message}"
|
||||
end
|
||||
STDERR.flush
|
||||
|
||||
show_backtraces
|
||||
exit 2
|
||||
if MSpec.subprocesses.empty?
|
||||
exit 2
|
||||
else
|
||||
# Do not exit but signal the subprocess so we can get their output
|
||||
MSpec.subprocesses.each do |pid|
|
||||
Process.kill :SIGTERM, pid
|
||||
end
|
||||
@fail = true
|
||||
@current_state = nil
|
||||
break # stop this thread, will fail in #after
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -65,6 +77,11 @@ class TimeoutAction
|
|||
@queue << -> do
|
||||
@current_state = nil
|
||||
end
|
||||
|
||||
if @fail
|
||||
STDERR.puts "\n\nThe last example #{@error_message}. See above for the subprocess stacktrace."
|
||||
exit 2
|
||||
end
|
||||
end
|
||||
|
||||
def finish
|
||||
|
@ -73,19 +90,38 @@ class TimeoutAction
|
|||
end
|
||||
|
||||
private def show_backtraces
|
||||
if RUBY_ENGINE == 'truffleruby'
|
||||
STDERR.puts 'Java stacktraces:'
|
||||
Process.kill :SIGQUIT, Process.pid
|
||||
sleep 1
|
||||
end
|
||||
java_stacktraces = -> pid {
|
||||
if RUBY_ENGINE == 'truffleruby' || RUBY_ENGINE == 'jruby'
|
||||
STDERR.puts 'Java stacktraces:'
|
||||
Process.kill :SIGQUIT, pid
|
||||
sleep 1
|
||||
end
|
||||
}
|
||||
|
||||
STDERR.puts "\nRuby backtraces:"
|
||||
if defined?(Truffle::Debug.show_backtraces)
|
||||
Truffle::Debug.show_backtraces
|
||||
if MSpec.subprocesses.empty?
|
||||
java_stacktraces.call Process.pid
|
||||
|
||||
STDERR.puts "\nRuby backtraces:"
|
||||
if defined?(Truffle::Debug.show_backtraces)
|
||||
Truffle::Debug.show_backtraces
|
||||
else
|
||||
Thread.list.each do |thread|
|
||||
unless thread == Thread.current
|
||||
STDERR.puts thread.inspect, thread.backtrace, ''
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
Thread.list.each do |thread|
|
||||
unless thread == Thread.current
|
||||
STDERR.puts thread.inspect, thread.backtrace, ''
|
||||
MSpec.subprocesses.each do |pid|
|
||||
STDERR.puts "\nFor subprocess #{pid}"
|
||||
java_stacktraces.call pid
|
||||
|
||||
if RUBY_ENGINE == 'truffleruby'
|
||||
STDERR.puts "\nRuby backtraces:"
|
||||
Process.kill :SIGALRM, pid
|
||||
sleep 1
|
||||
else
|
||||
STDERR.puts "Don't know how to print backtraces of a subprocess on #{RUBY_ENGINE}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,9 +38,10 @@ module MSpec
|
|||
@expectation = nil
|
||||
@expectations = false
|
||||
@skips = []
|
||||
@subprocesses = []
|
||||
|
||||
class << self
|
||||
attr_reader :file, :include, :exclude, :skips
|
||||
attr_reader :file, :include, :exclude, :skips, :subprocesses
|
||||
attr_writer :repeat, :randomize
|
||||
attr_accessor :formatter
|
||||
end
|
||||
|
|
|
@ -145,7 +145,7 @@ RSpec.describe Object, "#ruby_exe" do
|
|||
stub_const 'RUBY_EXE', 'ruby_spec_exe -w -Q'
|
||||
|
||||
@script = RubyExeSpecs.new
|
||||
allow(@script).to receive(:`).and_return('OUTPUT')
|
||||
allow(IO).to receive(:popen).and_return('OUTPUT')
|
||||
|
||||
status_successful = double(Process::Status, exited?: true, exitstatus: 0)
|
||||
allow(Process).to receive(:last_status).and_return(status_successful)
|
||||
|
@ -155,7 +155,7 @@ RSpec.describe Object, "#ruby_exe" do
|
|||
code = "code"
|
||||
options = {}
|
||||
output = "output"
|
||||
allow(@script).to receive(:`).and_return(output)
|
||||
expect(IO).to receive(:popen).and_return(output)
|
||||
|
||||
expect(@script.ruby_exe(code, options)).to eq output
|
||||
end
|
||||
|
@ -168,7 +168,7 @@ RSpec.describe Object, "#ruby_exe" do
|
|||
code = "code"
|
||||
options = {}
|
||||
expect(@script).to receive(:ruby_cmd).and_return("ruby_cmd")
|
||||
expect(@script).to receive(:`).with("ruby_cmd")
|
||||
expect(IO).to receive(:popen).with("ruby_cmd")
|
||||
@script.ruby_exe(code, options)
|
||||
end
|
||||
|
||||
|
@ -227,7 +227,7 @@ RSpec.describe Object, "#ruby_exe" do
|
|||
expect(ENV).to receive(:[]=).with("ABC", "xyz")
|
||||
expect(ENV).to receive(:[]=).with("ABC", "123")
|
||||
|
||||
expect(@script).to receive(:`).and_raise(Exception)
|
||||
expect(IO).to receive(:popen).and_raise(Exception)
|
||||
expect do
|
||||
@script.ruby_exe nil, :env => { :ABC => "xyz" }
|
||||
end.to raise_error(Exception)
|
||||
|
@ -248,7 +248,7 @@ RSpec.describe Object, "#ruby_exe" do
|
|||
|
||||
it "does not raise exception when command ends with expected status" do
|
||||
output = "output"
|
||||
allow(@script).to receive(:`).and_return(output)
|
||||
expect(IO).to receive(:popen).and_return(output)
|
||||
|
||||
expect(@script.ruby_exe("path", exit_status: 4)).to eq output
|
||||
end
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
# This script is used to check that each *_spec.rb file has
|
||||
# a relative_require for spec_helper which should live higher
|
||||
# up in the ruby/spec repo directory tree.
|
||||
#
|
||||
# Prints errors to $stderr and returns a non-zero exit code when
|
||||
# errors are found.
|
||||
#
|
||||
# Related to https://github.com/ruby/spec/pull/992
|
||||
|
||||
def check_file(fn)
|
||||
File.foreach(fn) do |line|
|
||||
return $1 if line =~ /^\s*require_relative\s*['"](.*spec_helper)['"]/
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
rootdir = ARGV[0] || "."
|
||||
fglob = File.join(rootdir, "**", "*_spec.rb")
|
||||
specfiles = Dir.glob(fglob)
|
||||
raise "No spec files found in #{fglob.inspect}. Give an argument to specify the root-directory of ruby/spec" if specfiles.empty?
|
||||
|
||||
errors = 0
|
||||
specfiles.sort.each do |fn|
|
||||
result = check_file(fn)
|
||||
if result.nil?
|
||||
warn "Missing require_relative for *spec_helper for file: #{fn}"
|
||||
errors += 1
|
||||
end
|
||||
end
|
||||
|
||||
puts "# Found #{errors} files with require_relative spec_helper issues."
|
||||
exit 1 if errors > 0
|
Загрузка…
Ссылка в новой задаче