Generating git patch before push is received

We have a situation where we have a number of satellite git repositories (slaves) which each contain a subset of the code in the master repository.  We want to keep the code separate to ensure that certain developers only have access to certain parts of the code, but it needs to be merged into a single system for overall system tests and release.

We’ve previously been using git subtree. But there are a couple of problems with it.  The first is that it will only merge one way.   You can split changes from the master to the slave repeatedly, but as soon as you try to push changes up from the slave to the master it breaks, for good reason.  It’s also getting increasingly slow as the projects get bigger and bigger.

So, we decided to completely disconnect the master and slave from a git point of view, and instead every time someone pushes a change to one of the repositories we will:

  1. lock all repositories so that other people cannot push a change at the same time
  2. create a patch from the commits just pushed
  3. test applying that patch to all other repositories
  4. if the test is successful, apply the patch
  5. if the test is unsuccessful, reject the push
  6. remove the lock file to let others push

this post covers the second part of that process, creating the patch from the commits just pushed.  Here’s the start of the script:

 

#!/bin/bash

refname="$1"
oldrev="$2"
newrev="$3"

function getChangeLog
{
   oldrev=$1
   newrev=$2

   if expr "$oldrev" : '0*$' >/dev/null
   then
          git rev-list "$newrev"
   else
          git rev-list "$newrev" "^$oldrev"
   fi
}

# Generate patches
filenumber=0;
for rev in $(getChangeLog $oldrev $newrev)
do
   revname=$(git show --pretty=format:%f $rev| head -1)
   thisFileNumber="$(printf "%04d" $filenumber)"
   filename="/tmp/$thisFileNumber-$revname.patch"

   git show --pretty=email --patch-with-stat $rev > "$filename"
   echo "--" >>  "$filename"
   git --version | cut -d ' ' -f 3  >> "$filename"

   filenumber=+1
done

exit 0;

Upgrading Zabbix from 1.8.2 to 1.8.5 on debian lenny

We had installed Zabbix using apt-get from the lenny-backport distribution, but wanted to upgrade to get the advantages of 1.8.5.  Here’s how we did it.

Backup files & database

First, stop the zabbix server, and back up your files & database:

sudo su
/etc/init.d/zabbix-server stop
/etc/init.d/zabbix-agent stop
mkdir -p /home/backups/zabbix
cd  /home/backups/zabbix
tar -cvzf zabbix-file-backup.`date -I`.tgz /etc/zabbix /etc/dbconfig-common/zabbix-frontend-php.conf /etc/dbconfig-common/zabbix-server-mysql.conf /etc/init.d/zabbix-agent/etc/zabbix /etc/dbconfig-common/zabbix-frontend-php.conf /etc/dbconfig-common/zabbix-server-mysql.conf /etc/init.d/zabbix-agent /etc/init.d/zabbix-server /etc/logrotate.d/zabbix-agent /etc/logrotate.d/zabbix-server-mysql /etc/zabbix /usr/bin/zabbix_agent /usr/bin/zabbix_get /usr/bin/zabbix_sender /usr/local/bin/zabbix_get /usr/local/bin/zabbix_sender /usr/local/sbin/zabbix_agent /usr/local/sbin/zabbix_agentd /usr/local/sbin/zabbix_server /usr/sbin/zabbix_agentd /usr/sbin/zabbix_server /usr/share/zabbix /usr/share/zabbix-agent /usr/share/zabbix-server/etc/init.d/zabbix-server /etc/logrotate.d/zabbix-agent /etc/logrotate.d/zabbix-server-mysql /etc/zabbix /usr/bin/zabbix_agent /usr/bin/zabbix_get /usr/bin/zabbix_sender /usr/local/bin/zabbix_get /usr/local/bin/zabbix_sender /usr/local/sbin/zabbix_agent /usr/local/sbin/zabbix_agentd /usr/local/sbin/zabbix_server /usr/sbin/zabbix_agentd /usr/sbin/zabbix_server /usr/share/zabbix /usr/share/zabbix-agent /usr/share/zabbix-server
mysqldump -u root -p zabbix | gzip -9 > zabbix-database-backup.`date -I`.sql.gz
cp 

Download Zabbix & Compile

Download:

mkdir -p /root/src/zabbix
cd /root/src/zabbix
wget http://downloads.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/1.8.5/zabbix-1.8.5.tar.gz

Untar:

tar -xvzf zabbix-1.8.5.tar.gz
cd zabbix-1.8.5

Configure:

./configure --enable-server --enable-agent --with-mysql --with-libcurl --with-net-snmp

Then if successful, install:

make install

This will compile and install Zabbix binaries in /usr/local/bin, /usr/local/sbin, etc.

Move the binaries into debian positions

mv /usr/local/bin/zabbix_sender /usr/bin/zabbix_sender
mv /usr/local/bin/zabbix_get /usr/bin/zabbix_get
mv /usr/local/sbin/zabbix_agent /usr/bin/zabbix_agent
mv /usr/local/sbin/zabbix_agentd /usr/sbin/zabbix_agentd
mv /usr/local/sbin/zabbix_server /usr/sbin/zabbix_server

Set up the website

Move the web php files:

mv /usr/share/zabbix /usr/share/zabbix-backup.`date -I`

Copy the new files:

mkdir /usr/share/zabbix/
cp -a ./frontends/php/* /usr/share/zabbix/

Copy your old web config file to the new structure:

cp -p /usr/share/zabbix-backup.`date -I`/conf/zabbix.conf.php /usr/share/zabbix/conf/zabbix.conf.php
chmod a+r /usr/share/zabbix/conf/zabbix.conf.php

Start Zabbix server and agent, and check the logs:

/etc/init.d/zabbix-server start
/etc/init.d/zabbix-agent start

You can now make use of the StartDbSyncers configuration parameter, which should mean that your item queue shouldn’t lag behind when you’re monitoring a load of servers:

vim /etc/zabbix/zabbix_server.conf

# Number of database syncers
StartDBSyncers=10

Using postfix to send mail via 1and1 or other authenticated SMTP

We recently wanted to set up postfix on web servers so that it could send messages generated by the website code. We’re using 1and1′s hosted email, and wanted to send the email from a user whose mailbox was hosted with 1and1, rather than relaying the email through 1and1′s mail servers. For us, this has the advantage of having our mailboxes hosted and managed by 1and1, and having a local postfix queue on each web server which will hold onto the mail if there’s a problem at 1and1.

Background over, here’s how we configured postfix on Debian 5 (lenny).

Install prerequisites

This bit’s important. Postfix will quietly fail to authenticate with the 1and1 servers with an extremely un-descriptive warning in /var/log/mail.log. Install these unless you want to spend loads of time trying to puzzle out what’s gone wrong!

sudo apt-get install postfix sasl2-bin libsasl2-2 libsasl2-modules

Configure postfix

Postfix configuration happens in /etc/postfix/main.cf. Essentially, any parameter starting smtp_ relates to postfix sending email. Any starting smtpd_ relates to it receiving mail for sending on. For this exercise we want to disable the receipt of mail (apart from over the loopback interface).

The sections below show you why to make changes, and the attached main.txt, which you should rename to main.cf, shows the finished file.

Error Notices

These notices will email postfix-errors@yourdomain.com when something goes wrong

delay_warning_time = 2h
bounce_notice_recipient = postfix-errors@yourdomain.com
delay_notice_recipient = postfix-errors@yourdomain.com
error_notice_recipient = postfix-errors@yourdomain.com

Only allow mail to be sent, not received

We only want to send mail from our mail servers, we don’t want to receive it. Here’s how:

myhostname = yourdomain.com
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydomain = yourdomain.com
myorigin = yourdomain.com
mydestination =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +
inet_interfaces = 127.0.0.1
inet_protocols = ipv4

SSL

These lines enable SSL and set up the config:

smtp_use_tls=yes
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_sasl_tls_security_options = noanonymous
tls_random_source = dev:/dev/urandom

Authentication

Finally, we want to log in to 1and1′s servers to send the email. Here’s the configuration settings:

smtp_sasl_auth_enable = yes
relayhost=[auth.smtp.1and1.co.uk]:587
smtp_sasl_password_maps=hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous

Creating the password file

The “smtp_sasl_password_maps” configuration option above sets a file which will contain the username & password used to log on to 1and1. To do this, first of all, we create the file:

sudo su
echo '' > /etc/postfix/sasl_passwd
chown root.root /etc/postfix/sasl_passwd
chmod 600 /etc/postfix/sasl_passwd
vim /etc/postfix/sasl_passwd

Now we need to put the username & password in there. It’s of the form:

[auth.smtp.1and1.co.uk]:587 name@yourdomain.com:password

The email address (name@yourdomain.com) should be of one of your mailboxes, and the password of that mailbox too. Once you have authenticated, you do not need to use the same email address to send from.

You should then save the file, and encrypt it as follows:

sudo postmap sasl_passwd

And then check:

sudo postfix check

And restart postfix:

sudo /etc/init.d/postfix restart

Testing postfix

To test postfix is working, try:

echo "Subject: Test"| sendmail -f name@yourdomain.com -v youremail@yourdomain.com

And then:

sudo tail -f /var/log/mail.log

to check that the email has been sent ok.

Troubleshooting

If you ever have trouble with postfix, edit /etc/postfix/master.cf and change the line:

smtp      unix  -       -       -       -       -       smtp

to

smtp      unix  -       -       -       -       -       smtp -v

And restart postfix.

Useful Resources

Speeding up firefox startup on Mac OS X

I’ve been a long time user of firefox and find that over time, starting firefox up takes a lot longer. Firefox uses sqlite as a database to store things like the list of places you’ve visited. Over time, these database files become fragmented, and need cleaning up. Here’s how to do it on mac OS X.

You should close Firefox, and then open up Terminal.app and type the following commands:

First, check the current size of your database files:

find ~/Library/Application\ Support/Firefox/Profiles -type f -name '*.sqlite' -exec ls -arlth {} \;

Next, vacuum and then re-index your database files. This may take some time – so don’t worry and leave it to finish.

find ~/Library/Application\ Support/Firefox/Profiles -type f -name '*.sqlite' -exec sqlite3 {} VACUUM \;
find ~/Library/Application\ Support/Firefox/Profiles -type f -name '*.sqlite' -exec sqlite3 {} REINDEX \;

Now check the sizes again:

find ~/Library/Application\ Support/Firefox/Profiles -type f -name '*.sqlite' -exec ls -arlth {} \;

You should see an instant speed increase.

Calling MySQL stored procedures from PHP’s PDO – output parameters

Unfortunately there’s a bug with the MySQL C API that PDO uses which means that trying to fetch an output parameter when calling a procedure results in the error:

“Syntax error or access violation: 1414 OUT or INOUT argument $parameter_number for routine $procedure_name is not a variable or NEW pseudo-variable”.

You can see the bug report on bugs.mysql.com. It’s been fixed for version 5.5.3+ & 6.0.8+.

To workaround the issue, you would need to keep in & out parameters separate and call the procedure.  Example #11 on the PHP PDO documentation would then read:

$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(:in_string, @out_string)");
$stmt->bindParam(':in_string', 'hello');

// call the stored procedure
$stmt->execute();

// fetch the output
$outputArray = $this->dbh->query("select @out_string")->fetch(PDO::FETCH_ASSOC);

print "procedure returned " . $outputArray['@out_string'] . "\n";

Running selenium tests on debian headlessly using iceweasel and firefox

We wanted to run selenium tests headlessly on a debian server from phpunit. Unfortunately the whole htmlunit via selenium2 isn’t available yet from PHPUnit. So, we installed xvfb (which is essentially a desktop), iceweasel (aka debian’s version of firefox) and set up xvfb to run in an init script at startup.

Install xvfb

To install xvfb:

sudo apt-get install xvfb

And then to check everything’s OK:

Xvfb :99

Where :99 is the display number. We set it to 99 to avoid any conflict with other displays, should they be attached. The command line should just hang without any comments until you press CTRL-C to close.

Install iceweasel (firefox)

To install iceweasel, which is currently the debian version of firefox:

sudo apt-get install iceweasel

And then, once you’re installed, to test that it works OK. Start Xvfb in one window as above, then in a second terminal window:

export DISPLAY=:99
firefox

you should see nothing – firefox should just sit there until you CTRL+C.
The “export DISPLAY=:99″ line is telling firefox to use display # 99, which we started above.

Create Xvfb startup script

We want xvfb to be running all the time, so that we can run selenium tests whenever we please. To do this, we create an init.d script. Here it is:

#!/bin/bash

XVFB=/usr/bin/Xvfb
# XVFBARGS=":99 -fbdir /var/run -ac"
XVFBARGS=":99 -nolisten tcp -fbdir /var/run"
PIDFILE=/var/run/xvfb.pid
case "$1" in
  start)
    echo -n "Starting virtual X frame buffer: Xvfb"
    start-stop-daemon --start --quiet --pidfile $PIDFILE --make-pidfile --background --exec $XVFB -- $XVFBARGS
    echo "."
    ;;
  stop)
    echo -n "Stopping virtual X frame buffer: Xvfb"
    start-stop-daemon --stop --quiet --pidfile $PIDFILE
    echo "."
    ;;
  restart)
    $0 stop
    $0 start
    ;;
  *)
        echo "Usage: /etc/init.d/xvfb {start|stop|restart}"
        exit 1
esac

exit 0

You can also download a copy of the init script here.

Save this as /etc/init.d/xvfb.

Then:

sudo chmod a+x xvfb

Note: We’re running xvfb on the same server as selenium, and so we’ve enabled access controls to ensure that only processes from the same server can connect. Should you want to connect selenium from another server, you can run with the “-ac” option, which disables all access controls – anyone can connect.

Finally, we will add it to rc.d so that it starts when the system does:

update-rc.d xvfb defaults

Changing the selenium startup script

Finally, when firefox is run from selenium we want it to use display # 99. Edit the selenium startup script from this earlier post and add “export DISPLAY=:99″ just before the selenium server is started in both the “start” and “restart” sections:

export DISPLAY=:99
java -jar /usr/lib/selenium/selenium-server-standalone-2.0a7.jar -port 4443 > /var/log
/selenium/selenium-output.log 2> /var/log/selenium/selenium-error.log & echo $! > /tmp/selenium.pid

Triggering a hudson build to run when git is updated

Hudson CI lets you configure a build so that it periodically polls git to check whether anything’s changed.  This is something of a waste of time & resources – it’s polling git when nothing has changed and there may be a lag between when you check something in and when it builds.

Below are instructions on how to get git to trigger the build once it has had changes pushed to it.  I’m assuming here that you have:

  • A central git repository on server A
  • A hudson server set up on server B (which may, or may not, be the same server as server A)

Note that it is simplest if you have set hudson up on the same server as git as per these instructions as then we can trigger the build via a call to localhost without going over the network, and you can keep port 8081 closed on your server.

On the git server, in the git repository, you should edit the post-receive hook which contains the following text:

vim /path/to/your/git/repository.git/hooks/post-receive

With the following lines:

URL='http://[serverB]/job/[YOUR-JOB-NAME]/build'

echo "Run Hudson build at $URL"
wget $URL > /dev/null 2>&1

Note that if you’ve set up hudson on the same server as per the previous instructions, then the [serverB] URL above will be “localhost:8081″.

Finally, you will need to make the hook executable by whoever will be checking code in.  As an example, assuming that the git repository is owned by a user called “git”, and a user called “userA” will be checking in via their own ssh account, you should:

sudo usermod -G git userA

If they’re not already a member of the “git” group, and then

chmod ug+x /path/to/your/git/repository.git/hooks/post-receive

To make the hook executable by the git group.

Installing Hudson on Ubuntu and displaying it through Apache

This tutorial goes through how to set up hudson on Ubuntu / Debian, and then expose it via Apache.

Installing and setting up hudson

1) Install prerequisites:

sudo apt-get update
sudo apt-get install daemon openjdk-6-jre

2) Install hudson by following these instructions: http://hudson-ci.org/debian/

3) edit /etc/default/hudson

Optionally, change the http port (default is 8080, but I found that that often conflicts with other Tomcat based services like Selenium):

HTTP_PORT=8081

And then change the last line so that it reads:

HUDSON_ARGS="--webroot=/var/run/hudson/war --httpPort=$HTTP_PORT --httpListenAddress=localhost --ajp13Port=$AJP_PORT  --prefix=$PREFIX"

We have added the option “–httpListenAddress=localhost” to ensure that hudson only listens on the loopback interface rather than publicly.

4) Restart hudson to pick up the changes:

/etc/init.d/hudson restart

Running Hudson through apache

Because of the changes in (3) above, hudson is now running at http://localhost:8081/.  You can confirm this by typing:

wget http://localhost:8081/

on the server, and then checking the contents of the downloaded index.html

We now want to proxy it through apache to make it available externally. 

You should add the following to the VirtualHost configuration for the website through which you wish to make it available:

  ProxyPass         /   http://localhost:8081/
  ProxyPassReverse  /   http://localhost:8081/
  ProxyRequests     Off

  # Local reverse proxy authorization override
  # Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)
  <proxy http://localhost:8081*>
    Order deny,allow
    Allow from all
  </proxy>

Which proxies the requests through to the hudson server. Restart apache and you should be ready to go.

Installing Watir-webdriver, Selenium and Ruby on Windows XP to run browser tests

Running local browser tests can be a pain for a couple of reasons. They’re generally not intuititive to write, and they take an age to run. Using the new selenium-webdriver with watir solves both these issues. Watir tests are easy to write:

browser.goto "http://google.com"
browser.text_field(:name => 'q').set("Watir is working!")
browser.button(:name => 'btnG').click

and you can run selenium in “headless” mode. This means that you don’t see a browser instance opening and running the tests like in normal selenium tests, but rather it’s run using HTMLUnit.

I wrote the instructions below to help people set up their environment for some recent training. You can also download them in PDF format.

Installing Ruby

Downloading

We will be installing Ruby version 1.9.2 – the latest version of Ruby. You can download the installer from:

http://rubyforge.org/frs/download.php/72170/rubyinstaller-1.9.2-p0.exe

Download the file, save it on your desktop, and once complete, double click on the .exe file to open it. Agree with any security warnings that appear.

Installing Ruby

You should now see this window:

  • Click “Next”
  • Select “I accept the license” and click “Next”

On the next screen:

  • Change the installation path to “C:\Tech\Ruby192”
  • Check the “Add Ruby executables to your PATH” checkbox
  • Check the “Associate .rb and .rbw files with this Ruby installation” checkbox

The screen should now look like this:

Click “Install”

Once installation is complete, you should see this screen:

Click “Finish”, and the installer will close.

Testing Ruby Installation

We’re now going to test that ruby has installed properly by running ruby.

Open the windows Command Prompt by clicking on the start menu, and clicking “Run”.

When the “Run” popup appears, type “cmd” into the text box and click “Ok”:

When the Command Prompt appears, type:

ruby –v

and press Enter. You should see the ruby version number as in this screenshot:

Here you can see we have installed ruby version 1.9.2p0.

Installing Ruby DevKit

The rest of this howto (except for the paths) works across pretty much any operating system. There are some problems compiling some Ruby gems on Windows because of the lack of a C compiler installed by default. The Ruby DevKit takes care of all of this for you.

First of all, download the DevKit from:

http://github.com/downloads/oneclick/rubyinstaller/DevKit-4.5.0-20100819-1536-sfx.exe

Download the file, save it on your desktop, and once complete, double click on the .exe file to open it. Agree with any security warnings that appear.

When the 7-Zip self-extracting archive window pops up, you should change the path to:

C:\Tech\Ruby-DevKit\

Once the file has extracted, open the Windows Command Prompt by select Start / Ru, typing “cmd” and pressing Enter.

Next, navigate into the directory that you just extracted the files into. For instance:

cd ../../
cd Tech/Ruby-DevKit

Now type:

ruby dk.rb init

Which will generate a config file which should list the version of Ruby that we installed earlier.

Type:

notepad config.yml

To check that it’s OK. You should see a line at the bottom of the file which reads:

- C:/Tech/Ruby192

Next, we will install the DevKit enhancements. To do this, type:

ruby dk.rb install

Which should produce:

Finally, to check that the installation has been successful, we’re going to try compiling a gem (see section 2.4 below for a full explanation of gems) to check this installation. Type:

gem install rdiscount --platform=ruby

RDiscount should install correctly and you should see:

Temporarily enhancing PATH to include DevKit...

in the screen messages.

Next type:

ruby -rubygems -e "require 'rdiscount'; puts RDiscount.new('**Hello RubyInstaller**').to_html"

and press enter. You should see:

<p><strong>Hello RubyInstaller</strong></p>

In summary:

Installing Ruby Gems

Gems in Ruby are self-contained programs or libraries. So, the “mysql” gem contains code that you may use to connect to mysql. I say may as there can be multiple gems that do the similar things in different ways. For instance there are two well known and competing Object Relational Mappers – DataMapper and ActiveRecord.

In this section we will download and install the gems you will need to test.

To do this, return to the command prompt you have open above, and type in:

gem list

This lists the gems which are already installed.

We will now download and install the gems you need; which are:

  • selenium-webdriver
  • watir-webdriver
  • rspec
  • ruby-debug-ide
  • test-unit

The gem package manager will also download any dependencies that are required by these gems, and that you do not have installed. Return to the Command Prompt window, and type:

gem install selenium-webdriver watir-webdriver rspec ruby-debug-ide test-unit --platform=ruby

and press “Enter”.

Note: When installing gems on Windows with DevKit, you should always append

-- platform=ruby

This ensures that the source is downloaded and compiled locally rather than binaries downloaded which will not work on windows. More information can be found here: http://github.com/oneclick/rubyinstaller/wiki/Development-Kit under the heading “Example Native RubyGem Installations using the DevKit”.

It may take a while to complete, but once done you should see output that looks like this:

Installing Selenium

Although we will be creating tests using Watir, which is a Ruby test API, the tests will be run by a Selenium server. The call stack looks like this:

Watir tests -> Watir-Webdriver -> Selenium-Webdriver -> Selenium Server

This means that you can run Selenium tests without having it open a browser window. This is called running “headlessly”. This is much, much faster than having watir open a browser and run the tests. This means that you can run tests headless locally, prior to checking in, and then the build server can take care of the longer and heavier cross browser testing in the nightly build.

We’re going to install the standalone selenium server on your PC. To do this:

Create a new directory; C:\Tech\Selenium\

Go to http://code.google.com/p/selenium/downloads/list, and download the latest version of the selenium-server-standalone-2* file, saving it to C:\Tech\Selenium\

Open the Windows Command Prompt by clicking Start / Run, typing “cmd” and pressing Enter.

Navigate to the Selenium directory and list the contents by typing:

cd ../..
cd Tech/Selenium

You should see:

Now we’re going to start the Selenium server. Type:

java –jar selenium-server-standalone-2.0a5.jar

replacing 2.0a5 with the version number of your version. The Selenium server will now start. When the security alert appears, click the “Unblock” button:

You should see something like this in the Command Prompt window:

This means that the Selenium server is up and running and waiting for connections on port 4444. Leave the window where it is, as we will return to it later.

Installing the IDE

Everyone has their favourite IDE, but if you do not have one yet and want one that works well with Ruby, then Netbeans is a good choice. In this section we will install Netbeans and configure it for use with the version of Ruby we just installed.

Install the Java JDK where required

Netbeans is a Java application and needs the JDK (Java Development Kit) to run. So that we can be sure that everyone’s IDE works in the same way, we’re first going to download the current version of the Java JDK from here: http://is.gd/fdHJl

Download the file, save it on your desktop, and once complete, double click on the .exe file to open it. Agree with any security warnings that appear.

You should now see this window:

Click “Next”

Next, you will see the installation options page. Leave the default options as they are and click “Next”:

The installation will start.

When the installation is about half way through, a second window will pop up. This is for the JRE – Java Runtime Environment. You will see a window that looks like this:

Click “Next”, and the JRE will be installed.

The second window will disappear when the JRE has been successfully installed, and you will be left with:

Click “Finish” to close the window. When the browser window opens asking you to register, close it again.

Installing Netbeans

We’re going to download the Ruby version of Netbeans, which you can get from here:

http://netbeans.org/downloads/index.html

Download the Ruby version, save it on your desktop, and once complete, double click on the .exe file to open it. Agree with any security warnings that appear.

The first installation screen asks you which server you want to install with the IDE. As we’re not going to be doing any web development, deselect the “Glassfish Server Open Source Edition 3.0.1” checkbox:

Then click “Next”.

On the next screen, accept the Terms & Conditions by checking the checkbox, and select “Next”.

The next screen asks you for your installation location and the location of the JDK. The screen should look like this:

You must ensure that the “Java environment for the NetBeans IDE” path matches the one you just installed:

C:\Program Files\Java\jdk1.6.0_21

Click “Next”.

Click “Install”

Once the registration is done, uncheck the “Register” checkbox and click “Finish”.

1.5.3 Configuring NetBeans

We’re now going to check that NetBeans is configured correctly. To start, open NetBeans by selecting:

“Start / All Programs / NetBeans / NetBeans IDE 6.9.1”

Once it’s finished loading, select the Tools menu and select “Ruby Platforms”

You should now see the “Ruby Platform Manager”, which shows the different versions of Ruby installed on your computer. You should see two versions:

  1. Built in JRuby 1.5.1 – which comes bundled with NetBeans
  2. Ruby 1.0.2-p0 – the version we installed earlier

Click “Close” to close.

Testing your installation

Lastly, we’re going to test that your installation works by writing a quick test that uses Watir to run a test against the google homepage.

Create a new project

With Netbeans open, select “File” from the top menu, and then “New Project”.
In the new project dialog, select “Ruby” in the middle section, and then “Ruby Application” in the right panel.

Click “Next”.

On the next screen:

  • Rename the project to “RubyTraining”
  • Change the “Project Path” to “C:\Tech\Projects”
  • Deselect the “Create Main File” checkbox
  • Change the Ruby Platform to “Ruby 1.9.2-p0”

The screen should now look like this:

Click “Finish”.

Create your test file

Once the project has been created, right click on “Source Files” in the project pane, select select “New” / “Ruby File”.

Enter “google_test” into the ‘File Name” text box, and click “Finish”.

When the file opens, select all of the text in the file and replace it with the text below:

require 'watir-webdriver'

browser = Watir::Browser.new(:remote, :url => "http://127.0.0.1:4444/wd/hub", :desired_capabilities => :htmlunit)
browser.goto "http://google.com"
browser.text_field(:name => 'q').set("Watir is working!")
browser.button(:name => 'btnG').click
puts browser.url
browser.close

Save the file by pressing “Ctrl + S” or selecting File / Save from the menu.

This script

  • goes to www.google.com
  • enters “Watir is working!” in the question box
  • Presses the search button (btnG)
  • “puts” (prints to screen) the new browser URL
  • closes the browser

Run your test file

We’re now going to run this file in debug mode. To do this, either press “Shift + F6”, or select “Run” / “Run File” from the top menu.

When the Windows Security Alert pops up, select “Unblock”.

You’ll only need to do this once.

The IDE’s appearance will now change as the file is run.

When it’s finished, click on the “Output – google_test” tab in the lower right pane. You will see the output of the script:

The important line here is:

http://www.google.co.uk/search?hl=en&source=hp&q=Watir+is+working%21&btnG=Google+Search

This is the new URL that the script “put”

If you check the Command Prompt window where you earlier left Selenium open, you will also be able to see that Selenium has also been logging the output.

Installing RVM on Mac OS X

RVM is the Ruby Version Manager.  It allows you to install multiple versions of Ruby, and within each of those versions, multiple sets of gems (gemsets).  So, for each project you’re working on you can have exactly the same version on all environments.   This is an excellent idea.

The documentation, whilst excellent, lacks howtos for different operating systems.  I installed it on both Mac OS X and on an Ubuntu server (see this post for details on how Ubuntu works).  Mac OS X 10.6 instructions are below.

Installing RVM

Open Terminal.  Then, as your user (NOT root) run the following:

cd
bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head )
vim .~/.profile

add the following right at the end to load RVM:

[[ -s "$HOME/.rvm/scripts/rvm" ]] && . “$HOME/.rvm/scripts/rvm” # This loads RVM into a shell session

Reload your profile (by typing . .profile) and type:

type rvm | head -n1

You should see:

rvm is a function

If you do not, it means that RVM has not loaded properly.  You’ll need to go into the installation process in more depth – a good place to start is the “Troubleshooting your install” section of this page.

RVM’s now installed. The next step is to set up the particular version of Ruby and gems that you want to use for a project.