Permalink
Browse files

Added hook support

git-svn-id: http://rspec-ext.rubyforge.org/svn/distributed/trunk@8 b9fc4567-813f-4f01-94b2-355dee807878
  • Loading branch information...
1 parent cbf405c commit f62d752d3a3c31bc3fe450ba89240cae34923b11 @aslakhellesoy committed Sep 14, 2007
View
@@ -3,11 +3,11 @@ License.txt
Manifest.txt
README.txt
Rakefile
-examples/first_spec.rb
-examples/fourth_spec.rb
-examples/second_spec.rb
-examples/third_spec.rb
+examples/slooow_examples.rb
lib/spec/distributed.rb
+lib/spec/distributed/hooks.rb
+lib/spec/distributed/hooks/master_detect_svn_rev.rb
+lib/spec/distributed/hooks/slave_update_svn.rb
lib/spec/distributed/master_runner.rb
lib/spec/distributed/rinda_master_runner.rb
lib/spec/distributed/rinda_slave_runner.rb
@@ -17,6 +17,7 @@ lib/spec/distributed/version.rb
scripts/txt2html
setup.rb
spec/spec.opts
+spec/spec/distributed/hooks_spec.rb
spec/spec/distributed/rinda_master_runner_spec.rb
spec/spec/distributed/rinda_slave_runner_spec.rb
spec/spec/distributed/tuple_args_spec.rb
View
@@ -131,3 +131,34 @@ Rake::Task['default'].send :instance_variable_set, "@prerequisites", FileList[]
desc "Default task is to run specs"
task :default => :spec
+namespace :example do
+ desc "Run examples the plain way"
+ Spec::Rake::SpecTask.new('plain') do |t|
+ t.spec_files = FileList['examples/**/*.rb']
+ t.spec_opts = [
+ '--color', '--diff'
+ ]
+ end
+
+ desc "Run a slave for examples"
+ Spec::Rake::SpecTask.new('slave') do |t|
+ t.spec_files = FileList['examples/**/*.rb']
+ t.spec_opts = [
+ '--color', '--diff',
+ '--require', 'rubygems,spec/distributed,spec/distributed/hooks/slave_update_svn',
+ '--runner', 'Spec::Distributed::RindaSlaveRunner'
+ ]
+ t.libs = ['lib'] # This line is not necessary if you have Spec::Distributes installed as a gem
+ end
+
+ desc "Run a master for examples"
+ Spec::Rake::SpecTask.new('master') do |t|
+ t.spec_files = FileList['examples/**/*.rb']
+ t.spec_opts = [
+ '--color', '--diff',
+ '--require', 'rubygems,spec/distributed,spec/distributed/hooks/master_detect_svn_rev',
+ '--runner', 'Spec::Distributed::RindaMasterRunner'
+ ]
+ t.libs = ['lib'] # This line is not necessary if you have Spec::Distributes installed as a gem
+ end
+end
View
@@ -1,9 +0,0 @@
-describe "first" do
- it "example a" do
- sleep 1
- end
-
- it "example b" do
- sleep 1
- end
-end
View
@@ -1,14 +0,0 @@
-describe "fourth" do
- it "example g" do
- sleep 1
- end
-
- it "example h" do
- sleep 0.5
- 1.should == 2
- end
-
- it "example i" do
- sleep 0.5
- end
-end
View
@@ -1,10 +0,0 @@
-describe "second" do
- it "example c" do
- sleep 1
- raise "error"
- end
-
- it "example d" do
- sleep 1
- end
-end
@@ -0,0 +1,45 @@
+describe "first" do
+ it "example a" do
+ sleep 1
+ end
+
+ it "example b" do
+ sleep 1
+ end
+end
+
+describe "second" do
+ it "example c" do
+ sleep 1
+ raise "error"
+ end
+
+ it "example d" do
+ sleep 1
+ end
+end
+
+describe "third" do
+ it "example e" do
+ sleep 1
+ end
+
+ it "example f" do
+ sleep 1
+ end
+end
+
+describe "fourth" do
+ it "example g" do
+ sleep 1
+ end
+
+ it "example h" do
+ sleep 0.5
+ 1.should == 2
+ end
+
+ it "example i" do
+ sleep 0.5
+ end
+end
View
@@ -1,9 +0,0 @@
-describe "third" do
- it "example e" do
- sleep 1
- end
-
- it "example f" do
- sleep 1
- end
-end
View
@@ -1,4 +1,5 @@
require 'spec/distributed/version'
+require 'spec/distributed/hooks'
require 'spec/distributed/master_runner'
require 'spec/distributed/slave_runner'
require 'spec/distributed/tuple_args'
@@ -0,0 +1,22 @@
+module Spec
+ module Distributed
+ class Hooks
+ class << self
+ def hooks
+ @hooks ||= []
+ end
+
+ def add_hook(&hook)
+ hooks << hook
+ end
+
+ def run_hooks(hash)
+ hooks.each do |hook|
+ hook.call(hash)
+ end
+ hash
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,15 @@
+module Spec
+ module Distributed
+ module Hooks
+ module Master
+ # This master hook detects local svn rev. It should be
+ # used in conjuction with Spec::Distributed::Hooks::Slave::UpdateSvn
+ module DetectSvnRev
+ Spec::Distributed::Hooks.add_hook do |slave_opts|
+ slave_opts[:master_svn_rev] = `svn info`.match(/Revision: (\d+)/m)[1]
+ end
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,39 @@
+module Spec
+ module Distributed
+ module Hooks
+ module Slave
+ # This slave hook updates svn working copy to a given revision.
+ # It should be used in conjuction with Spec::Distributed::Hooks::Master::DetectSvnRev
+ #
+ # It's smart enough to walk up the directory tree and update from the root.
+ class UpdateSvn
+ def update_wc(svn_rev)
+ Dir.chdir(top_svn_dir) do
+ local_rev = `svn info`.match(/^Revision: (\d+)$/n)[1]
+ if(local_rev.to_i != svn_rev.to_i)
+ system("svn up -r#{svn_rev}")
+ end
+ end
+ end
+
+ def top_svn_dir
+ dir = '.'
+ loop do
+ up = File.join(dir, '..')
+ if File.directory?(File.join(up, '.svn'))
+ dir = up
+ else
+ break
+ end
+ end
+ dir
+ end
+
+ Spec::Distributed::Hooks.add_hook do |slave_opts|
+ UpdateSvn.new.update_wc(slave_opts[:master_svn_rev])
+ end
+ end
+ end
+ end
+ end
+end
@@ -3,8 +3,8 @@
module Spec
module Distributed
- class MasterRunner < ::Spec::Runner::BehaviourRunner
- def initialize(options, args=nil)
+ class MasterRunner < ::Spec::Runner::BehaviourRunner
+ def initialize(options, args="")
super(options)
process_args(args)
end
@@ -16,8 +16,6 @@ def process_args(args)
def run(paths, exit_when_done)
@master_paths = paths
- @svn_rev = `svn info`.match(/Revision: (\d+)/m)[1] rescue nil
- STDERR.puts "WARNING - no local svn revision found. Your slaves may be out of sync." if @svn_rev.nil?
super(paths, exit_when_done)
end
@@ -27,9 +25,15 @@ def run_behaviours
index_queue = Queue.new
@behaviours.length.times {|index| index_queue << index}
+ # The master can do some prep work before starting slaves.
+ # It can also send some values (typically related to its prep work)
+ # to the slaves.
+ #
+ # A typical example is to detect local svn rev and send it to the slaves.
+ slave_opts = Hooks.run_hooks({})
@threads = slave_runners.map do |slave_runner|
Thread.new do
- slave_runner.prepare_run(@master_paths, @svn_rev)
+ slave_runner.prepare_run(@master_paths, slave_opts)
drb_error = nil
while !index_queue.empty?
begin
@@ -11,7 +11,7 @@ def process_args(args)
end
def run(paths, exit_when_done)
- start_or_find_ring_server
+ find_or_start_ring_server
register_self
@started = true
DRb.thread.join
@@ -24,10 +24,10 @@ def report_dump
register_self
end
- def start_or_find_ring_server
- DRb.start_service
- @url = DRb.uri.to_s
+ def find_or_start_ring_server
begin
+ DRb.start_service
+ @url = DRb.uri.to_s
puts "Looking for Ring server..."
@ring_server = Rinda::RingFinger.new
@service_ts = @ring_server.lookup_ring_any(2)
@@ -1,6 +1,6 @@
module Spec
module Distributed
- class SlaveRunner < ::Spec::Runner::BehaviourRunner
+ class SlaveRunner < ::Spec::Runner::BehaviourRunner
def initialize(options, args=nil)
super(options)
process_args(args)
@@ -19,9 +19,11 @@ def run(paths, exit_when_done)
end
# This is called by the master over DRb.
- def prepare_run(master_paths, master_svn_rev)
+ # The +hook_opts+ argument is a Hash that is
+ # populated by master's hook(s)
+ def prepare_run(master_paths, hook_opts)
begin
- update_wc(master_svn_rev)
+ Hooks.run_hooks(hook_opts)
prepare!(master_paths)
rescue => e
STDERR.puts e.message
@@ -55,29 +57,6 @@ def report_dump
puts "=" * 70
end
- def update_wc(master_svn_rev)
- Dir.chdir(top_svn_dir) do
- local_rev = `svn info`.match(/^Revision: (\d+)$/n)[1] rescue nil
- raise "This is not a svn working copy, but the master is (r#{master_svn_rev})" if master_svn_rev && local_rev.nil?
- if(local_rev.to_i != master_svn_rev.to_i)
- system("svn up -r#{master_svn_rev}")
- end
- end
- end
-
- def top_svn_dir
- dir = '.'
- loop do
- up = File.join(dir, '..')
- if File.directory?(File.join(up, '.svn'))
- dir = up
- else
- break
- end
- end
- dir
- end
-
def slave_watermark
@url
end
@@ -0,0 +1,23 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
+module Spec
+ module Distributed
+ describe Hooks do
+ before(:each) do
+ options = mock('options', :null_object => true)
+ @r = MasterRunner.new(options, "foo")
+ end
+
+ it "should register and run hooks" do
+ Hooks.add_hook do |slave_opts|
+ slave_opts[:foo] = :bar
+ end
+ Hooks.add_hook do |slave_opts|
+ slave_opts[:snip] = :snap
+ end
+ hash = Hooks.run_hooks({})
+ hash.should == {:foo => :bar, :snip => :snap}
+ end
+ end
+ end
+end
Oops, something went wrong.

0 comments on commit f62d752

Please sign in to comment.