Running cucumber features with sunspot_rails

We wanted to integrate the sunspot_rails gem into our cucumber features. I found a ticket where mat adviced to call Sunspot::Rails::Server.start / stop in one of the available cucumber hooks.

Code found in features/support/env.rb is run when Cucumber begins and exits so this seemed the right place to start Solr:

Sunspot::Rails::Server.new.start
 
at_exit do
  Sunspot::Rails::Server.new.stop
end

Also, make sure you’ve added a cucumber environment to the config/sunspot.yml file; we copied the test-environment for that:

test: &TEST
  solr:
    hostname: localhost
    port: 8981
    log_level: WARNING
 
cucumber:
  <<: *TEST

Running cucumber will let all scenarios fail unfortunately and we got a ‘Connection refused – connect(2) (RSolr::RequestError)‘ in our console.

The reason for this is simple (after I stepped into the sunspot_rails gem to be honest): the Sunspot::Rails::Server.new.start method will eventually launch a Java Servlet Container (Jetty) with the Solr WAR and uses the port defined in your sunspot.yml.
Now, starting up a server could take some time, so if cucumber’s features are run before the Solr server is up and running, the ‘Connection refused’ sounds trivial then.
First I added a sleep after starting up the server:

Sunspot::Rails::Server.new.start
sleep(5)

and this will work for most cases, but I thought it would be better to let cucumber wait just long enough until the server is up and running. When the server is up, you can open up your browser and enter http://localhost:8981/solr to administering Solr. This we can use to find out if we’ve waited long enough and start our features. I’ve put this into a seperate class named CukeSunspot and created this file in the features/support directory:

require "net/http"
 
class CukeSunspot
 
  def initialize
    @server = Sunspot::Rails::Server.new
  end
 
  def start
    @started = Time.now
    @server.start
    up
  end
 
  private
  def port
    @server.port
  end
 
  def uri
    "http://0.0.0.0:#{port}/solr/"
  end
 
  def up
    while starting
      puts "Sunspot server is starting..."
    end
    puts "Sunspot server took #{'%.2f' % (Time.now - @started)} sec. to get up and running. Let's cuke!"
  end
 
  def starting
    begin
      sleep(1)
      request = Net::HTTP.get_response(URI.parse(uri))
      false
    rescue Errno::ECONNREFUSED
      true
    end
  end
 
end

Now we can the alternative start method and remove the explicit sleep statement in our global before hook. features/support/env.rb:

Sunspot::Rails::Server.new.start
 
at_exit do
  Sunspot::Rails::Server.new.stop
end

And voila, if you run cucumber, you scenario’s should run successfully. On my machine:

Sunspot server is starting...
Sunspot server is starting...
Sunspot server took 3.74 sec. to get up and running. Let's cuke!
Posted in ruby | Leave a comment

Using transactions with Ruby DataMapper

With DataMapper, it can be quite a challenge to perform tasks that seem so simple at first. DataMapper is an object-relational mapper (ORM) written in Ruby, with a lot of great features and innovative approaches to common ORM-tasks. But it lacks documentation for some of the less-used features and even the more popular search engines don’t have the answer to all questions.

Note: the following examples have been tested with DataMapper version 0.10.2.

One of the questions I had was how to perform multiple queries within a single (database) transaction, so that I can ’stage’ a number of database queries and commit (or rollback) them all in one go. Fortunately, after some investigation of the DataMapper source code, it turns out to be an extremely simple task:

User.transaction do
  User.first.update(:name => "John Smith")
  Address.first.update(:street => "") # Invalid: street must not be blank
end

With this code neither the address nor the user will be updated in the database if one of the updates fails. The syntax is actually the same as for the ActiveRecord ORM. However, triggering a rollback is done differently, as can be seen in the following example.

User.transaction do |t|
  User.first.update(:name => "John Smith")
  Address.first.update(:street => "Oak St. 400")
  t.rollback # Transaction will be rolled back even when updates are OK.
end

That’s it for now. I’m sure there are some additional features that I haven’t mentioned here, but this is all I had to know at this point.

Posted in ruby | 1 Comment

Presentation: Heroku & Jeweler + Gemcutter

A small presentation by Ariejan on two topics:

  • Heroku – What is Heroku and how does it compare to Amazon EC2 and Kabisa’s Hosting
  • Jeweler + Gemcutter – How to use Jeweler to manage your gem and push it to gemcutter

Read More »

Posted in Talks | Tagged , , , , , , | Leave a comment

Xen: How to fix “SIOCSIFADDR: No such device”

Yesterday I had to clone a VPS to run some CPU and memory intensive tests. With our current setup (Xen + LVM), cloning an image on the fly is easy.

After configuring a new IP address for the clone, I booted up the system. Nice, but I ran into a problem:

Configuring network interfaces...SIOCSIFADDR: No such device
eth0: ERROR while getting interface flags: No such device
SIOCSIFNETMASK: No such device
SIOCSIFBRDADDR: No such device
eth0: ERROR while getting interface flags: No such device
eth0: ERROR while getting interface flags: No such device
Failed to bring up eth0.

After some investigation I found that the MAC address for eth0 is stored on disk in /etc/udev/rules.d/z25_persistent-net.rules. That makes sense, because the whole file system was cloned. But, I swapped the virtual network card, and I’d expect is to work. It didn’t.

The solution is quite easy. Empty /etc/udev/rules.d/z25_persistent-net.rules. Then shutdown and start your VPS. You must do a full shutdown, a reboot won’t work.

For the lazy folk out there, here’s how to quickly empty the file:

echo "" > /etc/udev/rules.d/z25_persistent-net.rules

After you have started your VPS back up again, you should be able to ping out over the network. If you peek in /etc/udev/rules.d/z25_persistent-net.rules you should see a line that contains the MAC address for your virtual network device.

Posted in hosting | Tagged , , , , | Leave a comment

How to setup Ruby on Rails, Apache and Passenger on Debian Linux

For this article I’m going to install a single (virtual) server to run a standard Ruby on Rails application. I will be using Apache2 and passenger for the webserver stack and MySQL as a database server.

Let’s start by installing Ruby and all tools:


# apt-get install build-essential
# apt-get install ruby irb ri rdoc libopenssl-ruby ruby1.8-dev
# ruby -v
# cd /usr/local/src
# wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz # replace with latest version of rubygems
# tar xfvz rubygems-1.3.5.tgz
# cd rubygems-1.3.5
# ruby setup.rb
# ln -s /usr/bin/gem1.8 /usr/bin/gem
# gem -v
# gem install gemcutter
# gem tumble
# apt-get install mysql-server # this will ask for a password during installation
# apt-get install libmysqlclient15-dev
# gem install mysql
# gem install rails
# apt-get install git-core
# apt-get install apache2
# gem install passenger
# passenger-install-apache2-module

Copy the following lines from the output and paste them at the end of the file /etc/apache2/apache2.conf. They should look something like this:


LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.7/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.7
PassengerRuby /usr/bin/ruby1.8

Finally let’s restart apache2:

/etc/init.d/apache2 restart

Phew! That's it... We now have all the software we need on the server that's required to deploy your Ruby on Rails app on Debian Linux (Lenny)!

In a future article I'll cover the basics of deployment using Capistrano.

Posted in ruby | Tagged , , , , , | 1 Comment

Ruby and SSL Certificate Validation

If your ruby app is doing SSL, you have probably seen one of the following errors:

doc = Hpricot(open("https://www.cert.org/blogs/vuls/rss.xml")) # => /usr/lib/ruby/1.8/net/http.rb:590:in `connect': certificate verify failed (OpenSSL::SSL::SSLError)

or

warning: peer certificate won't be verified in this SSL session

The solution is to make sure ruby has access to the right set of root certificates.
Read More »

Posted in ruby | Tagged , , | 1 Comment

Giving Love To the Community

Earlier this month Kabisa attended the Ruby en Rails 2009 conference in Amsterdam. Ruby en Rails is the largest dedicated Ruby and Rails conference in the Netherlands.

For the first time in its history Ruby en Rails was a multiple day event. The first day, October 31, was packed with interesting presentations on various Ruby and Rails related topics, by great speakers including renowned community idols like Yehuda Katz, Jeremy Kemper, Jonathan Weiss and many more. The second day (the ‘geek-day’) focused on more practical sessions and lightning talks. On this day another event was held: The RubyEnRails Rumble (RERR), a competition where teams of two had to complete an assignment within a certain time.
Read More »

Posted in ruby | Tagged , , , , | Leave a comment