Closed carmi closed 9 years ago
Couldn't find User with 'id'=1
is an application error. Sidekiq covers it a little bit here: https://github.com/mperham/sidekiq/wiki/FAQ#why-am-i-seeing-a-lot-of-cant-find-modelname-with-id12345-errors-with-sidekiq
Because sucker punch is always running workers, it means that the worker is attempting to run your job before the application code has created the user. Trying adding sleep to the worker to prove the theory.
You might also consider using the inline testing feature of sucker_punch
https://github.com/brandonhilkert/sucker_punch#testing. This will make everything synchronous so you don't have to worry about this.
Yeah, I was using the inline adapter for sucker punch by requiring require 'sucker_punch/testing/inline'
and I still got the error. Additionally, I put a binding in the invocation, so I could be sure that the database records existed before the error occured, and after. So that made me think it was a GlobalID issue or something with SuckerPunch.
Do you get the error when you use Sucker Punch outside of ActiveJob?
I have added to spec/rails_helper.rb
Rails.application.config.active_job.queue_adapter = :inline
and it helped
I'm getting this error too, meanwhile I'm using this:
# config/initializers/acive_job.rb
Rails.application.configure do
if Rails.env.test?
config.active_job.queue_adapter = :inline
else
config.active_job.queue_adapter = :sucker_punch
end
end
Quick question for everyone that has experienced this, are you using transactions? And if so, have you read this: https://github.com/brandonhilkert/sucker_punch#cleaning-test-data-transactions ?
@brandonhilkert yes, I'm using transactions.
# spec/support/database_cleaner.rb
RSpec.configure do |config|
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, type: :feature) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each, job: true) do
DatabaseCleaner.strategy = :truncation
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end
# spec/rails_helper.rb
RSpec.configure do |config|
...
config.use_transactional_fixtures = false
...
end
Using `config.active_job.queue_adapter = :inline`:
```ruby
$ bin/rspec spec
Finished in 2 seconds (files took 5.34 seconds to load)
106 examples, 0 failures
Requiring sucker_punch/testing/inline
in spec/rails_helper.rb
with config.active_job.queue_adapter = :sucker_punch
:
$ bin/rspec spec
......................................
An error occurred in an after hook
ActiveJob::DeserializationError: Error while trying to deserialize arguments: Couldn't find User with 'id'=4
occurred at /home/vagrant/.gem/ruby/2.2.0/gems/activerecord-4.2.0/lib/active_record/core.rb:154:in `find'
Finished in 22.41 seconds (files took 6.53 seconds to load)
106 examples, 1 failure
Let me know if I can help you to investigate this issue.
Just for further confirmation I am also seeing this behaviour on this project https://github.com/andypike/ruby_videos. I'm happy to help if you need further information :smile:
@andypike This project uses transactional fixtures without database cleaner, which as mentioned above won't work b/c the thread is running separately from the transaction.
@dbalexandre Can you put a public sample app for me to check out?
Sure, I tried using database_cleaner and truncation for specs that use sucker_punch and had the above behaviour. I reverted back to using the inline active_job adapter for the test environment to get my specs passing.
I can make these changes again for you and leave it in a branch as a test app that recreates the issue above. Will update this issue with the details shortly.
Thanks for the fast reply and awesome gem :heart:
Hi @brandonhilkert,
Here is a branch that recreates the issue: https://github.com/andypike/ruby_videos/tree/sucker_punch_spec_errors
To recap, it's a Rails 4.2 app using ActiveJob to send async emails via sucker_punch.
In this branch I do not use transactional fixtures and instead use database_cleaner with truncation. I've included sucker_punch/testing/inline
in rails_helper.rb
and specified the ActiveJob adapter as :sucker_punch
for all environments.
In this branch I get 8 failing specs, all with the Error while trying to deserialize arguments: Couldn't find Video with 'id'=47
(with varying ids).
Contrast this branch with master where I just use the inline ActiveJob adapter for the test environment (without user database_cleaner etc).
I hope this helps. If you need anything further I'd be more than happy to help.
Andy
Right, ignore all that!
I forgot to add the :job => true
to the specs that send async emails and now it's working fine. Will commit these to the branch so others can see a working example.
Andy
Interestingly, I changed the tag from :job
to :async
, ran my specs and it failed as described above (that's the tag I used originally). Then putting it back to :job
worked again. But then I put it back to use the :async
tag again and it worked fine.
I've since run the specs about 20 times now using the :async
tag and it always passes. So not sure what to add here, may totally be user error on my part but I'm pretty sure the error did happen when everything was configured correctly.
I'll update the issue if I can get a repeatable setup.
@andypike Thanks for the update. Would be happy to dig in to an example that doesn't work. But as long as it doesn't have the truncation stuff, it won't work. I have a hard time keeping with all the changes with Rspec
and syntax for database_cleaner
so it wouldn't surprise me if, at some point, the meta data starts working differently.
@brandonhilkert Hello. I'm having the same issue here. I'm using minitest engine instead of rspec. No problems running it on development, but in test it doesn't work.
I'm using
Database cleaner is set to truncation on every test. The only thing that makes rails find my model is: use_transactional_fixtures = false
But this breaks lots of my other tests.
Is there anyway to test Sucker Punch without disabling transaction_fixtures? Right now I'm skipping the tests using ActiveJob inline. Thanks for your help. JP
@jpaulomotta Keep transactional fixtures on defeats the purpose of using truncation. Unfortunately, if data is created in a transaction, it won't be available for the other thread that sucker punch is running in.
Not quite sure easiest way to report this error. But I just upgraded to Rails 4.2 which introduced GlobalID and in my test suite (rspec) I am getting errors when I use SuckerPunch as my ActiveJob backend in test environment.
When I do the following:
I got an error.
I've been using the SuckerPunch inline adapter
require 'sucker_punch/testing/inline'
but I still get the following error. When I switch to the Rails inline adapter, with no other change in my code:the error goes away.
Let me know if I can provide more information.