Archive for the ‘recykl.com’ Category

Timestamp vs. Datetime

We encountered a strange behavior in our Rails application: created_on timestamp was sometimes younger than updated_at_.

For each item in our application, we had a created_on and an updated_at field in the database. These were supposed to be updated by the Rails framework at item creation and item update times respectively. However, created_on got to be updated more reliably, even for small flag changes. We tried


but things got even worse: created_on kept changing with every little update but updated_at remained untouched. So, we sometimes had a strange situation that created_on was younger than updated_at.

So what could help? Read the good old manual? Well, sometimes you just have to…

And there it was: even though Rails does not seem to distinguish much between :datetime and :timestamp, our MySQL database has the following default behaviour:

The first TIMESTAMP column in table row automatically is updated to the current timestamp when the value of any other column in the row is changed, unless the TIMESTAMP column explicitly is assigned a value other than NULL.

So the innocently looking:

in create_tables.sql is completely wrong (don’t ask me how it got there, it has survived an unbelievable number of refactorings). This is made obvious by

What helped us in the end was:

Note: actually the error showed only for small flag changes, done by update_attributes. When using the full update, Rails keeps the correct old value of created_on.

Functional testing with Watir

So, we have a public web application accessible 24×7. Even if we do not process financial transactions or control airport traffic, this poses a kind of stress upon us. To relieve it, functional testing is our true companion.

By functional testing I mean simulating an end user’s traversal through the application. This means that, contrary to unit tests, we are testing what the user sees, not what the developer has written. The tests are thus less sensitive to software design changes, internal bug fixes, and even URL refactoring.1

As a tool, we have chosen Watir, an open-source library for controlling a web browser. It is light-weight and it does what it says on the box: “drives the … browser the same way people do. It clicks links, fills in forms, presses buttons… also checks results, such as whether expected text appears on the page.”

Technically, Watir is a library in Ruby2 for controlling Microsoft Internet Explorer on Windows (with support for Linux and Firefox planned in the next major release). The tested web application may be anything (ASP, JSP, PHP, etc.) producing browsable web pages.

Writing tests in Watir is fun in itself. Firstly, you can see the page in the browser and watch the elements being manipulated by an invisible user – buttons, links etc. get highlighted when the test suite accesses them. Secondly, you can even use Ruby console to write the tests interactively so that you command the browser like a starship.

def fBU1_log_in( username = "Adam", password = "Adam" )
    assert(@ie.pageContainsText("Login"))
    @ie.text_field(:id, "user_username").set(username)
    @ie.text_field(:id, "user_password").set(password)
# Clear the security warnings for HTTPS
    startClearers 
    @ie.button(:value, "Log in").click
# Show English version for test even if the user has 
# another language preference
    if not @ie.pageContainsText("Welcome ") 
        @ie.image(:alt, "English").click 
    end
    assert(@ie.pageContainsText("Welcome "+username))
end

Still, as we soon found out, there needs some home work to be done in order to achieve representative results of the tests:

  1. define test scenarios
  2. prepare test data

Test scenarios are needed to cover the whole functionality landscape, and to agree with the developers, what the application should do. In theory, this should completely be done at the beginning of the application lifecycle, but in an agile approach (as we had it with Recykl.com), you just define the main use cases at the beginning and fine-tune the details based on end user/customer feedback. Anyway, having the scenarios automated in tests is a good validation of the functional design.

Test data for the functional tests are indispensable for the predictability of the test results. In our case, another important requirement was isolation of the data for the individual tests, as we decided to use just one suite of test data for the whole suite of functional tests. For faster test execution the data is loaded once, not at the beginning of each test in the suite (which is a common Ruby test fixtures practice). To achieve isolation, we successively run the tests under different users, so the risk of interfering is reduced to a minimum.

Now, after some time of using Watir for the testing, there are some lessons learned:

  1. the most painful and unpredictable errors result from timing, e.g. in asynchronous AJAX calls – sometimes it’s difficult even for a human to tell if we are still waiting for something to happen or that’s all
  2. use some kind of automated reporting of results (unfortunately Watir currently has a very limited support here)
  3. tests are not carved in stone – you will have to update them as your functional design evolves (and it does in a successful application) – so write them flexibly. For example, do not rely on details like exact wording of a link, but instead use a regular expression matching just the main keyword, e.g. /[Ss]ubmit/
  4. even though it takes long to run the tests, try to run them after each major changeset – you’ll catch bugs and also easier keep up with the intentional changes

Having that in mind, doing functional testing with Watir has significantly increased our confidence in the functioning of our web application and saved us some hot moments in its (sometimes stormy) agile lifecycle.


Note 1: Although this looks like THE testing, other kinds of testing still have their important role: unit testing to make sure the application pieces are runnable after developers’ changes, performance testing to see the behavior of the application under heavier load than just one user, security testing and reviews to identify the possible weak spots exposed to the wild internet.

Note 2: Both Watir and Ruby are open-source products. Ruby is an object-oriented scripting language somewhere between Perl and Smalltalk. It is has garbage collection like C# or Java, but installs from a 5MB Linux RPM or 27MB Windows installer and starts up in an instant. Watir is an 800kB little gem ready to start after download.

No rhtml, rxml, rjs or delegate template found

After upgrading to Ruby on Rails 1.1.6 (with a one-day 1.1.5 intermezzo), we’ve found a strange error in our Recykl.com application. Most of the application behaved normally, but email sending got broken with the following error:


ActionView::ActionViewError (No rhtml, rxml, rjs or delegate template found for notification_email):
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_view/base.rb:389:in `find_template_extension_for’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_view/base.rb:323:in `pick_template_extension’
/vendor/plugins/globalize/lib/globalize/rails/action_view.rb:29:in `locate_globalize_path’
/vendor/plugins/globalize/lib/globalize/rails/action_view.rb:10:in `render_file’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_view/base.rb:274:in `render’
/usr/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb:427:in `render’
/usr/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb:422:in `render_message’
/vendor/plugins/globalize/lib/globalize/rails/action_mailer.rb:110:in `render_localized_normal_template’
/vendor/plugins/globalize/lib/globalize/rails/action_mailer.rb:98:in `render_localized_normal_template’
/vendor/plugins/globalize/lib/globalize/rails/action_mailer.rb:47:in `create!’
/usr/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb:331:in `initialize’
/usr/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb:290:in `method_missing’
/app/controllers/home_controller.rb:123:in `notify’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:941:in `perform_action_without_filters’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:368:in `perform_action_without_benchmark’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue’
/usr/lib/ruby/1.8/benchmark.rb:293:in `measure’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/benchmarking.rb:69:in `perform_action_without_rescue’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/rescue.rb:82:in `perform_action’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/base.rb:408:in `process_without_filters’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/filters.rb:377:in `process_without_session_management_support’
/usr/lib/ruby/gems/1.8/gems/actionpack-1.12.5/lib/action_controller/session_management.rb:117:in `process’
/usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/dispatcher.rb:38:in `dispatch’
/usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:150:in `process_request’
/usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:54:in `process!’
/usr/lib/ruby/gems/1.8/gems/fcgi-0.8.6.1/./fcgi.rb:600:in `each_cgi’
/usr/lib/ruby/gems/1.8/gems/fcgi-0.8.6.1/./fcgi.rb:597:in `each_cgi’
/usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:53:in `process!’
/usr/lib/ruby/gems/1.8/gems/rails-1.1.6/lib/fcgi_handler.rb:23:in `process!’
/recykl/public/dispatch.fcgi:36

The error only occurred in our production environment on Linux – I could not reproduce it anywhere else. :-(

Nothing in the application or server configuration had changed, so the problem had to be in the upgraded Rails – I compared the installed gems and among other things found the following difference in the actionmailer package:

—- /ruby/lib/ruby/gems/1.8/gems/actionmailer-1.2.3/lib/action_mailer/base.rb2006-07-01 10:53:54.500000000 +0200
+++ /ruby/lib/ruby/gems/1.8/gems/actionmailer-1.2.5/lib/action_mailer/base.rb2006-08-11 08:46:36.687500000 +0200
@ -5,20 +5,92 @
@ -127,7 +191,7 @

private_class_method :new #:nodoc:
– cattr_accessor :template_root
+ class_inheritable_accessor :template_root
cattr_accessor :logger
@@server_settings = {

This change in the inheritance scoping is not very well documented, but I’ve decided to anyway re-define the standard template root explicitly for our NotificationMailer class:

—- /recykl/app/models/notification_mailer.rb(revision 122)
+++ /recykl/app/models/notification_mailer.rb(revision 123)
@ -11,15 +11,18 @
class NotificationMailer < ActionMailer::Base

+ # for some reason, after upgrade to Rails 1.1.6 this is needed in production for correct operation, although earlier it was not
+ NotificationMailer.template_root = File.dirname(__FILE__) + ’/../views’
+
def confirm(notification)

@subject = ‘Notification regarding’.t

And, tada! It works!

Business Week: From Garbage to Gold

Business week has a great article on how entrepreneurs are turning “green” ways of doing things into businesses.

This is also the idea behind recykl.com, our service that allows people to share their items before they are thrown into garbage can. So, we are the Recykl Bin that you hit before you hit paper, plastic or bottle recycle-bins :).

The point, as also stated in the business week article, is that being “green” is not only the right way but there is whole new economics to being environmentally friendly. The conventional wisdom is that economics and environment are inversely proportional to each other, but I don’t think so, and that’s exactly what recykl.com is here to prove. You can protect the environment and at the same time profit economically. In fact, unless we find ways to make “green” technologies or ideas economically viable, it will not gain mass traction and hence no major impact.

The article has an example that there are about 1 billion printer cartridges in the land fill, and some of them might actually not even be empty or completely useless. Like the one on recykl.com is in a broken printer but is almost full and it’s probably worth $10. If you are in Prague, you can get it for free.

We have already discovered that among our friends and family there was so much stuff just lying around, or about to be thrown that turned out to be useful. Even if we are able to reduce the landfill by a couple of thousand items, it worth the effort. Happy Recykling :)

It’s getting closer

The launch of our first web 2.0 (Wow! buzzword compliant) application is getting closer. Here is a sneak preview.
preview1_blog.jpg