-
Notifications
You must be signed in to change notification settings - Fork 26
/
test_girl_friday_queue.rb
208 lines (187 loc) · 5.23 KB
/
test_girl_friday_queue.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
require 'helper'
class TestGirlFridayQueue < MiniTest::Unit::TestCase
class TestErrorHandler
include MiniTest::Assertions
end
def test_should_process_messages
async_test do |cb|
queue = GirlFriday::WorkQueue.new('process') do |msg|
assert_equal 'foo', msg[:text]
queue.shutdown do
cb.call
end
end
queue.push(:text => 'foo')
end
end
def test_should_handle_worker_error
async_test do |cb|
queue = nil
TestErrorHandler.send(:define_method, :handle) do |ex|
assert_equal 'oops', ex.message
assert_equal 'RuntimeError', ex.class.name
queue.shutdown do
cb.call
end
end
queue = GirlFriday::WorkQueue.new('error', :error_handler => TestErrorHandler) do |msg|
raise 'oops'
end
queue.push(:text => 'foo')
end
end
def test_should_use_a_default_error_handler_when_none_specified
async_test do |cb|
queue = GirlFriday::WorkQueue.new('error') do |msg|
end
queue.shutdown do
cb.call
end
queue.push(:text => 'foo') # Redundant
# Not an ideal method, but I can't see a better way without complex stubbing.
assert queue.instance_eval { @error_handlers }.length > 0
end
end
def test_should_call_callback_when_complete
async_test do |cb|
queue = GirlFriday::WorkQueue.new('callback', :size => 1) do |msg|
assert_equal 'foo', msg[:text]
'camel'
end
queue.push(:text => 'foo') do |result|
assert_equal 'camel', result
queue.shutdown do
cb.call
end
end
end
end
def test_should_provide_status
mutex = Mutex.new
total = 200
count = 0
incr = Proc.new do
mutex.synchronize do
count += 1
end
end
actual = nil
async_test do |cb|
queue = GirlFriday::WorkQueue.new('status', :size => 3) do |msg|
mycount = incr.call
actual = queue.status if mycount == 100
queue.shutdown do
cb.call
end if mycount == total
end
total.times do |idx|
queue.push(:text => 'foo')
end
end
refute_nil actual
refute_nil actual['status']
metrics = actual['status']
assert metrics[:total_queued] > 0
assert metrics[:total_queued] <= total
assert_equal 3, metrics[:pool_size]
assert_equal 3, metrics[:busy]
assert_equal 0, metrics[:ready]
assert(metrics[:backlog] > 0)
assert(metrics[:total_processed] > 0)
end
def test_should_persist_with_redis_connection_pool
begin
require 'redis'
require 'connection_pool'
pool = ConnectionPool.new(:size => 5, :timeout => 2){ Redis.new }
pool.flushdb
rescue LoadError
return puts "Skipping redis test, 'redis' gem not found: #{$!.message}"
rescue Errno::ECONNREFUSED
return puts 'Skipping redis test, not running locally'
end
mutex = Mutex.new
total = 100
count = 0
incr = Proc.new do
mutex.synchronize do
count += 1
end
end
async_test(2.0) do |cb|
queue = GirlFriday::WorkQueue.new('redis-pool', :size => 2, :store => GirlFriday::Store::Redis, :store_config => { :pool => pool }) do |msg|
incr.call
queue.shutdown do
cb.call
end if count == total
end
total.times do
queue.push(:text => 'foo')
end
refute_nil queue.status['redis-pool'][:backlog]
end
end
def test_should_raise_if_no_store_config_passed_in_for_redis_backend
assert_raises(ArgumentError) do
GirlFriday::WorkQueue.new('raise-test', :store => GirlFriday::Store::Redis) do |msg|
# doing work
end
end
end
def test_should_allow_graceful_shutdown
mutex = Mutex.new
total = 100
count = 0
incr = Proc.new do
mutex.synchronize do
count += 1
end
end
async_test do |cb|
queue = GirlFriday::WorkQueue.new('shutdown', :size => 2) do |msg|
incr.call
cb.call if count == total
end
total.times do
queue.push(:text => 'foo')
end
assert_equal 1, GirlFriday.queues.size
count = GirlFriday.shutdown!
assert_equal 0, count
cb.call
end
end
def test_should_create_workers_lazily
async_test do |cb|
queue = GirlFriday::Queue.new('lazy', :size => 2) do |msg|
assert_equal 1, queue.instance_variable_get(:@ready_workers).size
queue.shutdown do
cb.call
end
end
assert queue.instance_variable_defined?(:@ready_workers)
assert_nil queue.instance_variable_get(:@ready_workers)
# don't instantiate the worker threads until we actually put
# work onto the queue.
queue << 'empty msg'
end
end
def test_stubbing_girl_friday_with_flexmock
expected = Thread.current.to_s
actual = nil
processor = Proc.new do |msg|
actual = Thread.current.to_s
end
async_test do |cb|
queue = GirlFriday::Queue.new('flexmock', :size => 2, &processor)
flexmock(queue).should_receive(:push).zero_or_more_times.and_return do |msg|
processor.call(msg)
end
queue.push 'hello world!'
assert_equal expected, actual
queue.shutdown do
cb.call
end
end
end
end