nulogy-hydra 0.23.2.1

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 (75) hide show
  1. data/.document +5 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +39 -0
  4. data/Rakefile +56 -0
  5. data/TODO +18 -0
  6. data/VERSION +1 -0
  7. data/caliper.yml +6 -0
  8. data/hydra-icon-64x64.png +0 -0
  9. data/hydra.gemspec +131 -0
  10. data/hydra_gray.png +0 -0
  11. data/lib/hydra/cucumber/formatter.rb +29 -0
  12. data/lib/hydra/hash.rb +16 -0
  13. data/lib/hydra/js/lint.js +5150 -0
  14. data/lib/hydra/listener/abstract.rb +39 -0
  15. data/lib/hydra/listener/minimal_output.rb +24 -0
  16. data/lib/hydra/listener/notifier.rb +17 -0
  17. data/lib/hydra/listener/progress_bar.rb +48 -0
  18. data/lib/hydra/listener/report_generator.rb +31 -0
  19. data/lib/hydra/master.rb +252 -0
  20. data/lib/hydra/message/master_messages.rb +19 -0
  21. data/lib/hydra/message/runner_messages.rb +46 -0
  22. data/lib/hydra/message/worker_messages.rb +52 -0
  23. data/lib/hydra/message.rb +47 -0
  24. data/lib/hydra/messaging_io.rb +49 -0
  25. data/lib/hydra/pipe.rb +61 -0
  26. data/lib/hydra/proxy_config.rb +27 -0
  27. data/lib/hydra/runner.rb +306 -0
  28. data/lib/hydra/runner_listener/abstract.rb +23 -0
  29. data/lib/hydra/safe_fork.rb +31 -0
  30. data/lib/hydra/spec/autorun_override.rb +3 -0
  31. data/lib/hydra/spec/hydra_formatter.rb +26 -0
  32. data/lib/hydra/ssh.rb +41 -0
  33. data/lib/hydra/stdio.rb +16 -0
  34. data/lib/hydra/sync.rb +99 -0
  35. data/lib/hydra/tasks.rb +366 -0
  36. data/lib/hydra/threadsafe_io.rb +18 -0
  37. data/lib/hydra/tmpdir.rb +11 -0
  38. data/lib/hydra/trace.rb +29 -0
  39. data/lib/hydra/worker.rb +168 -0
  40. data/lib/hydra.rb +16 -0
  41. data/nulogy-hydra.gemspec +122 -0
  42. data/test/fixtures/assert_true.rb +7 -0
  43. data/test/fixtures/bad_proxy_config.yml +4 -0
  44. data/test/fixtures/config.yml +4 -0
  45. data/test/fixtures/conflicting.rb +10 -0
  46. data/test/fixtures/features/step_definitions.rb +21 -0
  47. data/test/fixtures/features/write_alternate_file.feature +7 -0
  48. data/test/fixtures/features/write_file.feature +7 -0
  49. data/test/fixtures/hello_world.rb +3 -0
  50. data/test/fixtures/hydra_worker_init.rb +2 -0
  51. data/test/fixtures/js_file.js +4 -0
  52. data/test/fixtures/json_data.json +4 -0
  53. data/test/fixtures/many_outputs_to_console.rb +9 -0
  54. data/test/fixtures/master_listeners.rb +10 -0
  55. data/test/fixtures/proxy_config.yml +4 -0
  56. data/test/fixtures/proxy_config_http.yml +4 -0
  57. data/test/fixtures/runner_listeners.rb +23 -0
  58. data/test/fixtures/slow.rb +9 -0
  59. data/test/fixtures/sync_test.rb +8 -0
  60. data/test/fixtures/task_test_config.yml +6 -0
  61. data/test/fixtures/write_file.rb +10 -0
  62. data/test/fixtures/write_file_alternate_spec.rb +10 -0
  63. data/test/fixtures/write_file_spec.rb +9 -0
  64. data/test/fixtures/write_file_with_pending_spec.rb +11 -0
  65. data/test/master_test.rb +383 -0
  66. data/test/message_test.rb +31 -0
  67. data/test/pipe_test.rb +38 -0
  68. data/test/proxy_config_test.rb +31 -0
  69. data/test/runner_test.rb +196 -0
  70. data/test/ssh_test.rb +25 -0
  71. data/test/sync_test.rb +113 -0
  72. data/test/task_test.rb +21 -0
  73. data/test/test_helper.rb +107 -0
  74. data/test/worker_test.rb +60 -0
  75. metadata +208 -0
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
+
@@ -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
metadata ADDED
@@ -0,0 +1,208 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nulogy-hydra
3
+ version: !ruby/object:Gem::Version
4
+ hash: 253
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 23
9
+ - 2
10
+ - 1
11
+ version: 0.23.2.1
12
+ platform: ruby
13
+ authors:
14
+ - Nick Gauthier
15
+ - Justin Fitzsimmons
16
+ - Victor Savkin
17
+ autorequire:
18
+ bindir: bin
19
+ cert_chain: []
20
+
21
+ date: 2011-11-09 00:00:00 Z
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: shoulda
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ none: false
28
+ requirements:
29
+ - - "="
30
+ - !ruby/object:Gem::Version
31
+ hash: 33
32
+ segments:
33
+ - 2
34
+ - 10
35
+ - 3
36
+ version: 2.10.3
37
+ type: :development
38
+ version_requirements: *id001
39
+ - !ruby/object:Gem::Dependency
40
+ name: rspec
41
+ prerelease: false
42
+ requirement: &id002 !ruby/object:Gem::Requirement
43
+ none: false
44
+ requirements:
45
+ - - "="
46
+ - !ruby/object:Gem::Version
47
+ hash: 62196421
48
+ segments:
49
+ - 2
50
+ - 0
51
+ - 0
52
+ - beta
53
+ - 19
54
+ version: 2.0.0.beta.19
55
+ type: :development
56
+ version_requirements: *id002
57
+ - !ruby/object:Gem::Dependency
58
+ name: cucumber
59
+ prerelease: false
60
+ requirement: &id003 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - "="
64
+ - !ruby/object:Gem::Version
65
+ hash: 63
66
+ segments:
67
+ - 0
68
+ - 9
69
+ - 2
70
+ version: 0.9.2
71
+ type: :development
72
+ version_requirements: *id003
73
+ - !ruby/object:Gem::Dependency
74
+ name: therubyracer
75
+ prerelease: false
76
+ requirement: &id004 !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - "="
80
+ - !ruby/object:Gem::Version
81
+ hash: 11
82
+ segments:
83
+ - 0
84
+ - 7
85
+ - 4
86
+ version: 0.7.4
87
+ type: :development
88
+ version_requirements: *id004
89
+ description: Spread your tests over multiple machines to test your code faster.
90
+ email: engineering@nulogy.com
91
+ executables: []
92
+
93
+ extensions: []
94
+
95
+ extra_rdoc_files:
96
+ - LICENSE
97
+ - README.rdoc
98
+ - TODO
99
+ files:
100
+ - .document
101
+ - LICENSE
102
+ - README.rdoc
103
+ - Rakefile
104
+ - TODO
105
+ - VERSION
106
+ - caliper.yml
107
+ - hydra-icon-64x64.png
108
+ - hydra.gemspec
109
+ - hydra_gray.png
110
+ - lib/hydra.rb
111
+ - lib/hydra/cucumber/formatter.rb
112
+ - lib/hydra/hash.rb
113
+ - lib/hydra/js/lint.js
114
+ - lib/hydra/listener/abstract.rb
115
+ - lib/hydra/listener/minimal_output.rb
116
+ - lib/hydra/listener/notifier.rb
117
+ - lib/hydra/listener/progress_bar.rb
118
+ - lib/hydra/listener/report_generator.rb
119
+ - lib/hydra/master.rb
120
+ - lib/hydra/message.rb
121
+ - lib/hydra/message/master_messages.rb
122
+ - lib/hydra/message/runner_messages.rb
123
+ - lib/hydra/message/worker_messages.rb
124
+ - lib/hydra/messaging_io.rb
125
+ - lib/hydra/pipe.rb
126
+ - lib/hydra/proxy_config.rb
127
+ - lib/hydra/runner.rb
128
+ - lib/hydra/runner_listener/abstract.rb
129
+ - lib/hydra/safe_fork.rb
130
+ - lib/hydra/spec/autorun_override.rb
131
+ - lib/hydra/spec/hydra_formatter.rb
132
+ - lib/hydra/ssh.rb
133
+ - lib/hydra/stdio.rb
134
+ - lib/hydra/sync.rb
135
+ - lib/hydra/tasks.rb
136
+ - lib/hydra/threadsafe_io.rb
137
+ - lib/hydra/tmpdir.rb
138
+ - lib/hydra/trace.rb
139
+ - lib/hydra/worker.rb
140
+ - nulogy-hydra.gemspec
141
+ - test/fixtures/assert_true.rb
142
+ - test/fixtures/bad_proxy_config.yml
143
+ - test/fixtures/config.yml
144
+ - test/fixtures/conflicting.rb
145
+ - test/fixtures/features/step_definitions.rb
146
+ - test/fixtures/features/write_alternate_file.feature
147
+ - test/fixtures/features/write_file.feature
148
+ - test/fixtures/hello_world.rb
149
+ - test/fixtures/hydra_worker_init.rb
150
+ - test/fixtures/js_file.js
151
+ - test/fixtures/json_data.json
152
+ - test/fixtures/many_outputs_to_console.rb
153
+ - test/fixtures/master_listeners.rb
154
+ - test/fixtures/proxy_config.yml
155
+ - test/fixtures/proxy_config_http.yml
156
+ - test/fixtures/runner_listeners.rb
157
+ - test/fixtures/slow.rb
158
+ - test/fixtures/sync_test.rb
159
+ - test/fixtures/task_test_config.yml
160
+ - test/fixtures/write_file.rb
161
+ - test/fixtures/write_file_alternate_spec.rb
162
+ - test/fixtures/write_file_spec.rb
163
+ - test/fixtures/write_file_with_pending_spec.rb
164
+ - test/master_test.rb
165
+ - test/message_test.rb
166
+ - test/pipe_test.rb
167
+ - test/proxy_config_test.rb
168
+ - test/runner_test.rb
169
+ - test/ssh_test.rb
170
+ - test/sync_test.rb
171
+ - test/task_test.rb
172
+ - test/test_helper.rb
173
+ - test/worker_test.rb
174
+ homepage: http://github.com/nulogy/hydra
175
+ licenses: []
176
+
177
+ post_install_message:
178
+ rdoc_options: []
179
+
180
+ require_paths:
181
+ - lib
182
+ required_ruby_version: !ruby/object:Gem::Requirement
183
+ none: false
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ hash: 3
188
+ segments:
189
+ - 0
190
+ version: "0"
191
+ required_rubygems_version: !ruby/object:Gem::Requirement
192
+ none: false
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ hash: 3
197
+ segments:
198
+ - 0
199
+ version: "0"
200
+ requirements: []
201
+
202
+ rubyforge_project:
203
+ rubygems_version: 1.8.10
204
+ signing_key:
205
+ specification_version: 3
206
+ summary: Distributed testing toolkit
207
+ test_files: []
208
+