So I've been using Culerity for my complex MongoDB-driven Rails app for a few days now. Love the concept. Love it -- I think it's the sanest Javascript Cucumber integration I've yet seen. (Granted, that's in a field of fairly insane competitors.) But I was having major problems keeping it up and running during my BDD cycle, especially when using autospec for automatic feature testing.
The behavior I saw was that it would run once just fine, and then on the second and subsequent runs I'd get a consistent error on every Celerity step:
NativeException: org.apache.commons.httpclient.NoHttpResponseException: The server localhost failed to respond (Culerity::CulerityException)
This happened on both Webrick and Thin. (I'm using Ruby 1.9 so Mongrel is out.) Thin was also throwing an interesting yet dramatic exception:
/opt/local/lib/ruby/gems/1.9.1/gems/thin-1.2.5/lib/thin/logging.rb:28:in `write': Broken pipe - <STDOUT> (Errno::EPIPE)
After a fair amount of experimentation and headbanging, I found the problem: both the Rake task and the Culerity steps' built-in $rails_server invocations are using IO.popen to start the Rails app. Which means that STDIN and STDOUT are both being captured and held by the Ruby process that invokes it. This makes sense for the Celerity server, which has to be communicated with; but the Rails server is just supposed to sit there. You never do anything with the IO object except retrieve its pid. This causes problems when the process that started it ends, leaving the Rails process orphaned with no input or output. (Hence the Broken pipe - <STDOUT>
error I saw with Thin.)
The fix to this is really simple: use Kernel.spawn to start the Rails server. The spawn
method returns immediately with the pid value, and doesn't interfere with the child's in/out in any way. For extra cleanness, use the -d option to script/server
to detach its output and keep it from interfering with Cucumber output in that shell.
This seems to work fine in my own app, so I'll be forking Culerity right now and submitting this to you shortly as a pull request. While I'm at it, I'll set up Thin as a viable server option and address issue #16 about the pid file location. (Thin seems to solve some other problems I was having with Webrick in Culerity, possibly related to startup time or request speed.)