Fixing Culerity (BROKENPIPE error)
So, today I decided to replace Cucumber with Steak + Capybara and Culerity. Albeit I believe this has been a good choice (I’ve found Cucumber too heavy for our needs, and since the stakeholders are also developers, we don’t really need, nor used Cucumber, so it wasn’t aggregating any value at all), I’ve had a small issue with Culerity, more specifically with its culerity:rails:start rake task.
If you check the documentation, you’ll see that before running your feature/acceptance specs that use Culerity (and hence, Celerity) you will need to start a Rails server, which will be used by the Celerity HTMLUnit client. Ok, so far, no problems, Cucumber and Webrat used to do that automatically for us, but it’s not a big deal. So I went to the terminal and typed:
$ rake culerity:rails:start
Boom! Got the following output:
rake culerity:rails:start/Library/Ruby/Gems/1.8/gems/rails-2.3.5/lib/commands/server.rb:104:in `write': Broken pipe (Errno::EPIPE) from /Library/Ruby/Gems/1.8/gems/rails-2.3.5/lib/commands/server.rb:104:in `puts' from /Library/Ruby/Gems/1.8/gems/rails-2.3.5/lib/commands/server.rb:104 from script/server:3:in `require' from script/server:3
I’ve opened the server.rb, and the line 104 for Rails 2.3.5, has the following code:
puts "=> Call with -d to detach"
Hmm… after a moment, I also realized this wasn’t a “fatal error”. The server was actually being started succesfully, behind the scenes. The issue was that the output was not being redirected to stdout, thus, a Errno::EPIPE (I’m not sure which component throws this exception though, if someone knows, please shed some light).
So, if you can live with it, just wait a few seconds and everything should work out fine.
However, it would be good to:
* See the output of your test Rails server;
* Use the debugger on this Rails server;
* Have the damn pid file removed when you send a SIGINT (Ctrl+C) to the rake task.
Well, fear not. Just replace the code for the task :start on RAILS_ROOT/lib/tasks/culerity.rake with the following code and go get some fresh coffee:
task :start do
port = ENV['PORT'] || 3001
environment = 'test'
pid_file = RAILS_ROOT + "/tmp/culerity_rails_server.pid"
if File.exists?(pid_file)
puts "culerity rails server already running; if not, delete tmp/culerity_rails_server.pid and try again"
exit 1
end
rails_server = IO.popen("script/server -e #{environment} -p #{port}", 'r+')
File.open(pid_file, "w") { |file| file << rails_server.pid }
running = true
Signal.trap('SIGINT') {
puts 'terminating'
running = false
rm = `rm -rf #{RAILS_ROOT}/tmp/culerity_rails_server.pid`
}
while running
$stdout << rails_server.gets
end
end
This works for culerity 0.2.10, as of 8/June 2010.
Another possibility would be to add a & here, like this:
culerity.rake:12
rails_server = IO.popen("script/server -e #{environment} -p #{port} &", 'r+')
I think this was the intended way to use the tasks, since there is also a rake task to stop the process (by using the pid in the pidfile), so probably the missing ampersand could be considered a bug.
