Idol Hands:
Days in the Life of an Alpha Geek

Corey Ehmke’s home on the web since 1996, IdolHands.com is an alpha-geek blog covering topics in Ruby on Rails development, Mac OS X, electronics, robotics, and other stuff important in the life of a technologist and tinkerer.

Tweetie Upgrade Message

Posted by Corey Ehmke on October 1st, 2009 in General Tech & Development | Permanent Link | Share/Save

How can anyone begrudge this guy $3 for the imminent 2.0 upgrade?

tweetie_upgrade.png

Tracking Down Slow-Running Examples in RSpec

Posted by Corey Ehmke on September 9th, 2009 in Ruby on Rails | Permanent Link | Share/Save

As the number of tests goes up in your Rails project, you’ll find yourself spending more and more time staring at the field of green dots waiting for the RSpec to finish.

You may notice some pauses, and be tempted to tail the test log file to figure out what’s slowing things down, but thankfully there’s a better way.

Profiling All Examples

Passing the --profile flag to RSpec produces some additional output, namely the running times of the ten slowest examples in your specs. So this:

spec -p spec/*/*_spec.rb --colour --format profile

Produces this output in Terminal:

Profiling enabled.
........................................................................
........................................................................
........................................................................
........................................................................
........................................................................
........................................................................
........................................................................
........................................................................
........................................................................
........................................................................
........................................................................
........................................................................
..................................................................*.....
........................................................................
...............*........................................................
........................................................................
........................................................................
........................................................................
.............................................................

Top 10 slowest examples: 
4.3889370 TemplatesController GET index lists templates admins
4.1541390 TemplatesController DELETE destroy with invalid params redirects to 404
0.7026320 FaqsController GET index lists all faqs for clients
0.6740070 FaqsController DELETE destroy with invalid params redirects admins to 404
0.6539990 FaqsController GET index lists all faqs for admins
0.6461050 FaqsController DELETE destroy with invalid params redirects clients to 404
0.4606460 SiteSection updates its site pages' URLs if its root_url changes
0.3915220 SitePage navigation items navbar items defaults link text
0.3357780 SitePage root page identifies root pages
0.3300710 SitePage url generation generates a url for a child page

Finished in 56.601493 seconds

1357 examples, 0 failures, 2 pending

This gives us a good place to start: based on the total number of examples (in this case, 1357) and the total running time (56.601493), the average example takes around .04 seconds to run. The slow examples that RSpec shows above range from almost 10 to over 100 times slower than the average, and definitely warrant investigation.

Profiling Specific Examples

Once you’ve eliminated the most egregious bottlenecks in your examples, the big performance gains in your overall tests are behind you. But fractions of seconds add up, and you can squeeze out a little more time by narrowing your focus.

You can get more granular results by pointing RSpec at a subset of specs, changing the pattern that you pass in to target specific sets of tests. For example, to find the slowest examples in your controller specs:

spec -p spec/controllers/*_spec.rb --colour --format profile

You can even limit it to examples in a single spec file (notice the omission of the -p flag):

spec spec/controllers/faqs_controller_spec.rb --colour --format profile

Make Profiling Examples Part of Your Routine

If you’re using autospec or rake:spec to run your examples, you can add support for the profiler to your settings in spec/spec.opts by replacing the format’s progress option with profile:

--colour
--loadby mtime
--reverse
--format profile

Alternatively, you can write the profiling information to a file instead by providing a relative path and filename. (Caveat: don’t write this file inside the spec folder, or you’ll find that RSpec’s modification trigger will kick in after it’s written, causing another run of your examples.)

--colour
--format progress
--loadby mtime
--reverse
--format profile:doc/profile.txt

At the time of this writing, there’s a bug in RSpec that causes the profile file output to become garbled if you have enabled color output using the colour flag. A fix has been submitted, but it’s not available in the core yet.

Testing Speed Counts

If you let your tests get too slow, you’ll end up testing less frequently than you should, a path which either leads to hell or one of its suburbs. Keeping your examples lean and fast, and refactoring when you need to, ensures that you get the most out of TDD and keep up your good habits.

I upgraded to Snow Leopard (Mac OS X 10.6) this week. Aside from some problems getting ImageMagick working, everything’s been pretty smooth.

A lot has been made of the fact that the Snow Leopard upgrade is less about new features and more about enhancements to what OS X already has to offer. That being said, there’s a lot to like about the new OS, aside from the modest speed bumps. Here’s a list of some of my favorites.

500x_Karl_Eastwood.jpg

Image from Gizmodo’s
Snow Leopard Box Redesign Gallery

Gestures

  • Swipe the trackpad left or right with four fingers to invoke application switcher
  • Swipe the trackpad up with four fingers to reveal the desktop. Swipe down again to restore your windows.
  • Swipe the trackpad up with four fingers to invoke Exposé
  • Resize icons in the Finder and on the Desktop with pinch/unpinch gestures

Menu Bar Widgets

  • Option-click the Airport icon in the menu bar for details on your wireless network
  • Option-click the speaker icon in the menu bar for audio options
  • Option-click the battery icon in the menu bar for battery stats and condition
  • You can set a preference for displaying the full date in the menu bar

Other Enhancements

  • Click and hold an application icon in the dock to see all of its open windows
  • Right click / option click an item in the trash to ‘put it back’ where it was before you threw it away
  • The play button on keyboard launches iTunes
  • Built-in data detectors now support flight numbers. This means that if there’s a flight number in an email, for example, you can click it and be presented a contextual menu that includes tracking the flight in Dashboard.

Did I miss anything cool? Leave a comment below.

If you’re following the instructions on the Ruby on Rails blog for upgrading to Snow Leopard, you should notice that one of the recommended steps is installing the 64-bit version of MySQL. What the article fails to mention is that there are a couple of clean-up steps that you should do, and that you will also need to restore your old data directory or risk losing your development databases.

The tips below assume that you’ve already downloaded and installed MySQL for OS X 10.5, 64-bit.

1. Shut down MySQL

If you installed MySQL using MacPorts, type this in Terminal to stop the MySQL daemon:

sudo /opt/local/share/mysql5/mysql/mysql.server stop

Otherwise, if you used the installer from mysql.com, go to Apple Menu > System Preferences and click on the MySQL preference pane. You’ll get a message stating that System Preferences has to restart; this is because the preference pane is a 32-bit app, and System Preferences is now a 64-bit app.

To use the 'MySQL' preferences pane, System Preferences must quit and reopen.

You’re going to get tired of restarting System Preferences, so I recommend that you go download the replacement pref pane from swoon dot net. Go ahead, I’ll wait.

When you’re all set, make sure that MySQL is not running. For a sanity check, fire up Applications > Utilities > Activity Monitor and search for ’sql’:

Activity Monitor showing MySQL daemon running

If you shut down MySQL correctly, you should not see the mysqld process running.

2. Locate your old data directory

Terminal is your friend:

Cerberus:~ bantik$ cd /usr/local
Cerberus:local bantik$ ls -al
total 7
drwxr-xr-x 16 root wheel 544 Sep 2 21:38 .
drwxr-xr-x@ 12 root wheel 408 Sep 2 21:20 ..
drwxr-xr-x 3 root wheel 102 Sep 2 20:52 OpenSourceLicenses
drwxr-xr-x 3 root wheel 102 Sep 2 20:52 OpenSourceVersions
drwxr-xr-x 36 root wheel 1224 Sep 2 20:52 bin
drwxr-xr-x 4 root wheel 136 Sep 2 20:52 etc
drwxr-xr-x 9 root wheel 306 Sep 2 20:52 git
drwxr-xr-x 5 root wheel 170 Sep 2 20:52 include
drwxr-xr-x 42 root wheel 1428 Sep 2 20:52 lib
drwxr-xr-x 3 root wheel 102 Sep 2 20:52 man
lrwxr-xr-x 1 root wheel 27 Sep 2 21:38 mysql -> mysql-5.1.37-osx10.5-x86_64
drwxr-xr-x 3 root wheel 102 Sep 2 21:38 mysql-5.0.77-osx10.5-x86
drwxr-xr-x 18 root wheel 612 Sep 2 22:03 mysql-5.1.37-osx10.5-x86_64
drwxr-xr-x 4 root wheel 136 Sep 2 20:52 share
drwxr-xr-x 4 root wheel 136 Sep 2 20:52 src
Cerberus:local bantik$

The new version of MySQL is aliased to /usr/local/mysql, and the old version is still there: in this case, in mysql-5.0.77-osx10.5-x86 (your version number may vary, but just look for the folder with the largest version number that ends with x86). Your data directory with all of your development databases is safely tucked away inside.

3. Copy your old data folder into the new MySQL directory

cd into the folder you located in the step above and then do the following:

sudo cp -R data ../mysql/data_prev

Now cd to the directory where the new version lives, move the (empty) data directory aside, and replace it with your previous version:


cd ../mysql
sudo mv data data_aside
sudo mv data_prev data

You’ll also need to change the owner on the newly moved data directory:

sudo chown -R _mysql:wheel data

4. Restart MySQL

Go back to Apple Menu > System Preferences > MySQL and click the ‘Start MySQL Server’ button. If you see a message like this:

Warning: The /usr/local/mysql/data directory is not owned by the ‘mysql’ or ‘_mysql’ user.’

…then you didn’t correctly change the owner in the previous step.

5. Delete your old MySQL installation(s)

Once you are sure that you’ve recovered your old data (hint: try script/console inside one of your Rails apps and see if your database exists), you can safely remove the old MySQL installation:

sudo rm -rf mysql-5.0.*

That’s it!

Everything should now be right with the world. Go write some code and enjoy the new 64-bit goodness of Ruby, Rails, and MySQL on Snow Leopard.

RCov 0.9.0 Now Available

Posted by Corey Ehmke on August 30th, 2009 in Ruby on Rails | Permanent Link | Share/Save
Tags: , , , , ,

I just spent a couple of hours this afternoon with Aaron from Relevance merging the UI enhancements to RCov into the core project. The merge went well, and the new version is available from http://github.com/relevance/rcov/tree/master.

Changes include:

  • General HTML and CSS cleanup to improve readability
  • Row highlighting
  • Sorting by file name, lines of code, and coverage
  • Ability to filter results by file location (e.g. controllers vs models) and by coverage % (e.g. < 100% coverage)
  • Better output for printing
  • A new color scheme that accommodates users with color blindness
  • Support for custom CSS

For a detailed look at what’s new, including screenshots, see this previous post detailing the HTML and CSS enhancements.

Thanks to jesperronn for some inspiration on the cleanup; he’s got some additional improvements that I’ll be working on implementing soon as well.

Happy testing!