ngauthier-hydra 0.24.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 (73) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.rdoc +51 -0
  6. data/Rakefile +8 -0
  7. data/TODO +18 -0
  8. data/hydra-icon-64x64.png +0 -0
  9. data/hydra.gemspec +24 -0
  10. data/hydra_gray.png +0 -0
  11. data/lib/hydra.rb +16 -0
  12. data/lib/hydra/cucumber/formatter.rb +29 -0
  13. data/lib/hydra/cucumber/partial_html.rb +24 -0
  14. data/lib/hydra/hash.rb +16 -0
  15. data/lib/hydra/js/lint.js +5150 -0
  16. data/lib/hydra/listener/abstract.rb +39 -0
  17. data/lib/hydra/listener/cucumber.css +279 -0
  18. data/lib/hydra/listener/cucumber_html_report.rb +148 -0
  19. data/lib/hydra/listener/jquery-min.js +154 -0
  20. data/lib/hydra/listener/minimal_output.rb +24 -0
  21. data/lib/hydra/listener/notifier.rb +17 -0
  22. data/lib/hydra/listener/progress_bar.rb +48 -0
  23. data/lib/hydra/listener/report_generator.rb +33 -0
  24. data/lib/hydra/master.rb +248 -0
  25. data/lib/hydra/message.rb +47 -0
  26. data/lib/hydra/message/master_messages.rb +19 -0
  27. data/lib/hydra/message/runner_messages.rb +46 -0
  28. data/lib/hydra/message/worker_messages.rb +52 -0
  29. data/lib/hydra/messaging_io.rb +49 -0
  30. data/lib/hydra/pipe.rb +61 -0
  31. data/lib/hydra/runner.rb +312 -0
  32. data/lib/hydra/runner_listener/abstract.rb +23 -0
  33. data/lib/hydra/safe_fork.rb +31 -0
  34. data/lib/hydra/spec/autorun_override.rb +3 -0
  35. data/lib/hydra/spec/hydra_formatter.rb +26 -0
  36. data/lib/hydra/ssh.rb +41 -0
  37. data/lib/hydra/stdio.rb +16 -0
  38. data/lib/hydra/sync.rb +99 -0
  39. data/lib/hydra/tasks.rb +375 -0
  40. data/lib/hydra/tmpdir.rb +11 -0
  41. data/lib/hydra/trace.rb +24 -0
  42. data/lib/hydra/version.rb +3 -0
  43. data/lib/hydra/worker.rb +170 -0
  44. data/test/fixtures/assert_true.rb +7 -0
  45. data/test/fixtures/config.yml +4 -0
  46. data/test/fixtures/conflicting.rb +10 -0
  47. data/test/fixtures/features/step_definitions.rb +21 -0
  48. data/test/fixtures/features/write_alternate_file.feature +7 -0
  49. data/test/fixtures/features/write_file.feature +7 -0
  50. data/test/fixtures/hello_world.rb +3 -0
  51. data/test/fixtures/hydra_worker_init.rb +2 -0
  52. data/test/fixtures/js_file.js +4 -0
  53. data/test/fixtures/json_data.json +4 -0
  54. data/test/fixtures/many_outputs_to_console.rb +9 -0
  55. data/test/fixtures/master_listeners.rb +10 -0
  56. data/test/fixtures/runner_listeners.rb +23 -0
  57. data/test/fixtures/slow.rb +9 -0
  58. data/test/fixtures/sync_test.rb +8 -0
  59. data/test/fixtures/task_test_config.yml +6 -0
  60. data/test/fixtures/write_file.rb +10 -0
  61. data/test/fixtures/write_file_alternate_spec.rb +10 -0
  62. data/test/fixtures/write_file_spec.rb +9 -0
  63. data/test/fixtures/write_file_with_pending_spec.rb +11 -0
  64. data/test/master_test.rb +383 -0
  65. data/test/message_test.rb +31 -0
  66. data/test/pipe_test.rb +38 -0
  67. data/test/runner_test.rb +196 -0
  68. data/test/ssh_test.rb +25 -0
  69. data/test/sync_test.rb +113 -0
  70. data/test/task_test.rb +21 -0
  71. data/test/test_helper.rb +107 -0
  72. data/test/worker_test.rb +60 -0
  73. metadata +229 -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
@@ -0,0 +1,196 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+ require File.join(File.dirname(__FILE__), 'fixtures', 'runner_listeners')
3
+
4
+ class RunnerTest < Test::Unit::TestCase
5
+ context "with a file to test and a destination to verify" do
6
+ setup do
7
+ sleep(0.2)
8
+ FileUtils.rm_f(target_file)
9
+ FileUtils.rm_f(alternate_target_file)
10
+ end
11
+
12
+ teardown do
13
+ FileUtils.rm_f(target_file)
14
+ FileUtils.rm_f(alternate_target_file)
15
+ end
16
+
17
+
18
+ should "run a test in the foreground" do
19
+ # flip it around to the parent is in the fork, this gives
20
+ # us more direct control over the runner and proper test
21
+ # coverage output
22
+ pipe = Hydra::Pipe.new
23
+ parent = Process.fork do
24
+ request_a_file_and_verify_completion(pipe, test_file)
25
+ end
26
+ run_the_runner(pipe)
27
+ Process.wait(parent)
28
+ end
29
+
30
+ # this flips the above test, so that the main process runs a bit of the parent
31
+ # code, but only with minimal assertion
32
+ should "run a test in the background" do
33
+ pipe = Hydra::Pipe.new
34
+ child = Process.fork do
35
+ run_the_runner(pipe)
36
+ end
37
+ request_a_file_and_verify_completion(pipe, test_file)
38
+ Process.wait(child)
39
+ end
40
+
41
+ should "run a js lint file and find errors" do
42
+ runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
43
+ results = runner.run_file(javascript_file)
44
+ assert results =~ /Missing semicolon/, results
45
+ end
46
+
47
+ should "run a json data file and find errors" do
48
+ runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
49
+ results = runner.run_file(json_file)
50
+ assert results =~ /trailing comma/, results
51
+ end
52
+
53
+ should "run two rspec tests" do
54
+ runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
55
+ runner.run_file(rspec_file)
56
+ assert File.exists?(target_file)
57
+ assert_equal "HYDRA", File.read(target_file)
58
+
59
+ FileUtils.rm_f(target_file)
60
+
61
+ runner.run_file(alternate_rspec_file)
62
+ assert File.exists?(alternate_target_file)
63
+ assert_equal "HYDRA", File.read(alternate_target_file)
64
+ assert !File.exists?(target_file), "Tests are double running!"
65
+ end
66
+
67
+ should "run rspec tests with pending examples" do
68
+ runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
69
+ assert File.exists?(rspec_file_with_pending)
70
+
71
+ runner.run_file(rspec_file_with_pending)
72
+
73
+ assert File.exists?(target_file)
74
+ assert_equal "HYDRA", File.read(target_file)
75
+
76
+ FileUtils.rm_f(target_file)
77
+ end
78
+
79
+ should "run two cucumber tests" do
80
+ # because of all the crap cucumber pulls in
81
+ # we run this in a fork to not contaminate
82
+ # the main test environment
83
+ capture_stderr do # redirect stderr
84
+ pid = Process.fork do
85
+ runner = Hydra::Runner.new(:io => File.new('/dev/null', 'w'))
86
+ runner.run_file(cucumber_feature_file)
87
+ assert File.exists?(target_file)
88
+ assert_equal "HYDRA", File.read(target_file)
89
+
90
+ FileUtils.rm_f(target_file)
91
+
92
+ runner.run_file(alternate_cucumber_feature_file)
93
+ assert File.exists?(alternate_target_file)
94
+ assert_equal "HYDRA", File.read(alternate_target_file)
95
+ assert !File.exists?(target_file)
96
+ end
97
+ Process.wait pid
98
+ end
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
+
126
+ context "using runner events" do
127
+ context "on successful termination" do
128
+ setup do
129
+ @pipe = Hydra::Pipe.new
130
+ @parent = Process.fork do
131
+ request_a_file_and_verify_completion(@pipe, test_file)
132
+ end
133
+ end
134
+
135
+ should "fire runner_begin event" do
136
+ run_the_runner(@pipe, [HydraExtension::RunnerListener::RunnerBeginTest.new] )
137
+ Process.wait(@parent)
138
+
139
+ # ensure runner_begin was fired
140
+ assert_file_exists alternate_target_file
141
+ end
142
+
143
+ should "fire runner_end event" do
144
+ run_the_runner(@pipe, [HydraExtension::RunnerListener::RunnerEndTest.new] )
145
+ Process.wait(@parent)
146
+
147
+ assert_file_exists alternate_target_file
148
+ end
149
+ end
150
+
151
+ should "fire runner_end event after losing communication with worker" do
152
+ pipe = Hydra::Pipe.new
153
+ parent = Process.fork do
154
+ pipe.identify_as_parent
155
+
156
+ # grab its response.
157
+ response = pipe.gets
158
+ pipe.close #this will be detected by the runner and it should call runner_end
159
+ end
160
+
161
+ run_the_runner(pipe, [HydraExtension::RunnerListener::RunnerEndTest.new] )
162
+ Process.wait(parent)
163
+
164
+ # ensure runner_end was fired
165
+ assert File.exists?( alternate_target_file )
166
+ end
167
+ end
168
+ end
169
+
170
+ module RunnerTestHelper
171
+ def request_a_file_and_verify_completion(pipe, file)
172
+ pipe.identify_as_parent
173
+
174
+ # make sure it asks for a file, then give it one
175
+ assert pipe.gets.is_a?(Hydra::Messages::Runner::RequestFile)
176
+ pipe.write(Hydra::Messages::Worker::RunFile.new(:file => file))
177
+
178
+ # grab its response. This makes us wait for it to finish
179
+ response = pipe.gets
180
+
181
+ # tell it to shut down
182
+ pipe.write(Hydra::Messages::Worker::Shutdown.new)
183
+
184
+ # ensure it ran
185
+ assert File.exists?(target_file)
186
+ assert_equal "HYDRA", File.read(target_file)
187
+ end
188
+
189
+ def run_the_runner(pipe, listeners = [])
190
+ pipe.identify_as_child
191
+ Hydra::Runner.new( :io => pipe, :runner_listeners => listeners )
192
+ end
193
+ end
194
+ include RunnerTestHelper
195
+ end
196
+
data/test/ssh_test.rb ADDED
@@ -0,0 +1,25 @@
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
+
15
+ should "be able to handle a large number of non-Hydra console output" do
16
+ ssh = Hydra::SSH.new(
17
+ 'localhost', # connect to this machine
18
+ File.expand_path(File.join(File.dirname(__FILE__))), # move to the test directory
19
+ "ruby fixtures/many_outputs_to_console.rb"
20
+ )
21
+ response = ssh.gets
22
+ assert_equal "My message", response.text
23
+ ssh.close
24
+ end
25
+ 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.consistent_tmpdir, 'hydra', 'local')
17
+ remote = File.join(Dir.consistent_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.consistent_tmpdir, 'hydra', 'local')
62
+ remote_a = File.join(Dir.consistent_tmpdir, 'hydra', 'remote_a')
63
+ remote_b = File.join(Dir.consistent_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/task_test.rb ADDED
@@ -0,0 +1,21 @@
1
+ require File.join(File.dirname(__FILE__), 'test_helper')
2
+ require 'hydra/tasks'
3
+ require 'rake'
4
+
5
+ class TaskTest < Test::Unit::TestCase
6
+ context "a task" do
7
+ should "execute the command in a remote machine" do
8
+
9
+ File.delete( "/tmp/new_file" ) if File.exists? "/tmp/new_file"
10
+
11
+ Hydra::RemoteTask.new('cat:text_file', 'touch new_file') do |t|
12
+ t.config = "test/fixtures/task_test_config.yml"
13
+ end
14
+
15
+ Rake.application['hydra:remote:cat:text_file'].invoke
16
+
17
+ assert( File.exists? "/tmp/new_file" )
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,107 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ gem 'shoulda', '2.10.3'
4
+ gem 'rspec', '2.0.0.beta.19'
5
+ require 'shoulda'
6
+ require 'tmpdir'
7
+ require "stringio"
8
+
9
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
10
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
11
+ require 'hydra'
12
+
13
+ # Since Hydra turns off testing, we have to turn it back on
14
+ Test::Unit.run = false
15
+
16
+ class Test::Unit::TestCase
17
+ def target_file
18
+ File.expand_path(File.join(Dir.consistent_tmpdir, 'hydra_test.txt'))
19
+ end
20
+
21
+ def alternate_target_file
22
+ File.expand_path(File.join(Dir.consistent_tmpdir, 'alternate_hydra_test.txt'))
23
+ end
24
+
25
+ def test_file
26
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'write_file.rb'))
27
+ end
28
+
29
+ def rspec_file
30
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'write_file_spec.rb'))
31
+ end
32
+
33
+ def alternate_rspec_file
34
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'write_file_alternate_spec.rb'))
35
+ end
36
+
37
+ def rspec_file_with_pending
38
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'write_file_with_pending_spec.rb'))
39
+ end
40
+
41
+ def cucumber_feature_file
42
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'features', 'write_file.feature'))
43
+ end
44
+
45
+ def alternate_cucumber_feature_file
46
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'features', 'write_alternate_file.feature'))
47
+ end
48
+
49
+ def javascript_file
50
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'js_file.js'))
51
+ end
52
+
53
+ def json_file
54
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'json_data.json'))
55
+ end
56
+
57
+ def conflicting_test_file
58
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'conflicting.rb'))
59
+ end
60
+
61
+ def remote_dir_path
62
+ File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib'))
63
+ end
64
+
65
+ def hydra_worker_init_file
66
+ File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'hydra_worker_init.rb'))
67
+ end
68
+
69
+ def capture_stderr
70
+ # The output stream must be an IO-like object. In this case we capture it in
71
+ # an in-memory IO object so we can return the string value. You can assign any
72
+ # IO object here.
73
+ previous_stderr, $stderr = $stderr, StringIO.new
74
+ yield
75
+ $stderr.string
76
+ ensure
77
+ # Restore the previous value of stderr (typically equal to STDERR).
78
+ $stderr = previous_stderr
79
+ end
80
+
81
+ #this method allow us to wait for a file for a maximum number of time, so the
82
+ #test can pass in slower machines. This helps to speed up the tests
83
+ def assert_file_exists file, time_to_wait = 2
84
+ time_begin = Time.now
85
+
86
+ until Time.now - time_begin >= time_to_wait or File.exists?( file ) do
87
+ sleep 0.01
88
+ end
89
+
90
+ assert File.exists?( file )
91
+ end
92
+ end
93
+
94
+ module Hydra #:nodoc:
95
+ module Messages #:nodoc:
96
+ class TestMessage < Hydra::Message
97
+ attr_accessor :text
98
+ def initialize(opts = {})
99
+ @text = opts.fetch(:text){ "test" }
100
+ end
101
+ def serialize
102
+ super(:text => @text)
103
+ end
104
+ end
105
+ end
106
+ end
107
+