beanstalk_integration_tests 0.0.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 (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