Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Tools
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Monthly Archives: January 2008

Chad Woolley

Standup 01/15/2008

Chad Woolley
Wednesday, January 16, 2008

Ask for Help

  • “Can you use Google Maps on an https page?”
    • Probably via an iframe. Is there a preferred way?
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Standup 01/14/2008

Pivotal Labs
Monday, January 14, 2008

Interesting Things

  • Thin is a new webserver that we haven’t tried yet, but we’re interested in. It’s billed as being faster than Mongrel; it uses the Mongrel parsing engine, Event Machine for I/O, and Rack to interface between server and Ruby framework. Because it uses Rack, it may have problems doing streaming. Anyone have experiences with it to report?
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Java Functional Testing with JRuby and RSpec

Pivotal Labs
Sunday, January 13, 2008

One of our client Java projects is pioneering the use of RSpec Story Framework for functional tests.

Overview

RSpec provides two frameworks for writing and executing examples of how your application should behave:

  • a Story Framework for describing behaviour at the application level
  • a Spec Framework for describing behaviour at the object level

JRuby is an 100% pure-Java implementation of the Ruby programming language.

How can Java projects benefit from RSpec Story Framework? Let’s consider an example.

Example

There is a Java back-end application server with proprietary remote interface. The server manages current states of all patents reviewed by multiple patent offices. Close to real life examples below have no proprietary information and object names has been changed. RSpec can help describe how server works and should be used, also what happens in special conditions.

stories/councilReview.txt

one of stories from the server specification:

Story: patent review by counsel

  A Council review of a patent should change the patent review state
  and affect rolled up state of the patent application case.

   Scenario: legal counsel reviews patent
    Given a patent
    And the patent roll up state is ACTIVE
    When the legal council reviews the patent
    Then patent state should be ON_HOLD
    And patent case rolled up state should be SUSPENDED

   Scenario: legal counsel releases patent from the review bin
    Given a patent
    And the patent roll up state is ON_HOLD
    When the legal council release the patent from the review bin
    Then the patent state should be ACTIVE
    And the patent case rolled up state should be ACTIVE

How it works with Java

steps/patentstateoperations.rb

Steps define our Domain Specific Language or DSL

steps_for(:patent_state_operations) do

 Given "a patent" do
   $patent_state_action_stub = PatentStateActionManager.new("local")
   $patent_id = Random.new
  end

 Given "the patent roll up state is '$state'" do |state|
   patent_state_action_stub.setState(patent_id, state);
 end

 When "a '$reviewer' releases the patent from the review bin" do |type|
    newState = patent_state_action_stub.releaseFromBin(patent_id, reviewer);
 end

 When "a '$reviewer' reviews the patent" do |type|
    newState = patent_state_action_stub.addToBin(patent_id, reviewer);
 end

 Then "patent state should be '$state'" do |state|
   newState.should be state
 end
end

helpers/helper.rb

loads required Java classes using JRuby:

 require 'rubygems'
 require 'spec'
 require 'spec/story'
 require 'java'

 include_class 'client.project.functionaltests.PatentStateActionManager'

 class Spec::Story::Runner::ScenarioRunner
   def initialize
    @listeners = []
  end
end

Dir[File.dirname(__FILE__) + "/../steps/*.rb"].uniq.each { |file| require file }

all.rb

JRuby runs all the stories for the project:

 dir = File.expand_path(File.dirname(__FILE__))
 require "#{dir}/helpers/helper"

 with_steps_for :patent_state_operations do
   run "#{dir}/stories/councilReview.txt"
 end

And since we are on Java Project developers use the above Ruby steps to delegate most of the calls to some Java manager, which serves as a fixture for the functional tests.

PatentStateActionManager.java

This is a Java fixture to pass data to the application via RPC

 public class PatentStateActionManager {

  public PatentStateActionManager(String instanceType) {
  ... // get connection to server via RPC
  }

  public String addToBin(long patentId, String review) {
  ... // call RPC method
  }

  public String releaseFromBin(long patentId, String review) {
  ... // another RPC call
  }

  public void setState(long patentId, String newState) {
  ... // java land, Java developers do what they want
  }
}

Results

As a result we have a executable text specification described in close to English language. Majority of the boiler-plate code contained in Java fixtures and Ruby steps.

Project Managers and Quality Engineers can use RSpec stories to define and exercise the behavior of the application.

Java Developers implemented a few stories to demonstrate the use of all steps for Quality Engineers. In addition to Java unit tests that cover the project code, functional tests cover the application use cases.

Next steps

Quality Engineers will fill the story book with more stories covering many conditions and states.

Java Developers will provide support for fixtures as interfaces evolves over the time.

Customers will define future stories as Pending stories.

And Test Valentines are moving to wider adoption of RSpec including:

  • continuous build integration
  • test results publishing
  • common steps for widely used interfaces:
    • Remote Control of Web apps using Selenium-RC
    • Command line and shell
  • interactive console introduction
  • functional point coverage
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Standup 2008-01-11

Pivotal Labs
Saturday, January 12, 2008

Interesting Things

  • We’ve started to run across this in one of our projects: Javascript DOM methods can be a nice way to create a DOM tree (with some practice, you can write clear, reusable JS UI components), but it’s slow. You probably won’t notice it if you’re only creating a few DOM nodes, but if you’re drawing thousands of them then it can turn into a performance bottleneck. The generally-accepted solution is to push a bunch of strings into an array, use Array#join(”") to create a single string, then stick it in an element’s innerHTML. Quirksmode has some numbers and Joseph Smarr has a related presentation.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

what to do with vtophys()

Pivotal Labs
Friday, January 11, 2008

outside of work, I do some things with OpenBSD. Over the last month or so, I’ve been poking at the DRI code, mostly to make it compile on my laptop. Why is it taking so long? I don’t know C, and are learning on the fly. Kernel space makes it interesting.

One problem with compiling: the code uses ‘vtophys()’, which is not portable. My laptop is running in AMD64 mode, which doesn’t have vtophys(). The solution: ‘bus_space_vaddr()’. it essentially is a drop-in replacement for vtophys(), but I have to set up the bus_space area first. Thats proving to be a little more of a challenge than I hoped. I think I’ll have to edit the headers, and add (yuck) some entries into a struct, so I can pass around the appropriate information.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

It Ain't Official, It Ain't Blabs… It's Everyone!

Joe Moore
Friday, January 11, 2008

Howdy, everyone! Don’t you hate it when one of your favorite Pivots blogs a non-official, non-blabs article about tea and you didn’t even know about it? It’s just too much effort to subscribe to everyone’s blog individually.

Fret no more! Now you can read and subscribe to every blog post with one easy URL: the All Pivots Blog. Just navigate to http://pivots.pivotallabs.com /everyone. You’ll see all Official, Blabs, and individual posts in chronological order.

A couple of points:

  • Exposing the All Pivots Blog reinforces the fact that all posts are public.
  • There are no links directly to the All Pivots Blog — you “just have to know”. We still want to drive traffic to the Official Blog and Pivotal Blabs; the All Pivots Blog is mostly for us Pivots, which is why I have not put a working link in this post.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Standup 2008-01-09

Pivotal Labs
Wednesday, January 9, 2008

Desert Fixes

Desert has been upgraded to work with Rails 2, solving problems with ActionMailer templates and Rails load paths.

Nested Describes in RSpec

A reminder: RSpec supports nested describe blocks. This can be useful for sharing setup and also for organization (one describe per method being tested, with multiple it blocks). Some people reported that there are some issues when using nested describe blocks with fixture scenarios. There was also a report of some flakiness around a single it block being run more than once.

Yay NetBeans

One of our projects has reported that they have been using NetBeans and are happy with it.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Chad Woolley

ruby-debug in 30 seconds (we don't need no stinkin' GUI!)

Chad Woolley
Tuesday, January 8, 2008


Alfonso Bedoya, Treasure of the Sierra Madre

Many people (including me) have complained about the lack of a good GUI debugger for Ruby. Now that some are finally getting usable, I’ve found I actually prefer IRB-style ruby-debug to a GUI.

There’s good tutorial links on the ruby-debug homepage, and a very good Cheat sheet, but I wanted to give a bare-bones HOWTO to help you get immediately productive with ruby-debug.

Install the latest gem

$ gem install ruby-debug

Install the cheatsheet

$ gem install cheat
$ cheat rdebug

Set autolist, autoeval, and autoreload as defaults

$ vi ~/.rdebugrc
set autolist
set autoeval
set autoreload

Run Rails (or other app) via rdebug

$ rdebug script/server

Breakpoint from rdebug

(rdb:1) b app/controllers/my_controller.rb:10

Breakpoint in source

require 'ruby-debug'
debugger
my_buggy_method('foo')

Catchpoint

(rdb:1) cat RuntimeError

Continue to breakpoint

(rdb:1) c

Next Line (Step Over)

(rdb:1) n

Step Into

(rdb:1) s

Continue

(rdb:1) c

Where (Display Frame / Call Stack)

(rdb:1) where

List current line

(rdb:1) l=

Evaluate any var or expression

(rdb:1) myvar.class

Modify a var

(rdb:1) @myvar = 'foo'

Help

(rdb:1) h

There are many other commands, but these are the basics you need to poke around. Check the Cheat sheet for details.

This can also be used directly from any IDE that supports input into a running console (such as Intellij Idea).

That should get you started. So, before you stick in another ‘p’ to debug, try out ruby-debug instead!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Prototype, Ajax, Firefox, Caching

Pivotal Labs
Saturday, January 5, 2008

By default, Ajax.Updater will send a POST request to whatever URL is specified. That’s fine, and it prevents certain browser caching issues, but it won’t play well with Rails’ resource routes. Rails will map POST requests to the create controller action, which is not always desirable.

For example, let’s say we have an Ajax.Updater that refreshes a list of posts (GET /posts). Unfortunately, the request that is created by default will be different (POST /posts). You can force the GET method, like so

remote_function(:update => "posts_container",
:url => posts_path, :method => :get))

One problem remains, however. If the URL for the remote_function and the URL for the full (html) version of the resource are the same, as they probably ought to be, and if the Ajax call is a GET request, Firefox will cache the data returned by the remote_function call as the most recent version of the page /posts. When a user navigates away from /posts, and subsequently decides to return to /posts by hitting the back button, the remote_function data will be displayed (as opposed to the full html version of the page). That’s not very user-friendly.

To avoid this, one will need to set the appropriate header:

headers["Cache-Control"] = "no-store"

Interestingly enough, IE7 appears to deal with this situation correctly.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Chad Woolley

The Power of Versions (Monkey Patches Targeted with Friggin Laser Beams!)

Chad Woolley
Friday, January 4, 2008

We all love to Monkey Patch Rails and other Ruby apps. However, we sometimes want to target these patches to the specific versions where they are needed.

Here’s the easiest way to do this, via RubyGem’s built-in version requirement support. The version 0.11.0 should indeed be greater than version 0.9.0:

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> Gem::Version::Requirement.new(['> 0.9.0']).satisfied_by?(Gem::Version.new('0.11.0'))
=> true

Notice that you can’t do this with string comparison, because with a per-character comparison,1 is not greater than 9:

irb(main):001:0> '0.11.0' > '0.9.0'
=> false

Here’s a little class which puts some helper and example methods around this approach (these methods are all in real use for some of our multipart mailer hacks):

module Pivotal
  class VersionChecker
    def self.current_rails_version_matches?(version_requirement)
      version_matches?(Rails::VERSION::STRING, version_requirement)
    end

    def self.version_matches?(version, version_requirement)
      Gem::Version::Requirement.new([version_requirement]).satisfied_by?(Gem::Version.new(version))
    end

    def self.rails_version_is_below_2?
      result = Pivotal::VersionChecker.current_rails_version_matches?('<1.99.0')
      result
    end

    def self.rails_version_is_below_rc2?
      Pivotal::VersionChecker.current_rails_version_matches?('<1.99.1')
    end

    def self.rails_version_is_1991?
      Pivotal::VersionChecker.current_rails_version_matches?('=1.99.1')
    end
  end
end

(note: some angle brackets changed due to code formatting bug)

Here’s an example of how you’d use this:

if Pivotal::VersionChecker.rails_version_is_below_2?
  # do some backward compatibility stuff
  # or handle bugs that have been fixed in Rails > 2
end

Note that this is only possible now that Rails has started using a more sensible strategy for versioning edge gems and improved support for using advanced versioning with RAILS_GEM_VERSION.

For many projects, this may be overkill. It is useful at Pivotal, though, where many various projects may be on different rails versions, but still want to use the latest common core libraries (and monkey patches) without having to upgrade Rails for their app.

This isn’t only useful for monkey patching. It can be handy for any library that wants to be backward- or forward-compatible with its dependencies. I’ve used this approach at Pivotal and on my personal projects to have Continuous Integration automatically run my tests against multiple dependency versions, without having to change anything other than the CI project name:


'GemInstaller Continuous Integration automatically running against multiple versions of RubyGems'

There are numerous other related topics for discussion in this area, such as the power of versions or the wisdom of freezing, but I’ll save those for future posts. Even if you do freeze the trunk of Rails/plugins/gems, since the version is included in the source, this approach should work barring any conflicts with trunk changes since the last release.

Happy Versioning!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (783)
  • rails (117)
  • testing (90)
  • ruby (86)
  • ruby on rails (71)
  • jobs (62)
  • javascript (59)
  • techtalk (44)
  • ironblogger (42)
  • rspec (39)
  • bloggerdome (34)
  • productivity (34)
  • activerecord (30)
  • rubymine (30)
  • git (29)
  • gogaruco (29)
  • nyc (27)
  • design (24)
  • mobile (23)
  • pivotal tracker (22)
  • process (21)
  • cucumber (21)
  • jasmine (19)
  • ios (18)
  • tracker ecosystem (17)
  • webos (17)
  • objective-c (17)
  • fun (16)
  • android (16)
  • palm (16)
  • ci (16)
  • "soft" ware (16)
  • bdd (15)
  • tdd (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • css (14)
  • gem (13)
  • mouse-free development (12)
  • selenium (12)
  • goruco (12)
  • bundler (12)
  • api (12)
  • keyboard (11)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
Subscribe to Community Feed
  1. ←
  2. 1
  3. 2
  4. 3
  5. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Tools
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >