-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Add test to reproduce bug with Warden test helper #930
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
Add test to reproduce bug with Warden test helper #930
Conversation
When using the `login_as` Warden test helper, it depends whether or not the API class under test is evaluated *before* or *after* the tests. Given that this bug first appeared in v0.10.0, my current theory is the use of `deep_dup` is responsible. Warden persists registered hooks in instance variables (ex. http://git.io/NhKG). When an API class is evaluated *before* the tests, the hooks are registered *after* duplication takes place, so the original object is left with an empty array of hooks.
Unfortunately, this test only fails when run in isolation. My apologies!
Below is the expected output:
|
I would dig into Warden next to find out what causes the 401 and what's different at that place when it fails vs. succeeds. |
Hi, @dblock! Thanks for looking into this. I believe it's related to the state of the # spec/grape/warden_test_helpers_spec.rb
require 'spec_helper'
module Warden
module Hooks
def dup
_on_request # before duplicating, initialize @_on_request
super
end
end
end …both tests pass: bundle exec rspec spec/grape/warden_test_helpers_spec.rb
|
I see. Generally using locals there is assuming that the scope used for the request is the same one after initialization, but that's no longer the case in Grape. I would change this to an |
Cool! Happy to try to fix this upstream in Warden, but I'm having trouble understanding the root cause (or the suggested solution), my apologies. Is this the |
Just wanted to share a one-liner alternative to the monkey-patch mentioned above: # spec/grape/warden_test_helpers_spec.rb
require 'spec_helper'
Warden::Manager._on_request I'm still a little confused about what to try to merge upstream in Warden. Any assistance would be most appreciated! Thanks in advance. |
I think something that doesn't rely on instance variables. Ultimately the issue is that after a deep_dup those don't survive, right? Or the scope of instance variables changes when you manipulate the dup? |
Hi @dblock, I think there are two distinct "bugs" at work here related to Bug 1: why the first test failsSummaryThe hook is registered on Example
Bug 2: why the second test passesSummaryThe hook is registered on Example
Sharing stateI was surprised by some "spooky action at a distance" behavior of require 'active_support'
require 'active_support/core_ext'
class Atom
attr_accessor :electrons
end
hydrogen = Atom.new
hydrogen.electrons = ['-']
hydrogen.electrons.count
# => 1
helium = hydrogen.deep_dup
helium.electrons << '-'
helium.electrons.count
# => 2
hydrogen.electrons.count
# => 2 <-- ಠ_ಠ SolutionsNot
|
This is some very good research! I think we should fix this in Grape, but white-listing things that need to be deep_dup'ed, which is really about settings and stacks of things in Grape. I would start by defaulting things to not be actually dup-ed, and then white-listing those that do by examining spec failures. I would merge anything that has all the existing grape tests passing along these lines. |
@toddmazierski You should give my suggestion a try, I'll do my best to help. |
Sounds good, @dblock! I'll give it a go. Thanks! |
@dblock's suggestion (http://git.io/vvmJj) was instead of `deep_dup`ing _all_ settings by default, to only `deep_dup` settings on a whitelist. However, after implementing this, at least according to the tests, there doesn't appear to be **any** settings need to be `deep_dup`ed. Instead, a shallow clone (a `dup`) looks to be sufficient. I've confirmed that with this change, the test `warden_test_helpers_spec.rb` passes in the suite and in isolation (i.e. the bug described is fixed).
The code looks ok, if no tests break you can PR it. |
So for this one to be merged, build needs to be fixed, commits squashed, readme/changelogs updated. |
Moved to #1034! |
When using the
login_as
Warden test helper, it depends whether or not the API class under test is evaluated before or after the tests.Given that this bug first appeared in v0.10.0, my current theory is the use of
deep_dup
is responsible. Warden persists registered hooks in instance variables. When an API class is evaluated before the tests, the hooks are registered after duplication takes place, so the original object is left with an empty array of hooks.Any help or suggestions are most appreciated. Thanks for this great library! 😄