sskirby-hydra 0.17.1 → 0.21.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/Rakefile +6 -5
- data/VERSION +1 -1
- data/bin/warmsnake.rb +76 -0
- data/lib/hydra/cucumber/formatter.rb +0 -1
- data/lib/hydra/js/lint.js +5150 -0
- data/lib/hydra/listener/abstract.rb +11 -2
- data/lib/hydra/listener/progress_bar.rb +1 -1
- data/lib/hydra/master.rb +43 -19
- data/lib/hydra/message/worker_messages.rb +6 -0
- data/lib/hydra/messaging_io.rb +1 -0
- data/lib/hydra/runner.rb +68 -20
- data/lib/hydra/spec/autorun_override.rb +2 -11
- data/lib/hydra/spec/hydra_formatter.rb +16 -7
- data/lib/hydra/ssh.rb +1 -0
- data/lib/hydra/tasks.rb +26 -6
- data/lib/hydra/trace.rb +6 -1
- data/lib/hydra/worker.rb +9 -4
- data/test/fixtures/conflicting.rb +10 -0
- data/test/fixtures/js_file.js +4 -0
- data/test/fixtures/json_data.json +4 -0
- data/test/fixtures/write_file_alternate_spec.rb +1 -1
- data/test/fixtures/write_file_spec.rb +1 -1
- data/test/fixtures/write_file_with_pending_spec.rb +1 -1
- data/test/master_test.rb +29 -0
- data/test/runner_test.rb +15 -6
- data/test/test_helper.rb +12 -0
- data/test/trace_test.rb +72 -0
- data/test/worker_test.rb +3 -1
- metadata +63 -30
- data/hydra.gemspec +0 -122
data/lib/hydra/trace.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module Hydra #:nodoc:
|
2
2
|
# Trace output when in verbose mode.
|
3
3
|
module Trace
|
4
|
+
REMOTE_IDENTIFIER = 'REMOTE'
|
5
|
+
|
4
6
|
module ClassMethods
|
5
7
|
# Make a class traceable. Takes one parameter,
|
6
8
|
# which is the prefix for the trace to identify this class
|
@@ -16,7 +18,10 @@ module Hydra #:nodoc:
|
|
16
18
|
# Trace some output with the class's prefix and a newline.
|
17
19
|
# Checks to ensure we're running verbosely.
|
18
20
|
def trace(str)
|
19
|
-
|
21
|
+
return unless @verbose
|
22
|
+
remote_info = @remote ? "#{REMOTE_IDENTIFIER} #{@remote} " : ''
|
23
|
+
str = str.gsub /\n/, "\n#{remote_info}"
|
24
|
+
$stdout.write "#{Time.now.to_f} #{remote_info}#{self.class._traceable_prefix}| #{str}\n"
|
20
25
|
end
|
21
26
|
end
|
22
27
|
end
|
data/lib/hydra/worker.rb
CHANGED
@@ -9,24 +9,29 @@ module Hydra #:nodoc:
|
|
9
9
|
class Worker
|
10
10
|
include Hydra::Messages::Worker
|
11
11
|
traceable('WORKER')
|
12
|
+
|
13
|
+
attr_reader :runners
|
12
14
|
# Create a new worker.
|
13
15
|
# * io: The IO object to use to communicate with the master
|
14
16
|
# * num_runners: The number of runners to launch
|
15
17
|
def initialize(opts = {})
|
16
18
|
@verbose = opts.fetch(:verbose) { false }
|
19
|
+
@remote = opts.fetch(:remote) { false }
|
17
20
|
@io = opts.fetch(:io) { raise "No IO Object" }
|
18
21
|
@runners = []
|
19
22
|
@listeners = []
|
20
23
|
|
21
24
|
boot_runners(opts.fetch(:runners) { 1 })
|
25
|
+
@io.write(Hydra::Messages::Worker::WorkerBegin.new)
|
26
|
+
|
22
27
|
process_messages
|
23
|
-
|
28
|
+
|
24
29
|
@runners.each{|r| Process.wait r[:pid] }
|
25
30
|
end
|
26
31
|
|
27
32
|
|
28
33
|
# message handling methods
|
29
|
-
|
34
|
+
|
30
35
|
# When a runner wants a file, it hits this method with a message.
|
31
36
|
# Then the worker bubbles the file request up to the master.
|
32
37
|
def request_file(message, runner)
|
@@ -70,7 +75,7 @@ module Hydra #:nodoc:
|
|
70
75
|
pipe = Hydra::Pipe.new
|
71
76
|
child = SafeFork.fork do
|
72
77
|
pipe.identify_as_child
|
73
|
-
Hydra::Runner.new(:io => pipe, :verbose => @verbose)
|
78
|
+
Hydra::Runner.new(:io => pipe, :verbose => @verbose, :remote => @remote)
|
74
79
|
end
|
75
80
|
pipe.identify_as_parent
|
76
81
|
@runners << { :pid => child, :io => pipe, :idle => false }
|
@@ -99,7 +104,7 @@ module Hydra #:nodoc:
|
|
99
104
|
begin
|
100
105
|
message = @io.gets
|
101
106
|
if message and !message.class.to_s.index("Master").nil?
|
102
|
-
trace "Received Message from Master"
|
107
|
+
trace "Received Message from Master"
|
103
108
|
trace "\t#{message.inspect}"
|
104
109
|
message.handle(self)
|
105
110
|
else
|
data/test/master_test.rb
CHANGED
@@ -20,6 +20,35 @@ class MasterTest < Test::Unit::TestCase
|
|
20
20
|
assert_equal "HYDRA", File.read(target_file)
|
21
21
|
end
|
22
22
|
|
23
|
+
# this test simulates what happens when we have 2 tests with the same
|
24
|
+
# class name but with different parent classes. This can happen when
|
25
|
+
# we have a functional and an integration test class with the same name.
|
26
|
+
should "run even with a test that will not require" do
|
27
|
+
class FileOutputListener < Hydra::Listener::Abstract
|
28
|
+
attr_accessor :output
|
29
|
+
def initialize(&block)
|
30
|
+
self.output = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def file_end(file, output)
|
34
|
+
self.output[file] = output
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
listener = FileOutputListener.new
|
39
|
+
sync_test = File.join(File.dirname(__FILE__), 'fixtures', 'sync_test.rb')
|
40
|
+
Hydra::Master.new(
|
41
|
+
# we want the actual test to run last to make sure the runner can still run tests
|
42
|
+
:files => [sync_test, conflicting_test_file, test_file],
|
43
|
+
:autosort => false,
|
44
|
+
:listeners => [listener]
|
45
|
+
)
|
46
|
+
assert_match /superclass mismatch for class SyncTest/, listener.output[conflicting_test_file]
|
47
|
+
assert_match conflicting_test_file, listener.output[conflicting_test_file]
|
48
|
+
assert File.exists?(target_file)
|
49
|
+
assert_equal "HYDRA", File.read(target_file)
|
50
|
+
end
|
51
|
+
|
23
52
|
should "run a spec with pending examples" do
|
24
53
|
progress_bar = Hydra::Listener::ProgressBar.new(StringIO.new)
|
25
54
|
Hydra::Master.new(
|
data/test/runner_test.rb
CHANGED
@@ -37,6 +37,18 @@ class RunnerTest < Test::Unit::TestCase
|
|
37
37
|
Process.wait(child)
|
38
38
|
end
|
39
39
|
|
40
|
+
should "run a js lint file and find errors" do
|
41
|
+
runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
|
42
|
+
results = runner.run_file(javascript_file)
|
43
|
+
assert results =~ /Missing semicolon/, results
|
44
|
+
end
|
45
|
+
|
46
|
+
should "run a json data file and find errors" do
|
47
|
+
runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
|
48
|
+
results = runner.run_file(json_file)
|
49
|
+
assert results =~ /trailing comma/, results
|
50
|
+
end
|
51
|
+
|
40
52
|
should "run two rspec tests" do
|
41
53
|
runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
|
42
54
|
runner.run_file(rspec_file)
|
@@ -48,7 +60,7 @@ class RunnerTest < Test::Unit::TestCase
|
|
48
60
|
runner.run_file(alternate_rspec_file)
|
49
61
|
assert File.exists?(alternate_target_file)
|
50
62
|
assert_equal "HYDRA", File.read(alternate_target_file)
|
51
|
-
assert !File.exists?(target_file)
|
63
|
+
assert !File.exists?(target_file), "Tests are double running!"
|
52
64
|
end
|
53
65
|
|
54
66
|
should "run rspec tests with pending examples" do
|
@@ -68,8 +80,8 @@ class RunnerTest < Test::Unit::TestCase
|
|
68
80
|
# we run this in a fork to not contaminate
|
69
81
|
# the main test environment
|
70
82
|
pid = Process.fork do
|
71
|
-
|
72
|
-
|
83
|
+
# need to get into the fixtures directory so cucumber doesn't load up the whole project
|
84
|
+
Dir.chdir(File.join(File.dirname(__FILE__), 'fixtures'))
|
73
85
|
|
74
86
|
runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
|
75
87
|
runner.run_file(cucumber_feature_file)
|
@@ -82,8 +94,6 @@ class RunnerTest < Test::Unit::TestCase
|
|
82
94
|
assert File.exists?(alternate_target_file)
|
83
95
|
assert_equal "HYDRA", File.read(alternate_target_file)
|
84
96
|
assert !File.exists?(target_file)
|
85
|
-
|
86
|
-
puts "END IGNORABLE OUTPUT"
|
87
97
|
end
|
88
98
|
Process.wait pid
|
89
99
|
end
|
@@ -124,7 +134,6 @@ class RunnerTest < Test::Unit::TestCase
|
|
124
134
|
|
125
135
|
# grab its response. This makes us wait for it to finish
|
126
136
|
response = pipe.gets
|
127
|
-
puts response.output
|
128
137
|
|
129
138
|
# tell it to shut down
|
130
139
|
pipe.write(Hydra::Messages::Worker::Shutdown.new)
|
data/test/test_helper.rb
CHANGED
@@ -42,6 +42,18 @@ class Test::Unit::TestCase
|
|
42
42
|
def alternate_cucumber_feature_file
|
43
43
|
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'features', 'write_alternate_file.feature'))
|
44
44
|
end
|
45
|
+
|
46
|
+
def javascript_file
|
47
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'js_file.js'))
|
48
|
+
end
|
49
|
+
|
50
|
+
def json_file
|
51
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'json_data.json'))
|
52
|
+
end
|
53
|
+
|
54
|
+
def conflicting_test_file
|
55
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'conflicting.rb'))
|
56
|
+
end
|
45
57
|
end
|
46
58
|
|
47
59
|
module Hydra #:nodoc:
|
data/test/trace_test.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class TraceTester
|
4
|
+
traceable("TEST")
|
5
|
+
attr_accessor :verbose, :remote
|
6
|
+
def initialize verbose, remote
|
7
|
+
self.verbose, self.remote = verbose, remote
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class TraceTest < Test::Unit::TestCase
|
12
|
+
def setup
|
13
|
+
@result = StringIO.new("")
|
14
|
+
end
|
15
|
+
|
16
|
+
def run_trace object, str
|
17
|
+
old_stdout = $stdout
|
18
|
+
$stdout = @result
|
19
|
+
object.trace str
|
20
|
+
return @result.string
|
21
|
+
ensure
|
22
|
+
$stdout = old_stdout
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with no tracing enabled" do
|
26
|
+
setup do
|
27
|
+
@tracer = TraceTester.new false, false
|
28
|
+
end
|
29
|
+
|
30
|
+
should "not output" do
|
31
|
+
result = run_trace @tracer, "testing"
|
32
|
+
assert_equal '', result
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with a local object" do
|
37
|
+
setup do
|
38
|
+
@tracer = TraceTester.new true, false
|
39
|
+
end
|
40
|
+
|
41
|
+
should "output" do
|
42
|
+
result = run_trace @tracer, 'testing'
|
43
|
+
assert_match /TEST/, result
|
44
|
+
assert_match /testing/, result
|
45
|
+
assert_no_match /#{Hydra::Trace::REMOTE_IDENTIFIER}/, result
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "with a remote object" do
|
50
|
+
setup do
|
51
|
+
@tracer = TraceTester.new true, 'localhost'
|
52
|
+
end
|
53
|
+
|
54
|
+
should "output" do
|
55
|
+
result = run_trace @tracer, 'testing'
|
56
|
+
assert_match /TEST/, result
|
57
|
+
assert_match /testing/, result
|
58
|
+
assert_equal "\n"[0], result[-1]
|
59
|
+
assert_match /#{Hydra::Trace::REMOTE_IDENTIFIER} localhost/, result
|
60
|
+
end
|
61
|
+
|
62
|
+
should "output a multiline message" do
|
63
|
+
result = run_trace @tracer, "testing\ntrace line #1\ntrace line #2"
|
64
|
+
assert_match /TEST/, result
|
65
|
+
assert_match /testing/, result
|
66
|
+
assert_match /#{Hydra::Trace::REMOTE_IDENTIFIER} localhost TEST/, result
|
67
|
+
assert_match /\n#{Hydra::Trace::REMOTE_IDENTIFIER} localhost trace line #1/, result
|
68
|
+
assert_match /\n#{Hydra::Trace::REMOTE_IDENTIFIER} localhost trace line #2/, result
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
data/test/worker_test.rb
CHANGED
@@ -41,8 +41,10 @@ class WorkerTest < Test::Unit::TestCase
|
|
41
41
|
|
42
42
|
def request_a_file_and_verify_completion(pipe, num_runners)
|
43
43
|
pipe.identify_as_parent
|
44
|
+
pipe.gets # grab the WorkerBegin
|
44
45
|
num_runners.times do
|
45
|
-
|
46
|
+
response = pipe.gets # grab the RequestFile
|
47
|
+
assert response.is_a?(Hydra::Messages::Worker::RequestFile), "Expected RequestFile but got #{response.class.to_s}"
|
46
48
|
end
|
47
49
|
pipe.write(Hydra::Messages::Master::RunFile.new(:file => test_file))
|
48
50
|
|
metadata
CHANGED
@@ -1,32 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sskirby-hydra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
+
hash: 75
|
4
5
|
prerelease: false
|
5
6
|
segments:
|
6
7
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
8
|
+
- 21
|
9
|
+
- 0
|
10
|
+
version: 0.21.0
|
10
11
|
platform: ruby
|
11
12
|
authors:
|
12
13
|
- Nick Gauthier
|
13
|
-
- Sean Kirby
|
14
|
-
- Tanzeeb Khalili
|
15
|
-
- Matt Briggs
|
16
14
|
autorequire:
|
17
15
|
bindir: bin
|
18
16
|
cert_chain: []
|
19
17
|
|
20
|
-
date: 2010-
|
21
|
-
default_executable:
|
18
|
+
date: 2010-08-29 00:00:00 -04:00
|
19
|
+
default_executable: warmsnake.rb
|
22
20
|
dependencies:
|
23
21
|
- !ruby/object:Gem::Dependency
|
24
22
|
name: shoulda
|
25
23
|
prerelease: false
|
26
24
|
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
27
26
|
requirements:
|
28
27
|
- - "="
|
29
28
|
- !ruby/object:Gem::Version
|
29
|
+
hash: 33
|
30
30
|
segments:
|
31
31
|
- 2
|
32
32
|
- 10
|
@@ -38,34 +38,56 @@ dependencies:
|
|
38
38
|
name: rspec
|
39
39
|
prerelease: false
|
40
40
|
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
41
42
|
requirements:
|
42
43
|
- - "="
|
43
44
|
- !ruby/object:Gem::Version
|
45
|
+
hash: 62196421
|
44
46
|
segments:
|
45
|
-
-
|
46
|
-
- 3
|
47
|
+
- 2
|
47
48
|
- 0
|
48
|
-
|
49
|
+
- 0
|
50
|
+
- beta
|
51
|
+
- 19
|
52
|
+
version: 2.0.0.beta.19
|
49
53
|
type: :development
|
50
54
|
version_requirements: *id002
|
51
55
|
- !ruby/object:Gem::Dependency
|
52
56
|
name: cucumber
|
53
57
|
prerelease: false
|
54
58
|
requirement: &id003 !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
55
60
|
requirements:
|
56
61
|
- - "="
|
57
62
|
- !ruby/object:Gem::Version
|
63
|
+
hash: 53
|
58
64
|
segments:
|
59
65
|
- 0
|
60
|
-
-
|
61
|
-
-
|
62
|
-
version: 0.
|
66
|
+
- 8
|
67
|
+
- 5
|
68
|
+
version: 0.8.5
|
63
69
|
type: :development
|
64
70
|
version_requirements: *id003
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: therubyracer
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - "="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
hash: 11
|
80
|
+
segments:
|
81
|
+
- 0
|
82
|
+
- 7
|
83
|
+
- 4
|
84
|
+
version: 0.7.4
|
85
|
+
type: :development
|
86
|
+
version_requirements: *id004
|
65
87
|
description: Spread your tests over multiple machines to test your code faster.
|
66
|
-
email:
|
67
|
-
executables:
|
68
|
-
|
88
|
+
email: nick@smartlogicsolutions.com
|
89
|
+
executables:
|
90
|
+
- warmsnake.rb
|
69
91
|
extensions: []
|
70
92
|
|
71
93
|
extra_rdoc_files:
|
@@ -80,13 +102,14 @@ files:
|
|
80
102
|
- Rakefile
|
81
103
|
- TODO
|
82
104
|
- VERSION
|
105
|
+
- bin/warmsnake.rb
|
83
106
|
- caliper.yml
|
84
107
|
- hydra-icon-64x64.png
|
85
|
-
- hydra.gemspec
|
86
108
|
- hydra_gray.png
|
87
109
|
- lib/hydra.rb
|
88
110
|
- lib/hydra/cucumber/formatter.rb
|
89
111
|
- lib/hydra/hash.rb
|
112
|
+
- lib/hydra/js/lint.js
|
90
113
|
- lib/hydra/listener/abstract.rb
|
91
114
|
- lib/hydra/listener/minimal_output.rb
|
92
115
|
- lib/hydra/listener/notifier.rb
|
@@ -111,10 +134,13 @@ files:
|
|
111
134
|
- lib/hydra/worker.rb
|
112
135
|
- test/fixtures/assert_true.rb
|
113
136
|
- test/fixtures/config.yml
|
137
|
+
- test/fixtures/conflicting.rb
|
114
138
|
- test/fixtures/features/step_definitions.rb
|
115
139
|
- test/fixtures/features/write_alternate_file.feature
|
116
140
|
- test/fixtures/features/write_file.feature
|
117
141
|
- test/fixtures/hello_world.rb
|
142
|
+
- test/fixtures/js_file.js
|
143
|
+
- test/fixtures/json_data.json
|
118
144
|
- test/fixtures/slow.rb
|
119
145
|
- test/fixtures/sync_test.rb
|
120
146
|
- test/fixtures/write_file.rb
|
@@ -128,9 +154,10 @@ files:
|
|
128
154
|
- test/ssh_test.rb
|
129
155
|
- test/sync_test.rb
|
130
156
|
- test/test_helper.rb
|
157
|
+
- test/trace_test.rb
|
131
158
|
- test/worker_test.rb
|
132
159
|
has_rdoc: true
|
133
|
-
homepage: http://github.com/
|
160
|
+
homepage: http://github.com/ngauthier/hydra
|
134
161
|
licenses: []
|
135
162
|
|
136
163
|
post_install_message:
|
@@ -139,41 +166,47 @@ rdoc_options:
|
|
139
166
|
require_paths:
|
140
167
|
- lib
|
141
168
|
required_ruby_version: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
142
170
|
requirements:
|
143
171
|
- - ">="
|
144
172
|
- !ruby/object:Gem::Version
|
173
|
+
hash: 3
|
145
174
|
segments:
|
146
175
|
- 0
|
147
176
|
version: "0"
|
148
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
178
|
+
none: false
|
149
179
|
requirements:
|
150
180
|
- - ">="
|
151
181
|
- !ruby/object:Gem::Version
|
182
|
+
hash: 3
|
152
183
|
segments:
|
153
184
|
- 0
|
154
185
|
version: "0"
|
155
186
|
requirements: []
|
156
187
|
|
157
188
|
rubyforge_project:
|
158
|
-
rubygems_version: 1.3.
|
189
|
+
rubygems_version: 1.3.7
|
159
190
|
signing_key:
|
160
191
|
specification_version: 3
|
161
192
|
summary: Distributed testing toolkit
|
162
193
|
test_files:
|
163
|
-
- test/sync_test.rb
|
164
|
-
- test/test_helper.rb
|
165
194
|
- test/message_test.rb
|
166
|
-
- test/
|
167
|
-
- test/
|
168
|
-
- test/fixtures/
|
169
|
-
- test/fixtures/
|
195
|
+
- test/master_test.rb
|
196
|
+
- test/ssh_test.rb
|
197
|
+
- test/fixtures/assert_true.rb
|
198
|
+
- test/fixtures/slow.rb
|
170
199
|
- test/fixtures/write_file_alternate_spec.rb
|
200
|
+
- test/fixtures/hello_world.rb
|
171
201
|
- test/fixtures/write_file_with_pending_spec.rb
|
172
|
-
- test/fixtures/
|
173
|
-
- test/fixtures/
|
202
|
+
- test/fixtures/write_file.rb
|
203
|
+
- test/fixtures/conflicting.rb
|
174
204
|
- test/fixtures/write_file_spec.rb
|
175
205
|
- test/fixtures/features/step_definitions.rb
|
176
|
-
- test/
|
206
|
+
- test/fixtures/sync_test.rb
|
207
|
+
- test/test_helper.rb
|
208
|
+
- test/runner_test.rb
|
209
|
+
- test/trace_test.rb
|
210
|
+
- test/sync_test.rb
|
177
211
|
- test/pipe_test.rb
|
178
|
-
- test/master_test.rb
|
179
212
|
- test/worker_test.rb
|