Flavio Castelli

Debugging my life.

Jump: A Bookmarking System for the Bash Shell

| Comments

Let me introduce a small project I’ve been working on with a friend of mine, Giuseppe Capizzi. The project is called jump and allows you to quickly change directories in the bash shell using bookmarks.

Thanks to Jump, you won’t have to type those long paths anymore.

You can find jump’s source code, detailed documentation and installation instructions here.

SUSE packages can be found here.

Fast User Switch Plasmoid Improvements

| Comments

Just a quick note, I released a new version of the fastuserswitch plasmoid. This new release implements all the improvements suggested by the users plus some minor fixes.

Code can be downloaded from here. openSUSE packages are already available on the build service.

These are some screenshots illustrating fastuserswitch’s new features.

Fast User Switch Plasmoid

| Comments

Last week my mother in law started to share her Linux laptop with my wife. Suddenly my wife asked me how she could switch from one user session to another. She was looking for something similar to OS X fast user switch feature but she couldn’t find it. In fact there wasn’t a fast and easy way to switch between users’ sessions with KDE, until… now :)

Let me introduce my first plasmoid: the fast user switch plasmoid. It’s a simple icon in the panel that allows users to swich to another open session or to open a new login page. Here you can see the mandatory screenshots.

You can find the source code here. Binary packages for openSUSE are already available on the build service.

One last thought about KDM

I think that KDM should allow to switch back to an already open session in a more transparent way. Right now if an user has already one session open, he goes back to the login screen and enters his credentials a new session is started. I think that most users would expect to be switched back to their already running session. Starting a new session is just confusing for them.

How to Run a Single Rails Unit Test

| Comments

This post explains how to execute a single unit test (or even a single test method) instead of running the complete unit test suite.

In order to run the unit tests of your rails application, basically you have these official possibilities:

  • rake test: runs all unit, functional and integration tests.
  • rake test:units: runs all the unit tests.
  • rake test:functionals: runs all the functional tests.
  • rake test:integration: runs all the integration tests. Each one of these commands requires some time and they are not the best solution while developing a new feature or fixing a bug. In this circumstance we just want to have a quick feedback from the unit test of the code we are editing.

Waiting for all the unit/functional tests to complete decreases our productivity, what we need is to execute just a single unit test. Fortunately there are different solutions for this problem, let’s go through them.

The easy approach: use your favorite IDE

Most of the IDE supporting ruby allow you to run a single unit test. If you are using Netbeans running a single unit test is really easy:

  • make sure the editor if showing the file you want to test or the file containing its unit tests
  • Hit Ctrl+Shift+F6 or click on the following menu entry: Debug->Debug Test File Two new windows will be opened: one will contain the output produced by your unit test, the other one will show the results of the unit test.

As you will notice the summary window contains also some useful information like the:

  • hyper links to the exact location of the code that produced the error/failure.
  • execution time required by each one of the test methods. As you will experience it will be like “compiling” your ruby code.

From the console

If you are not using Netbeans you can always rely on some command line tools.

No additional tools

These “tricks” don’t require additional gems, hence they will work out of the box.

The first solution is to call this rake task:

rake test TEST=path_to_test_file

So the final command should look like

rake test TEST=test/unit/invitation_test.rb

Unfortunately on my machine this command repeats the same test three times, I hope you won’t have the same weird behavior also on your systems…

Alternatively you can use the following command:

ruby -I"lib:test" path_to_test_file"

It’s even possible to call a specific test method of your testcase:

ruby -I"lib:test" path_to_test_file -n name_of_the_method"

So calling:

ruby -I"lib:test" test/unit/invitation_test.rb - test_should_create_invitation

will execute only InvitationTest::test_should_create_invitation.

It’s also possible to execute only the test methods matching a regular expression. Look at this example:

ruby -I"lib:test" test/unit/invitation_test.rb -n /.*between.*/

This command will execute only the test methods matching the /.between./ regexp.

Using the single_test gem

If you want to avoid the awful syntax showed in the previous paragraph there’s a gem that can help you, it’s called single_test.

The github page contains a nice documentation, but let’s go through the most common use cases.

You can install the gem as a rails plugin:

script/plugin install git://github.com/grosser/single_test.git

single_test will add new rake tasks to your rails project, but won’t override the original ones.

Suppose we want to execute the unit test of user.rb, just type the following command:

rake test:user

If you want to execute the functional test of User just call:

rake test:user_c

Appending c”_ to the class name will automatically execute its functional test (if it exists).

It’s still possible to execute a specif test method:

rake test:user_c:_test_name_

So calling:

rake test:user_c:test_update_user

Will execute the test_update_user method written inside of test/functional/user_controller_test.rb.

It’s still possible to use regexp:

rake test:invitation:.*between.*

This syntax is equivalent to ruby -I"lib:test" test/unit/invitation_test.rb -n /.*between.*/.

Possible issues

When a single unit test is run all the usual database initialization tasks are not performed. If your code is relying on newly created migrations you will surely have lots of errors. This is happening because the new migrations have not been applied to the test database.

In order to fix these errors just execute:

rake db:test:prepare

before running your unit test.

QJson and Symbian

| Comments

I’m really pleased to announce that latest version of QJson on master is working on Symbian. You can find the installation instruction here.

Since I’m not a Symbian developer it has been a little hard for me to achieve that. I would like to thank Antti Luoma for his help.

There are also good news for Windows developers: now building QJson under Windows is easier. Checkout the new installation instruction page.

I hope this will help all the Windows developers who want to use QJson.

QJson Code Moves to Gitorious

| Comments

Just a quick note: I have just moved QJson source code to this git repository hosted by gitorious.

I’ll keep the code on KDE’s svn synchronized with the git repository.

QJson: From QObject to JSON and Vice-versa

| Comments

Some days ago I introduced the possibility to serialize a QObject instance to JSON. Today I’m going to show you the opposite operation: initializing a QObject using a JSON object.

I refactored a bit my latest changes: I created a new class called QObjectHelper that provides the methods required to convert a QObject instance to a QVariantMap and vice-versa.

This class can be used in conjunction with the Serializer and Parser classes to serialize and deserialize QObject instances to and from JSON.

Let me show a quick example, suppose the declaration of Person class looks like this:

[class definition] [ ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Person : public QObject
{
  Q_OBJECT
  Q_PROPERTY(QString name READ name WRITE setName)
  Q_PROPERTY(int phoneNumber READ phoneNumber WRITE setPhoneNumber)
  Q_PROPERTY(Gender gender READ gender WRITE setGender)
  Q_PROPERTY(QDate dob READ dob WRITE setDob)
  Q_ENUMS(Gender)

  public:
    Person(QObject* parent = 0);
    ~Person();
    QString name() const;
    void setName(const QString& name);
    int phoneNumber() const;
    void setPhoneNumber(const int  phoneNumber);
    enum Gender {Male, Female};
    void setGender(Gender gender);
    Gender gender() const;
    QDate dob() const;
    void setDob(const QDate& dob);
  private:
    QString m_name;
    int m_phoneNumber;
    Gender m_gender;
    QDate m_dob;
};

From QObject to JSON

The following code will serialize an instance of Person to JSON :

[From QObject to JSON] [ ]
1
2
3
4
5
6
7
8
Person person;
person.setName("Flavio");
person.setPhoneNumber(123456);
person.setGender(Person::Male);
person.setDob(QDate(1982, 7, 12));
QVariantMap variant = QObjectHelper::qobject2qvariant(&person;);
Serializer serializer;
qDebug() << serializer.serialize( variant);

The generated output will be:

[JSON data] [ ]
1
{ "dob" : "1982-07-12", "gender" : 0, "name" : "Flavio", "phoneNumber" : 123456 }

From JSON to QObject

Suppose you have the following JSON data stored into a QString:

[JSON data] [ ]
1
{ "dob" : "1982-07-12", "gender" : 0, "name" : "Flavio", "phoneNumber" : 123456 }

The following code will initialize an already allocated instance of Person using the JSON values:

[From JSON to QObject] [ ]
1
2
3
4
Parser parser;
QVariant variant = parser.parse(json);
Person person;
QObjectHelper::qvariant2qobject(variant.toMap(), &person;);

A new release

These changes have been included inside the new release of QJson: 0.7.0.

Packages for openSUSE are building right now.

QJson: Easier Serialization of QObject Instances to JSON

| Comments

I have just committed into trunk a couple of changes that make easier to serialize a QObject instance to JSON.

This solution relies on the awesome Qt’s property system.

Suppose the declaration of Person class looks like this:

[class definition] [ ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Person : public QObject
{
  Q_OBJECT
    Q_PROPERTY(QString name READ name WRITE setName)
    Q_PROPERTY(int phoneNumber READ phoneNumber WRITE setPhoneNumber)
    Q_PROPERTY(Gender gender READ gender WRITE setGender)
    Q_PROPERTY(QDate dob READ dob WRITE setDob)
    Q_ENUMS(Gender)
  public:
    Person(QObject* parent = 0);
    ~Person();
    QString name() const;
    void setName(const QString& name);
    int phoneNumber() const;
    void setPhoneNumber(const int  phoneNumber);
    enum Gender {Male, Female};
    void setGender(Gender gender);
    Gender gender() const;
    QDate dob() const;
    void setDob(const QDate& dob);
  private:
    QString m_name;
    int m_phoneNumber;
    Gender m_gender;
    QDate m_dob;
};

The following code will serialize an instance of Person to JSON:

[Serialize to JSON] [ ]
1
2
3
4
5
6
7
    Person person;
    person.setName("Flavio");
    person.setPhoneNumber(123456);
    person.setGender(Person::Male);
    person.setDob(QDate(1982, 7, 12));
    Serializer serializer;
    qDebug() << serializer.serialize( &person;);

The generated output will be:

[JSON data] [ ]
1
    { "dob" : "1982-07-12", "gender" : 0, "name" : "Flavio", "phoneNumber" : 123456 }

I hope you will find this new feature useful. I’m also considering to create a similar method inside the Parser class.

As usual suggestions are welcome.

Kaveau Updates

| Comments

Some weeks have passed since the announcement of kaveau. I’m really proud and happy about this project because I received a lot of positive feedback messages and it has been chosen as one of the best Hackweek’s projects.

In the meantime I kept working on kaveau, so let me show you what has changed:

  • rdiff-backup has been replaced by rsync.
  • the setup wizard has been improved according to the feedback messages I received.
  • old backups are now automatically removed.
  • the code has been refactored a lot.

The switch to rsync

Previously kaveau used rdiff-backup as backup back-end. rdiff-backup is a great program but unfortunately it relies on the outdated librsync library. The latest release of librsync is dated 2004. It has a couple of serious bugs still open and, while rsync has reached version three, this library is still stuck at version one.

These are the reasons of the switch from rdiff-backup to rsync. This choice breaks the compatibility with the previous backups but it introduces a lot of advantages. One of the most important improvements brought by the adoption of rsync is an easier restore procedure: now all the backups can be accessed using a standard file manager, while previously rdiff-backup was needed to access the old backups.

Backup directory structure

On the backup device everything is saved under the kaveau/hostname/username path.

The directory will have a similar structure:

drwxr-xr-x 3 flavio users 4096 2009-09-12 18:50 2009-09-12T18:50:19
drwxr-xr-x 3 flavio users 4096 2009-09-14 23:07 2009-09-14T23:07:46
drwxr-xr-x 3 flavio users 4096 2009-09-14 23:30 2009-09-14T23:30:36
lrwxrwxrwx 1 flavio users   19 2009-09-14 23:30 current -> 2009-09-14T23:30:36

As you can see there’s one directory per backup, plus a symlink called current pointing to the latest backup.

Old backup deletion

Nowadays big external storage devices are pretty cheap, but it’s always good to save some disk space. Now kaveau keeps:

  • hourly backups for the past 24 hours.
  • daily backups for the past month.
  • weekly backups until the external disk is full. Thanks to hard links’ magic, old backups can be deleted without causing damages to the other ones.

Plans for the future

Before starting to work on the restore user interface I will spend some time figuring out how to add support for network devices.

A lot of users requested this feature, hence I want to make them happy :) .

I’m planning to use avahi to discover network shares (nfs, samba) or network machines running ssh and use them as backup devices. Honestly, I want to achieve something similar to Apple’s time capsule.

As usual, feedback messages are really appreciated.

Using QJson Under Windows

| Comments

Recently lots of people asked me how to build QJson under Windows. Most of them reported build/link errors, so I decided to try personally.

The good news is that QJson can be successfully built under Window, I can show you proof ;)

I have written the build instructions on QJson website: just take a look here.

One last note: if you have problems with QJson please subscribe to the developer mailing list and post a message.