Remote and Global tasks
This commit is contained in:
parent
9b428bcf95
commit
6544e9eec3
|
@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|||
|
||||
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
||||
s.authors = ["Nick Gauthier"]
|
||||
s.date = %q{2010-02-09}
|
||||
s.date = %q{2010-02-10}
|
||||
s.description = %q{Spread your tests over multiple machines to test your code faster.}
|
||||
s.email = %q{nick@smartlogicsolutions.com}
|
||||
s.extra_rdoc_files = [
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
require 'open3'
|
||||
module Hydra #:nodoc:
|
||||
# Define a test task that uses hydra to test the files.
|
||||
#
|
||||
# TODO: examples
|
||||
class TestTask
|
||||
# Hydra Task Common attributes and methods
|
||||
class Task
|
||||
# Name of the task. Default 'hydra'
|
||||
attr_accessor :name
|
||||
|
||||
|
@ -19,6 +18,35 @@ module Hydra #:nodoc:
|
|||
# Path to the hydra config file.
|
||||
# If not set, it will check 'hydra.yml' and 'config/hydra.yml'
|
||||
attr_accessor :config
|
||||
#
|
||||
# Search for the hydra config file
|
||||
def find_config_file
|
||||
@config ||= 'hydra.yml'
|
||||
return @config if File.exists?(@config)
|
||||
@config = File.join('config', 'hydra.yml')
|
||||
return @config if File.exists?(@config)
|
||||
@config = nil
|
||||
end
|
||||
|
||||
# Add files to test by passing in a string to be run through Dir.glob.
|
||||
# For example:
|
||||
#
|
||||
# t.add_files 'test/units/*.rb'
|
||||
def add_files(pattern)
|
||||
@files += Dir.glob(pattern)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Define a test task that uses hydra to test the files.
|
||||
#
|
||||
# Hydra::TestTask.new('hydra') do |t|
|
||||
# t.add_files 'test/unit/**/*_test.rb'
|
||||
# t.add_files 'test/functional/**/*_test.rb'
|
||||
# t.add_files 'test/integration/**/*_test.rb'
|
||||
# t.verbose = false # optionally set to true for lots of debug messages
|
||||
# end
|
||||
class TestTask < Hydra::Task
|
||||
|
||||
# Create a new HydraTestTask
|
||||
def initialize(name = :hydra)
|
||||
|
@ -45,6 +73,7 @@ module Hydra #:nodoc:
|
|||
define
|
||||
end
|
||||
|
||||
private
|
||||
# Create the rake task defined by this HydraTestTask
|
||||
def define
|
||||
desc "Hydra Tests" + (@name == :hydra ? "" : " for #{@name}")
|
||||
|
@ -55,22 +84,95 @@ module Hydra #:nodoc:
|
|||
exit(0) #bypass test on_exit output
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Add files to test by passing in a string to be run through Dir.glob.
|
||||
# For example:
|
||||
#
|
||||
# t.add_files 'test/units/*.rb'
|
||||
def add_files(pattern)
|
||||
@files += Dir.glob(pattern)
|
||||
# Setup a task that will be run across all remote workers
|
||||
# Hydra::RemoteTask.new('db:reset')
|
||||
#
|
||||
# Then you can run:
|
||||
# rake hydra:remote:db:reset
|
||||
class RemoteTask < Hydra::Task
|
||||
include Open3
|
||||
# Create a new hydra remote task with the given name.
|
||||
# The task will be named hydra:remote:<name>
|
||||
def initialize(name)
|
||||
@name = name
|
||||
yield self if block_given?
|
||||
@config = find_config_file
|
||||
|
||||
unless @config
|
||||
$stderr.write "No config file. Can't run a remote task without remote workers\n"
|
||||
return
|
||||
end
|
||||
|
||||
define
|
||||
end
|
||||
|
||||
# Search for the hydra config file
|
||||
def find_config_file
|
||||
@config ||= 'hydra.yml'
|
||||
return @config if File.exists?(@config)
|
||||
@config = File.join('config', 'hydra.yml')
|
||||
return @config if File.exists?(@config)
|
||||
@config = nil
|
||||
private
|
||||
def define
|
||||
desc "Run #{@name} remotely on all workers"
|
||||
task "hydra:remote:#{@name}" do
|
||||
config = YAML.load_file(@config)
|
||||
workers = config.fetch('workers') { [] }
|
||||
workers = workers.select{|w| w['type'] == 'ssh'}
|
||||
raise "No remote workers" if workers.empty?
|
||||
workers.each do |worker|
|
||||
$stdout.write "==== Hydra Running #{@name} on #{worker['connect']} ====\n"
|
||||
ssh_opts = worker.fetch('ssh_opts') { '' }
|
||||
writer, reader, error = popen3("ssh -tt #{ssh_opts} #{worker['connect']} ")
|
||||
writer.write("cd #{worker['directory']}\n")
|
||||
writer.write "echo BEGIN HYDRA\n"
|
||||
writer.write("RAILS_ENV=test rake #{@name}\n")
|
||||
writer.write "echo END HYDRA\n"
|
||||
writer.write("exit\n")
|
||||
writer.close
|
||||
ignoring = true
|
||||
while line = reader.gets
|
||||
line.chomp!
|
||||
if line =~ /echo END HYDRA$/
|
||||
ignoring = true
|
||||
end
|
||||
$stdout.write "#{line}\n" unless ignoring
|
||||
if line == 'BEGIN HYDRA'
|
||||
ignoring = false
|
||||
end
|
||||
end
|
||||
$stdout.write "\n==== Hydra Running #{@name} COMPLETE ====\n\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# A Hydra global task is a task that is run both locally and remotely.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# Hydra::GlobalTask.new('db:reset')
|
||||
#
|
||||
# Allows you to run:
|
||||
#
|
||||
# rake hydra:db:reset
|
||||
#
|
||||
# Then, db:reset will be run locally and on all remote workers. This
|
||||
# makes it easy to setup your workers and run tasks all in a row.
|
||||
#
|
||||
# For example:
|
||||
#
|
||||
# rake hydra:db:reset hydra:factories hydra:tests
|
||||
#
|
||||
# Assuming you setup hydra:db:reset and hydra:db:factories as global
|
||||
# tasks and hydra:tests as a Hydra::TestTask for all your tests
|
||||
class GlobalTask < Hydra::Task
|
||||
def initialize(name)
|
||||
@name = name
|
||||
define
|
||||
end
|
||||
|
||||
private
|
||||
def define
|
||||
Hydra::RemoteTask.new(@name)
|
||||
desc "Run #{@name.to_s} Locally and Remotely across all Workers"
|
||||
task "hydra:#{@name.to_s}" => [@name.to_s, "hydra:remote:#{@name.to_s}"]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue