xing-gearman-ruby 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift('../lib')
4
+ require 'gearman'
5
+ require 'gearman/testlib'
6
+ require 'test/unit'
7
+ require 'thread'
8
+
9
+ Thread.abort_on_exception = true
10
+
11
+ class TestWorker < Test::Unit::TestCase
12
+ def setup
13
+ @server = FakeJobServer.new(self)
14
+ @server2 = FakeJobServer.new(self)
15
+ end
16
+
17
+ def teardown
18
+ @server.stop
19
+ @server2.stop
20
+ end
21
+
22
+ def test_complete
23
+ @server = FakeJobServer.new(self)
24
+ worker = nil
25
+ sock = nil
26
+
27
+ s = TestScript.new
28
+ w = TestScript.new
29
+
30
+ server_thread = Thread.new { s.loop_forever }.run
31
+ worker_thread = Thread.new { w.loop_forever }.run
32
+
33
+ # Create a worker and wait for it to connect to us.
34
+ w.exec {
35
+ worker = Gearman::Worker.new(
36
+ "localhost:#{@server.port}", { :client_id => 'test' })
37
+ }
38
+ s.exec { sock = @server.expect_connection }
39
+ s.wait
40
+
41
+ # After it connects, it should send its ID, and it should tell us its
42
+ # abilities when we report them.
43
+ s.exec { @server.expect_request(sock, :set_client_id, 'test') }
44
+ w.exec { worker.add_ability('echo') {|d,j| j.report_status(1, 1); d } }
45
+ s.exec { @server.expect_request(sock, :can_do, 'echo') }
46
+
47
+ # It should try to grab a job when we tell it to work.
48
+ w.exec { worker.work }
49
+ s.exec { @server.expect_request(sock, :grab_job) }
50
+
51
+ # If we tell it there aren't any jobs, it should go to sleep.
52
+ s.exec { @server.send_response(sock, :no_job) }
53
+ s.exec { @server.expect_request(sock, :pre_sleep) }
54
+
55
+ # When we send it a noop, it should wake up and ask for a job again.
56
+ s.exec { @server.send_response(sock, :noop) }
57
+ s.exec { @server.expect_request(sock, :grab_job) }
58
+
59
+ # When we give it a job, it should do it.
60
+ s.exec { @server.send_response(sock, :job_assign, "a\0echo\0foo") }
61
+ s.exec { @server.expect_request(sock, :work_status, "a\0001\0001") }
62
+ s.exec { @server.expect_request(sock, :work_complete, "a\0foo") }
63
+
64
+ # Test that functions are unregistered correctly.
65
+ w.exec { worker.remove_ability('echo') }
66
+ s.exec { @server.expect_request(sock, :cant_do, 'echo') }
67
+ s.wait
68
+ end
69
+
70
+ def test_multiple_servers
71
+ # This is cheesy. We want to know the order that Worker#work will
72
+ # iterate through the servers, so we make sure that server1 will be the
73
+ # first one when the names are lexographically sorted.
74
+ if @server2.port.to_s < @server.port.to_s
75
+ tmp = @server
76
+ @server = @server2
77
+ @server2 = tmp
78
+ end
79
+ worker = nil
80
+ sock1, sock2 = nil
81
+
82
+ s1 = TestScript.new
83
+ s2 = TestScript.new
84
+ w = TestScript.new
85
+
86
+ @server_thread = Thread.new { s1.loop_forever }.run
87
+ @server2_thread = Thread.new { s2.loop_forever }.run
88
+ worker_thread = Thread.new { w.loop_forever }.run
89
+
90
+ # Create a worker, which should connect to both servers.
91
+ w.exec {
92
+ worker = Gearman::Worker.new(
93
+ nil, { :client_id => 'test', :reconnect_sec => 0.1 }) }
94
+ w.exec { worker.add_ability('foo') {|d,j| 'bar' } }
95
+ w.exec {
96
+ worker.job_servers =
97
+ [ "localhost:#{@server.port}", "localhost:#{@server2.port}" ]
98
+ }
99
+ s1.exec { sock1 = @server.expect_connection }
100
+ s2.exec { sock2 = @server2.expect_connection }
101
+ s1.wait
102
+ s2.wait
103
+
104
+ # It should register itself with both.
105
+ s1.exec { @server.expect_request(sock1, :set_client_id, 'test') }
106
+ s1.exec { @server.expect_request(sock1, :can_do, 'foo') }
107
+ s2.exec { @server2.expect_request(sock2, :set_client_id, 'test') }
108
+ s2.exec { @server2.expect_request(sock2, :can_do, 'foo') }
109
+
110
+ # It should try to get a job from both servers and then sleep.
111
+ w.exec { worker.work }
112
+ s1.exec { @server.expect_request(sock1, :grab_job) }
113
+ s1.exec { @server.send_response(sock1, :no_job) }
114
+ s2.exec { @server2.expect_request(sock2, :grab_job) }
115
+ s2.exec { @server2.send_response(sock2, :no_job) }
116
+ s1.exec { @server.expect_request(sock1, :pre_sleep) }
117
+ s2.exec { @server2.expect_request(sock2, :pre_sleep) }
118
+
119
+ # If the second server wakes it up, it should again try to get a job
120
+ # and then do it.
121
+ s2.exec { @server2.send_response(sock2, :noop) }
122
+ s1.exec { @server.expect_request(sock1, :grab_job) }
123
+ s1.exec { @server.send_response(sock1, :no_job) }
124
+ s2.exec { @server2.expect_request(sock2, :grab_job) }
125
+ s2.exec { @server2.send_response(sock2, :job_assign, "a\0foo\0") }
126
+ s2.exec { @server2.expect_request(sock2, :work_complete, "a\0bar") }
127
+
128
+ w.wait
129
+ s1.wait
130
+ s2.wait
131
+
132
+ # Stop the first job server and make the worker try to reconnect to
133
+ # both.
134
+ old_servers = worker.job_servers
135
+ @server.stop
136
+ worker.job_servers = []
137
+ worker.job_servers = old_servers
138
+ s2.exec { sock2 = @server2.expect_connection }
139
+ s2.wait
140
+
141
+ # It shouldn't have any trouble with the second server. Tell it to go
142
+ # to work.
143
+ s2.exec { @server2.expect_request(sock2, :set_client_id, 'test') }
144
+ s2.exec { @server2.expect_request(sock2, :can_do, 'foo') }
145
+ w.exec { worker.work }
146
+ s2.exec { @server2.expect_request(sock2, :grab_job) }
147
+ s2.exec { @server2.send_response(sock2, :no_job) }
148
+ s2.exec { @server2.expect_request(sock2, :pre_sleep) }
149
+ s2.wait
150
+
151
+ # Start the first server and wait for the worker to connect to it and
152
+ # register.
153
+ @server.start
154
+ s1.exec { sock1 = @server.expect_connection }
155
+ s1.wait
156
+ s1.exec { @server.expect_request(sock1, :set_client_id, 'test') }
157
+ s1.exec { @server.expect_request(sock1, :can_do, 'foo') }
158
+ s1.wait
159
+
160
+ # Let the second server wake the worker up and then give it a job.
161
+ s2.exec { @server2.send_response(sock2, :noop) }
162
+ s1.exec { @server.expect_request(sock1, :grab_job) }
163
+ s1.exec { @server.send_response(sock1, :no_job) }
164
+ s2.exec { @server2.expect_request(sock2, :grab_job) }
165
+ s2.exec { @server2.send_response(sock2, :job_assign, "a\0foo\0") }
166
+ s2.exec { @server2.expect_request(sock2, :work_complete, "a\0bar") }
167
+ s1.wait
168
+ s2.wait
169
+ w.wait
170
+ end
171
+
172
+ def test_timeout
173
+ worker = nil
174
+ sock = nil
175
+
176
+ s = TestScript.new
177
+ w = TestScript.new
178
+
179
+ server_thread = Thread.new { s.loop_forever }.run
180
+ worker_thread = Thread.new { w.loop_forever }.run
181
+
182
+ w.exec {
183
+ worker = Gearman::Worker.new("localhost:#{@server.port}",
184
+ { :client_id => 'test',
185
+ :reconnect_sec => 0.15,
186
+ :network_timeout_sec => 0.1 })
187
+ }
188
+ s.exec { sock = @server.expect_connection }
189
+ s.wait
190
+ s.exec { @server.expect_request(sock, :set_client_id, 'test') }
191
+
192
+ w.exec { worker.add_ability('foo') {|d,j| 'bar' } }
193
+ s.exec { @server.expect_request(sock, :can_do, 'foo') }
194
+
195
+ # Don't do anything after the client asks for a job.
196
+ w.exec { worker.work }
197
+ s.exec { @server.expect_request(sock, :grab_job) }
198
+ s.exec { sleep 0.16 }
199
+ s.wait
200
+
201
+ # The client should reconnect and ask for a job again.
202
+ s.exec { sock = @server.expect_connection }
203
+ s.wait
204
+
205
+ s.exec { @server.expect_request(sock, :set_client_id, 'test') }
206
+ s.exec { @server.expect_request(sock, :can_do, 'foo') }
207
+ s.exec { @server.expect_request(sock, :grab_job) }
208
+ s.exec { @server.send_response(sock, :job_assign, "a\0foo\0") }
209
+ s.exec { @server.expect_request(sock, :work_complete, "a\0bar") }
210
+ s.wait
211
+ w.wait
212
+ end
213
+ end
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'mocha'
4
+
5
+ $:.unshift('../lib')
6
+ require 'gearman'
7
+ require 'gearman/testlib'
8
+ require 'test/unit'
9
+
10
+ class TestClient < Test::Unit::TestCase
11
+ ##
12
+ # Test Gearman::Worker::Ability.
13
+ def test_ability
14
+ data, job = nil
15
+ ability = Gearman::Worker::Ability.new(
16
+ Proc.new {|d, j| data = d; job = j; true }, 5)
17
+ assert_equal(5, ability.timeout)
18
+ assert_equal(true, ability.run(1, 2))
19
+ assert_equal(1, data)
20
+ assert_equal(2, job)
21
+ end
22
+
23
+ ##
24
+ # Test Gearman::Worker::Job.
25
+ def test_job
26
+ server = FakeJobServer.new(self)
27
+ Thread.new do
28
+ sock = TCPSocket.new('localhost', server.port)
29
+ job = Gearman::Worker::Job.new(sock, 'handle')
30
+ job.report_status(10, 20)
31
+ end.run
32
+ sock = server.expect_connection
33
+ server.expect_request(sock, :work_status, "handle\00010\00020")
34
+ end
35
+
36
+
37
+ def test_job_reconnection
38
+ server = FakeJobServer.new(self)
39
+ Thread.new do
40
+ sock = server.expect_connection
41
+ server.expect_anything_and_close_socket(sock)
42
+ end
43
+
44
+ servers = ["localhost:#{server.port}"]
45
+ w = Gearman::Worker.new(servers)
46
+ Gearman::Util.stubs(:send_request).raises(Exception.new)
47
+ w.add_ability('sleep') do |data,job|
48
+ seconds = data
49
+ (1..seconds.to_i).each do |i|
50
+ sleep 1
51
+ print i
52
+ # Report our progress to the job server every second.
53
+ job.report_status(i, seconds)
54
+ end
55
+ # Report success.
56
+ true
57
+ end
58
+
59
+ assert(w.bad_servers.size == 1)
60
+ end
61
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xing-gearman-ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Daniel Erat
8
+ - Ladislav Martincik
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-06-25 00:00:00 -07:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Library for the Gearman distributed job system
18
+ email: ladislav.martincik@xing.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - LICENSE
25
+ - README
26
+ files:
27
+ - .gitignore
28
+ - LICENSE
29
+ - README
30
+ - Rakefile
31
+ - VERSION.yml
32
+ - examples/Net/Gearman/Client.php
33
+ - examples/Net/Gearman/Connection.php
34
+ - examples/Net/Gearman/Exception.php
35
+ - examples/Net/Gearman/Job.php
36
+ - examples/Net/Gearman/Job/Common.php
37
+ - examples/Net/Gearman/Job/Exception.php
38
+ - examples/Net/Gearman/Job/Sleep.php
39
+ - examples/Net/Gearman/Manager.php
40
+ - examples/Net/Gearman/Set.php
41
+ - examples/Net/Gearman/Task.php
42
+ - examples/Net/Gearman/Worker.php
43
+ - examples/client.php
44
+ - examples/client.rb
45
+ - examples/scale_image.rb
46
+ - examples/scale_image_worker.rb
47
+ - examples/server.rb
48
+ - examples/worker.php
49
+ - examples/worker.rb
50
+ - gearman-ruby.gemspec
51
+ - lib/gearman.rb
52
+ - lib/gearman/client.rb
53
+ - lib/gearman/server.rb
54
+ - lib/gearman/task.rb
55
+ - lib/gearman/taskset.rb
56
+ - lib/gearman/testlib.rb
57
+ - lib/gearman/util.rb
58
+ - lib/gearman/worker.rb
59
+ - test/client_test.rb
60
+ - test/mock_client_test.rb
61
+ - test/mock_worker_test.rb
62
+ - test/worker_test.rb
63
+ has_rdoc: true
64
+ homepage: http://github.com/xing/gearman-ruby
65
+ post_install_message:
66
+ rdoc_options:
67
+ - --charset=UTF-8
68
+ require_paths:
69
+ - lib
70
+ required_ruby_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: "0"
75
+ version:
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ requirements: []
83
+
84
+ rubyforge_project:
85
+ rubygems_version: 1.2.0
86
+ signing_key:
87
+ specification_version: 2
88
+ summary: Library for the Gearman distributed job system
89
+ test_files:
90
+ - test/client_test.rb
91
+ - test/mock_client_test.rb
92
+ - test/mock_worker_test.rb
93
+ - test/worker_test.rb
94
+ - examples/client.rb
95
+ - examples/scale_image.rb
96
+ - examples/scale_image_worker.rb
97
+ - examples/server.rb
98
+ - examples/worker.rb