Keep Your Build Fast with a Timebomb

June 27, 2013 Hunter Gillane

The virtues of having a fast build have been well extolled. While there are strategies for speeding up an existing slow build, let’s look at a tool that can help us keep us from getting in that position. We will assume you are using a current version of RSpec to test Ruby code.

Before we look at the code, let’s outline the approach. First, we will add a setting to RSpec’s configuration that specifies how long of a build you want to tolerate. Next, we’ll adds hooks that make sure the build will fail if it takes longer than the time you specify.

spec/support/build_bomb.rb



class BuildBomb

  include Singleton

  attr_accessor :start_time, :fail_after

  def self.setup(rspec_config)
    raise 'Your version of RSpec does not allow settings to be added' unless rspec_config.respond_to?(:add_setting)

    self.add_bomb_settings(rspec_config)
    self.add_bomb_hooks(rspec_config)
  end

  def build_started(fail_after)
    self.start_time = Time.now
    self.fail_after = fail_after
  end

  def build_ended(end_time)
    if build_was_too_slow?(start_time, end_time, fail_after)
      raise BuildBomb::BuildTooSlowException.new('Build was too slow!!!')
    end
  end

  private

  def self.add_bomb_settings(config)
    config.add_setting :fail_after
  end

  def self.add_bomb_hooks(config)
    config.before(:suite) do
      BuildBomb.instance.build_started(config.fail_after)
    end

    config.after(:suite) do
      BuildBomb.instance.build_ended(Time.now)
    end
  end

  def build_was_too_slow?(start_time, end_time, max_time)
    (end_time - start_time) > max_time
  end

  class BuildTooSlowException < RuntimeError;
  end
end

BuildBomb.setup(RSpec.configuration)

Then configure the fail_after setting in your spec helper.

spec/spec_helper.rb


...
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

RSpec.configure do |config|
  ...
  config.fail_after = 60  # seconds to fail you build after
  ...
end


That’s it. With this setting, the build bomb will go off if your build takes longer than 60 seconds.


Hunters-MacBook-Pro:bomber-rails huntergillane$ rspec spec
.

Finished in 60.06 seconds
1 example, 0 failures

Randomized with seed 6736

/Users/huntergillane/workspace/gems/bomber-rails/spec/support/build_bomb.rb:21:in `build_ended': Build was too slow!!! (BuildBomb::BuildTooSlowException)
	from /Users/huntergillane/workspace/gems/bomber-rails/spec/support/build_bomb.rb:37:in `block in add_bomb_hooks'
	from /Users/huntergillane/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rspec-core-2.13.1/lib/rspec/core/example_group.rb:470:in `instance_eval'
	from /Users/huntergillane/.rbenv/versions/1.9.3-p327/lib/ruby/gems/1.9.1/gems/rspec-core-2.13.1/lib/rspec/core/example_group.rb:470:in `instance_eval_with_rescue'
...

Mike Barinek first introduced this on a project I was working on last year and it has since proven to be a useful tool to have. Even if you have an existing slow build, you could use something like this to keep it from getting slower.

About the Author

Biography

More Content by Hunter Gillane
Previous
Deploying a Rails App to CloudFoundry
Deploying a Rails App to CloudFoundry

CloudFoundry has launched a private beta, and if you’re lucky enough to have access to it, you can get free...

Next
5 Key Highlights: A Field Report from #HadoopSummit
5 Key Highlights: A Field Report from #HadoopSummit

In this field report from the Hadoop Summit, we cover community growth, the focus on real-time data, SQL on...

Enter curious. Exit smarter.

Register Now