beanstalk_integration_tests 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/.gitignore +17 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE +22 -0
  4. data/README.md +38 -0
  5. data/Rakefile +9 -0
  6. data/beanstalk_integration_tests.gemspec +26 -0
  7. data/lib/beanstalk_integration_tests.rb +2 -0
  8. data/lib/beanstalk_integration_tests/bury_test.rb +137 -0
  9. data/lib/beanstalk_integration_tests/delete_test.rb +160 -0
  10. data/lib/beanstalk_integration_tests/ignore_test.rb +127 -0
  11. data/lib/beanstalk_integration_tests/kick_job_test.rb +68 -0
  12. data/lib/beanstalk_integration_tests/kick_test.rb +207 -0
  13. data/lib/beanstalk_integration_tests/list_tube_used_test.rb +26 -0
  14. data/lib/beanstalk_integration_tests/list_tubes_test.rb +26 -0
  15. data/lib/beanstalk_integration_tests/list_tubes_watched_test.rb +26 -0
  16. data/lib/beanstalk_integration_tests/pause_tube_test.rb +166 -0
  17. data/lib/beanstalk_integration_tests/peek_test.rb +242 -0
  18. data/lib/beanstalk_integration_tests/put_test.rb +255 -0
  19. data/lib/beanstalk_integration_tests/quit_test.rb +24 -0
  20. data/lib/beanstalk_integration_tests/release_test.rb +191 -0
  21. data/lib/beanstalk_integration_tests/reserve_test.rb +385 -0
  22. data/lib/beanstalk_integration_tests/stats_job_test.rb +116 -0
  23. data/lib/beanstalk_integration_tests/stats_test.rb +130 -0
  24. data/lib/beanstalk_integration_tests/stats_tube_test.rb +141 -0
  25. data/lib/beanstalk_integration_tests/test_helper.rb +88 -0
  26. data/lib/beanstalk_integration_tests/tests.rb +4 -0
  27. data/lib/beanstalk_integration_tests/touch_test.rb +118 -0
  28. data/lib/beanstalk_integration_tests/use_test.rb +118 -0
  29. data/lib/beanstalk_integration_tests/version.rb +3 -0
  30. data/lib/beanstalk_integration_tests/watch_test.rb +128 -0
  31. metadata +157 -0
@@ -0,0 +1,24 @@
1
+ require 'beanstalk_integration_tests/test_helper'
2
+
3
+ class QuitTest < BeanstalkIntegrationTest
4
+
5
+ context 'quit' do
6
+
7
+ should 'close the connection' do
8
+ other_client = build_client
9
+ initial_current_connections = client.transmit('stats')[:body]['current-connections']
10
+ # Send quit directly because transmit will die.
11
+ other_client.connection.write("quit\r\n")
12
+ # Make sure there are no further responses
13
+ other_client.connection.write("stats\r\n")
14
+ begin
15
+ assert_nil other_client.connection.gets
16
+ rescue Errno::ECONNRESET
17
+ # Occasionally occurs after disconnect
18
+ end
19
+ assert_equal(initial_current_connections - 1, client.transmit('stats')[:body]['current-connections'], 'Expected current-connections to be decremented after quit')
20
+ end
21
+
22
+ end
23
+
24
+ end
@@ -0,0 +1,191 @@
1
+ require 'beanstalk_integration_tests/test_helper'
2
+
3
+ class ReleaseTest < BeanstalkIntegrationTest
4
+
5
+ context 'release with a reserved job' do
6
+
7
+ setup do
8
+ client.transmit("use #{tube_name}")
9
+ client.transmit("watch #{tube_name}")
10
+ message = uuid
11
+ client.transmit("put 0 0 120 #{message.bytesize}\r\n#{message}")
12
+ timeout(2) do
13
+ @reserved_id = client.transmit('reserve')[:id]
14
+ end
15
+ stats = client.transmit('stats')[:body]
16
+ @initial_cmd_release = stats['cmd-release']
17
+ @initial_server_jobs_urgent = stats['current-jobs-urgent']
18
+ @initial_server_jobs_ready = stats['current-jobs-ready']
19
+ @initial_server_jobs_delayed = stats['current-jobs-delayed']
20
+ tube_stats = client.transmit("stats-tube #{tube_name}")[:body]
21
+ @initial_tube_jobs_urgent = tube_stats['current-jobs-urgent']
22
+ @initial_tube_jobs_ready = tube_stats['current-jobs-ready']
23
+ @initial_tube_jobs_delayed = tube_stats['current-jobs-delayed']
24
+ @initial_job_releases = client.transmit("stats-job #{@reserved_id}")[:body]['releases']
25
+ end
26
+
27
+
28
+ should 'release a job reserved by the client' do
29
+ release_response = client.transmit("release #{@reserved_id} 0 0")
30
+ assert_equal 'RELEASED', release_response[:status]
31
+ assert_equal 'ready', client.transmit("stats-job #{@reserved_id}")[:body]['state']
32
+ assert_counter_delta
33
+ end
34
+
35
+
36
+ should 'release a job reserved by the client when job deadline is pending' do
37
+ message = uuid
38
+ client.transmit("delete #{@reserved_id}")
39
+ client.transmit("put 0 0 1 #{message.bytesize}\r\n#{message}")
40
+ timeout(2) do
41
+ @reserved_id = client.transmit('reserve')[:id]
42
+ end
43
+ assert_raises(Beaneater::DeadlineSoonError, 'Expected reserve to raise an error when deadline pending') do
44
+ timeout(2) do
45
+ client.transmit('reserve')
46
+ end
47
+ end
48
+ release_response = client.transmit("release #{@reserved_id} 0 0")
49
+ assert_equal 'RELEASED', release_response[:status]
50
+ assert_equal 'ready', client.transmit("stats-job #{@reserved_id}")[:body]['state']
51
+ assert_counter_delta
52
+ end
53
+
54
+
55
+ should 'release a job to the original tube' do
56
+ release_response = client.transmit("release #{@reserved_id} 0 0")
57
+ assert_equal 'RELEASED', release_response[:status]
58
+ assert_equal tube_name, client.transmit("stats-job #{@reserved_id}")[:body]['tube']
59
+ end
60
+
61
+
62
+ should 'release a job with the provided delay' do
63
+ delay = 25
64
+ release_response = client.transmit("release #{@reserved_id} 0 #{delay}")
65
+ assert_equal 'RELEASED', release_response[:status]
66
+ job_stats = client.transmit("stats-job #{@reserved_id}")[:body]
67
+ assert_equal delay, job_stats['delay']
68
+ assert_equal 'delayed', job_stats['state']
69
+ assert_counter_delta(1, 'delayed')
70
+ end
71
+
72
+
73
+ should 'release a job with the provided priority' do
74
+ pri = 25
75
+ release_response = client.transmit("release #{@reserved_id} #{pri} 0")
76
+ assert_equal 'RELEASED', release_response[:status]
77
+ job_stats = client.transmit("stats-job #{@reserved_id}")[:body]
78
+ assert_equal pri, job_stats['pri']
79
+ end
80
+
81
+
82
+ should 'return a job released with a delay to ready after timeout' do
83
+ delay = 1
84
+ release_response = client.transmit("release #{@reserved_id} 0 #{delay}")
85
+ assert_equal 'RELEASED', release_response[:status]
86
+ job_stats = client.transmit("stats-job #{@reserved_id}")[:body]
87
+ assert_equal delay, job_stats['delay']
88
+ assert_equal 'delayed', job_stats['state']
89
+ assert_counter_delta(1, 'delayed')
90
+ sleep 1.1
91
+ assert_equal 'ready', client.transmit("stats-job #{@reserved_id}")[:body]['state']
92
+ assert_counter_delta
93
+ end
94
+
95
+
96
+ should 'not be able to release a job reserved by another client' do
97
+ initial_cmd_release = client.transmit('stats')[:body]['cmd-release']
98
+ assert_raises(Beaneater::NotFoundError, 'Expected releaing a job reserved by another client to raise an error') do
99
+ build_client.transmit("release #{@reserved_id} 0 0")
100
+ end
101
+ assert_equal(initial_cmd_release + 1, client.transmit('stats')[:body]['cmd-release'], 'Expected cmd-release stats to be incremented')
102
+ client.transmit("delete #{@reserved_id}")
103
+ end
104
+
105
+
106
+ should 'not be able to release an unreserved job' do
107
+ initial_cmd_release = client.transmit('stats')[:body]['cmd-release']
108
+ initial_job_releases = client.transmit("stats-job #{@reserved_id}")[:body]['releases']
109
+ client.transmit("release #{@reserved_id} 0 0")
110
+ assert_raises(Beaneater::NotFoundError, 'Expected releaing an unreserved job to raise an error') do
111
+ client.transmit("release #{@reserved_id} 0 0")
112
+ end
113
+ assert_equal(initial_cmd_release + 2, client.transmit('stats')[:body]['cmd-release'], 'Expected cmd-release stats to be incremented')
114
+ assert_equal(initial_job_releases + 1, client.transmit("stats-job #{@reserved_id}")[:body]['releases'], 'Expected job releases to be unchanged')
115
+ end
116
+
117
+
118
+ should 'return BAD_FORMAT with negative delay or priority' do
119
+ args = [-1, 1]
120
+ initial_cmd_release = client.transmit('stats')[:body]['cmd-release']
121
+ initial_job_releases = client.transmit("stats-job #{@reserved_id}")[:body]['releases']
122
+ args.length.times do
123
+ assert_raises(Beaneater::BadFormatError, 'Expected release with negative argument to raise BAD_FORMAT') do
124
+ client.transmit(['release', @reserved_id].concat(args).join(' '))
125
+ end
126
+ assert_equal(initial_cmd_release, client.transmit('stats')[:body]['cmd-release'], 'Expected cmd-release to be unchanged')
127
+ assert_equal(initial_job_releases, client.transmit("stats-job #{@reserved_id}")[:body]['releases'], 'Expected job releases to be unchanged')
128
+ args.cycle
129
+ end
130
+ client.transmit("delete #{@reserved_id}")
131
+ end
132
+
133
+ end
134
+
135
+
136
+ context 'release not requiring a reserved job' do
137
+
138
+ should 'return BAD_FORMAT with trailing space or arguments' do
139
+ initial_cmd_release = client.transmit('stats')[:body]['cmd-release']
140
+ assert_raises(Beaneater::BadFormatError, 'Expected release with trailing space to return BAD_FORMAT') do
141
+ client.transmit('release 1 0 0 ')
142
+ end
143
+ assert_equal(initial_cmd_release, client.transmit('stats')[:body]['cmd-release'], 'Expected cmd-release stats to be unchanged')
144
+
145
+ assert_raises(Beaneater::BadFormatError, 'Expected release with trailing space to return BAD_FORMAT') do
146
+ client.transmit('release 1 0 0 x')
147
+ end
148
+ assert_equal(initial_cmd_release, client.transmit('stats')[:body]['cmd-release'], 'Expected cmd-release stats to be unchanged')
149
+ end
150
+
151
+
152
+ should 'return BAD_FORMAT with non-integer job_id, delay, or priority' do
153
+ args = ['foo', 1, 1]
154
+ args.length.times do
155
+ initial_cmd_release = client.transmit('stats')[:body]['cmd-release']
156
+ assert_raises(Beaneater::BadFormatError, 'Expected release with non-integer argument to raise BAD_FORMAT') do
157
+ client.transmit(['release'].concat(args).join(' '))
158
+ end
159
+ assert_equal(initial_cmd_release, client.transmit('stats')[:body]['cmd-release'], 'Expected cmd-release stats to be unchanged')
160
+ args.cycle
161
+ end
162
+ end
163
+
164
+
165
+ should 'return NOT_FOUND with negative job_id' do
166
+ initial_cmd_release = client.transmit('stats')[:body]['cmd-release']
167
+ assert_raises(Beaneater::NotFoundError, 'Expected release with negative job_id to raise NOT_FOUND') do
168
+ client.transmit('release -1 0 0')
169
+ end
170
+ assert_equal(initial_cmd_release + 1, client.transmit('stats')[:body]['cmd-release'], 'Expected cmd-release stats to be incremented')
171
+ end
172
+
173
+ end
174
+
175
+
176
+ def assert_counter_delta(delta = 1, job_state = 'ready')
177
+ stats = client.transmit('stats')[:body]
178
+ tube_stats = client.transmit("stats-tube #{tube_name}")[:body]
179
+ assert_equal(@initial_cmd_release + delta, stats['cmd-release'], 'Expected cmd-release to be incremented')
180
+ assert_equal(instance_variable_get("@initial_server_jobs_#{job_state}") + delta, stats["current-jobs-#{job_state}"], "Expected server current-jobs-#{job_state} to be incremented")
181
+ assert_equal(instance_variable_get("@initial_tube_jobs_#{job_state}") + delta, tube_stats["current-jobs-#{job_state}"], "Expected tube current-jobs-#{job_state} to be incremented")
182
+ if job_state == 'ready'
183
+ assert_equal(@initial_server_jobs_urgent + delta, stats['current-jobs-urgent'], 'Expected server current-jobs-urgent to be incremented')
184
+ assert_equal(@initial_tube_jobs_urgent + delta, tube_stats['current-jobs-urgent'], 'Expected tube current-jobs-urgent to be incremented')
185
+ end
186
+ assert_equal(@initial_job_releases + delta, client.transmit("stats-job #{@reserved_id}")[:body]['releases'], 'Expected job releases to be incremented')
187
+ assert_equal(0, stats['current-jobs-reserved'], 'Expected server current-jobs-reserved to be zero')
188
+ assert_equal(0, tube_stats['current-jobs-reserved'], 'Expected tube current-jobs-reserved to be zero')
189
+ end
190
+
191
+ end
@@ -0,0 +1,385 @@
1
+ require 'beanstalk_integration_tests/test_helper'
2
+ require 'timeout'
3
+
4
+ class ReserveTest < BeanstalkIntegrationTest
5
+
6
+ context 'common reserve behavior' do
7
+
8
+ setup do
9
+ client.transmit("watch #{tube_name}")
10
+ client.transmit("use #{tube_name}")
11
+ @message = uuid
12
+ end
13
+
14
+ {
15
+ 'reserve' => 'reserve',
16
+ 'reserve-with-timeout' => 'reserve-with-timeout 0'
17
+ }.each do |command, reserve_command|
18
+ context reserve_command.split(/\s/).first do
19
+
20
+ context 'a single watched tube' do
21
+
22
+ should 'reserve a job' do
23
+ put_response = client.transmit("put 0 0 60 #{@message.bytesize}\r\n#{@message}")
24
+ job_id = put_response[:id]
25
+ assert_equal tube_name, client.transmit("stats-job #{job_id}")[:body]['tube']
26
+ assert client.transmit('list-tubes-watched')[:body].include?(tube_name)
27
+ timeout(2) do
28
+ reservation_id = client.transmit(reserve_command)[:id]
29
+ assert_equal job_id, reservation_id
30
+ client.transmit("delete #{job_id}")
31
+ end
32
+ end
33
+
34
+
35
+ should "increment reserves count on job, current-jobs-reserved on tube, and current-jobs-reserved, current-producers, and cmd-#{command} on server" do
36
+ other_client = build_client
37
+ other_client.transmit("use #{tube_name}")
38
+ job_id = other_client.transmit("put 0 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
39
+ initial_job_reserves = client.transmit("stats-job #{job_id}")[:body]['reserves']
40
+ initial_tube_reserved = client.transmit("stats-tube #{tube_name}")[:body]['current-jobs-reserved']
41
+ server_stats = client.transmit('stats')[:body]
42
+ initial_server_reserved = server_stats['current-jobs-reserved']
43
+ initial_server_cmds = server_stats["cmd-#{command}"]
44
+ initial_server_workers = server_stats['current-workers']
45
+
46
+ timeout(2) do
47
+ client.transmit(reserve_command)[:id]
48
+ end
49
+
50
+ assert_equal initial_job_reserves + 1, client.transmit("stats-job #{job_id}")[:body]['reserves']
51
+ assert_equal initial_tube_reserved + 1, client.transmit("stats-tube #{tube_name}")[:body]['current-jobs-reserved']
52
+ server_stats = client.transmit('stats')[:body]
53
+ assert_equal initial_server_reserved + 1, server_stats['current-jobs-reserved']
54
+ assert_equal initial_server_cmds + 1, server_stats["cmd-#{command}"]
55
+ assert_equal initial_server_workers + 1, server_stats['current-workers']
56
+ client.transmit("delete #{job_id}")
57
+ end
58
+
59
+
60
+ should 'receive a job enqueued to the watched tube while reserving' do
61
+ client2 = build_client
62
+ client2.transmit("use #{tube_name}")
63
+
64
+ thread = Thread.new do
65
+ timeout(2) do
66
+ alt_command = command == 'reserve' ? 'reserve' : 'reserve-with-timeout 1'
67
+ reservation_id = client.transmit(alt_command)[:id]
68
+ assert reservation_id
69
+ client.transmit("delete #{reservation_id}")
70
+ end
71
+ assert_equal 0, client.transmit("stats-tube #{tube_name}")[:body]['current-waiting']
72
+ end
73
+ while client2.transmit("stats-tube #{tube_name}")[:body]['current-waiting'] == 0
74
+ sleep 0.1
75
+ end
76
+ client2.transmit("put 0 0 120 #{@message.bytesize}\r\n#{@message}")
77
+ thread.join
78
+ end
79
+
80
+
81
+ should 'reserve the job with the lowest priority' do
82
+ job_ids = []
83
+ job_ids << client.transmit("put 5000 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
84
+ job_ids << client.transmit("put 1024 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
85
+ job_ids << client.transmit("put 1023 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
86
+ job_ids << client.transmit("put 0 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
87
+ job_ids.length.times do
88
+ timeout(2) do
89
+ job_id = job_ids.pop
90
+ assert_equal job_id, client.transmit(reserve_command)[:id]
91
+ client.transmit("delete #{job_id}")
92
+ end
93
+ end
94
+ end
95
+
96
+
97
+ should 'reserve the job received first if priorities equal' do
98
+ job_ids = 4.times.map do
99
+ client.transmit("put 0 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
100
+ end
101
+ job_ids.length.times do
102
+ timeout(2) do
103
+ job_id = job_ids.shift
104
+ assert_equal job_id, client.transmit(reserve_command)[:id]
105
+ client.transmit("delete #{job_id}")
106
+ end
107
+ end
108
+ end
109
+
110
+ end
111
+
112
+ context 'multiple watched tubes' do
113
+
114
+ setup do
115
+ @client2 = build_client
116
+ @client2_tube = generate_tube_name
117
+ @client2.transmit("use #{@client2_tube}")
118
+ @client3 = build_client
119
+ @client3_tube = generate_tube_name
120
+ @client3.transmit("use #{@client3_tube}")
121
+ client.transmit("watch #{@client2_tube}")
122
+ client.transmit("watch #{@client3_tube}")
123
+ end
124
+
125
+
126
+ should 'reserve a job from any watched tube' do
127
+ [client, @client2, @client3].each do |tube_client|
128
+ timeout(2) do
129
+ job_id = tube_client.transmit("put 0 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
130
+ assert_equal job_id, client.transmit(reserve_command)[:id]
131
+ client.transmit("delete #{job_id}")
132
+ end
133
+ end
134
+ end
135
+
136
+
137
+ should 'receive a job enqueued to any watched tube while reserving' do
138
+ client_clone = build_client
139
+ client_clone.transmit("use #{tube_name}")
140
+ alt_command = command == 'reserve' ? 'reserve' : 'reserve-with-timeout 1'
141
+ {client_clone => tube_name, @client2 => @client2_tube, @client3 => @client3_tube}.each do |tube_client, tube_client_tube|
142
+ thread = Thread.new do
143
+ timeout(2) do
144
+ job_id = client.transmit(alt_command)[:id]
145
+ assert_equal tube_client_tube, client.transmit("stats-job #{job_id}")[:body]['tube']
146
+ client.transmit("delete #{job_id}")
147
+ end
148
+ end
149
+
150
+ while tube_client.transmit("stats-tube #{tube_client_tube}")[:body]['current-waiting'] == 0
151
+ sleep 0.1
152
+ end
153
+
154
+ tube_client.transmit("put 0 0 120 #{@message.bytesize}\r\n#{@message}")
155
+ thread.join
156
+ end
157
+ end
158
+
159
+
160
+ should 'reserve the job with the lowest priority' do
161
+ job_ids = []
162
+ subset_ids = []
163
+ [5000, 1024, 1023, 0].each do |pri|
164
+ subset_ids << client.transmit("put #{pri} 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
165
+ subset_ids << @client2.transmit("put #{pri} 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
166
+ subset_ids << @client3.transmit("put #{pri} 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
167
+ job_ids.concat(subset_ids.reverse)
168
+ subset_ids.clear
169
+ end
170
+ job_ids.length.times do
171
+ timeout(2) do
172
+ job_id = job_ids.pop
173
+ assert_equal job_id, client.transmit(reserve_command)[:id]
174
+ client.transmit("delete #{job_id}")
175
+ end
176
+ end
177
+ end
178
+
179
+
180
+ should 'reserve the job received first if priorities equal' do
181
+ job_ids = []
182
+ job_ids << client.transmit("put 0 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
183
+ job_ids << @client2.transmit("put 0 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
184
+ job_ids << @client3.transmit("put 0 0 60 #{@message.bytesize}\r\n#{@message}")[:id]
185
+
186
+ client.transmit("watch #{@client2_tube}")
187
+ client.transmit("watch #{@client3_tube}")
188
+
189
+ job_ids.length.times do
190
+ timeout(2) do
191
+ job_id = job_ids.shift
192
+ assert_equal job_id, client.transmit(reserve_command)[:id]
193
+ client.transmit("delete #{job_id}")
194
+ end
195
+ end
196
+ end
197
+
198
+
199
+ should 'not reserve a job from a tube not watched' do
200
+ client.transmit("put 0 0 120 #{@message.bytesize}\r\n#{@message}")
201
+ client.transmit("watch #{generate_tube_name}")
202
+ client.transmit("ignore #{tube_name}")
203
+
204
+ expected_error = command == 'reserve' ? Timeout::Error : Beaneater::TimedOutError
205
+ assert_raises(expected_error, 'Expected client to timeout while waiting for reservation') do
206
+ timeout(1) do
207
+ client.transmit(reserve_command)
208
+ end
209
+ end
210
+ end
211
+
212
+
213
+ should 'supply clients with jobs in the order client reservations were received' do
214
+ clients = Hash[[build_client, @client2, @client3].shuffle.zip([0, 1, 2])]
215
+ alt_command = command == 'reserve' ? 'reserve' : 'reserve-with-timeout 1'
216
+ threads = []
217
+ clients.each_pair do |tube_client, reservation_number|
218
+ tube_client.transmit("watch #{tube_name}")
219
+ sleep 0.25
220
+ threads << Thread.new do
221
+ timeout(3) do
222
+ reservation = tube_client.transmit(alt_command)
223
+ assert_equal reservation_number.to_s, reservation[:body][-1]
224
+ tube_client.transmit("delete #{reservation[:id]}")
225
+ end
226
+ end
227
+ end
228
+
229
+ while client.transmit("stats-tube #{tube_name}")[:body]['current-waiting'] != 3
230
+ sleep 0.1
231
+ end
232
+
233
+ 3.times do |reservation_number|
234
+ message = [@message, reservation_number].join(' ')
235
+ client.transmit("put 0 0 120 #{message.bytesize}\r\n#{message}")
236
+ end
237
+ threads.each(&:join)
238
+ end
239
+
240
+
241
+ should 'return a reserved job to the ready state and correct tube if the ttr expires' do
242
+ [client, @client2, @client3].each do |tube_client|
243
+ tube_client.transmit("put 0 0 1 #{@message.bytesize}\r\n#{@message}")
244
+ end
245
+ [tube_name, @client2_tube, @client3_tube].each do |tube_client_tube|
246
+ job_id = nil
247
+ timeout(2) do
248
+ job_id = client.transmit('reserve')[:id]
249
+ end
250
+ assert_equal 'reserved', client.transmit("stats-job #{job_id}")[:body]['state']
251
+ sleep 1
252
+ job_stats = client.transmit("stats-job #{job_id}")[:body]
253
+ assert_equal 'ready', job_stats['state']
254
+ assert_equal tube_client_tube, job_stats['tube']
255
+ client.transmit("delete #{job_id}")
256
+ end
257
+ end
258
+
259
+ end
260
+
261
+
262
+ should 'return deadline_soon if a ttr expiration is pending' do
263
+ job_id = client.transmit("put 0 0 1 #{@message.bytesize}\r\n#{@message}")[:id]
264
+ timeout(2) do
265
+ client.transmit('reserve')
266
+ assert_raises(Beaneater::DeadlineSoonError, 'Expected reserve during ttr expiration to return deadlinesoon') do
267
+ client.transmit('reserve')
268
+ end
269
+ end
270
+ client.transmit("delete #{job_id}")
271
+ end
272
+
273
+ end
274
+
275
+ end
276
+
277
+ end
278
+
279
+
280
+ context 'reserve' do
281
+
282
+ should 'return BAD_FORMAT with trailing space or any trailing args' do
283
+ initial_cmd_reserve = client.transmit('stats')[:body]['cmd-reserve']
284
+ timeout(1) do
285
+ assert_raises(Beaneater::BadFormatError, 'Expected reserve with trailing space to return BAD_FORMAT') do
286
+ client.transmit('reserve ')
287
+ end
288
+ end
289
+ assert_equal(initial_cmd_reserve, client.transmit('stats')[:body]['cmd-reserve'], 'Expected cmd-reserve to be unchanged')
290
+
291
+ timeout(1) do
292
+ assert_raises(Beaneater::BadFormatError, 'Expected reserve with args to return BAD_FORMAT') do
293
+ client.transmit('reserve 1')
294
+ end
295
+ end
296
+ assert_equal(initial_cmd_reserve, client.transmit('stats')[:body]['cmd-reserve'], 'Expected cmd-reserve to be unchanged')
297
+ end
298
+
299
+ end
300
+
301
+ context 'reserve-with-timeout' do
302
+
303
+ should 'return TIMED_OUT immediately if timeout of zero and no jobs available' do
304
+ initial_cmd_reserve_with_timeout = client.transmit('stats')[:body]['cmd-reserve-with-timeout']
305
+ timeout(1) do
306
+ assert_raises(Beaneater::TimedOutError, 'Expected reserve-with-timeout to timeout') do
307
+ client.transmit('reserve-with-timeout 0')
308
+ end
309
+ end
310
+ assert_equal(initial_cmd_reserve_with_timeout + 1, client.transmit('stats')[:body]['cmd-reserve-with-timeout'], 'Expected cmd-reserve-with-timeout to be incremented')
311
+ end
312
+
313
+
314
+ should 'return TIMED_OUT after timeout if no jobs available' do
315
+ initial_cmd_reserve_with_timeout = client.transmit('stats')[:body]['cmd-reserve-with-timeout']
316
+ timeout(2) do
317
+ assert_raises(Beaneater::TimedOutError, 'Expected reserve-with-timeout to timeout') do
318
+ client.transmit('reserve-with-timeout 1')
319
+ end
320
+ end
321
+ assert_equal(initial_cmd_reserve_with_timeout + 1, client.transmit('stats')[:body]['cmd-reserve-with-timeout'], 'Expected cmd-reserve-with-timeout to be incremented')
322
+ end
323
+
324
+
325
+ should 'return BAD_FORMAT without space trailing space or timeout' do
326
+ initial_cmd_reserve_with_timeout = client.transmit('stats')[:body]['cmd-reserve-with-timeout']
327
+ timeout(2) do
328
+ assert_raises(Beaneater::BadFormatError, 'Expected reserve-with-timeout to return BAD_FORMAT without trailing space or timeout') do
329
+ client.transmit('reserve-with-timeout')
330
+ end
331
+ end
332
+ assert_equal(initial_cmd_reserve_with_timeout, client.transmit('stats')[:body]['cmd-reserve-with-timeout'], 'Expected cmd-reserve-with-timeout to be unchanged')
333
+ end
334
+
335
+
336
+ should 'should coerce non-integer timeouts to zero' do
337
+ initial_cmd_reserve_with_timeout = client.transmit('stats')[:body]['cmd-reserve-with-timeout']
338
+ message = uuid
339
+ job_id = client.transmit("put 0 0 1 #{message.bytesize}\r\n#{message}")[:id]
340
+ timeout(1) do
341
+ assert_equal job_id, client.transmit("reserve-with-timeout I really don't think this should be valid.")[:id]
342
+ end
343
+ client.transmit("delete #{job_id}")
344
+ assert_equal(initial_cmd_reserve_with_timeout + 1, client.transmit('stats')[:body]['cmd-reserve-with-timeout'], 'Expected cmd-reserve-with-timeout to be incremented')
345
+ end
346
+
347
+
348
+ should 'should coerce space with no timeout to zero' do
349
+ initial_cmd_reserve_with_timeout = client.transmit('stats')[:body]['cmd-reserve-with-timeout']
350
+ message = uuid
351
+ job_id = client.transmit("put 0 0 1 #{message.bytesize}\r\n#{message}")[:id]
352
+ timeout(1) do
353
+ assert_equal job_id, client.transmit("reserve-with-timeout ")[:id]
354
+ end
355
+ client.transmit("delete #{job_id}")
356
+ assert_equal(initial_cmd_reserve_with_timeout + 1, client.transmit('stats')[:body]['cmd-reserve-with-timeout'], 'Expected cmd-reserve-with-timeout to be incremented')
357
+ end
358
+
359
+
360
+ should 'should handle negative timeout like normal reserve' do
361
+ initial_cmd_reserve_with_timeout = client.transmit('stats')[:body]['cmd-reserve-with-timeout']
362
+ message = uuid
363
+ client.transmit("watch #{tube_name}")
364
+ other_client = build_client
365
+ other_client.transmit("use #{tube_name}")
366
+
367
+ reserve_thread = Thread.new do
368
+ value = nil
369
+ timeout(2) do
370
+ value = client.transmit("reserve-with-timeout -1")[:id]
371
+ end
372
+ value
373
+ end
374
+
375
+ # Sleep one to verify abs(timeout) not used
376
+ sleep 1
377
+ job_id = other_client.transmit("put 0 0 120 #{message.bytesize}\r\n#{message}")[:id]
378
+ assert_equal job_id, reserve_thread.value
379
+ assert_equal(initial_cmd_reserve_with_timeout + 1, client.transmit('stats')[:body]['cmd-reserve-with-timeout'], 'Expected cmd-reserve-with-timeout to be incremented')
380
+ client.transmit("delete #{job_id}")
381
+ end
382
+
383
+ end
384
+
385
+ end