Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rake test on mountable engine require library twice. #26457

Closed
asdacap opened this issue Sep 11, 2016 · 6 comments
Closed

rake test on mountable engine require library twice. #26457

asdacap opened this issue Sep 11, 2016 · 6 comments
Labels

Comments

@asdacap
Copy link

asdacap commented Sep 11, 2016

Steps to reproduce

  1. Create a new rails mountable engine
  2. Create a dummy scaffold, let say a post rails g scaffold Post title:string description:string
  3. (optional) Put some puts statement in the engine.rb file to see when it is loaded.
  4. Migrate then run rake test

Expected behavior

The engine should be loaded only once.

Actual behavior

The engine.rb was loaded twice. Got some warnings that said warning: method redefined; discarding old test_engine_posts. If I put a puts statement in engine.rb, it will be printed twice. This is a problem when having multiple other gems that is required in engine.rb. In an application that I try to port to mountable engines, a bunch of "method redefined" warning appear. Additionally, some gem may not expect this behavior and could cause problems.

System configuration

Rails version: 4.2.2, 4.2.7.1 and 5.0

Ruby version: 2.1.4 and 2.2.2

@maclover7
Copy link
Contributor

Hi @asdacap! By "being required twice" do you mean that engine.rb was loaded twice during the DB migration, and then twice during rake test (for a total of four times), or that it was loaded only two times total?

@asdacap
Copy link
Author

asdacap commented Sep 12, 2016

By "being required twice", I mean engine.rb is loaded twice during rake test. Its a total of two times.... I think. Other task seems to load it only once.

@maclover7
Copy link
Contributor

Am able to reproduce this locally (bundle exec rake test loads engine.rb twice). Here are the two callstacks:

Callstack 1:

["/Users/jon/code/rails/rails/blorgh/lib/blorgh/engine.rb:6:in `<top (required)>'",
 "/Users/jon/code/rails/rails/blorgh/lib/blorgh.rb:6:in `require'",
 "/Users/jon/code/rails/rails/blorgh/lib/blorgh.rb:6:in `<top (required)>'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:86:in `require'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:86:in `block (2 levels) in require'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:81:in `each'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:81:in `block in require'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:70:in `each'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:70:in `require'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler.rb:102:in `require'",
 "/Users/jon/code/rails/rails/blorgh/test/dummy/config/application.rb:5:in `<top (required)>'",
 "/Users/jon/code/rails/rails/blorgh/test/dummy/config/environment.rb:2:in `require_relative'",
 "/Users/jon/code/rails/rails/blorgh/test/dummy/config/environment.rb:2:in `<top (required)>'",
 "/Users/jon/code/rails/rails/blorgh/test/test_helper.rb:4:in `require'",
 "/Users/jon/code/rails/rails/blorgh/test/test_helper.rb:4:in `<top (required)>'",
 "/Users/jon/code/rails/rails/blorgh/test/blorgh_test.rb:1:in `require'",
 "/Users/jon/code/rails/rails/blorgh/test/blorgh_test.rb:1:in `<top (required)>'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/rake_test_loader.rb:10:in `require'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/rake_test_loader.rb:10:in `block (2 levels) in <main>'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/rake_test_loader.rb:9:in `each'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/rake_test_loader.rb:9:in `block in <main>'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/rake_test_loader.rb:4:in `select'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/rake_test_loader.rb:4:in `<main>'"]

Callstack Two:

 "/Users/jon/code/rails/rails/blorgh/lib/blorgh/engine.rb:6:in `<top (required)>'",
 "/Users/jon/code/rails/rails/blorgh/lib/blorgh.rb:6:in `require'",
 "/Users/jon/code/rails/rails/blorgh/lib/blorgh.rb:6:in `<top (required)>'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:86:in `require'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:86:in `block (2 levels) in require'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:81:in `each'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:81:in `block in require'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:70:in `each'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler/runtime.rb:70:in `require'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/bundler-1.12.1/lib/bundler.rb:102:in `require'",
 "/Users/jon/code/rails/rails/blorgh/test/dummy/config/application.rb:5:in `<top (required)>'",
 "/Users/jon/code/rails/rails/blorgh/test/dummy/Rakefile:4:in `require_relative'",
 "/Users/jon/code/rails/rails/blorgh/test/dummy/Rakefile:4:in `<top (required)>'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/rake_module.rb:28:in `load'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/rake_module.rb:28:in `load_rakefile'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/application.rb:686:in `raw_load_rakefile'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/application.rb:96:in `block in load_rakefile'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/application.rb:178:in `standard_exception_handling'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/application.rb:95:in `load_rakefile'",
 "/Users/jon/code/rails/rails/railties/lib/rails/commands/rake_proxy.rb:13:in `block in run_rake_task'",
 "/Users/jon/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rake-11.2.2/lib/rake/application.rb:178:in `standard_exception_handling'",
 "/Users/jon/code/rails/rails/railties/lib/rails/commands/rake_proxy.rb:11:in `run_rake_task'",
 "/Users/jon/code/rails/rails/railties/lib/rails/commands/common_commands_tasks.rb:9:in `run_command!'",
 "/Users/jon/code/rails/rails/railties/lib/rails/commands.rb:18:in `<top (required)>'",
 "bin/rails:4:in `require'",
 "bin/rails:4:in `<main>'"]

@aterletskiy
Copy link

I noticed that changing file permissions of dummy/bin/* to 0644 fixed "double" loading issue for me along with other issues, like Don't know how to build task 'db:test:prepare' (see --tasks) and everything still works. Any particular reason bin files within dummy app are generated with 0755 permissions?

@HashNotAdam
Copy link

HashNotAdam commented Oct 21, 2018

This is because ActiveRecord calls

system("bin/rails db:test:prepare")

In 5.2.1, this is called in Migration::load_schema_if_pending! which is triggered when the test_helper requires rails/test_help.

The double load goes away as soon as you have migrations and all migrations have been run.

To stop the double load, it would be necessary to pull the logic out of Active Record and into Rails but, given the small impact this issue has, it could be a challenge to make the case for that. You wouldn't want to move the whole method into Rails—just trigger the db:test:prepare command—so there would need to be a mechanism for letting Active Record check the migrations, clear the connections, hand back to Rails to perform the test preparation, then go back to Active Record to establish new connections.

@skipkayhil
Copy link
Member

I tried reproducing this on 7.0.4.2:

$ rails _7.0.4.2_ plugin new --mountable rails26457
# edit TODOs out of gemspec
$ bin/rails g scaffold Post title:string description:string
# add `puts "engine"` at bottom of engine.rb
$ rake test
engine

but it looks like the engine only gets required once now. I'm going to close this as its been 4+ years and doesn't appear to be reproducible now, but if someone provides a reproduction on Rails 7 or main I'll reopen

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants