opensoul.org

Cucumber and Sunspot

If you haven’t checked out Sunspot yet, you should. I have tried every solution for doing real full-text searching in a Rails app. Sunspot, backed by solr, is the only one that I haven’t had issues with in production. Hopefully I’ll get around to posting more about my experience with it.

But for today, here’s how I got Sunspot working with Cucumber.

First, add a configuration for the cucumber environment in config/sunspot.yml. I usually just use the same settings as test.

test: &TEST
  solr:
    hostname: localhost
    port: 8981
    log_level: WARNING

cucumber:
  <<: *TEST

Then, throw this bit of nastiness in the bottom of your env.rb file.

$original_sunspot_session = Sunspot.session

Before("~@search") do
  Sunspot.session = Sunspot::Rails::StubSessionProxy.new($original_sunspot_session)
end

Before("@search") do
  unless $sunspot
    $sunspot = Sunspot::Rails::Server.new
    pid = fork do
      STDERR.reopen('/dev/null')
      STDOUT.reopen('/dev/null')
      $sunspot.run
    end
    # shut down the Solr server
    at_exit { Process.kill('TERM', pid) }
    # wait for solr to start
    sleep 5
  end
  Sunspot.session = $original_sunspot_session

  MyModel.remove_all_from_index!
end

This will start up Sunspot for scenarios tagged with @search, and mock out the sunspot connection for ones that aren’t.

cucumber and sunspot April 07, 2010

6 Comments

  1. xinuc xinuc May 21, 2010

    Oh man… I owe you for this… Thanks

  2. Wes Morgan Wes Morgan January 20, 2011

    Have you tried this with autotest? It seems to make it loop forever. I’ve even added the solr directory as an exception so it shouldn’t trigger on changes to that dir, but it does anyway. Hmm…

  3. Lee Hambley Lee Hambley February 21, 2011

    Wes, for what it’s worth – see the Sunspot wiki for RSpec, with information, something about forking the server interferes with Rails’s mechanism, and it triggers tests… maybe that’s related?

  4. Navin Navin February 27, 2011

    Thanks much for writing this up – helped me get unstuck today!

  5. docgecko docgecko May 2, 2011

    Instead of using autotest, switch to guard (see github), then you won’t suffer from the continual looping!

  6. Alexander Lang Alexander Lang October 26, 2011

    Instead of just sleeping for 5s to wait for solr you can do this, which might be faster and is more reliable:

    def server_running?
      begin
        open("http://localhost:#{$sunspot.port}/")
        true
      rescue Errno::ECONNREFUSED =&gt; e
        # server not running yet
        false
      rescue OpenURI::HTTPError
        # getting a response so the server is running
        true
      end
    end
    
    # wait for solr to start
    print "Waiting for Solr to start"
    until server_running?
      sleep 0.5
      print '.' 
    end
    puts 'solr started'
    

Post a Comment

Comments use textile. Anonymous comments will be deleted.

I am Brandon Keepers. I build Internet things, usually with Ruby or JavaScript. I work at GitHub and live in Holland, MI.

Popular Posts