Today’s xkcd: the whole World’s map

xkcd is a fantastic webcomic. I follow it for a few years now, and I must say I love it.

Today’s comic (number 1110) featured an enormous scrollable world to visit.

I downloaded all images of this world and assembled them to see the global picture. This way you are sure to not miss anything 😉
The whole world map sizes 169984×83968 pixels!
Here I upload a 1:10 scale of it.
If you are interested, I also uploaded the 1:1 scale files, but unassembled.
If I manage to assemble them, I will update this post.

Enjoy!

(If it does not display correctly in your browser, you can still right-click on it an save the image.)
XKCD World map

Full scale images unassembled:
1:1 scale images unassembled

My life , , ,

Howto: Install RMagick on Windows 64 bits

I ran into a lot of problems trying to install RMagick on my 64bits Windows, but finally succeeded.

Here is how:

  1. Install ImageMagick: version 6.6.9-5 32 bits. The version is important: I tried with 64bits versions, and also with 6.6.9-9 and 6.7.* versions and it failed miserably. You can find it here. Don’t forget to include development headers for C and C++ and also modify the PATH environment variable during the installation process.
  2. Install the Ruby Development Kit. You can find it here.
  3. Modify a little header in the DevKit. Search for the file /mingw/include/sys/types.h, and replace int with long at line 115:
    #ifndef _SIGSET_T_
    #define	_SIGSET_T_
    typedef int	_sigset_t;
    
    #ifndef	_NO_OLDNAMES
    typedef _sigset_t	sigset_t;
    #endif
    #endif	/* Not _SIGSET_T_ */
    
    #ifndef _SSIZE_T_
    #define _SSIZE_T_
    typedef long _ssize_t;
    
    #ifndef	_NO_OLDNAMES
    typedef _ssize_t ssize_t;
    #endif
    #endif /* Not _SSIZE_T_ */ 
    
  4. In a terminal, modify your environment this way:
    set DFImageMagick=<ImageMagickInstallationPath>
    set CPATH=%DFImageMagick%\include;%CPATH%
    set LIBRARY_PATH=%DFImageMagick%\lib;%LIBRARY_PATH%
    
  5. Install RMagick gem:
    gem install rmagick
    

This worked for me, I hope it will help others.

Howto, Ruby, Windows , , , , , , ,

A little helper to understand French companies’ system

Lately I was focused on understanding the way French companies work, how are taxes paid, and how to best choose companies’ statuses based on this. I wanted to have real figures and understand where does money go when ruling a company.

Basically I endorsed the “expert-comptable” cap for a few weeks and delved into law texts, official government agencies, taxes administration, entrepreneurs helping agencies, several “expert-comptable” advices and so on.

First, I couldn’t realize how complex it can be before searching by myself, and the first impression I got was: “Nobody knows, the field is too complex and so badly written in the law.”
… And sadly this impression was later confirmed: any expert I consulted on the topic has a different and contradictory information on the state of the law, and a lot of them gave me wrong advices. Always cross-check any information you get with at least 3 or 4 different sources (this post is no exception), and do not rely too much on self-evidences, as they very often prove wrong either.

This being said, here is my view on the topic: this is a very simplified view, but can be used as an overall base to understand the process, and later delve into details and local exceptions to this big picture.
I will quote French words as their meaning can be really precise and important.

Please note that this study has been made during summer 2012. As French law changes very often, it is possible that parts of this post will be outdated soon.

If you happen to find wrong information, please do not hesitate to comment on it, I will be really glad to correct it.

Table of contents:

  1. French companies categories
  2. Where does the money go ?
  3. Some figures
    1. Social contributions
    2. Taxes on incomes and societies
    3. Others
  4. A nice spreadsheet computing and comparing statuses
  5. Resources for further investigations

French companies categories

In France, there are 2 kinds of companies: “Entreprises” (handled by physical people), and “Sociétés” (existing as moral persons). People ruling a company are called “Associés”. Usually “Entreprises” comprise just 1 “Associé”, whereas “Sociétés” comprise 1 to an infinite number of them (either physical or moral). Whatever the form and the number of “Associés”, a company can always hire “Salariés” (wage-earning) people to whom you give salaries.

Usually, “Sociétés” (and the “EIRL” type of “Entreprise”) have a dedicated sum of money (called “Réserve” or “Patrimoine”) that is formed by the “Associés” (people ruling the company). This money belongs to the company itself, and is not taxed unless given back to the “Associés”. As “Associés” may have contributed to the “Patrimoine” in different sums, each “Associé” is affected a “Quote-part” of the company: this is the percentage of its provision to the “Patrimoine”. This “Quote-part” then defines whether the “Associé” is majority (>50%), minority (<50%) or egalitarian (=50%).

French companies have then 3 different attributes that govern how they will pay taxes:

  • The “Régime social” (social scheme) of it “Associés”: Depending on the company’s status, its “Associés” will have a specific social status, giving them different rights to social protection, and making them pay taxes differently. The 3 social statuses “Associés” can have are:
    • “Travailleurs Non Salariés” (TNS): usually given to “Associés” being majority in the affected “Patrimoine”,
    • “Assimilés Salariés” (AS): usually given to “Associés” being minority or egalitarian in the affected “Patrimoine”,
    • “Micro-social”: a specific status dedicated to some “Micro-entreprises” (a type of “Entreprises” comprising just 1 “Associé” and having its benefits capped to something less than € 85 000 – limit depends on the company’s activity). With this status, social contributions are paid based on a percentage of the total “Chiffre d’Affaires”.
  • The “Régime fiscal” (fiscal scheme) of the company. This scheme governs the way taxes on the company’s benefits are paid. 2 possibilities:
    • “Impôt sur le revenu” (IR): This makes the “Associés” pay taxes on the company’s benefits, as if these benefits were perceived as salaries by each “Associé” (taxes will be payed even if no salary is given). With the “IR” fiscal scheme comes an option called “Prélèvement libératoire”, allowing the “Associés” to pay taxes as a percentage of the company’s “Chiffre d’Affaires” ; this option is only possible for “Micro-entreprises” that have “Associés” belonging to the “Micro-social” social scheme.
    • “Impôt sur les sociétés” (IS): This makes the company itself pay taxes on its benefits.
  • The part of the company’s benefits that will be subject to taxes (“Bénéfices imposables”) can also differ. 2 possibilities:
    • “Régime réel” (real scheme): Real benefits will be taxed, meaning the “Chiffre d’Affaires” minus the expenses, salaries and some social contributions,
    • “Micro-entreprise” (not to be confused with the “Micro-entreprise” type of “Entreprises” – I know it reads the same, but here we are talking about the way benefits are taxed): taxes will be computed based on a percentage of the total “Chiffre d’Affaires”. If your company has a lot of expenses, this is not a good option to take, as you will pay taxes on them.

The following diagram sums the different companies’ statuses and their specific attributes (it is not exhaustive, but gives the main statuses encountered):

Where does the money go ?

Each year, a French company sums up the money taken from its clients as a “Chiffre d’Affaires” (CA). This money is then shared among the following:

  • Expenses, needed for the company to work,
  • “Salaires” (salaries) given to the “Salariés” or “Assimilé Salariés”,
  • “Rémunérations”, given to the “Travailleurs Non Salariés”,
  • “Dividendes”, given to any “Associé”,
  • social contributions, payed for any physical people working at the company (“Associé”, “Salarié”),
  • social contributions to the director’s wife/husband if accepted as a contributor to the company,
  • “Impôt sur les sociétés”, a tax usually paid by the “Sociétés” on their benefits, and
  • “Mise en réserve”, the rest of the “Chiffre d’Affaires” that will be put to the “Patrimoine” again.

This picture sums up the situation:

There are simple rules to keep in mind while reading this diagram:

  • Social contributions are always paid for any person working in the company: “Associé”, “Salarié” and even the director’s wife/husband as a contributor
  • Social contributions are also paid for any “Dividendes” given to “Associés”
  • If the company’s fiscal scheme is “Impôt sur le revenu”, there are no possible “Dividendes” to be distributed (they can be assimilated as “Rémunération”), and there is no “Impôt sur les sociétés” to be payed by the company.
  • Social contributions for “Salaires” are computed based on the “Salaire brut” (gross salary). They comprise a part paid by the company, and a part paid by the wage-earning. Therefore the salary given on the wage-earning bank account (“Salaire net”) equals the “Salaire brut” minus the social contributions’ part paid by the wage-earning. The wage-earning will then pay taxes on this income later.
  • Each sum of money given to a “Salarié” or “Associé” is taxed on the person’s end (not the company’s), as an income (“Salaires”, “Rémunérations” and “Dividendes”). Taxes on those incomes are computed using the “Impôt sur le revenu” (IR) scheme.

Some figures

To help you better figure out the costs involved, here are some figures I can broadly give during the year 2012.
Those figures were computed having in mind a “Chiffre d’Affaires” of € 200 000.

Social contributions

  • Social contributions paid for a “Travailleur Non Salarié” having a “Rémunération” of € 100 000 is around € 30 000
  • Social contributions (counting both the company and wage-earning parts) paid for a “Assimilé Salarié” having a “Salaire net” (deposited on the wage-earning bank account) of € 100 000 is around € 85 000
  • Social contributions (counting both the company and wage-earning parts) paid for a “Salarié” having a “Salaire net” (deposited on the wage-earning bank account) of € 100 000 is around € 100 000
  • Social contributions paid for a “Dividendes” amount of € 100 000 is exactly € 15 500
  • For the “Micro-social” social scheme, social contributions equal a direct percentage of the “Chiffre d’Affaires”, depending on the company’s activity:
    • 12.3% for “BIC” activities dealing with sales
    • 21.6% for “BIC” activities dealing with services
    • 21.5% for “BNC” activities
    • 18.3% for special “BNC” activities (dealing with “Cipav”)

Taxes on incomes and societies

  • The “Impôt sur le revenu” works in layers. To each layer of the sum to be taxed (monthly) corresponds a rate giving the tax amount applied on this layer.
    1. € 0 <= x <= € 5 963: 0%
    2. € 5 963 < x <= € 11 896: 5.5%
    3. € 11 896 < x <= € 26 420: 14%
    4. € 26 420 < x <= € 70 830: 30%
    5. € 70 830 < x: 41%

    Please note also that the layers apply to a fraction of the taxed sum: a first deduction of 10% for professional expenses, and divided by the number of parts in your family (alone: 1 part, a couple: 2 parts, a couple with 1 child: 2.5 parts …). The computed tax is then multiplied back by the number of family parts.
    As an example, if a couple earns € 50 000 a year, here is the computation of its “Impôt sur le revenu”:

    1. Remove 10%: € 45 000
    2. Divide by number of family parts (2): € 22 500
    3. Compute taxes per layers up to € 22 500: ( 0% * € 5 963 ) + ( 5.5% * ( € 11 896 – € 5 963 ) ) + ( 14% * ( € 22 500 – € 11 896 ) ) = € 0 + € 326.315 + € 1 484.56 = € 1 810.875
    4. Multiply by number of family parts (2): € 3 621.75
  • The “Impôt sur les sociétés” also works in layers, the same way “Impôt sur le revenu” does (without deductions):
    1. € 0 <= x <= € 38 120: 15%
    2. € 38 120 < x: 33.33%
  • For the “Micro-entreprise” fiscal scheme, the part of the “Chiffre d’Affaires” used to compute taxes differs depending on the company’s activity. They take the whole “Chiffre d’Affaires”, minus a percentage of it:
    • 71% for commercial activities dealing with sales (“Bénéfices Industriels et Commerciaux” – “BIC” with sales)
    • 50% for commercial activities dealing with services (“BIC” with services)
    • 34% for non-commercial activities (“Bénéfices Non Commerciaux” – “BNC”)

    This reduction can’t be less than € 305.

  • The “Prélèvement libératoire” option that can be chosen for paying taxes for “Micro-entreprises” also using the “Micro-social” social scheme, is computed using an exact percentage of the total “Chiffre d’Affaires”, also depending on the company’s activity:
    • 1% for “BIC” activities dealing with sales
    • 1.7% for “BIC” activities dealing with services
    • 2.2% for “BNC” activities

Others

  • The company’s status “Micro-entreprise” has a limitation on its “Chiffre d’Affaires”. If it exceeds a certain limit, the company has to change statuses. This limit also depends on the company’s activity:
    • € 81 500 for “BIC” activities dealing with sales
    • € 32 600 for other activities

A nice spreadsheet computing and comparing statuses

As a part of my study, I created a nice spreadsheet that references the main company statuses with their characteristics.

Then, for each (or all) company status(es), you can enter figures (“Chiffre d’Affaires”, number of associates, expenses, salaries…), and the spreadsheet will compute the social contributions, benefits, taxes and incomes for each “Associé”.
It follows the diagram given above and shows all details about social contributions and computations. It can be a bit daunting at first but can prove really useful.

You can use this spreadsheet to compare the different statuses depending on your situation.
Comparatif Statut Entreprises

Resources for further investigations

Here are some links to resources I found very helpful during my study.
However please be aware that you might find wrong, obsolete and contradictory information in a lot of them: you will have to cross-check them to get the real picture.

Hope this will help others making their mind on those really complex statuses.

Entrepreneurship , , , , , , , , , , , ,

Unobtrusive Ajax on Rails3: Welcome to rails-ajax

My recent contribution to Rails: rails-ajax.

Here is its story:

I am always amazed to see how simple the Ajax use-case can be, how many websites could take benefit from a basic Ajax setup, and yet how difficult it is to integrate a decent Ajax solution to existing websites.

Ajax is a set of techniques allowing asynchronous data exchanges between a web server and its client browsers. Most of the time, those data exchanges tend to refresh parts of web pages, without having to refresh the whole web page. Faster, saves bandwidth, smoother user experience… all benefits.
However with Ajax implementations on websites, many drawbacks have to be taken care of: browser’s URL don’t update, scripts aren’t executed, browser’s history does not work, browsers disabling JavaScript need special attention…

Lately I wanted to use Ajax on an existing Rails 3.2 website. Could not find any decent gem that was still maintained, used state-of-the-art libraries and worked with Rails > 2.

Therefore I decided to use some of the best libraries handling Ajax, HTML5, browsers’ history and no JavaScript fall-back solutions, and integrate them into a nice gem that would turn any Rails3 website into an ajaxified one. Welcome to rails-ajax !

It uses Rails’ UJS, History.js and jQuery to ajaxify websites without altering their application code.

It is unobtrusive, very simple to setup, handles browser’s history and bookmarking, takes care of scripts and redirections, is customizable to refresh several parts of web pages, works with all common browsers, falls back nicely when JavaScript is disabled.

You can check the complete documentation and examples on the rails-ajax web page directly.

Feel free to use it and contribute to it too !

New gem, Ruby on Rails , , , , , , , ,

Full stack integration testing with Rails3: browser-oriented, JavaScript, continuous integration

This post is a complete summary of all my efforts to have a complete and decent solution to test Rails applications.

As it is a long post, here you have the table of contents:

  1. Introduction
  2. Prerequisite for this tutorial
    1. Ruby and Rails environment
    2. OS
  3. First: helpers to write readable tests: RSpec and Cucumber
  4. Test your website using a real browser engine: Capybara and Webkit
  5. First step in continuous integration: having a running instance forking the Rails environment: Spork
  6. Second step in continuous integration: listening to source changes with Guard
  7. Summary

Introduction

Rails comes with a natural support for ruby’s Test::Unit, that comes very handy and lightweight. I still think this is a great lib to write your unit tests. However when it comes to integration testing, you will likely end up with writing big helper methods that will mimic a browser’s behaviour, and its corresponding assertions.

So, I wanted to have a great, efficient, portable and easily maintainable solution to test the complete integration of my Rails applications.
Complete integration testing means that I have complex work-flows to test, using heavy JavaScript (jQuery, Mootools…), dynamic DOM manipulations, involving several HTTP requests.
I also wanted to have a little plus in using this solution into a continuous integration process (a stand-alone instance monitors my source repository, and automatically executes tests upon file changes, producing reports).

Well… I found it and I am pretty happy with it so far.

The winning stack is:

I will explain the use of each one of them, for you to be able to pick exactly what you just need.

The goal of this tutorial is not to teach all the tricks of those libraries, but to show you their usage, how they can be useful to you, and how to integrate them together along with simple examples. If you want to get more in depth with each library/framework, please visit their associated link.

Prerequisite for this tutorial

Ruby and Rails environment

This tutorial assumes that you have a working Rails (I tested with 3.2.6, but I think >=3.2.1 is enough) application. Working at least means that it does not fail when running it using rails server and accessing it through your local browser at http://localhost:3000

The Ruby versions I used for this tutorial are 1.9.2 and 1.9.3. However unless some gems require otherwise, other Ruby versions should be accepted also.

I am also using Bundle in this tutorial. This is not mandatory, but I think this is a great way to express gem dependencies, and so I will illustrate this tutorial with Gemfile modifications, adding gems to it. If you don’t use bundle, just look at the gems I am adding to the file called Gemfile, and install them manually using gem install gem_name.

OS

I tested this tutorial on several OS, with the following results:

  • Windows 7 64bits system (native): Guard does not work on native Windows. However the tutorial can still be applied up to Spork usage.
  • Windows 7 64bits system (Cygwin): I could not make Cucumber work with Spork (however my Cygwin install might have been old and corrupted, so you can be luckier than me).
  • Ubuntu 12.04: Everything works fine.

First: helpers to write readable tests: RSpec and Cucumber

Tests should be written for developers to see them fail.
Then, those developers should understand quickly the implications of the failed test. That means a very important thing for a test case is that the developer should understand what is tested, to help him narrow his bug’s location in the code.
Therefore, writing readable tests is a must.

I found out 2 very useful libs for this purpose:

  • RSpec: it adds a lot of graceful vocabulary to your tests, and organize them clearly. In this tutorial, I mainly use RSpec for the extra helpers it provides.
  • Cucumber: it makes you use your own language and DSL to describe your tests. With this framework, even a newbie will be able to understand your tests. In this tutorial, I use cucumber to write the test cases themselves, and also run them.

Installing these libs in your Rails application is really easy:

  1. Add the gems dependencies in your application’s Gemfile, for group :test only:

    group :test do
    
      # RSpec
      gem 'rspec'
      gem 'rspec-rails'
    
      # Cucumber
      gem 'cucumber-rails', :require => false
      gem 'database_cleaner'
    
    end
    
  2. Run the bundle command to install the gems:

    > bundle
    
    Fetching gem metadata from https://rubygems.org/.......
    ...
    Installing gherkin (2.11.1)
    Installing cucumber (1.2.1)
    Installing cucumber-rails (1.3.0)
    Installing database_cleaner (0.8.0)
    Installing rspec-core (2.11.0)
    Installing rspec-expectations (2.11.1)
    Installing rspec-mocks (2.11.1)
    Installing rspec (2.11.0)
    Installing rspec-rails (2.11.0)
    ...
    Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
    
  3. If this is the first time you run tests on your application, don’t forget to first prepare your test database:

    > rake db:migrate
    > rake db:test:load
    
  4. Those frameworks need little configuration files. They can be generated with the following commands:

    > rails generate rspec:install
          create  .rspec
          create  spec
          create  spec/spec_helper.rb
    

    and

    > rails generate cucumber:install
          create  config/cucumber.yml
          create  script/cucumber
           chmod  script/cucumber
          create  features/step_definitions
          create  features/support
          create  features/support/env.rb
           exist  lib/tasks
          create  lib/tasks/cucumber.rake
            gsub  config/database.yml
            gsub  config/database.yml
           force  config/database.yml
    
  5. Finally you can write a nice test. This tutorial will make use of Cucumber to write and run tests.
    Therefore I define my test in my own language in a features file:

    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code
        When I visit the page "/"
        Then the response code should be "200"
    
  6. And I can run my test by invoking cucumber:

    > cucumber
    
    Using the default profile...
    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code # features\test_cases\simple.feature:3
        When I visit the page "/"                               # features\test_cases\simple.feature:4
          Undefined step: "I visit the page "/"" (Cucumber::Undefined)
          features\test_cases\simple.feature:4:in `When I visit the page "/"'
        Then the response code should be "200"                  # features\test_cases\simple.feature:5
          Undefined step: "the response code should be "200"" (Cucumber::Undefined)
          features\test_cases\simple.feature:5:in `Then the response code should be "200"'
    
    1 scenario (1 undefined)
    2 steps (2 undefined)
    0m0.020s
    
    You can implement step definitions for undefined steps with these snippets:
    
    When /^I visit the page "(.*?)"$/ do |arg1|
      pending # express the regexp above with the code you wish you had
    end
    
    Then /^the response code should be "(.*?)"$/ do |arg1|
      pending # express the regexp above with the code you wish you had
    end
    

    You can see a colored output (on Windows, you will need to use Ansicon to see the colors), much more sexier than usual Test::Unit output.

    Currently our test is failing, as Cucumber does not know yet what to do with our language. As you can see at the end of the output, it suggests a nice code snippet with a regular expression to implement the missing definition.
    This is a real time saver: all you have to do is copy/paste this code snippet to your definition file, and implement it.

  7. So next step is to implement the missing definition, done in a definitions file:

    When /^I visit the page "(.*?)"$/ do |iPagePath|
      visit iPagePath
    end
    
    Then /^the response code should be "(.*?)"$/ do |iResponseCode|
      page.status_code.should == iResponseCode.to_i
    end
    

    In this example, some RSpec and Capybara syntax has been used. For a complete description of the associated DLL, see RSpec documentation and Capybara documentation.

  8. Now you can re-run your cucumber test suite and admire the result:

    > cucumber
    Using the default profile...
    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code # features\test_cases\simple.feature:3
        When I visit the page "/"                               # features/step_definitions/main_steps.rb:1
        Then the response code should be "200"                  # features/step_definitions/main_steps.rb:5
    
    1 scenario (1 passed)
    2 steps (2 passed)
    0m2.551s
    

With these you can already write a great test suite, very easy to maintain with reusable and understandable sentences in your tests. Developers working after you on your project will thank you!

Test your website using a real browser engine: Capybara and Webkit

The best way for your tests to be as close as what a user on his browser might do, is to have a real browser engine for your tests, along with a browser-oriented API.
This is the exact purpose of Capybara.

Capybara gives you a browser-oriented API (like visit '/path/to/page?param=1', fill_in 'Login', :with => 'user@example.com', click_link 'Sign in'…)

It comes with a variety of browser engines or emulations, and one of the best is simply the Webkit engine, used in modern browsers such as Safari or Chrome.
Using Capybara/webkit can be a bit cumbersome on some systems as it requires the presence of Qt installed. If this is too much trouble, you can use default capybara drivers (selenium is a good choice) for your tests to pass.

For the sake of this tutorial, we will use the Webkit engine on capybara.

  1. First step is to add the gems to your Gemfile (still in the :test group):

      # Capybara-webkit
      gem 'capybara-webkit'
    

    If you decided to use capybara with default drivers, the gem name is capybara.

  2. And once again, install it:

    > bundle
    ...
    Using capybara-webkit (0.12.1)
    ...
    Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
    
  3. You can then modify capybara’s configuration by editing the cucumber’s environment file. Most importantly you need to select the desired driver (Webkit in our example):

    Capybara.javascript_driver = :webkit
    

    If you want the selenium driver, the name is :selenium.

  4. Now we will add a new test case involving some JavaScript, and parse it using Capybara’s API:

    Feature: JavaScript testing
    
      @javascript
      Scenario: Arriving on home page and executing JavaScript
        When I visit the page "/"
          And I add a link "Click me to replace content" replacing "body" content with "New content"
          And I click "Click me to replace content"
        Then "body" content should be "New content"
    

    Please note the use of the @javascript tag, mandatory for each test requiring the JavaScript engine to run.

  5. Run cucumber a first time to check for missing definitions

    > cucumber
    Using the default profile...
    Feature: JavaScript testing
    
      Scenario: Arriving on home page and executing JavaScript                                                   # features\test_cases\javascript.feature:3
        When I visit the page "/"                                                                                # features/step_definitions/main_steps.rb:1
        And I add a link "Click me to replace content" replacing "body" content with "Content has been replaced" # features\test_cases\javascript.feature:5
          Undefined step: "I add a link "Click me to replace content" replacing "body" content with "Content has been replaced"" (Cucumber::Undefined)
          features\test_cases\javascript.feature:5:in `And I add a link "Click me to replace content" replacing "body" content with "Content has been replaced"'
        And I click "Click me to replace content"                                                                # features\test_cases\javascript.feature:6
          Undefined step: "I click "Click me to replace content"" (Cucumber::Undefined)
          features\test_cases\javascript.feature:6:in `And I click "Click me to replace content"'
        Then "body" content should be "Content has been replaced"                                                # features\test_cases\javascript.feature:7
          Undefined step: ""body" content should be "Content has been replaced"" (Cucumber::Undefined)
          features\test_cases\javascript.feature:7:in `Then "body" content should be "Content has been replaced"'
    
    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code # features\test_cases\simple.feature:3
        When I visit the page "/"                               # features/step_definitions/main_steps.rb:1
        Then the response code should be "200"                  # features/step_definitions/main_steps.rb:5
    
    2 scenarios (1 undefined, 1 passed)
    6 steps (3 undefined, 3 passed)
    0m3.581s
    
    You can implement step definitions for undefined steps with these snippets:
    
    When /^I add a link "(.*?)" replacing "(.*?)" content with "(.*?)"$/ do |arg1, arg2, arg3|
      pending # express the regexp above with the code you wish you had
    end
    
    When /^I click "(.*?)"$/ do |arg1|
      pending # express the regexp above with the code you wish you had
    end
    
    Then /^"(.*?)" content should be "(.*?)"$/ do |arg1, arg2|
      pending # express the regexp above with the code you wish you had
    end
    
  6. And now implement those definitions:

    ...
    When /^I add a link "(.*?)" replacing "(.*?)" content with "(.*?)"$/ do |iLinkName, iElementSelector, iNewContent|
      page.execute_script("
        var lLinkElement = document.createElement('a');
        lLinkElement.setAttribute('onclick','$(\\'#{iElementSelector}\\')[0].innerHTML = \\'#{iNewContent}\\'');
        lLinkElement.setAttribute('href', '#');
        lLinkElement.innerHTML = '#{iLinkName}';
        $('body')[0].appendChild(lLinkElement);
      ")
    end
    
    When /^I click "(.*?)"$/ do |iLinkName|
      click_on iLinkName
    end
    
    Then /^"(.*?)" content should be "(.*?)"$/ do |iElementSelector, iContent|
      find(iElementSelector).should have_content(iContent)
    end
    
  7. Check everything works fine:

    > cucumber
    Using the default profile...
    Feature: JavaScript testing
    
      @javascript
      Scenario: Arriving on home page and executing JavaScript                                     # features\test_cases\javascript.feature:4
        When I visit the page "/"                                                                  # features/step_definitions/main_steps.rb:1
        And I add a link "Click me to replace content" replacing "body" content with "New content" # features/step_definitions/main_steps.rb:9
        And I click "Click me to replace content"                                                  # features/step_definitions/main_steps.rb:19
        Then "body" content should be "New content"                                                # features/step_definitions/main_steps.rb:23
    
    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code # features\test_cases\simple.feature:3
        When I visit the page "/"                               # features/step_definitions/main_steps.rb:1
        Then the response code should be "200"                  # features/step_definitions/main_steps.rb:5
    
    2 scenarios (2 passed)
    6 steps (6 passed)
    0m9.140s
    

Now you have all the power to write complete integration tests, readable, maintainable and also very complex thanks to Capybara’s browser-oriented API.

First step in continuous integration: having a running instance forking the Rails environment: Spork

Up to now, each time you want to run your tests suite, your whole Rails application is booted and your test suite is run.
This booting process can be very time consuming, and if you want to run your tests often (and in fact you should), then you want to get rid of this booting time.

Here is when Spork shows up.
Spork is a test server that keeps your Rails environment in memory and forks it each time a test suite requires a fresh new instance of your Rails application. Therefore instead of having to boot your application before a test suite run, you just have a simple process fork: much faster!

  1. As usual we start by adding the Spork gem dependency in the Gemfile (still the :test group):

      # Spork
      gem 'spork-rails'
    
  2. And we install again:

    > bundle
    ...
    Using spork (1.0.0rc3)
    Using spork-rails (3.2.0)
    ...
    Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
    
  3. Now Spork needs some generated configuration:

    > spork cucumber --bootstrap
    Using Cucumber, Rails
    Bootstrapping /path/to/rails_app/features/support/env.rb.
    Done. Edit /path/to/rails_app/features/support/env.rb now with your favorite text editor and follow the instructions.
    
  4. The environment file has been modified. Now you really need to read and edit it, as you have to dispatch its content into 2 generated Spork callbacks. One will be called during Spork startup (prefork), the other by each instance that will be forked (each_run).
    For our example, we just have to move the complete capybara configuration in the booting callback:

    require 'rubygems'
    require 'spork'
    #uncomment the following line to use spork with the debugger
    #require 'spork/ext/ruby-debug'
    
    Spork.prefork do
      # Loading more in this block will cause your tests to run faster. However,
      # if you change any configuration or code from libraries loaded here, you'll
      # need to restart spork for it take effect.
    
      require 'cucumber/rails'
      Capybara.default_selector = :css
      Capybara.javascript_driver = :webkit
      ActionController::Base.allow_rescue = false
      begin
        DatabaseCleaner.strategy = :transaction
      rescue NameError
        raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
      end
      Cucumber::Rails::Database.javascript_strategy = :truncation
    
    end
    
    Spork.each_run do
      # This code will be run each time you run your specs.
    
    end
    
  5. Now it is time to boot Spork. This is done with the following command:

    > spork cuc
    Using Cucumber, Rails
      -- Rinda Ring Server listening for connections...
    
      -- Starting to fill pool...
         Wait until at least one slave is provided before running tests...
      ** CTRL+BREAK to stop Spork and kill all ruby slave processes **
    Spork is ready and listening on 8990!
       -- build slave 1...
       -- build slave 2...
    Preloading Rails environment
    Preloading Rails environment
    Loading Spork.prefork block...
    Loading Spork.prefork block...
      --> DRb magazine_slave_service: 1 provided...
      --> DRb magazine_slave_service: 2 provided...
    

    After some time, Spork will be ready to receive incoming test suites. This terminal will be occupied by this Spork process. Therefore you will have to open a new one to issue next commands.

  6. It is now time to run our Cucumber test suite using Spork test server. to do so, we invoke Cucumber with the --drb option:

    > cucumber --drb
    Using the default profile...
    Disabling profiles...
    Feature: JavaScript testing
    
      @javascript
      Scenario: Arriving on home page and executing JavaScript                                     # features\test_cases\javascript.feature:4
        When I visit the page "/"                                                                  # features/step_definitions/main_steps.rb:1
        And I add a link "Click me to replace content" replacing "body" content with "New content" # features/step_definitions/main_steps.rb:9
        And I click "Click me to replace content"                                                  # features/step_definitions/main_steps.rb:19
        Then "body" content should be "New content"                                                # features/step_definitions/main_steps.rb:23
    
    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code # features\test_cases\simple.feature:3
        When I visit the page "/"                               # features/step_definitions/main_steps.rb:1
        Then the response code should be "200"                  # features/step_definitions/main_steps.rb:5
    
    2 scenarios (2 passed)
    6 steps (6 passed)
    0m21.407s
      <-- Slave(2) run done!
    

    If everything goes well, you should see the same output as before, but with a tremendous improvement concerning the time spent running your test suite: no more boot time.

Now we have a listening test server, ready to run our test suite as often as we need.

On my local Windows 7 (native), time improvements are clearly visible:

  • Without Spork: 102 secs
  • With Spork: 22 secs

Second step in continuous integration: listening to source changes with Guard

Next step is to automatically run our test suite as soon as some files have changed.
This way, developers won’t need to run the test suite manually, taking the risk to forget it.

A nice gem, named Guard is here to monitor a files system and take actions on modifications. This gem has nice plugins designed specifically for Spork, our test server: guard-spork, and for Cucumber: guard-cucumber.
These plugins will help generating the default configuration that will monitor files related to each of these services (ie restarting Spork when config changes, restarting Cucumber tests when Cucumber scenarios change).

/!\ At the time of this writing, Guard does not work on native Windows, due to this issue. If you are running a Windows system, I would recommend using Cygwin for Guard to work correctly. If you can’t use Cygwin, then you can try alternatives to Guard, such as Watchr or Autotest.

  1. Once again, we add gem dependencies in the :test group:

      # Guard
      gem 'guard'
      gem 'guard-cucumber'
      gem 'guard-spork'
    
  2. And once again, we install them:

    > bundle
    ...
    Using guard (1.2.3)
    ...
    Using guard-cucumber (1.2.0) 
    ...
    Using guard-spork (1.1.0)
    ...
    Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
    
  3. Then we need to extend Guard’s configuration file with each plugin’s default configuration:

    > bundle exec guard init spork
    Writing new Guardfile to /path/to/rails_app/Guardfile
    spork guard added to Guardfile, feel free to edit it
    
    > bundle exec guard init cucumber
    cucumber guard added to Guardfile, feel free to edit it
    
  4. We need to alter the generated Guard configuration file to tell Cucumber it has to run using Spork. This is done by adding the :cli => '--drb' option:

    guard 'cucumber', :cli => '--drb' do
      watch(%r{^features/.+\.feature$})
      watch(%r{^features/support/.+$})          { 'features' }
      watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
    end
    
  5. It is now time to launch a Guard instance:

    > bundle exec guard start
    Guard uses NotifySend to send notifications.
    Guard is now watching at '/path/to/rails_app'
    Starting Spork for RSpec, Cucumber
    Using Cucumber, Rails
    Using RSpec, Rails
    /path/to/rails_app/spec/spec_helper.rb has not been bootstrapped.  Run spork --bootstrap to do so.
    Preloading Rails environment
    Loading Spork.prefork block...
    Spork is ready and listening on 8990!
    Preloading Rails environment
    Spork is ready and listening on 8989!
    Spork server for RSpec, Cucumber successfully started
    Running all features
    Using the default profile...
    Running tests with args ["--require", "/path/to/gems/guard-cucumber-1.2.0/lib/guard/cucumber/notification_formatter.rb", "--format", "Guard::Cucumber::NotificationFormatter", "--out", "/dev/null", "--require", "features", "features", "--format", "pretty", "--strict", "--tags", "~@wip", "features", "--no-profile"]...
    Disabling profiles...
    Feature: JavaScript testing
    
      @javascript
      Scenario: Arriving on home page and executing JavaScript                                     # features/test_cases/javascript.feature:4
        When I visit the page "/"                                                                  # features/step_definitions/main_steps.rb:1
        And I add a link "Click me to replace content" replacing "body" content with "New content" # features/step_definitions/main_steps.rb:9
        And I click "Click me to replace content"                                                  # features/step_definitions/main_steps.rb:19
        Then "body" content should be "New content"                                                # features/step_definitions/main_steps.rb:23
    
    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code # features/test_cases/simple.feature:3
        When I visit the page "/"                               # features/step_definitions/main_steps.rb:1
        Then the response code should be "200"                  # features/step_definitions/main_steps.rb:5
    
    2 scenarios (2 passed)
    6 steps (6 passed)
    0m17.172s
    Done.
    
    > 
    

    You can see in the output that just after booting, Guard has started Spork, then run the Cucumber tests suite. You should also have received some system notifications, stating that:

    1. Spork was booted correctly
    2. Your Cucumber tests have passed successfully

    Notes:

    • /!\ At the time of this writing, this command will not succeed on native Windows.
    • Please note that you should first kill (using Ctrl-C) the previous Spork instance that was run during this tutorial: it becomes useless once we use Guard.
    • If you happen to run through an error stating Could not start Spork server for RSpec, Cucumber, 2 things might help you:
      1. Try adding a :wait parameter to the Guard configuration for Spork:
        guard 'spork', :wait => 60, :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do
        
      2. Try removing the eventual test/ folder that might be in your Rails application (rename it if you prefer).

    Now it is time to check that the Cucumber tests are run upon some files modifications.

  6. First, modify, save or just touch one of the features file. For this tutorial, I issue a touch features/test_cases/simple.feature.
    And look at the output of the Guard process:

    Running Cucumber features: bundle exec cucumber --drb --require /path/to/gems/guard-cucumber-1.2.0/lib/guard/cucumber/notification_formatter.rb --format Guard::Cucumber::NotificationFormatter --out /dev/null --require features features/test_cases/simple.feature
    Using the default profile...
    Running tests with args ["--require", "/path/to/gems/guard-cucumber-1.2.0/lib/guard/cucumber/notification_formatter.rb", "--format", "Guard::Cucumber::NotificationFormatter", "--out", "/dev/null", "--require", "features", "features/test_cases/simple.feature", "--format", "pretty", "--strict", "--tags", "~@wip", "--no-profile"]...
    Disabling profiles...
    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code # features/test_cases/simple.feature:3
        When I visit the page "/"                               # features/step_definitions/main_steps.rb:1
        Then the response code should be "200"                  # features/step_definitions/main_steps.rb:5
    
    1 scenario (1 passed)
    2 steps (2 passed)
    0m8.071s
    Done.
    
    > 
    

    You can see that Guard has automatically relaunched Cucumber (using Spork), and running just the Simple.feature scenarios (as it was the only file being modified).
    A system notification has also been sent to tell you that those 2 steps have passed successfully.

  7. Then, do the same on a configuration file that might affect your Rails environment (and therefore the running Spork instance).
    For this tutorial, I issued a touch config/application.rb.
    Look at the Guard output:

    Reloading Spork for RSpec, Cucumber
    Using Cucumber, Rails
    Using RSpec, Rails
    /path/to/rails_app/spec/spec_helper.rb has not been bootstrapped.  Run spork --bootstrap to do so.
    Preloading Rails environment
    Loading Spork.prefork block...
    Spork is ready and listening on 8990!
    Preloading Rails environment
    Spork is ready and listening on 8989!
    Spork server for RSpec, Cucumber successfully reloaded
    > 
    

    You can see that the Spork instance has been rebooted, also along with a system notification.

  8. Usually you also want to execute your test suite as soon as application files are modified. By default Guard for Cucumber does not include Rails application files to be monitored. Time to add them to the Guard configuration file:

    guard 'cucumber', :cli => '--drb' do
      watch(%r{^features/.+\.feature$})
      watch(%r{^features/support/.+$})          { 'features' }
      watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
      # Add Rails application files
      watch(/^app\/.+$/) { 'features' }
      watch(/^public\/.+$/) { 'features' }
    end
    
  9. Then, after a touch app/views/layouts/application.html.rb, look at the Guard output:

    Running all features
    Using the default profile...
    Running tests with args ["--require", "/path/to/gems/guard-cucumber-1.2.0/lib/guard/cucumber/notification_formatter.rb", "--format", "Guard::Cucumber::NotificationFormatter", "--out", "/dev/null", "--require", "features", "features", "--format", "pretty", "--strict", "--tags", "~@wip", "features", "--no-profile"]...
    Disabling profiles...
    Feature: JavaScript testing
    
      @javascript
      Scenario: Arriving on home page and executing JavaScript                                     # features/test_cases/javascript.feature:4
        When I visit the page "/"                                                                  # features/step_definitions/main_steps.rb:1
        And I add a link "Click me to replace content" replacing "body" content with "New content" # features/step_definitions/main_steps.rb:9
        And I click "Click me to replace content"                                                  # features/step_definitions/main_steps.rb:19
        Then "body" content should be "New content"                                                # features/step_definitions/main_steps.rb:23
    
    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code # features/test_cases/simple.feature:3
        When I visit the page "/"                               # features/step_definitions/main_steps.rb:1
        Then the response code should be "200"                  # features/step_definitions/main_steps.rb:5
    
    2 scenarios (2 passed)
    6 steps (6 passed)
    0m14.726s
    Done.
    
    > 
    

    You can check that all tests have been run, along with system notification. I will leave it up to you to better fine tune your Guard configuration file.

Finally you have a running test server, listening to your changes in your source code repository, and executing a comprehensive and maintainable test suite.

You should be all set to tackle large Rails application test suites with those great tools.

Summary

Here I recap all the commands to execute and the files to edit to get the whole stack up and running.

  1. Add gem dependencies
    group :test do
    
      # RSpec
      gem 'rspec'
      gem 'rspec-rails'
    
      # Cucumber
      gem 'cucumber-rails', :require => false
      gem 'database_cleaner'
    
      # Capybara-webkit
      gem 'capybara-webkit'
    
      # Spork
      gem 'spork-rails'
    
      # Guard
      gem 'guard'
      gem 'guard-cucumber'
      gem 'guard-spork'
    
    end
    
  2. Install gems
    > bundle
    
    Fetching gem metadata from https://rubygems.org/.......
    ...
    Installing gherkin (2.11.1)
    Installing cucumber (1.2.1)
    Installing cucumber-rails (1.3.0)
    Installing database_cleaner (0.8.0)
    Installing rspec-core (2.11.0)
    Installing rspec-expectations (2.11.1)
    Installing rspec-mocks (2.11.1)
    Installing rspec (2.11.0)
    Installing rspec-rails (2.11.0)
    ...
    Using capybara-webkit (0.12.1)
    ...
    Using spork (1.0.0rc3)
    Using spork-rails (3.2.0)
    ...
    Using guard (1.2.3)
    ...
    Using guard-cucumber (1.2.0) 
    ...
    Using guard-spork (1.1.0)
    ...
    Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
    
  3. Prepare your test database if needed
    > rake db:migrate
    > rake db:test:load
    
  4. Generate RSpec and Cucumber configuration files:
    > rails generate rspec:install
          create  .rspec
          create  spec
          create  spec/spec_helper.rb
    

    and

    > rails generate cucumber:install
          create  config/cucumber.yml
          create  script/cucumber
           chmod  script/cucumber
          create  features/step_definitions
          create  features/support
          create  features/support/env.rb
           exist  lib/tasks
          create  lib/tasks/cucumber.rake
            gsub  config/database.yml
            gsub  config/database.yml
           force  config/database.yml
    
  5. Modify Capybara’s configuration to use Webkit driver
    Capybara.javascript_driver = :webkit
    
  6. Generate Spork configuration:
    > spork cucumber --bootstrap
    Using Cucumber, Rails
    Bootstrapping /path/to/rails_app/features/support/env.rb.
    Done. Edit /path/to/rails_app/features/support/env.rb now with your favorite text editor and follow the instructions.
    
  7. Edit environment file to adapt it to Spork:
    require 'rubygems'
    require 'spork'
    #uncomment the following line to use spork with the debugger
    #require 'spork/ext/ruby-debug'
    
    Spork.prefork do
      # Loading more in this block will cause your tests to run faster. However,
      # if you change any configuration or code from libraries loaded here, you'll
      # need to restart spork for it take effect.
    
      require 'cucumber/rails'
      Capybara.default_selector = :css
      Capybara.javascript_driver = :webkit
      ActionController::Base.allow_rescue = false
      begin
        DatabaseCleaner.strategy = :transaction
      rescue NameError
        raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
      end
      Cucumber::Rails::Database.javascript_strategy = :truncation
    
    end
    
    Spork.each_run do
      # This code will be run each time you run your specs.
    
    end
    
  8. Generate Guard configuration file, for Spork and Cucumber:
    > bundle exec guard init spork
    Writing new Guardfile to /path/to/rails_app/Guardfile
    spork guard added to Guardfile, feel free to edit it
    
    > bundle exec guard init cucumber
    cucumber guard added to Guardfile, feel free to edit it
    
  9. Modify the Guard configuration file to add Spork support to Cucumber, and monitor Rails application files
    guard 'cucumber', :cli => '--drb' do
      watch(%r{^features/.+\.feature$})
      watch(%r{^features/support/.+$})          { 'features' }
      watch(%r{^features/step_definitions/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'features' }
      # Add Rails application files
      watch(/^app\/.+$/) { 'features' }
      watch(/^public\/.+$/) { 'features' }
    end
    
  10. Write your test files:
    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code
        When I visit the page "/"
        Then the response code should be "200"
    

    and

    Feature: JavaScript testing
    
      @javascript
      Scenario: Arriving on home page and executing JavaScript
        When I visit the page "/"
          And I add a link "Click me to replace content" replacing "body" content with "New content"
          And I click "Click me to replace content"
        Then "body" content should be "New content"
    
  11. Implement Cucumber test definitions:
    When /^I visit the page "(.*?)"$/ do |iPagePath|
      visit iPagePath
    end
    
    Then /^the response code should be "(.*?)"$/ do |iResponseCode|
      page.status_code.should == iResponseCode.to_i
    end
    
    When /^I add a link "(.*?)" replacing "(.*?)" content with "(.*?)"$/ do |iLinkName, iElementSelector, iNewContent|
      page.execute_script("
        var lLinkElement = document.createElement('a');
        lLinkElement.setAttribute('onclick','$(\\'#{iElementSelector}\\')[0].innerHTML = \\'#{iNewContent}\\'');
        lLinkElement.setAttribute('href', '#');
        lLinkElement.innerHTML = '#{iLinkName}';
        $('body')[0].appendChild(lLinkElement);
      ")
    end
    
    When /^I click "(.*?)"$/ do |iLinkName|
      click_on iLinkName
    end
    
    Then /^"(.*?)" content should be "(.*?)"$/ do |iElementSelector, iContent|
      find(iElementSelector).should have_content(iContent)
    end
    
  12. Launch a Guard instance:
    > bundle exec guard start
    Guard uses NotifySend to send notifications.
    Guard is now watching at '/path/to/rails_app'
    Starting Spork for RSpec, Cucumber
    Using Cucumber, Rails
    Using RSpec, Rails
    /path/to/rails_app/spec/spec_helper.rb has not been bootstrapped.  Run spork --bootstrap to do so.
    Preloading Rails environment
    Loading Spork.prefork block...
    Spork is ready and listening on 8990!
    Preloading Rails environment
    Spork is ready and listening on 8989!
    Spork server for RSpec, Cucumber successfully started
    Running all features
    Using the default profile...
    Running tests with args ["--require", "/path/to/gems/guard-cucumber-1.2.0/lib/guard/cucumber/notification_formatter.rb", "--format", "Guard::Cucumber::NotificationFormatter", "--out", "/dev/null", "--require", "features", "features", "--format", "pretty", "--strict", "--tags", "~@wip", "features", "--no-profile"]...
    Disabling profiles...
    Feature: JavaScript testing
    
      @javascript
      Scenario: Arriving on home page and executing JavaScript                                     # features/test_cases/javascript.feature:4
        When I visit the page "/"                                                                  # features/step_definitions/main_steps.rb:1
        And I add a link "Click me to replace content" replacing "body" content with "New content" # features/step_definitions/main_steps.rb:9
        And I click "Click me to replace content"                                                  # features/step_definitions/main_steps.rb:19
        Then "body" content should be "New content"                                                # features/step_definitions/main_steps.rb:23
    
    Feature: Simple testing
    
      Scenario: Arriving on home page gives a 200 response code # features/test_cases/simple.feature:3
        When I visit the page "/"                               # features/step_definitions/main_steps.rb:1
        Then the response code should be "200"                  # features/step_definitions/main_steps.rb:5
    
    2 scenarios (2 passed)
    6 steps (6 passed)
    0m17.172s
    Done.
    
    > 
    

I hope this tutorial will help you have a great environment to test your Rails applications with.

What are your thoughts ?

Cygwin, Howto, Ruby, Ruby on Rails, Web development, Windows , , , , , , , , , , , ,

How to compile FastCGI library

The simple answer, as usual is ./configure; make; make install
… Well not in this case: it will break in some environments (mine is x86_64-linux with gcc 4.4.5 and fcgi >= 2.4.0).

During the make command, you will likely fall into the following errors. Here is how to get rid of them:

  1. First error: a missing object file to be moved
    make  all-recursive
    make[1]: Entering directory `/homez.160/ultimact/jicmail1/fcgi-2.4.0'
    Making all in libfcgi
    make[2]: Entering directory `/homez.160/ultimact/jicmail1/fcgi-2.4.0/libfcgi'
    source='fcgiapp.c' object='libfcgi_la-fcgiapp.lo' libtool=yes \
            depfile='.deps/libfcgi_la-fcgiapp.Plo' tmpdepfile='.deps/libfcgi_la-fcgiapp.TPlo' \
            depmode=gcc3 /bin/sh ../depcomp \
            /bin/sh ../libtool --mode=compile gcc -DHAVE_CONFIG_H -I. -I. -I..   -I../include -pthread -g -O2 -Wall -c -o libfcgi_la-fcgiapp.lo `test -f fcgiapp.c || echo './'`fcgiapp.c
    rm -f .libs/libfcgi_la-fcgiapp.lo
    gcc -DHAVE_CONFIG_H -I. -I. -I.. -I../include -pthread -g -O2 -Wall -c fcgiapp.c -MT libfcgi_la-fcgiapp.lo -MD -MP -MF .deps/libfcgi_la-fcgiapp.TPlo  -fPIC -DPIC
    fcgiapp.c: In function 'ProcessManagementRecord':
    fcgiapp.c:1490: warning: dereferencing type-punned pointer will break strict-aliasing rules
    fcgiapp.c:1495: warning: dereferencing type-punned pointer will break strict-aliasing rules
    fcgiapp.c:1498: warning: dereferencing type-punned pointer will break strict-aliasing rules
    mv -f libfcgi_la-fcgiapp.o .libs/libfcgi_la-fcgiapp.lo
    mv: cannot stat `libfcgi_la-fcgiapp.o': No such file or directory
    make[2]: *** [libfcgi_la-fcgiapp.lo] Error 1
    make[2]: Leaving directory `/homez.160/ultimact/jicmail1/fcgi-2.4.0/libfcgi'
    make[1]: *** [all-recursive] Error 1
    make[1]: Leaving directory `/homez.160/ultimact/jicmail1/fcgi-2.4.0'
    make: *** [all] Error 2
    

    This may be due to a buggy version of libtool shipped with FastCGI.
    I don’t have a clean fix for this, but I have a very simple (yet dirty) work-around. Just have to add a make command at line 867 of the libtool file:

          # Just move the object if needed, then go on to compile the next one
          if test x"$output_obj" != x"$libobj"; then
            make $output_obj
            $show "$mv $output_obj $libobj"
            if $run $mv $output_obj $libobj; then :
            else
              error=$?
              $run $rm $removelist
              exit $error
            fi
          fi
    
  2. Second error: an undeclared symbol
    fcgio.cpp: In destructor 'virtual fcgi_streambuf::~fcgi_streambuf()':
    fcgio.cpp:50: error: 'EOF' was not declared in this scope
    fcgio.cpp: In member function 'virtual int fcgi_streambuf::overflow(int)':
    fcgio.cpp:70: error: 'EOF' was not declared in this scope
    fcgio.cpp:75: error: 'EOF' was not declared in this scope
    fcgio.cpp: In member function 'virtual int fcgi_streambuf::sync()':
    fcgio.cpp:86: error: 'EOF' was not declared in this scope
    fcgio.cpp:87: error: 'EOF' was not declared in this scope
    fcgio.cpp: In member function 'virtual int fcgi_streambuf::underflow()':
    fcgio.cpp:107: error: 'EOF' was not declared in this scope
    make[2]: *** [fcgio.lo] Error 1
    make[2]: Leaving directory `/somepath/fcgi-2.4.0/libfcgi'
    make[1]: *** [all-recursive] Error 1
    make[1]: Leaving directory `/somepath/fcgi-2.4.0'
    make: *** [all] Error 2
    

    This is due to a missing stdio.h include in the file libfcgi/fcgio.cpp. Just add it yourself.

    #ifdef _WIN32
    #define DLLAPI  __declspec(dllexport)
    #endif
    
    #include <stdio.h>
    #include <limits.h>
    #include "fcgio.h"
    
    using std::streambuf;
    using std::istream;
    using std::ostream;
    using std::streamsize;
    

These are the 2 errors that prevented me from compiling and linking FastCGI on my Linux system.

Hope it will avoid headaches to others.

Howto, Web development , , , , , , , , , ,

Using data sets in Ruby: performance of Hash vs Set

A data set is a collection of objects that ensures each object is present only once in the collection.

In Ruby, there are 2 simple ways to define data sets:

  1. use the Set Ruby standard library, or
  2. use the Hash standard class.

Of course using Set is the preferred way, as it has been designed specifically for this purpose:

require 'set'
my_set = Set.new
my_set << 5
my_set << 9
my_set << 5
puts my_set.to_a.join(', ') # 5, 9

Using Hash is relatively easy too: just use the Hash’s keys to represent the data set, and associate a useless dummy value (nil) for each key:

my_set = {}
my_set[5] = nil
my_set[9] = nil
my_set[5] = nil
puts my_set.keys.join(', ') # 5, 9

So what about comparing them performance based ?
Here is the benchmark code:

require 'set'
require 'profile'

nbr_inserts = 100000
nbr_reads = 1000
size_set = 1000

Profiler__::start_profile
my_set = Set.new
nbr_inserts.times do |i|
  my_set << rand(size_set)
end
Profiler__::stop_profile
puts "===================== Set INSERT ==================="
Profiler__::print_profile($stdout)

Profiler__::start_profile
my_hash = {}
nbr_inserts.times do |i|
  my_hash[rand(size_set)] = nil
end
Profiler__::stop_profile
puts "===================== Hash INSERT ==================="
Profiler__::print_profile($stdout)

Profiler__::start_profile
nbr_reads.times do |i|
  c = 0
  my_set.each do |i|
    c += i
  end
end
Profiler__::stop_profile
puts "===================== Set READ ==================="
Profiler__::print_profile($stdout)

Profiler__::start_profile
nbr_reads.times do |i|
  d = 0
  my_hash.each do |k, v|
    d += k
  end
end
Profiler__::stop_profile
puts "===================== Hash READ ==================="
Profiler__::print_profile($stdout)

And here is the result:

===================== Set INSERT ===================
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 47.60     2.07      2.07        1  2072.00  4353.00  Integer#times
 31.22     3.43      1.36   100000     0.01     0.02  Set#add
 10.77     3.90      0.47   100000     0.00     0.00  Hash#[]=
 10.41     4.35      0.45   100000     0.00     0.00  Kernel.rand
  0.00     4.35      0.00        1     0.00     0.00  Set#initialize
  0.00     4.35      0.00        1     0.00     0.00  NilClass#nil?
  0.00     4.35      0.00        2     0.00     0.00  Class#new
  0.00     4.35      0.00        1     0.00     0.00  Hash#initialize
  0.00     4.35      0.00        1     0.00     0.00  Kernel.set_trace_func
  0.00     4.35      0.00        1     0.00  4353.00  #toplevel
===================== Hash INSERT ===================
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 72.25     1.92      1.92        1  1916.00  2652.00  Integer#times
 14.18     2.29      0.38   100000     0.00     0.00  Kernel.rand
 13.57     2.65      0.36   100000     0.00     0.00  Hash#[]=
  0.00     2.65      0.00        1     0.00  2652.00  #toplevel
===================== Set READ ===================
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
 99.48     3.09      3.09     1000     3.09     3.09  Hash#each_key
  0.52     3.10      0.02        1    16.00  3104.00  Integer#times
  0.00     3.10      0.00     1000     0.00     3.09  Set#each
  0.00     3.10      0.00     1000     0.00     0.00  Kernel.block_given?
  0.00     3.10      0.00        1     0.00  3104.00  #toplevel
===================== Hash READ ===================
  %   cumulative   self              self     total
 time   seconds   seconds    calls  ms/call  ms/call  name
100.00     1.70      1.70     1000     1.70     1.70  Hash#each
  0.00     1.70      0.00        1     0.00  1700.00  Integer#times
  0.00     1.70      0.00        1     0.00  1700.00  #toplevel

Nice chart:

Conclusion

Using Hash is around 73% faster than using Set.
This does not mean we should always use Hash instead of Set. Hash’s syntax is not as clear as Set’s one when dealing with data sets. Nil value objects make the code look a bit glitchy.
However if performance is a concern to you, as sometimes data sets can be used intensively, you may consider using Hash before thinking of implementing your algorithms in a C extension.

Benchmark, Ruby , , , , ,

How to change Rake tasks’ prerequisites dynamically

Several times in my developer’s life I have found it very useful to use Dependency Graph Programming. That means mapping processes into invokable targets having dependencies on other targets that need to be invoked prior. This is typically what Rake has been created for.

This is especially useful when I want to map processes that can be represented in dependency graphs, and need

  • a lot of computing time,
  • to reuse previously computed results to re-execute a minimal set of code when changing input data,
  • heavy files processing with intermediary files

For such processes, tools such as Make, Ant or Rake are perfectly fit.

However each time I mapped processes with these tools, I faced the same problem: the Dependency Graph itself needs to be changed dynamically during the processing. That means that some targets need to modify other targets’ dependencies. And this is rarely implemented in those tools, therefore needing complex workarounds.

The most obvious example is found when dealing with C libraries compilation and linking (a very common use-case, especially when using Make). If you want to dynamically compute the list of object files to include in a library (based on their symbols, location, naming, whatever …), you want to change the library’s target’s dependencies dynamically. This can be done using a new target computing dependencies, and make the library’s target depend on this new target.

Processing this graph to build mylib.so will first invoke target compute_dependencies. This target will compute that only files c_file_1.c and c_file_2.c need to be included in mylib.so and so will modify the dependency graph as following:

This way, a new build of mylib.so that should change the dependencies will change the graph again by executing compute_dependencies target again and adapt the list of object files for mylib.so.

To get this working, the build system needs to have the following properties:

  • be able to change dependencies during a target’s execution,
  • reprocess dependencies if they have changed during a target’s execution,
  • keep dependencies sorted for each target (it is important that the first dependency computing other dependencies be invoked first).

And now onto Rake. The previous example can be coded this way:

require 'rake'
# Dump targets' invocation
Rake.application.options.trace = true

# Tasks for c files
task :"c_file_1.c"
task :"c_file_2.c"
task :"c_file_3.c"
task :"c_file_1.o" => :"c_file_1.c"
task :"c_file_2.o" => :"c_file_2.c"
task :"c_file_3.o" => :"c_file_3.c"

# Begin by defining only the compute_dependencies
# dependency
task :"mylib.so" => :"compute_dependencies" do |t|
  puts "Dependencies of #{t}: #{t.prerequisites.inspect}"
end

# The task modifying the graph
task :"compute_dependencies" do |t|
  puts "Modify dependencies of :mylib.so"
  Rake::Task[:"mylib.so"].prerequisites.replace(
    [ :"compute_dependencies",
      :"c_file_1.o",
      :"c_file_2.o" ] )
end

# Build the library: this will output the whole
# invocation/execution sequence
Rake::Task[:"mylib.so"].invoke

Using Rake 0.8.7, here is the output:

** Invoke mylib.so (first_time)
** Invoke compute_dependencies (first_time)
** Execute compute_dependencies
Modify dependencies of :mylib.so
** Invoke c_file_1.o (first_time)
** Invoke c_file_1.c (first_time)
** Execute c_file_1.c
** Execute c_file_1.o
** Invoke c_file_2.o (first_time)
** Invoke c_file_2.c (first_time)
** Execute c_file_2.c
** Execute c_file_2.o
** Execute mylib.so
Dependencies of mylib.so: [:compute_dependencies, :"c_file_1.o", :"c_file_2.o"]

We can see that compute_dependencies invocation has modified the graph, and the modifications were taken into account as c_file_1.o and c_file_2.o were correctly invoked before mylib.so. It works perfectly.

Using Rake 0.9.2.2, here is the output:

** Invoke mylib.so (first_time)
** Invoke compute_dependencies (first_time)
** Execute compute_dependencies
Modify dependencies of :mylib.so
** Execute mylib.so
Dependencies of mylib.so: [:compute_dependencies, :"c_file_1.o", :"c_file_2.o"]

Now it is broken: dependencies have been modified (as per the last log), but the invocation chain has not been re-evaluated, and targets c_file_1.o and c_file_2.o have not been invoked.

A simple way to fix it for Rake 0.9.2.2 is to rewrite its Rake::Task::invoke_prerequisites method:

module Rake
  class Task
    # Keep original method
    alias :invoke_prerequisites_ORG :invoke_prerequisites
    # Rewrite it
    def invoke_prerequisites(task_args, invocation_chain)
      prerequisites_changed = true
      while (prerequisites_changed)
        # Keep original prerequisites list
        original_prerequisites = prerequisite_tasks.clone
        # Call original method (this call might change the prerequisites list)
        invoke_prerequisites_ORG(task_args, invocation_chain)
        prerequisites_changed = (prerequisite_tasks != original_prerequisites)
      end
    end
  end
end

And now the output proves targets have been invoked correctly:

** Invoke mylib.so (first_time)
** Invoke compute_dependencies (first_time)
** Execute compute_dependencies
Modify dependencies of :mylib.so
** Invoke compute_dependencies
** Invoke c_file_1.o (first_time)
** Invoke c_file_1.c (first_time)
** Execute c_file_1.c
** Execute c_file_1.o
** Invoke c_file_2.o (first_time)
** Invoke c_file_2.c (first_time)
** Execute c_file_2.c
** Execute c_file_2.o
** Execute mylib.so
Dependencies of mylib.so: [:compute_dependencies, :"c_file_1.o", :"c_file_2.o"]

I think this can come very handy for a lot of processes.

EDIT: A pull request has already been made for integrating these specs here.

Howto, Rake, Ruby , , , , , , , ,

How to require Rake >= 0.9 with Ruby >= 1.9

Very simple problem, judging by this title.

  • I have Ruby 1.9.2
  • I installed Rake 0.9.2.2 with RubyGems (gem install rake)
  • I want to use Rake 0.9.2.2 in my Ruby environment (Rake 0.9.2.2 defines Rake::DSL module). How can I do ?

Simple answer (the one everyone is expecting to work):

require 'rake' # => true
Rake::DSL      # => NameError: uninitialized constant Rake::DSL

=> Wrong

The problem here is that Ruby 1.9 comes already with Rake 0.8.7 in its standard library, and require will always give priority to standard library over installed gems. So whatever Rake version you may install on your system, require 'rake' will always come up with version 0.8.7.

So basically, 2 solutions:

  1. Force Rake version using RubyGems:
    gem 'rake', '0.9.2.2' # => true
    require 'rake'        # => true
    Rake::DSL             # => Rake::DSL
    
  2. Include a rb file present in Rake 0.9.2.2 and unknown to 0.8.7, before requiring rake:
    require 'rake/dsl_definition' # => true
    require 'rake'                # => true
    Rake::DSL                     # => Rake::DSL
    

Hope this helps !

Howto, Rake, Ruby , , , , , , , , ,

How to pilot external processes’ stdin and stdout in real time using Ruby

I finally made it!
Regarding my previous post about failing to pilot processes on Windows, I searched again and finally found a solution.

[EDIT] I have bundled the solution I explain in this article in a nice gem that you can use very easily: ProcessPilot.

The 4 underlying problems I was not getting were the following:

  • Ruby has its own buffer mechanism for STDOUT. This was the reason I was getting the output only on processes’ termination. This problem does not affect non-Ruby programs.
  • Windows processes cannot take interactive input from a file to stdin.
  • Windows processes can only redirect STDOUT and STDERR to files (at least with the libraries I tested)
  • Native Ruby processes on Windows cannot have STDOUT redirected to a file in a thread, then having another thread read the same file without breaking STDIN pipes between parent and child processes (however this works under Cygwin environment)

So here are the points leading to the solution:

  • Use files to get STDOUT and STDERR
  • Use a proper descriptor to pilot STDIN in real time (no file)
  • Pilot from an external thread
  • Do not use STDOUT and STDERR redirections in child program, but instead create child process with STDOUT and STDERR connected directly to files during creation
  • When your external process is a Ruby program, deactivate Ruby internal buffering (I don’t like this point but could not find a better way)

A lot of this code is already written in the childprocess gem (implements STDOUT/ERR/IN connections correctly, is threaded, gives access to stdin in real time).
It really needs a better documentation, but looking at the code was ok to get it working.

So now onto the code…

I used 2 different test processes, 1 Ruby script and 1 Windows batch file. Both of them produce output and ask for user input, with kind sleeps in between to better follow the process:

The Ruby test program:

puts 'Line 1'
sleep 1
puts 'Line 2'
$stdout << 'Type a string: '
puts $stdin.gets
puts 'Line 3'
sleep 1
puts 'Line 4'
$stdout << 'Type another string: '
puts $stdin.gets
puts 'Line 5'

The Batch test program:

@echo off
set var=
echo Line 1
ruby -e "sleep 1"
echo Line 2
set /p var="Type a string: " %=%
echo %var%
echo Line 3
ruby -e "sleep 1"
echo Line 4
set /p var="Type another string: " %=%
echo written: %var%
echo Line 5

Both of these programs produce the same output when issued from the command line:

Line 1
Line 2
Type a string: My string 1
My string 1
Line 3
Line 4
Type another string: My string 2
My string 2
Line 5

Here is the code executing correctly the test program:

require 'childprocess'

process = ChildProcess.build("test.bat")

# Indication of stdin usage
process.duplex = true

# Specify files for stdout/stderr
# ! Use w+ mode to make it possible for our monitoring
# thread to reopen the file in r mode
process.io.stdout = File.new('std.out', 'w+')
process.io.stderr = File.new('std.err', 'w+')

# Start the process: this creates the background
# thread running our command
process.start

# In our main thread: open the STDOUT/ERR files
stdout = File.open('std.out', 'r')
stderr = File.open('std.err', 'r')
stdin = process.io.stdin

# Implement a blocking read a new string on an IO.
# Make sure we wait for the end of a string before
# returning.
# This is done to ensure we will get the new string
# we are expecting.
# Proper implementation should add a timeout, and
# have a more efficient algo.
#
# Parameters:
# * *io* (_IO_): The IO to query
# Return:
# * _String_: The next string from IO (separator is $/)
def get_out_str(io)
  rStr = ''

  # Concatenate chunks unless we have the separator.
  # As we deal with stdin flow, it is possible to have a
  # line without ending already written in the file and
  # already flushed by the IO.
  while (rStr[-1..-1] != $/)
    newChunk=nil
    while ((newChunk = io.gets) == nil)
      sleep 0.1
    end
    rStr.concat(newChunk)
  end

  return rStr
end

# Send a synchronized input to an IO.
# Make sure it will be flushed.
#
# Parameters:
# * *io* (_IO_): The IO to send to
# * *str* (_String_): The string to send
def send_str_in(io, str)
  io.write str
  io.flush
end

# Now display the output step by step, and send inputs
# when needed.
# Add some kind sleeps for better following
puts "=Line1=> #{get_out_str(stdout)}"
puts "=Line2=> #{get_out_str(stdout)}"
sleep 1
send_str_in(stdin, "My string 1\n")
puts "=InputLine1=> #{get_out_str(stdout)}"
puts "=Line3=> #{get_out_str(stdout)}"
puts "=Line4=> #{get_out_str(stdout)}"
sleep 1
send_str_in(stdin, "My string 2\n")
puts "=InputLine2=> #{get_out_str(stdout)}"
puts "=Line5=> #{get_out_str(stdout)}"

# Wait for the process termination in case it is late
while !process.exited?
  sleep 1
end

And here is its output, without any input entered manually:

>ruby -w pilot.rb
=Line1=> Line 1
=Line2=> Line 2
=InputLine1=> Type a string: My string 1
=Line3=> Line 3
=Line4=> Line 4
=InputLine2=> Type another string: written: My string 2
=Line5=> Line 5

For executing a Ruby process, things are a little different: we need to make sure STDOUT is not cached by Ruby internals.
The simple way to do so is to use this as one of the first lines of your external Ruby program:

STDOUT.sync = true

However I prefer not modifying external Ruby program sources. Therefore I came up with a special function launching a Ruby file with arguments (which should cover 99% of Ruby’s interpreter usage).
This function then uses a little wrapper to execute the external Ruby file in the context of a non-cached STDOUT.

Replace the ChildProcess creation from the former script with the following:

# Prepare a Ruby process with his arguments to be executed
#
# Parameters:
# * *rbfile* (_String_): The rb file to execute
# * *args* (<em>list<String></em>): The arguments list [optional = []]
# Return:
# * _ChildProcess_: Corresponding child process
def prepare_rb_process(rbfile, *args)
  return ChildProcess.build(*([ 'ruby', 'wrapper.rb', rbfile ] + args))
end

process = prepare_rb_process("test.rb")

And use the wrapper file, responsible for executing a ruby file with its arguments, but with STDOUT caching disabled:

# Disable STDOUT caching
$stdout.sync = true

# Get the rb file to execute
rb_file = ARGV[0]

# Adapt ARGV for this rb file to get its arguments
# correctly
# TODO: Maybe adapt other variables ...
ARGV.replace(ARGV[1..-1])

load rb_file

And here you go with the output:

>ruby -w pilot.rb
=Line1=> Line 1
=Line2=> Line 2
=InputLine1=> Type a string: My string 1
=Line3=> Line 3
=Line4=> Line 4
=InputLine2=> Type another string: My string 2
=Line5=> Line 5

This has been tested on Windows 7 native terminal (cmd.exe) and on Cygwin environment: works perfectly with both Ruby 1.8.7 and 1.9.2.

Conclusion:

It is now possible to pilot either Ruby and non-Ruby applications in real-time, parsing both STDOUT and STDERR, and controlling completely STDIN flow.

I will make a nice Gem wrapping up all this very soon.

I hope this will help other people by avoiding them the 2 headache days I got to come up with this solution!

Enjoy

PS: Thanks to @luislavena and @_philant_ for their precious help on this matter!

Howto, Ruby, Windows , , , , , , , , , , , , , ,