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.
Files changed (5) hide show
  1. data/README.rdoc +26 -0
  2. data/VERSION +1 -1
  3. data/hydra.gemspec +2 -2
  4. data/lib/hydra/tasks.rb +119 -17
  5. metadata +2 -2
@@ -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.9.0
1
+ 0.10.0
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{hydra}
8
- s.version = "0.9.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-09}
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 = [
@@ -1,8 +1,7 @@
1
+ require 'open3'
1
2
  module Hydra #:nodoc:
2
- # Define a test task that uses hydra to test the files.
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
- # Add files to test by passing in a string to be run through Dir.glob.
60
- # For example:
61
- #
62
- # t.add_files 'test/units/*.rb'
63
- def add_files(pattern)
64
- @files += Dir.glob(pattern)
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
- # Search for the hydra config file
68
- def find_config_file
69
- @config ||= 'hydra.yml'
70
- return @config if File.exists?(@config)
71
- @config = File.join('config', 'hydra.yml')
72
- return @config if File.exists?(@config)
73
- @config = nil
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.9.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-09 00:00:00 -05:00
12
+ date: 2010-02-10 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency