Permalink
Browse files

remote_job_runner became job_runner. Moved all job running behaviour …

…into job. Hooks are run before jobs

git-svn-id: http://rspec-ext.rubyforge.org/svn/distributed/branches/multi_transport@37 b9fc4567-813f-4f01-94b2-355dee807878
  • Loading branch information...
1 parent e27849f commit 228ecca40d587895967bd3097b4e7a6080e0bf37 @bcotton bcotton committed Feb 5, 2008
View
@@ -3,7 +3,7 @@ License.txt
Manifest.txt
README.txt
Rakefile
-bin/remote_job_runner
+bin/job_runner
examples/slooow_examples.rb
lib/spec/distributed.rb
lib/spec/distributed/example_group_value_holder.rb
@@ -12,11 +12,11 @@ lib/spec/distributed/hooks.rb
lib/spec/distributed/hooks/spec_path_hook.rb
lib/spec/distributed/hooks/svn_update_hooks.rb
lib/spec/distributed/job.rb
+lib/spec/distributed/job_runner.rb
lib/spec/distributed/job_runner_option_parser.rb
lib/spec/distributed/marshaled_delegate.rb
lib/spec/distributed/master_example_group_runner.rb
lib/spec/distributed/recording_reporter.rb
-lib/spec/distributed/remote_job_runner.rb
lib/spec/distributed/remote_job_runner_option_parser.rb
lib/spec/distributed/slave_example_group_runner.rb
lib/spec/distributed/transport_manager.rb
@@ -33,11 +33,11 @@ spec/spec/distributed/example_group_value_holder_spec.rb
spec/spec/distributed/example_value_holder_spec.rb
spec/spec/distributed/hooks_spec.rb
spec/spec/distributed/job_runner_option_parser_spec.rb
+spec/spec/distributed/job_runner_spec.rb
spec/spec/distributed/job_spec.rb
spec/spec/distributed/marshaled_delegate_spec.rb
spec/spec/distributed/master_example_group_runner_spec.rb
spec/spec/distributed/recording_formatter_spec.rb
-spec/spec/distributed/remote_job_runner_spec.rb
spec/spec/distributed/slave_example_group_runner_spec.rb
spec/spec/distributed/transport_manager_spec.rb
spec/spec/distributed/transports/rinda/rinda_connection_spec.rb
@@ -3,5 +3,5 @@ $LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__) + "/../lib"))
require 'spec/distributed'
options = ::Spec::Distributed::JobRunnerOptionParser.parse(ARGV, STDERR, STDOUT)
-exit ::Spec::Distributed::RemoteJobRunner.new(options).run
+exit ::Spec::Distributed::JobRunner.new(options).run
@@ -29,7 +29,7 @@ def describe_with_nested_example_group_spec_path(*args, &example_group_block)
require 'spec/distributed/recording_reporter'
require 'spec/distributed/job_runner_option_parser'
require 'spec/distributed/remote_job_runner_option_parser'
-require 'spec/distributed/remote_job_runner'
+require 'spec/distributed/job_runner'
require 'spec/distributed/job'
require 'spec/distributed/transport_manager'
require 'spec/distributed/transports'
@@ -2,13 +2,15 @@ module Spec
module Distributed
class ExampleGroupValueHolder
def initialize(example_group)
- @object_id = example_group.description_options[:remote_example_group_object_id]
+ @object_id = example_group.description_options[:example_group_object_id]
end
def value
- rspec_options.example_groups.find do |eg|
+ value = rspec_options.example_groups.find do |eg|
eg.object_id == @object_id
end
+ debugger if value.nil?
+ value
end
end
end
@@ -12,11 +12,15 @@ def update_wc(svn_rev, patch)
end
def apply_changeset(diff)
+ puts diff
IO.popen("patch -p0", "w+") do |patch|
patch.puts diff
patch.close_write
patch.readlines
end
+ File.open("last_patch.txt", "w") do |f|
+ f << diff
+ end
end
def local_diff
@@ -33,6 +37,13 @@ def local_revision
end
def revert
+ if File.exists?('last_patch.txt')
+ `egrep '^Index:' last_patch.txt`.split(/\n/).each do |line|
+ file = line.match(/\AIndex: (.*)/)[1]
+ FileUtils.rm_rf file.strip
+ end
+ FileUtils.rm 'last_patch.txt'
+ end
`svn revert -R .`
end
@@ -62,7 +73,7 @@ module MasterHooks
# make sure your new files are 'svn add'ed
module DetectSvnRev
Spec::Distributed::Hooks.add_master_hook do |job|
- job.add_library 'spec/distributed/hooks/svn_update_hooks'
+ job.add_hook_library 'spec/distributed/hooks/svn_update_hooks'
svn = UpdateSvn.new
job.master_svn_rev = svn.local_revision
@@ -1,16 +1,11 @@
+require 'tempfile'
+require 'systemu'
+
module Spec
module Distributed
-
- # Stuff we're going to want:
- # - in process or out
- # - path to spec file
- # - Load path
- # - CWD
- # - enviroment variables
- # - return path
- # - DRb location of formatters IO?
-
# OpenStruct is a bug waiting to happen...
+ # btw, don't add instance variables, OpenStruct has it's own
+ # marshal_dump etc
class Job < OpenStruct
class << self
def create_job(example_group, options, return_path)
@@ -29,6 +24,7 @@ def strip_line_number(spec_path)
spec_path.gsub(/:\d+.*\Z/, "")
end
+ # push this into File
# http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/20586
def rel_path(a, b)
# Should work in in win and *nix
@@ -56,49 +52,86 @@ def rel_path(a, b)
parent = ".." + sep
(parent * a.size) + b.join(sep)
end
-
- # path transformation
- # The master may want to set a path transformation in a few scenarios:
- # A. The master wants the slave to load the spec from the master's
- # directory, most likely over network. The master will
- # specify a transformation resulting in:
- # /absolute/path/to/where/the/specs/are ->
- # /network/path/to/where/the/specs/are
- # This is a substitution of s/absolute/network/ where the
- # rest of the path remains the same. e.g. If a user's home
- # directory were exported over NFS, then the master would transform
- # the spec_path from /Users/john/project/spec ->
- # /net/johns_machine/Users/john/project/spec
- #
- # B. The master wants the slave to load libraries relative to
- # some known CWD, therefore wants the slave to run in a
- # specific CWD.
- # B1. The master wants the slave to run in a known CWD.
- # B1.1 This may be the CWD the remote_runner was started in (because
- # those starting the master/slave know this)
- # B1.2 or some other CWD that the master suggests (e.g. run in
- # branch dir vs. the trunk)
- #
- # B2. The master wants the slave to run in a CWD that is on
- # the masters machine, thus the path would be would be
- # similar to A.
- #
- # How to deal with win/unix path transformations?
end
-
+
def initialize(args={})
super
self.libraries ||= []
+ self.hook_libraries ||= []
self.environment ||= {}
+
+ add_library("spec/distributed")
end
def add_library(library_path)
self.libraries << library_path
end
+ def add_hook_library(library_path)
+ self.hook_libraries << library_path
+ end
+
def add_environment(key, value)
environment[key] = value
end
+
+ def command_line
+ command_string = "spec"
+ libraries.each do |lib|
+ command_string << " --require '#{lib}'"
+ end
+ command_string << " --runner Spec::Distributed::SlaveExampleGroupRunner:#{temp_filename}"
+ # TODO: escape the EG descriptions for quote chars
+ command_string << " -e \"#{example_group_description}\""
+ command_string << " #{spec_path}"
+ command_string
+ end
+
+ def run
+ begin
+ run_hooks
+ setup_environment
+ setup_temp_filename
+ fork_command
+ collect_reporter
+ rescue Exception => e
+ self.fatal_failure = true
+ self.exception = e
+ end
+ ensure
+ temp_file.delete if temp_file
+ self.temp_file = nil
+ end
+
+ def run_hooks
+ hook_libraries.each { |lib| require lib }
+ Hooks.run_slave_hooks(self)
+ end
+
+ def setup_environment
+ if example_group_object_id
+ add_environment('REMOTE_EXAMPLE_GROUP_OBJECT_ID', example_group_object_id)
+ end
+ end
+
+ def setup_temp_filename
+ self.temp_file = Tempfile.new('job')
+ self.temp_filename = temp_file.path
+ end
+
+ def fork_command
+ self.status, self.stdout, self.stderr = systemu command_line, 'env' => environment
+ end
+
+ def collect_reporter
+ if File.stat(temp_file.path).size > 0
+ temp_file.open
+ self.reporter = Marshal.load(temp_file)
+ else
+ self.fatal_failure = true
+ end
+ end
+
end
end
end
@@ -0,0 +1,46 @@
+module Spec
+ module Distributed
+ class JobRunner
+ def initialize(options)
+ @options = options
+ end
+
+ def run
+ prepare
+ begin
+ next_job
+ run_job
+ publish_result
+ end while keep_running?
+ end
+
+ def prepare
+ #transport_manager.start_local_server_if_required_or_somesuch
+ transport_manager.connect(true)
+ end
+
+ def next_job
+ @job = transport_manager.next_job
+ end
+
+ def run_job
+ @job.run # options?
+ end
+
+ def publish_result
+ Marshal.dump(@job) # safety check for now. Don't need any
+ # remote references
+ transport_manager.publish_result(@job)
+ end
+
+ def keep_running?
+ true
+ end
+
+ protected
+ def transport_manager
+ @options.transport_manager
+ end
+ end
+ end
+end
@@ -14,11 +14,33 @@ def valid?
end
def transport_type_valid?
+ transport_type && transport_manager
+ end
+
+ def transport_manager
+ @transport_manager ||= create_transport_manager
+ end
+
+ protected
+ def create_transport_manager
begin
- TransportManager.manager_for(transport_type)
+ type, options = parse_transport_manager_options
+ @transport_manager = TransportManager.manager_for(type).new(options)
rescue NoSuchTransportException => e
- false
+ nil
+ end
+ end
+
+ def parse_transport_manager_options
+ start = transport_type.index(':')
+ if start
+ type = transport_type[0...start]
+ options = start ? transport_type[start +1..-1] : ""
+ else
+ type = transport_type
+ options = ""
end
+ return type, options
end
end
@@ -71,14 +71,14 @@ def report_jobs_with_exceptions
if jobs_with_exceptions.length > 0
puts "The following jobs had fatal failures: "
jobs_with_exceptions.each do |job|
- e = job.slave_exception
+ e = job.exception
if e
puts "#{job.spec_path} -e '#{job.example_group_description}'"
puts "#{e}"
puts e.backtrace
end
- puts job.slave_status
- puts job.slave_stout
+ puts job.status
+ puts job.stout
puts job.stderr
puts
end
Oops, something went wrong. Retry.

0 comments on commit 228ecca

Please sign in to comment.