Try not to BCrypt so much.

Posted by Venerable High Pope Swanage I, Cogent Animal of Our Lady of Discord 13 August 2011 at 10:14AM

At Relevance, one of our favorite tools to use is Devise. It has become the de facto standard for authorization when we need a solution, and with good reason. It solves a specific problems and plays nicely with others.

However, it can totally ruin your test suite's performance.

By default, Devise ships configured to use bcrypt. If you investigate your config/initializers/devise.rb file, on or about line 64 you should see something like the following:

config.stretches = 10

Shortly put, this is configuring the computational complexity bcrypt will calculate encrypted passwords with. This is a pretty cool feature of bcrypt, and it is a valuable security feature in its default configuration. If for some horrible reason, someone gets a hold of all the encrypted passwords in your db, the amount of time it will take to brute force crack the passwords with this default strength is sufficiently long as to allow you plenty of time to react and change passwords. (Assuming you are aware of the breach...)

However, if you're using factory_girl and rspec (as we do), and generate a bunch of devise users who happen to have passwords (as we do), then you'll spend a lot of time in your tests calculating encrypted passwords with this config. There are some other solutions out there (mentioned in this github issue) for getting around the bcrypt bottleneck when testing. Jason Rudolph and I have a better one though.

First, change the line in your config/initializers/devise.rb from

config.stretches = 10
to
config.stretches ||= 10
Then in your config/environments/test.rb add
Devise.setup do |config|
  config.stretches = 1
end

This configures your app to by default use an aggressive bcrypt strength, but allows you to override that configuration on a per environment basis.