hydra 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +26 -0
- data/VERSION +1 -1
- data/hydra.gemspec +2 -2
- data/lib/hydra/tasks.rb +119 -17
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -32,6 +32,26 @@ Run:
|
|
32
32
|
Hydra defaults to Single Core mode, so you may want to configure it
|
33
33
|
to use two (or more) of your cores if you have a multi-processing machine.
|
34
34
|
|
35
|
+
== Running Remote Tasks
|
36
|
+
|
37
|
+
You can run tasks across all of your remote workers easily with Hydra. In your rake file, add:
|
38
|
+
|
39
|
+
Hydra::RemoteTask.new('db:reset')
|
40
|
+
|
41
|
+
Then you can run:
|
42
|
+
|
43
|
+
rake hydra:remote:db:reset
|
44
|
+
|
45
|
+
== Running Global Tasks
|
46
|
+
|
47
|
+
A Global task is a task run locally *and* remotely. It's used in the same way as RemoteTask:
|
48
|
+
|
49
|
+
Hydra::GlobalTask.new('db:reset')
|
50
|
+
|
51
|
+
But it is invoked in a higher namespace:
|
52
|
+
|
53
|
+
rake hydra:db:reset
|
54
|
+
|
35
55
|
== Configuration
|
36
56
|
|
37
57
|
Place the config file in the main project directory as
|
@@ -112,6 +132,12 @@ Use ssh_opts to set the port or compression options.
|
|
112
132
|
The *directory* option is the path for the project directory
|
113
133
|
where the tests should be run.
|
114
134
|
|
135
|
+
== More Information
|
136
|
+
|
137
|
+
For more information on Hydra, check out the rdocs:
|
138
|
+
|
139
|
+
http://rdoc.info/projects/ngauthier/hydra
|
140
|
+
|
115
141
|
== Copyright
|
116
142
|
|
117
143
|
Copyright (c) 2010 Nick Gauthier. See LICENSE for details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.10.0
|
data/hydra.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{hydra}
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.10.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Nick Gauthier"]
|
12
|
-
s.date = %q{2010-02-
|
12
|
+
s.date = %q{2010-02-10}
|
13
13
|
s.description = %q{Spread your tests over multiple machines to test your code faster.}
|
14
14
|
s.email = %q{nick@smartlogicsolutions.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/hydra/tasks.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
|
+
require 'open3'
|
1
2
|
module Hydra #:nodoc:
|
2
|
-
#
|
3
|
-
|
4
|
-
# TODO: examples
|
5
|
-
class TestTask
|
3
|
+
# Hydra Task Common attributes and methods
|
4
|
+
class Task
|
6
5
|
# Name of the task. Default 'hydra'
|
7
6
|
attr_accessor :name
|
8
7
|
|
@@ -19,6 +18,35 @@ module Hydra #:nodoc:
|
|
19
18
|
# Path to the hydra config file.
|
20
19
|
# If not set, it will check 'hydra.yml' and 'config/hydra.yml'
|
21
20
|
attr_accessor :config
|
21
|
+
#
|
22
|
+
# Search for the hydra config file
|
23
|
+
def find_config_file
|
24
|
+
@config ||= 'hydra.yml'
|
25
|
+
return @config if File.exists?(@config)
|
26
|
+
@config = File.join('config', 'hydra.yml')
|
27
|
+
return @config if File.exists?(@config)
|
28
|
+
@config = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# Add files to test by passing in a string to be run through Dir.glob.
|
32
|
+
# For example:
|
33
|
+
#
|
34
|
+
# t.add_files 'test/units/*.rb'
|
35
|
+
def add_files(pattern)
|
36
|
+
@files += Dir.glob(pattern)
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
# Define a test task that uses hydra to test the files.
|
42
|
+
#
|
43
|
+
# Hydra::TestTask.new('hydra') do |t|
|
44
|
+
# t.add_files 'test/unit/**/*_test.rb'
|
45
|
+
# t.add_files 'test/functional/**/*_test.rb'
|
46
|
+
# t.add_files 'test/integration/**/*_test.rb'
|
47
|
+
# t.verbose = false # optionally set to true for lots of debug messages
|
48
|
+
# end
|
49
|
+
class TestTask < Hydra::Task
|
22
50
|
|
23
51
|
# Create a new HydraTestTask
|
24
52
|
def initialize(name = :hydra)
|
@@ -45,6 +73,7 @@ module Hydra #:nodoc:
|
|
45
73
|
define
|
46
74
|
end
|
47
75
|
|
76
|
+
private
|
48
77
|
# Create the rake task defined by this HydraTestTask
|
49
78
|
def define
|
50
79
|
desc "Hydra Tests" + (@name == :hydra ? "" : " for #{@name}")
|
@@ -55,22 +84,95 @@ module Hydra #:nodoc:
|
|
55
84
|
exit(0) #bypass test on_exit output
|
56
85
|
end
|
57
86
|
end
|
87
|
+
end
|
58
88
|
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
89
|
+
# Setup a task that will be run across all remote workers
|
90
|
+
# Hydra::RemoteTask.new('db:reset')
|
91
|
+
#
|
92
|
+
# Then you can run:
|
93
|
+
# rake hydra:remote:db:reset
|
94
|
+
class RemoteTask < Hydra::Task
|
95
|
+
include Open3
|
96
|
+
# Create a new hydra remote task with the given name.
|
97
|
+
# The task will be named hydra:remote:<name>
|
98
|
+
def initialize(name)
|
99
|
+
@name = name
|
100
|
+
yield self if block_given?
|
101
|
+
@config = find_config_file
|
102
|
+
|
103
|
+
unless @config
|
104
|
+
$stderr.write "No config file. Can't run a remote task without remote workers\n"
|
105
|
+
return
|
106
|
+
end
|
107
|
+
|
108
|
+
define
|
65
109
|
end
|
66
110
|
|
67
|
-
|
68
|
-
def
|
69
|
-
@
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
111
|
+
private
|
112
|
+
def define
|
113
|
+
desc "Run #{@name} remotely on all workers"
|
114
|
+
task "hydra:remote:#{@name}" do
|
115
|
+
config = YAML.load_file(@config)
|
116
|
+
workers = config.fetch('workers') { [] }
|
117
|
+
workers = workers.select{|w| w['type'] == 'ssh'}
|
118
|
+
raise "No remote workers" if workers.empty?
|
119
|
+
workers.each do |worker|
|
120
|
+
$stdout.write "==== Hydra Running #{@name} on #{worker['connect']} ====\n"
|
121
|
+
ssh_opts = worker.fetch('ssh_opts') { '' }
|
122
|
+
writer, reader, error = popen3("ssh -tt #{ssh_opts} #{worker['connect']} ")
|
123
|
+
writer.write("cd #{worker['directory']}\n")
|
124
|
+
writer.write "echo BEGIN HYDRA\n"
|
125
|
+
writer.write("RAILS_ENV=test rake #{@name}\n")
|
126
|
+
writer.write "echo END HYDRA\n"
|
127
|
+
writer.write("exit\n")
|
128
|
+
writer.close
|
129
|
+
ignoring = true
|
130
|
+
while line = reader.gets
|
131
|
+
line.chomp!
|
132
|
+
if line =~ /echo END HYDRA$/
|
133
|
+
ignoring = true
|
134
|
+
end
|
135
|
+
$stdout.write "#{line}\n" unless ignoring
|
136
|
+
if line == 'BEGIN HYDRA'
|
137
|
+
ignoring = false
|
138
|
+
end
|
139
|
+
end
|
140
|
+
$stdout.write "\n==== Hydra Running #{@name} COMPLETE ====\n\n"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
# A Hydra global task is a task that is run both locally and remotely.
|
147
|
+
#
|
148
|
+
# For example:
|
149
|
+
#
|
150
|
+
# Hydra::GlobalTask.new('db:reset')
|
151
|
+
#
|
152
|
+
# Allows you to run:
|
153
|
+
#
|
154
|
+
# rake hydra:db:reset
|
155
|
+
#
|
156
|
+
# Then, db:reset will be run locally and on all remote workers. This
|
157
|
+
# makes it easy to setup your workers and run tasks all in a row.
|
158
|
+
#
|
159
|
+
# For example:
|
160
|
+
#
|
161
|
+
# rake hydra:db:reset hydra:factories hydra:tests
|
162
|
+
#
|
163
|
+
# Assuming you setup hydra:db:reset and hydra:db:factories as global
|
164
|
+
# tasks and hydra:tests as a Hydra::TestTask for all your tests
|
165
|
+
class GlobalTask < Hydra::Task
|
166
|
+
def initialize(name)
|
167
|
+
@name = name
|
168
|
+
define
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
def define
|
173
|
+
Hydra::RemoteTask.new(@name)
|
174
|
+
desc "Run #{@name.to_s} Locally and Remotely across all Workers"
|
175
|
+
task "hydra:#{@name.to_s}" => [@name.to_s, "hydra:remote:#{@name.to_s}"]
|
74
176
|
end
|
75
177
|
end
|
76
178
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hydra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Gauthier
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-02-
|
12
|
+
date: 2010-02-10 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|