Monday, April 13, 2009

Cucumber and couchdb-lucene

‹prev | My Chain | next›

Yesterday, I ended work seemingly unable to search a couchdb-lucene index via Cucumber. At the time, I suspected the design document of being the source of the trouble. In my spike, I had created the design document via the futon interface to CouchDB. That is not an option in an automated test, so I used RestClient to put the design document.

Brief investigation revealed that this was not the problem. Creating the design document in the development database via RestClient worked as expected.

The source of the trouble turns out to be the frequency with which couchdb-lucene updates its index. Fortunately, couchdb-lucene exposes configuration for the time it will wait after updates before re-indexing. The configuration value that controls this is couchdb.lucene.commit.min. This is set in the couchdb.ini file, or, in the case of running locally, the local_dev.ini file:
;; Do NOT set couchdb.lucene.commit.min this low in production!!!
[update_notification]
indexer=/usr/bin/java -Dcouchdb.lucene.commit.min=50 -jar /home/cstrom/repos/couchdb-lucene/target/couchdb-lucene-0.3-SNAPSHOT-jar-with-dependencies.jar -index
This sets the amount of time after an update until a re-indexing to 50 milliseconds. This is much better for testing purposes that the default, which is 10 seconds.

There is a similar couchdb.lucene.commit.max configuration value. Unlike the min setting, it will not wait for updates to complete once this setting is reached—after couchdb.lucene.commit.max milliseconds, couchdb-lucene will re-index regardless. In practice, this setting was not as effective as the min.

A delay is going to be needed in the cucumber scenarios. Something like this ought to do:
      And a 5 second wait to allow the search index to be updated
I may end up tweaking that, so I make the amount of time to wait configurable:
Given /^a (\d+) second wait to allow the search index to be updated$/ do |seconds|
sleep seconds.to_i
end
With that in place, my first search scenario now passes:
cstrom@jaynestown:~/repos/eee-code$ cucumber features/recipe_search.feature -n \
-s "Matching a word in the ingredient list in full recipe search"
Feature: Search for recipes

So that I can find one recipe among many
As a web user
I want to be able search recipes
Scenario: Matching a word in the ingredient list in full recipe search
Given a "pancake" recipe with "chocolate chips" in it
And a "french toast" recipe with "eggs" in it
And a 5 second wait to allow the search index to be updated
When I search for "chocolate"
Then I should see the "pancake" recipe in the search results
And I should not see the "french toast" recipe in the search results


1 scenario
5 steps passed
1 step pending (1 with no step definition)

You can use these snippets to implement pending steps which have no step definition:

Then /^I should not see the "french toast" recipe in the search results$/ do
end
I do tweak the wait down to 1 second, without introducing race-condition-like failure. At some point, I may need a sub-second wait, but I can live with a second delay for now.

No comments:

Post a Comment