mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
560541ffde
Hopefully the first of many related to #11700. With these changes the railties tests wont 100% pass but at least they will run and show the errors. The first problem was the @method_name variable was never set. This was causing ENV["ISOLATION_TEST"] to always be nil which would cause the test output to never be written to the tempfile. The second problem was that an invalid -t option was being passed to minitest and minitest was erroring out. The third problem was the run method needs to always return an instance of the test class it is trying to isolate. We were returning a ProxyTestResult instead.
92 lines
2.3 KiB
Ruby
92 lines
2.3 KiB
Ruby
require 'rbconfig'
|
|
require 'minitest/parallel_each'
|
|
|
|
module ActiveSupport
|
|
module Testing
|
|
module Isolation
|
|
require 'thread'
|
|
|
|
def self.included(klass) #:nodoc:
|
|
klass.extend(Module.new {
|
|
def test_methods
|
|
ParallelEach.new super
|
|
end
|
|
})
|
|
end
|
|
|
|
def self.forking_env?
|
|
!ENV["NO_FORK"] && ((RbConfig::CONFIG['host_os'] !~ /mswin|mingw/) && (RUBY_PLATFORM !~ /java/))
|
|
end
|
|
|
|
@@class_setup_mutex = Mutex.new
|
|
|
|
def _run_class_setup # class setup method should only happen in parent
|
|
@@class_setup_mutex.synchronize do
|
|
unless defined?(@@ran_class_setup) || ENV['ISOLATION_TEST']
|
|
self.class.setup if self.class.respond_to?(:setup)
|
|
@@ran_class_setup = true
|
|
end
|
|
end
|
|
end
|
|
|
|
def run
|
|
serialized = run_in_isolation do
|
|
super
|
|
end
|
|
|
|
Marshal.load(serialized)
|
|
end
|
|
|
|
module Forking
|
|
def run_in_isolation(&blk)
|
|
read, write = IO.pipe
|
|
|
|
pid = fork do
|
|
read.close
|
|
yield
|
|
write.puts [Marshal.dump(self.dup)].pack("m")
|
|
exit!
|
|
end
|
|
|
|
write.close
|
|
result = read.read
|
|
Process.wait2(pid)
|
|
return result.unpack("m")[0]
|
|
end
|
|
end
|
|
|
|
module Subprocess
|
|
ORIG_ARGV = ARGV.dup unless defined?(ORIG_ARGV)
|
|
|
|
# Crazy H4X to get this working in windows / jruby with
|
|
# no forking.
|
|
def run_in_isolation(&blk)
|
|
require "tempfile"
|
|
|
|
if ENV["ISOLATION_TEST"]
|
|
yield
|
|
File.open(ENV["ISOLATION_OUTPUT"], "w") do |file|
|
|
file.puts [Marshal.dump(self.dup)].pack("m")
|
|
end
|
|
exit!
|
|
else
|
|
Tempfile.open("isolation") do |tmpfile|
|
|
ENV["ISOLATION_TEST"] = self.class.name
|
|
ENV["ISOLATION_OUTPUT"] = tmpfile.path
|
|
|
|
load_paths = $-I.map {|p| "-I\"#{File.expand_path(p)}\"" }.join(" ")
|
|
`#{Gem.ruby} #{load_paths} #{$0} #{ORIG_ARGV.join(" ")}`
|
|
|
|
ENV.delete("ISOLATION_TEST")
|
|
ENV.delete("ISOLATION_OUTPUT")
|
|
|
|
return tmpfile.read.unpack("m")[0]
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
include forking_env? ? Forking : Subprocess
|
|
end
|
|
end
|
|
end
|