causes-hydra 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/.document +5 -0
- data/.gitignore +22 -0
- data/LICENSE +20 -0
- data/README.rdoc +39 -0
- data/Rakefile +56 -0
- data/TODO +18 -0
- data/VERSION +1 -0
- data/bin/warmsnake.rb +76 -0
- data/caliper.yml +6 -0
- data/hydra-icon-64x64.png +0 -0
- data/hydra.gemspec +130 -0
- data/hydra_gray.png +0 -0
- data/lib/hydra.rb +16 -0
- data/lib/hydra/cucumber/formatter.rb +29 -0
- data/lib/hydra/hash.rb +16 -0
- data/lib/hydra/js/lint.js +5150 -0
- data/lib/hydra/listener/abstract.rb +39 -0
- data/lib/hydra/listener/minimal_output.rb +24 -0
- data/lib/hydra/listener/notifier.rb +17 -0
- data/lib/hydra/listener/progress_bar.rb +48 -0
- data/lib/hydra/listener/report_generator.rb +30 -0
- data/lib/hydra/master.rb +249 -0
- data/lib/hydra/message.rb +47 -0
- data/lib/hydra/message/master_messages.rb +19 -0
- data/lib/hydra/message/runner_messages.rb +52 -0
- data/lib/hydra/message/worker_messages.rb +52 -0
- data/lib/hydra/messaging_io.rb +46 -0
- data/lib/hydra/pipe.rb +61 -0
- data/lib/hydra/runner.rb +305 -0
- data/lib/hydra/safe_fork.rb +31 -0
- data/lib/hydra/spec/autorun_override.rb +3 -0
- data/lib/hydra/spec/hydra_formatter.rb +26 -0
- data/lib/hydra/ssh.rb +41 -0
- data/lib/hydra/stdio.rb +16 -0
- data/lib/hydra/sync.rb +99 -0
- data/lib/hydra/tasks.rb +342 -0
- data/lib/hydra/trace.rb +24 -0
- data/lib/hydra/worker.rb +150 -0
- data/test/fixtures/assert_true.rb +7 -0
- data/test/fixtures/config.yml +4 -0
- data/test/fixtures/features/step_definitions.rb +21 -0
- data/test/fixtures/features/write_alternate_file.feature +7 -0
- data/test/fixtures/features/write_file.feature +7 -0
- data/test/fixtures/hello_world.rb +3 -0
- data/test/fixtures/js_file.js +4 -0
- data/test/fixtures/json_data.json +4 -0
- data/test/fixtures/slow.rb +9 -0
- data/test/fixtures/sync_test.rb +8 -0
- data/test/fixtures/write_file.rb +10 -0
- data/test/fixtures/write_file_alternate_spec.rb +10 -0
- data/test/fixtures/write_file_spec.rb +9 -0
- data/test/fixtures/write_file_with_pending_spec.rb +11 -0
- data/test/master_test.rb +152 -0
- data/test/message_test.rb +31 -0
- data/test/pipe_test.rb +38 -0
- data/test/runner_test.rb +153 -0
- data/test/ssh_test.rb +14 -0
- data/test/sync_test.rb +113 -0
- data/test/test_helper.rb +68 -0
- data/test/worker_test.rb +60 -0
- metadata +209 -0
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class MessageTest < Test::Unit::TestCase
|
4
|
+
class MyMessage < Hydra::Message
|
5
|
+
attr_accessor :my_var
|
6
|
+
def serialize
|
7
|
+
super(:my_var => @my_var)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "with a message" do
|
12
|
+
setup do
|
13
|
+
@m = MyMessage.new(:my_var => 'my value')
|
14
|
+
end
|
15
|
+
should "set values" do
|
16
|
+
assert_equal 'my value', @m.my_var
|
17
|
+
end
|
18
|
+
should "serialize" do
|
19
|
+
assert_equal(
|
20
|
+
{:class=>MyMessage, :my_var=>"my value"},
|
21
|
+
eval(@m.serialize)
|
22
|
+
)
|
23
|
+
end
|
24
|
+
should "build from serialization" do
|
25
|
+
assert_equal(
|
26
|
+
@m.my_var,
|
27
|
+
Hydra::Message.build(eval(@m.serialize)).my_var
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/test/pipe_test.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class PipeTest < Test::Unit::TestCase
|
4
|
+
context "a pipe" do
|
5
|
+
setup do
|
6
|
+
@pipe = Hydra::Pipe.new
|
7
|
+
end
|
8
|
+
teardown do
|
9
|
+
@pipe.close
|
10
|
+
end
|
11
|
+
should "be able to write messages" do
|
12
|
+
child = Process.fork do
|
13
|
+
@pipe.identify_as_child
|
14
|
+
assert_equal "Test Message", @pipe.gets.text
|
15
|
+
@pipe.write Hydra::Messages::TestMessage.new(:text => "Message Received")
|
16
|
+
@pipe.write Hydra::Messages::TestMessage.new(:text => "Second Message")
|
17
|
+
end
|
18
|
+
@pipe.identify_as_parent
|
19
|
+
@pipe.write Hydra::Messages::TestMessage.new(:text => "Test Message")
|
20
|
+
assert_equal "Message Received", @pipe.gets.text
|
21
|
+
assert_equal "Second Message", @pipe.gets.text
|
22
|
+
Process.wait(child) #ensure it quits, so there is nothing to write to
|
23
|
+
assert_raise IOError do
|
24
|
+
@pipe.write Hydra::Messages::TestMessage.new(:text => "anyone there?")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
should "not allow writing if unidentified" do
|
28
|
+
assert_raise IOError do
|
29
|
+
@pipe.write Hydra::Messages::TestMessage.new(:text => "Test Message")
|
30
|
+
end
|
31
|
+
end
|
32
|
+
should "not allow reading if unidentified" do
|
33
|
+
assert_raise IOError do
|
34
|
+
@pipe.gets
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/test/runner_test.rb
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class RunnerTest < Test::Unit::TestCase
|
4
|
+
context "with a file to test and a destination to verify" do
|
5
|
+
setup do
|
6
|
+
sleep(0.2)
|
7
|
+
FileUtils.rm_f(target_file)
|
8
|
+
FileUtils.rm_f(alternate_target_file)
|
9
|
+
end
|
10
|
+
|
11
|
+
teardown do
|
12
|
+
FileUtils.rm_f(target_file)
|
13
|
+
FileUtils.rm_f(alternate_target_file)
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
should "run a test in the foreground" do
|
18
|
+
# flip it around to the parent is in the fork, this gives
|
19
|
+
# us more direct control over the runner and proper test
|
20
|
+
# coverage output
|
21
|
+
pipe = Hydra::Pipe.new
|
22
|
+
parent = Process.fork do
|
23
|
+
request_a_file_and_verify_completion(pipe, test_file)
|
24
|
+
end
|
25
|
+
run_the_runner(pipe)
|
26
|
+
Process.wait(parent)
|
27
|
+
end
|
28
|
+
|
29
|
+
# this flips the above test, so that the main process runs a bit of the parent
|
30
|
+
# code, but only with minimal assertion
|
31
|
+
should "run a test in the background" do
|
32
|
+
pipe = Hydra::Pipe.new
|
33
|
+
child = Process.fork do
|
34
|
+
run_the_runner(pipe)
|
35
|
+
end
|
36
|
+
request_a_file_and_verify_completion(pipe, test_file)
|
37
|
+
Process.wait(child)
|
38
|
+
end
|
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
|
+
|
52
|
+
should "run two rspec tests" do
|
53
|
+
runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
|
54
|
+
runner.run_file(rspec_file)
|
55
|
+
assert File.exists?(target_file)
|
56
|
+
assert_equal "HYDRA", File.read(target_file)
|
57
|
+
|
58
|
+
FileUtils.rm_f(target_file)
|
59
|
+
|
60
|
+
runner.run_file(alternate_rspec_file)
|
61
|
+
assert File.exists?(alternate_target_file)
|
62
|
+
assert_equal "HYDRA", File.read(alternate_target_file)
|
63
|
+
assert !File.exists?(target_file), "Tests are double running!"
|
64
|
+
end
|
65
|
+
|
66
|
+
should "run rspec tests with pending examples" do
|
67
|
+
runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
|
68
|
+
assert File.exists?(rspec_file_with_pending)
|
69
|
+
|
70
|
+
runner.run_file(rspec_file_with_pending)
|
71
|
+
|
72
|
+
assert File.exists?(target_file)
|
73
|
+
assert_equal "HYDRA", File.read(target_file)
|
74
|
+
|
75
|
+
FileUtils.rm_f(target_file)
|
76
|
+
end
|
77
|
+
|
78
|
+
should "run two cucumber tests" do
|
79
|
+
# because of all the crap cucumber pulls in
|
80
|
+
# we run this in a fork to not contaminate
|
81
|
+
# the main test environment
|
82
|
+
pid = Process.fork do
|
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'))
|
85
|
+
|
86
|
+
runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
|
87
|
+
runner.run_file(cucumber_feature_file)
|
88
|
+
assert File.exists?(target_file)
|
89
|
+
assert_equal "HYDRA", File.read(target_file)
|
90
|
+
|
91
|
+
FileUtils.rm_f(target_file)
|
92
|
+
|
93
|
+
runner.run_file(alternate_cucumber_feature_file)
|
94
|
+
assert File.exists?(alternate_target_file)
|
95
|
+
assert_equal "HYDRA", File.read(alternate_target_file)
|
96
|
+
assert !File.exists?(target_file)
|
97
|
+
end
|
98
|
+
Process.wait pid
|
99
|
+
end
|
100
|
+
|
101
|
+
should "be able to run a runner over ssh" do
|
102
|
+
ssh = Hydra::SSH.new(
|
103
|
+
'localhost',
|
104
|
+
File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')),
|
105
|
+
"ruby -e \"require 'rubygems'; require 'hydra'; Hydra::Runner.new(:io => Hydra::Stdio.new, :verbose => true);\""
|
106
|
+
)
|
107
|
+
assert ssh.gets.is_a?(Hydra::Messages::Runner::RequestFile)
|
108
|
+
ssh.write(Hydra::Messages::Worker::RunFile.new(:file => test_file))
|
109
|
+
|
110
|
+
# grab its response. This makes us wait for it to finish
|
111
|
+
echo = ssh.gets # get the ssh echo
|
112
|
+
response = ssh.gets
|
113
|
+
|
114
|
+
assert_equal Hydra::Messages::Runner::Results, response.class
|
115
|
+
|
116
|
+
# tell it to shut down
|
117
|
+
ssh.write(Hydra::Messages::Worker::Shutdown.new)
|
118
|
+
|
119
|
+
ssh.close
|
120
|
+
|
121
|
+
# ensure it ran
|
122
|
+
assert File.exists?(target_file)
|
123
|
+
assert_equal "HYDRA", File.read(target_file)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
module RunnerTestHelper
|
128
|
+
def request_a_file_and_verify_completion(pipe, file)
|
129
|
+
pipe.identify_as_parent
|
130
|
+
|
131
|
+
# make sure it asks for a file, then give it one
|
132
|
+
assert pipe.gets.is_a?(Hydra::Messages::Runner::RequestFile)
|
133
|
+
pipe.write(Hydra::Messages::Worker::RunFile.new(:file => file))
|
134
|
+
|
135
|
+
# grab its response. This makes us wait for it to finish
|
136
|
+
response = pipe.gets
|
137
|
+
|
138
|
+
# tell it to shut down
|
139
|
+
pipe.write(Hydra::Messages::Worker::Shutdown.new)
|
140
|
+
|
141
|
+
# ensure it ran
|
142
|
+
assert File.exists?(target_file)
|
143
|
+
assert_equal "HYDRA", File.read(target_file)
|
144
|
+
end
|
145
|
+
|
146
|
+
def run_the_runner(pipe)
|
147
|
+
pipe.identify_as_child
|
148
|
+
Hydra::Runner.new(:io => pipe)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
include RunnerTestHelper
|
152
|
+
end
|
153
|
+
|
data/test/ssh_test.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class SSHTest < Test::Unit::TestCase
|
4
|
+
should "be able to execute a command over ssh" do
|
5
|
+
ssh = Hydra::SSH.new(
|
6
|
+
'localhost', # connect to this machine
|
7
|
+
File.expand_path(File.join(File.dirname(__FILE__))), # move to the test directory
|
8
|
+
"ruby fixtures/hello_world.rb"
|
9
|
+
)
|
10
|
+
response = ssh.gets
|
11
|
+
assert_equal "Hello World", response.text
|
12
|
+
ssh.close
|
13
|
+
end
|
14
|
+
end
|
data/test/sync_test.rb
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class SyncTest < Test::Unit::TestCase
|
4
|
+
context "with a file to test and a destination to verify" do
|
5
|
+
setup do
|
6
|
+
# avoid having other tests interfering with us
|
7
|
+
sleep(0.2)
|
8
|
+
#FileUtils.rm_f(target_file)
|
9
|
+
end
|
10
|
+
|
11
|
+
teardown do
|
12
|
+
#FileUtils.rm_f(target_file)
|
13
|
+
end
|
14
|
+
|
15
|
+
should "synchronize a test file over ssh with rsync" do
|
16
|
+
local = File.join(Dir.tmpdir, 'hydra', 'local')
|
17
|
+
remote = File.join(Dir.tmpdir, 'hydra', 'remote')
|
18
|
+
sync_test = File.join(File.dirname(__FILE__), 'fixtures', 'sync_test.rb')
|
19
|
+
[local, remote].each{|f| FileUtils.rm_rf f; FileUtils.mkdir_p f}
|
20
|
+
|
21
|
+
# setup the folders:
|
22
|
+
# local:
|
23
|
+
# - test_a
|
24
|
+
# - test_c
|
25
|
+
# remote:
|
26
|
+
# - test_b
|
27
|
+
#
|
28
|
+
# add test_c to exludes
|
29
|
+
FileUtils.cp(sync_test, File.join(local, 'test_a.rb'))
|
30
|
+
FileUtils.cp(sync_test, File.join(local, 'test_c.rb'))
|
31
|
+
FileUtils.cp(sync_test, File.join(remote, 'test_b.rb'))
|
32
|
+
|
33
|
+
# ensure a is not on remote
|
34
|
+
assert !File.exists?(File.join(remote, 'test_a.rb')), "A should not be on remote"
|
35
|
+
# ensure c is not on remote
|
36
|
+
assert !File.exists?(File.join(remote, 'test_c.rb')), "C should not be on remote"
|
37
|
+
# ensure b is on remote
|
38
|
+
assert File.exists?(File.join(remote, 'test_b.rb')), "B should be on remote"
|
39
|
+
|
40
|
+
Hydra::Sync.new(
|
41
|
+
{
|
42
|
+
:type => :ssh,
|
43
|
+
:connect => 'localhost',
|
44
|
+
:directory => remote,
|
45
|
+
:runners => 1
|
46
|
+
},
|
47
|
+
{
|
48
|
+
:directory => local,
|
49
|
+
:exclude => ['test_c.rb']
|
50
|
+
}
|
51
|
+
)
|
52
|
+
# ensure a is copied
|
53
|
+
assert File.exists?(File.join(remote, 'test_a.rb')), "A was not copied"
|
54
|
+
# ensure c is not copied
|
55
|
+
assert !File.exists?(File.join(remote, 'test_c.rb')), "C was copied, should be excluded"
|
56
|
+
# ensure b is deleted
|
57
|
+
assert !File.exists?(File.join(remote, 'test_b.rb')), "B was not deleted"
|
58
|
+
end
|
59
|
+
|
60
|
+
should "synchronize a test file over ssh with rsync to multiple workers" do
|
61
|
+
local = File.join(Dir.tmpdir, 'hydra', 'local')
|
62
|
+
remote_a = File.join(Dir.tmpdir, 'hydra', 'remote_a')
|
63
|
+
remote_b = File.join(Dir.tmpdir, 'hydra', 'remote_b')
|
64
|
+
sync_test = File.join(File.dirname(__FILE__), 'fixtures', 'sync_test.rb')
|
65
|
+
[local, remote_a, remote_b].each{|f| FileUtils.rm_rf f; FileUtils.mkdir_p f}
|
66
|
+
|
67
|
+
# setup the folders:
|
68
|
+
# local:
|
69
|
+
# - test_a
|
70
|
+
# remote_a:
|
71
|
+
# - test_b
|
72
|
+
# remote_b:
|
73
|
+
# - test_c
|
74
|
+
#
|
75
|
+
# add test_c to exludes
|
76
|
+
FileUtils.cp(sync_test, File.join(local, 'test_a.rb'))
|
77
|
+
FileUtils.cp(sync_test, File.join(remote_a, 'test_b.rb'))
|
78
|
+
FileUtils.cp(sync_test, File.join(remote_b, 'test_c.rb'))
|
79
|
+
|
80
|
+
# ensure a is not on remotes
|
81
|
+
assert !File.exists?(File.join(remote_a, 'test_a.rb')), "A should not be on remote_a"
|
82
|
+
assert !File.exists?(File.join(remote_b, 'test_a.rb')), "A should not be on remote_b"
|
83
|
+
# ensure b is on remote_a
|
84
|
+
assert File.exists?(File.join(remote_a, 'test_b.rb')), "B should be on remote_a"
|
85
|
+
# ensure c is on remote_b
|
86
|
+
assert File.exists?(File.join(remote_b, 'test_c.rb')), "C should be on remote_b"
|
87
|
+
|
88
|
+
Hydra::Sync.sync_many(
|
89
|
+
:workers => [{
|
90
|
+
:type => :ssh,
|
91
|
+
:connect => 'localhost',
|
92
|
+
:directory => remote_a,
|
93
|
+
:runners => 1
|
94
|
+
},
|
95
|
+
{
|
96
|
+
:type => :ssh,
|
97
|
+
:connect => 'localhost',
|
98
|
+
:directory => remote_b,
|
99
|
+
:runners => 1
|
100
|
+
}],
|
101
|
+
:sync => {
|
102
|
+
:directory => local
|
103
|
+
}
|
104
|
+
)
|
105
|
+
# ensure a is copied to both remotes
|
106
|
+
assert File.exists?(File.join(remote_a, 'test_a.rb')), "A was not copied to remote_a"
|
107
|
+
assert File.exists?(File.join(remote_b, 'test_a.rb')), "A was not copied to remote_b"
|
108
|
+
# ensure b and c are deleted from remotes
|
109
|
+
assert !File.exists?(File.join(remote_a, 'test_b.rb')), "B was not deleted from remote_a"
|
110
|
+
assert !File.exists?(File.join(remote_b, 'test_c.rb')), "C was not deleted from remote_b"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'tmpdir'
|
5
|
+
|
6
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
|
+
require 'hydra'
|
9
|
+
|
10
|
+
# Since Hydra turns off testing, we have to turn it back on
|
11
|
+
Test::Unit.run = false
|
12
|
+
|
13
|
+
class Test::Unit::TestCase
|
14
|
+
def target_file
|
15
|
+
File.expand_path(File.join(Dir.tmpdir, 'hydra_test.txt'))
|
16
|
+
end
|
17
|
+
|
18
|
+
def alternate_target_file
|
19
|
+
File.expand_path(File.join(Dir.tmpdir, 'alternate_hydra_test.txt'))
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_file
|
23
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'write_file.rb'))
|
24
|
+
end
|
25
|
+
|
26
|
+
def rspec_file
|
27
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'write_file_spec.rb'))
|
28
|
+
end
|
29
|
+
|
30
|
+
def alternate_rspec_file
|
31
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'write_file_alternate_spec.rb'))
|
32
|
+
end
|
33
|
+
|
34
|
+
def rspec_file_with_pending
|
35
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'write_file_with_pending_spec.rb'))
|
36
|
+
end
|
37
|
+
|
38
|
+
def cucumber_feature_file
|
39
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'features', 'write_file.feature'))
|
40
|
+
end
|
41
|
+
|
42
|
+
def alternate_cucumber_feature_file
|
43
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'features', 'write_alternate_file.feature'))
|
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
|
+
end
|
54
|
+
|
55
|
+
module Hydra #:nodoc:
|
56
|
+
module Messages #:nodoc:
|
57
|
+
class TestMessage < Hydra::Message
|
58
|
+
attr_accessor :text
|
59
|
+
def initialize(opts = {})
|
60
|
+
@text = opts.fetch(:text){ "test" }
|
61
|
+
end
|
62
|
+
def serialize
|
63
|
+
super(:text => @text)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
data/test/worker_test.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'test_helper')
|
2
|
+
|
3
|
+
class WorkerTest < Test::Unit::TestCase
|
4
|
+
context "with a file to test and a destination to verify" do
|
5
|
+
setup do
|
6
|
+
FileUtils.rm_f(target_file)
|
7
|
+
end
|
8
|
+
|
9
|
+
teardown do
|
10
|
+
FileUtils.rm_f(target_file)
|
11
|
+
end
|
12
|
+
|
13
|
+
# run the worker in the foreground and the requests in the background
|
14
|
+
should "run a test in the foreground" do
|
15
|
+
num_runners = 4
|
16
|
+
pipe = Hydra::Pipe.new
|
17
|
+
child = Process.fork do
|
18
|
+
request_a_file_and_verify_completion(pipe, num_runners)
|
19
|
+
end
|
20
|
+
run_the_worker(pipe, num_runners)
|
21
|
+
Process.wait(child)
|
22
|
+
end
|
23
|
+
|
24
|
+
# inverse of the above test to run the worker in the background
|
25
|
+
should "run a test in the background" do
|
26
|
+
num_runners = 4
|
27
|
+
pipe = Hydra::Pipe.new
|
28
|
+
child = Process.fork do
|
29
|
+
run_the_worker(pipe, num_runners)
|
30
|
+
end
|
31
|
+
request_a_file_and_verify_completion(pipe, num_runners)
|
32
|
+
Process.wait(child)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
module WorkerTestHelper
|
37
|
+
def run_the_worker(pipe, num_runners)
|
38
|
+
pipe.identify_as_child
|
39
|
+
Hydra::Worker.new({:io => pipe, :runners => num_runners})
|
40
|
+
end
|
41
|
+
|
42
|
+
def request_a_file_and_verify_completion(pipe, num_runners)
|
43
|
+
pipe.identify_as_parent
|
44
|
+
pipe.gets # grab the WorkerBegin
|
45
|
+
num_runners.times do
|
46
|
+
response = pipe.gets # grab the RequestFile
|
47
|
+
assert response.is_a?(Hydra::Messages::Worker::RequestFile), "Expected RequestFile but got #{response.class.to_s}"
|
48
|
+
end
|
49
|
+
pipe.write(Hydra::Messages::Master::RunFile.new(:file => test_file))
|
50
|
+
|
51
|
+
assert pipe.gets.is_a?(Hydra::Messages::Worker::Results)
|
52
|
+
|
53
|
+
pipe.write(Hydra::Messages::Master::Shutdown.new)
|
54
|
+
|
55
|
+
assert File.exists?(target_file)
|
56
|
+
assert_equal "HYDRA", File.read(target_file)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
include WorkerTestHelper
|
60
|
+
end
|