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

Specs fail following upgrade from 4.3.1 to 4.4.0 #163

Closed
tirdadc opened this issue Feb 11, 2016 · 7 comments · Fixed by #165
Closed

Specs fail following upgrade from 4.3.1 to 4.4.0 #163

tirdadc opened this issue Feb 11, 2016 · 7 comments · Fixed by #165

Comments

@tirdadc
Copy link

tirdadc commented Feb 11, 2016

I have these pretty standard specs:

require 'rails_helper'

describe 'Visitor triggers Rack::Attack throttling' do
  include Rack::Test::Methods

  def app
    Rails.application
  end

  ...

  describe "throttle excessive POST requests to /u/sign_in by IP address" do
    let(:limit) { 5 }
    let(:login_url) { '/u/sign_in' }

    context "number of requests is lower than the limit" do
      it "does not change the request status" do
        limit.times do |i|
          post login_url, { email: "example1#{i}@gmail.com" }, "REMOTE_ADDR" => "1.2.3.6"
          expect(last_response.status).to_not eq(429)
        end
      end
    end
  end
end

and they worked fine prior to the upgrade. Now I get:


  1) Visitor triggers Rack::Attack throttling throttle excessive POST requests to /u/sign_in by IP address number of requests is lower than the limit does not change the request status
     Failure/Error: post login_url, { email: "example1#{i}@gmail.com" }, "REMOTE_ADDR" => "1.2.3.6"

     LoadError:
       cannot load such file -- dalli
     # ./spec/features/visitor_triggers_rack_attack_throttling_spec.rb:43:in `block (5 levels) in <top (required)>'
     # ./spec/features/visitor_triggers_rack_attack_throttling_spec.rb:42:in `times'
     # ./spec/features/visitor_triggers_rack_attack_throttling_spec.rb:42:in `block (4 levels) in <top (required)>'

I'm not using memcached:

# environment/test.rb
config.cache_store = :memory_store
@tirdadc
Copy link
Author

tirdadc commented Feb 12, 2016

So in the meantime I switched over to using Redis as the cache store, but 4.4.0 still causes the specs to fail:

You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install

Why is this dependency introduced?

@ktheory
Copy link
Collaborator

ktheory commented Feb 12, 2016

Thanks for reporting this bug. I'll try to track it down.

On Fri, Feb 12, 2016 at 12:30 PM Tirdad C. [email protected] wrote:

So in the meantime I switched over to using Redis as the cache store, but
4.4.0 still causes the specs to fail:

You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install

Why is this dependency introduced?


Reply to this email directly or view it on GitHub
#163 (comment)
.

@ktheory
Copy link
Collaborator

ktheory commented Feb 12, 2016

@tirdadc It's not obvious to me how the dalli dependency was introduced. It's certainly unintentional. 🐛

Can you please include a longer backtrace to help debug the issue? In particular, please include the lines including rack/attack/*.

Thanks!

@tirdadc
Copy link
Author

tirdadc commented Feb 13, 2016

@ktheory sure thing:

You don't have dalli installed in your application. Please add it to your Gemfile and run bundle install
Coverage report generated for RSpec to /private/var/srv/testproject/public/coverage. 0.0 / 0.0 LOC (100.0%) covered.
/Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:274:in `require': cannot load such file -- dalli (LoadError)
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:274:in `block in require'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:240:in `load_dependency'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:274:in `require'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5.1/lib/active_support/cache/mem_cache_store.rb:2:in `<top (required)>'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:274:in `require'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:274:in `block in require'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:240:in `load_dependency'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:274:in `require'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rack-attack-4.4.0/lib/rack/attack/store_proxy.rb:10:in `build'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rack-attack-4.4.0/lib/rack/attack/cache.rb:14:in `store='
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rack-attack-4.4.0/lib/rack/attack/cache.rb:8:in `initialize'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rack-attack-4.4.0/lib/rack/attack.rb:74:in `new'
    from /Users/tirdad/.rbenv/versions/2.3.0/lib/ruby/gems/2.3.0/gems/rack-attack-4.4.0/lib/rack/attack.rb:74:in `cache'
    from /private/var/srv/testproject/config/initializers/rack-attack.rb:18:in `<class:Attack>'
    from /private/var/srv/testproject/config/initializers/rack-attack.rb:1:in `<top (required)>'

I'm using Redis for the cache store:
Rack::Attack.cache.store = Rack::Attack::StoreProxy::RedisStoreProxy.new(Redis.current)

@dmke
Copy link

dmke commented Feb 15, 2016

I've got the exact same issue after upgrading from 4.3.0:

/home/dmke/.rbenv/versions/ruby-2.2/gemsets/testapp/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:274:in `require': cannot load such file -- dalli (LoadError)
  from /home/dmke/.rbenv/versions/ruby-2.2/gemsets/testapp/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:274:in `block in require'
  from /home/dmke/.rbenv/versions/ruby-2.2/gemsets/testapp/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:240:in `load_dependency'
  from /home/dmke/.rbenv/versions/ruby-2.2/gemsets/testapp/gems/activesupport-4.2.5.1/lib/active_support/dependencies.rb:274:in `require'
  from /home/dmke/.rbenv/versions/ruby-2.2/gemsets/testapp/gems/activesupport-4.2.5.1/lib/active_support/cache/mem_cache_store.rb:2:in `<top (required)>'
  from /home/dmke/.rbenv/versions/ruby-2.2/gemsets/testapp/gems/rack-attack-4.4.0/lib/rack/attack/store_proxy.rb:10:in `build'
  from /home/dmke/.rbenv/versions/ruby-2.2/gemsets/testapp/gems/rack-attack-4.4.0/lib/rack/attack/cache.rb:14:in `store='
  from /home/dmke/.rbenv/versions/ruby-2.2/gemsets/testapp/gems/rack-attack-4.4.0/lib/rack/attack/cache.rb:8:in `initialize'
  from /home/dmke/.rbenv/versions/ruby-2.2/gemsets/testapp/gems/rack-attack-4.4.0/lib/rack/attack.rb:74:in `new'
  from /home/dmke/.rbenv/versions/ruby-2.2/gemsets/testapp/gems/rack-attack-4.4.0/lib/rack/attack.rb:74:in `cache'
  from /home/dmke/code/testapp/config/initializers/rack-attack.rb:2:in `<class:Attack>'
  from /home/dmke/code/testapp/config/initializers/rack-attack.rb:1:in `<top (required)>'

My config/initializers/rack-attack.rb reads:

class Rack::Attack
  Rack::Attack.cache.store   = ActiveSupport::Cache::RedisStore.new
  Rack::Attack.cache.prefix  = 'testapp:rack:attack'
  # snip
end

@ktheory
Copy link
Collaborator

ktheory commented Feb 16, 2016

Ok, made some progress tracking this down. This'll affect anyone using ActiveSupport & not dalli.

In StoreProxy, we check:

defined?(::ActiveSupport::Cache::MemCacheStore)

This causes MemCacheStore to autoload, which triggers the dalli load error.

I'm working on a patch.

ktheory added a commit that referenced this issue Feb 16, 2016
In v4.4.0, checking `defined?(ActiveSupport::Cache::MemCacheStore)`
could trigger an error loading dalli, which isn’t needed.

This fixes that bug, and prevents similar bugs by checking
`store.class.to_s` rather than `defined?(klass) && store.is_a?(klass)`.

Writing an automated test to ensure that dalli is truly optional is
difficult, but I was able to recreate the dalli load error in v4.4.0 by
running:

    gem uninstall dalli
    ruby -Ilib -ractive_support/all -ractive_support/cache/redis_store
-rrack/attack -e 'p Rack::Attack::StoreProxy.build(Redis::Store.new)'

Fixes #163
@ktheory
Copy link
Collaborator

ktheory commented Feb 17, 2016

Please upgrade to v4.4.1. That should fix this. 😄

Thanks for reporting this and helping me track it down.

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

Successfully merging a pull request may close this issue.

4 participants