Updating to rails 2.3.2

As Ruby on Rails 2.3.2 is out, I am updating WoW Gossips to use the brand new Rails version.

First thing, install the new version of rails :

gem install rails

This installs the new version of the Rails gem, with its dependancies (ActiveRecord, Active Support, …)

Next, you need to update config/environment.php and change the required version to 2.3.2 :

RAILS_GEM_VERSION = '2.3.2' unless defined? RAILS_GEM_VERSION

Once this is done, you need to run the upgrade script :

rake rails:update

Congratulations ! Your app is now updated to Rails 2.3. But there is still some work to do. I recommend you to read the release notes, which contains all informations you will need. Here are some of the changes i needed to do.

When I ran my test suite, I got this error :

./test/test_helper.rb:27: undefined method `use_transactional_fixtures=' for Test::Unit::TestCase:Class (NoMethodError)

This is because Test::Unit::TestCase switched to ActiveSupport::TestCase. You need to change this in test/test_helper.rb :

class ActiveSupport::TestCase # old : class Test::Unit::TestCase

I also got warnings like this in my tests :

.DEPRECATION WARNING: formatted_character_url() has been deprecated. Please pass format to the standard changes_character_url method instead

This is because formatted_ routes are no longer generated when using resources. If you have things like this :

link_to @character.name, formatted_character_url(@character, :atom)

You now need to use :

link_to @character.name, character_url(@character, :format => :atom)

I will update this entry if I find more thinks I needed to update, but it seems ok for me right now, based on my automated tests and some manual browsing.

Update : When I deployed the new Rails 2.3.2 version of WoW Gossips, I got this error :

$ ./script/about
/usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require': no such file to load -- application (MissingSourceFile)
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:158:in `require'
        from /home/wowgossips/production/releases/20090317132628/config/environments/production.rb:41:in `load_environment'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/initializer.rb:592:in `call'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/initializer.rb:592:in `after_initialize'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/initializer.rb:591:in `each'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/initializer.rb:591:in `after_initialize'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/initializer.rb:177:in `process'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/initializer.rb:113:in `send'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/initializer.rb:113:in `run'
        from /home/wowgossips/production/releases/20090317132628/config/environment.rb:13
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rails-2.3.2/lib/commands/about.rb:1
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
        from /usr/local/ruby-enterprise-1.8.6-20090113/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `require'
        from ./script/about:4

This is due to the exception logger plugin. To protect the Exception page, you need to add some code to config/environments/production.rb. You need to change it to reflect the rename of app/controllers/application.rb to app/controllers/application_controller.rb :

config.after_initialize do
  require 'application' unless Object.const_defined?(:ApplicationController)
  LoggedExceptionsController.class_eval do
# ...

Must be :

config.after_initialize do
  require 'application_controller' unless Object.const_defined?(:ApplicationController)
  LoggedExceptionsController.class_eval do
# ...

It seems you also need Passenger 2.0.6 to handle the new name of the ApplicationController file. I recommend you the latest Passenger version (2.1.2) which works fine for me.

Tags , ,

Posted in | Posted on 16 Mar 2009 21:23by Renaud Chaput | 2 comments

Testing: Mocha and Fakeweb

About two months ago, I started a new project which heavily depends on World of Warcraft Armory data.

I found Wowr, a great ruby library which allows me to avoid the fetching and parsing of these informations, and started to use it (and contribute).

As my first version of Wowgossips is near finished, I started to run rcov on it to have a robust test suite for the future. I haven’t wrote a lot of tests during the development, and got a coverage of 60%. I started to write missings tests, and arrived to a 85% coverage. And that is here that the main problem comes : how can I test my data fetching algorythm, as it heavily uses a library (Wowr), which in turn uses an external data source (WoW Armory).

After some googling, I found a way to achieve this, using two very useful testing tool : Fakeweb and Mocha.

Mocha is a Ruby mock library, allowing you to “override” some methods with values of you choice. I use it to force Wowr to returns values I expect in my tests, without the need to fetch and parse a huge XML file from the Armory.

Before that, I started writing some XMLs, based on the Armory’s original, but with the change i wanted to test (change the character level, …). It quickly started to be unmaintenable, and pretty ugly. Now, I have a basic XML file, and I can override the Wowr method i want to test. The main problem with this approach it that is still uses an HTTP request to the Armory. As Blizzard blocks your IP address it you hit too much their servers, I was quickly limited by the number of tests I can run. And there comes Fakeweb.

Fakeweb can disable web requests made by your application (or libraries used in your code), and, like Mocha, returns a spacific string of file in place of the remote document. I installed it, configured it to return static XML files stored in my fixtures directory. Now, when I write a test involving Wowr, I add a mock on the Wowr methods involved and thats done. When I run the test, my XML fixture file is loaded, Wowr parses it, and methods I want to use always returns what I want.

A quick example :

# Setup a fake character
def fake_character character_name
  character = characters(character_name) 
  # Force last modified date to today
  character.armory_character.strubs(:last_modified).returns(Date.today)
  return character
end

test "that we detects a level change" do
  character = fake_character :voreen
  # Overide the level returned by Wowr
  character.wowr_character.stubs(:level).returns(80)

  character.wowr_to_db

  assert_equal 80, character.level
end

That is a clean, fast, and very flexible way to test your code if you depend on external services and/or libraries.

Tags , , , ,

Posted in | Posted on 17 Feb 2009 14:14by Renaud Chaput | no comments

Categories

Links

Projects

Syndicate

Archives

Tags

Copyright © Ruby, Rails and Sysadmin

Tech Blue designed by Hive Designs • Ported by Free WordPress Themes and Frédéric de Villamil Powered by Typo