Search code examples
ruby-on-railssolrsunspot

connection rejected from solr in Rspec


I use the sunspot-rails for search. These is a Rspec looks like:

describe "GET search" do
  before(:all) do
    system("rake", "sunspot:solr:start")
  end

  after(:all) do
    system("rake", "sunspot:solr:stop")
  end

  it "should do some search" do
    Text.search do
      ...
    end
  end
end

But it doesn't work. I got a failure:

Errno::ECONNREFUSED:
   Connection refused - connect(2)

But if I type rake sunspot:solr:start RAILS_ENV=test by hand in command line, and then run the spec, it passes.

What's wrong? Isn't rake sunspot:solr:start RAILS_ENV=test equivalent to system("rake", "sunspot:solr:start") in test mode?

(I tried `system("rake", "sunspot:solr:start RAILS_EVN=test"). Same.)


Solution

  • Your before(:all) probably just isn't giving Solr enough time to start.

    That said, you'll probably want to think hard about just what you're asking your specs to verify here. You can go a long way with mocking out calls to Solr with a library like Fakeweb.

    Pivotal Labs also has a library called sunspot_matchers that can capture more fine-grained assertions about the searches you're invoking.

    If you are going for real integration specs against Solr, I advise just keeping a test Solr running while you work. A tool like Foreman can help manage your Solr proceses. I might use a Procfile like the following:

    solr_dev:  rake sunspot:solr:run RAILS_ENV=development
    solr_test: rake sunspot:solr:run RAILS_ENV=test
    

    (Development is, of course, the default environment if no RAILS_ENV is otherwise provided to foreman start)

    Finally, if you want to start Solr within your specs, you're already on the right track. Just toss a sleep in there with enough time to let Solr fully boot itself before your specs start running. Don't be surprised if that introduces a bit of unpredictable failure into your spec suite when the system is under load.

    [Edit: Quick and dirty before :all which uses Sunspot.remove_all to poll for availability.]

    before :all do
      `sunspot-solr start`
      begin
        Sunspot.remove_all!
      rescue Errno::ECONNREFUSED
        sleep 1 && retry
      end
    end