1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Fix arguments passing in testing isolation

The issue affects MRI 2.2.5, MRI 2.3.3, JRuby 9.1.6.0. It can be reproduced by:

```
$ cd activemodel
$ NO_FORK=1 bundle exec rake test
```

If we wrap original arguments in quotes, it will be considered as a one big single argument.
Later, [`rake/rake_test_loader.rb`](https://github.com/ruby/rake/blob/7863b97/lib/rake/rake_test_loader.rb#L15)
will iterate over ARGS and try to require that huge single "argument" (which is a list of multiple .rb files).
This leads to an exception:

```
/Users/kir/Project
s/opensource/rails/vendor/bundle/gems/rake-11.3.0/lib/rake/rake_test_loader.rb:15:in `require': cannot load such file -- /Users/kir/Projects/opensource/rails/activemodel/test/cases/
attribute_assignment_test.rb [stripped] /Users/kir/Projects/opensource/rails/activemodel/test/cases/validations/with_validation_test.rb /Users/kir/Projects/opensource/rails/activemodel/test/cases/validations_test
.rb (LoadError)

        from /Users/kir/Projects/opensource/rails/vendor/bundle/gems/rake-11.3.0/lib/rake/rake_test_loader.rb:15:in `block in <main>'
        from /Users/kir/Projects/opensource/rails/vendor/bundle/gems/rake-11.3.0/lib/rake/rake_test_loader.rb:4:in `select'
        from /Users/kir/Projects/opensource/rails/vendor/bundle/gems/rake-11.3.0/lib/rake/rake_test_loader.rb:4:in `<main>'
```

Originally quotes were introduced in https://github.com/rails/rails/pull/19819 to fix MRI 2.2.2.

The fix solves issue on all affected platforms: MRI 2.2.5, MRI 2.3.3, JRuby 9.1.6.0.
This commit is contained in:
Kir Shatrov 2016-11-28 21:12:47 -05:00
parent 6d6249b1c1
commit 4b3cd4b0fe

View file

@ -2,7 +2,6 @@ module ActiveSupport
module Testing module Testing
module Isolation module Isolation
require "thread" require "thread"
require "shellwords"
def self.included(klass) #:nodoc: def self.included(klass) #:nodoc:
klass.class_eval do klass.class_eval do
@ -79,13 +78,15 @@ module ActiveSupport
"ISOLATION_OUTPUT" => tmpfile.path "ISOLATION_OUTPUT" => tmpfile.path
} }
load_paths = $-I.map { |p| "-I\"#{File.expand_path(p)}\"" }.join(" ") test_opts = "-n#{self.class.name}##{self.name}"
orig_args = ORIG_ARGV.join(" ")
test_opts = "-n#{self.class.name}##{Shellwords.escape(self.name)}"
command = "#{Gem.ruby} #{load_paths} #{$0} '#{orig_args}' #{test_opts}"
# IO.popen lets us pass env in a cross-platform way load_path_args = []
child = IO.popen(env, command) $-I.each do |p|
load_path_args << "-I"
load_path_args << File.expand_path(p)
end
child = IO.popen([env, Gem.ruby, *load_path_args, $0, *ORIG_ARGV, test_opts])
begin begin
Process.wait(child.pid) Process.wait(child.pid)