gilmour 0.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,339 @@
1
+ # encoding: utf-8
2
+ require 'rspec/given'
3
+ require 'securerandom'
4
+ require './testservice/test_service_base'
5
+
6
+ require_relative 'helpers/common'
7
+ require_relative 'helpers/connection'
8
+
9
+ def install_test_subscriber(parent)
10
+ waiter = Waiter.new
11
+ TestSubscriber.callback do |topic, data|
12
+ @topic = topic
13
+ @data = data
14
+ waiter.signal
15
+ end
16
+ waiter
17
+ end
18
+
19
+ describe 'TestSubscriber' do
20
+ opts = redis_connection_options
21
+
22
+ test_subscriber_path = './testservice/subscribers/test_subscriber'
23
+ after(:all) do
24
+ EM.stop
25
+ end
26
+ Given(:subscriber) { TestServiceBase }
27
+ Given do
28
+ subscriber.load_subscriber(test_subscriber_path)
29
+ end
30
+ Then do
31
+ handlers = subscriber.subscribers(TestSubscriber::Topic)
32
+ module_present = handlers.find { |h| h[:subscriber] == TestSubscriber }
33
+ module_present.should be_truthy
34
+ end
35
+
36
+ context 'Running Service' do
37
+ before(:all) do
38
+ @service = TestServiceBase.new(opts, 'redis')
39
+ end
40
+ Given(:connection_opts) { opts }
41
+ before(:all) do
42
+ @service.registered_subscribers.each do |s|
43
+ s.backend = 'redis'
44
+ end
45
+ @service.start
46
+ end
47
+
48
+ context 'Handler Register' do
49
+ When { install_test_subscriber(subscriber) }
50
+ context 'Check registered handlers' do
51
+ When(:handlers) do
52
+ subscriber.subscribers(TestSubscriber::Simulation)
53
+ .map { |h| h[:handler] }
54
+ end
55
+ Then { handlers.each { |h| h.should be_kind_of Proc } }
56
+ Then do
57
+ arg1 = TestSubscriber::Simulation
58
+ handlers.each do |h|
59
+ arg2 = SecureRandom.hex
60
+ # simualate a handler call
61
+ h.call(arg1, arg2)
62
+ @topic.should be == arg1
63
+ @data.should be == arg2
64
+ end
65
+ end
66
+ end
67
+ end
68
+
69
+ context 'Non Fork can add dynamic listeners', :fork_dynamic do
70
+ Given(:ping_opts) do
71
+ redis_ping_options
72
+ end
73
+
74
+ When(:sub) do
75
+ Gilmour::RedisBackend.new({})
76
+ end
77
+ When(:code) do
78
+ waiter = Waiter.new
79
+ dynamicaly_subscribed = 0
80
+
81
+ sub.publish(1, TestSubscriber::ReListenTopic) do |d, c|
82
+ sub.confirm_subscriber("test.world") do |present|
83
+ dynamicaly_subscribed = present
84
+ waiter.signal
85
+ end
86
+ end
87
+
88
+ waiter.wait(5)
89
+ dynamicaly_subscribed
90
+ end
91
+ Then do
92
+ code.should be == true
93
+ end
94
+ end
95
+
96
+ context 'Publisher side timeout' do
97
+ Given(:ping_opts) do
98
+ redis_ping_options
99
+ end
100
+
101
+ When(:sub) do
102
+ Gilmour::RedisBackend.new({})
103
+ end
104
+ When(:code) do
105
+ code = nil
106
+ waiter_code = Waiter.new
107
+
108
+ sub.publish(3, TestSubscriber::TimeoutTopic, {:timeout => 1}) do |d, c|
109
+ code = c
110
+ waiter_code.signal
111
+ end
112
+
113
+ waiter_code.wait(5)
114
+ code
115
+ end
116
+ Then do
117
+ code.should be == 499
118
+ end
119
+ end
120
+
121
+ context 'Handler sleeps longer than the Timeout' do
122
+ Given(:ping_opts) do
123
+ redis_ping_options
124
+ end
125
+
126
+ When(:sub) do
127
+ Gilmour::RedisBackend.new({})
128
+ end
129
+ When(:code) do
130
+ waiter_error = Waiter.new
131
+ waiter_code = Waiter.new
132
+ code = nil
133
+
134
+ error_listener_proc = sub.add_listener Gilmour::ErrorChannel do
135
+ waiter_error.signal
136
+ end
137
+
138
+ sub.publish(3, TestSubscriber::TimeoutTopic) do |d, c|
139
+ code = c
140
+ waiter_code.signal
141
+ end
142
+
143
+ waiter_code.wait(5)
144
+ waiter_error.wait(5)
145
+
146
+ sub.remove_listener Gilmour::ErrorChannel, error_listener_proc
147
+
148
+ code
149
+ end
150
+ Then do
151
+ code.should be == 504
152
+ end
153
+ end
154
+
155
+ context 'Handler sleeps just enough to survive the timeout' do
156
+ Given(:ping_opts) do
157
+ redis_ping_options
158
+ end
159
+
160
+ When(:sub) do
161
+ Gilmour::RedisBackend.new({})
162
+ end
163
+ When(:code) do
164
+ waiter = Waiter.new
165
+ code = nil
166
+
167
+ sub.publish(1, TestSubscriber::TimeoutTopic) do |d, c|
168
+ code = c
169
+ waiter.signal
170
+ end
171
+
172
+ waiter.wait(5)
173
+ code
174
+ end
175
+ Then do
176
+ code.should be == 200
177
+ end
178
+ end
179
+
180
+ context 'Receive messages' do
181
+ context 'Receive a message' do
182
+ Given(:ping_opts) { redis_ping_options }
183
+ When do
184
+ @data = @topic = nil
185
+ waiter = install_test_subscriber(TestServiceBase)
186
+ redis_publish_async(connection_opts,
187
+ ping_opts[:message],
188
+ TestSubscriber::Topic)
189
+ waiter.wait(5)
190
+ end
191
+ Then do
192
+ @data.should be == ping_opts[:message]
193
+ @topic.should be == TestSubscriber::Topic
194
+ end
195
+ And { expect(EM.reactor_thread.alive?).to be_truthy }
196
+ end
197
+
198
+ context 'Recieve a message on a wildcard key' do
199
+ Given(:wildcard_opts) { redis_wildcard_options }
200
+ When do
201
+ @data = @topic = nil
202
+ waiter = install_test_subscriber(TestServiceBase)
203
+ redis_publish_async(connection_opts,
204
+ wildcard_opts[:message],
205
+ wildcard_opts[:topic])
206
+ waiter.wait(5)
207
+ end
208
+ Then { @data.should == wildcard_opts[:message] }
209
+ And { @topic.should == wildcard_opts[:topic] }
210
+ end
211
+ end
212
+
213
+ context 'Publish sans subscriber timeout' do
214
+ Given(:ping_opts) do
215
+ redis_ping_options
216
+ end
217
+
218
+ When(:sub) do
219
+ Gilmour::RedisBackend.new({})
220
+ end
221
+ When(:response) do
222
+ waiter = Waiter.new
223
+ data = code = nil
224
+ sub.publish(ping_opts[:message], "hello.world") do |d, c|
225
+ data = d
226
+ code = c
227
+ waiter.signal
228
+ end
229
+ waiter.wait(5)
230
+ [data, code]
231
+ end
232
+ Then do
233
+ data, code = response
234
+ data.should be == nil
235
+ code.should be == nil
236
+ end
237
+
238
+ end
239
+
240
+ context 'Send and receive a message' do
241
+ Given(:ping_opts) { redis_ping_options }
242
+ When(:sub) do
243
+ Gilmour::RedisBackend.new({})
244
+ end
245
+ When(:response) do
246
+ waiter = Waiter.new
247
+ data = code = nil
248
+ sub.publish(ping_opts[:message], TestSubscriber::Topic, { confirm_subscriber: true }) do |d, c|
249
+ data = d
250
+ code = c
251
+ waiter.signal
252
+ end
253
+ waiter.wait(5)
254
+ [data, code]
255
+ end
256
+ Then do
257
+ data, code = response
258
+ data.should be == ping_opts[:response]
259
+ code.should be == 200
260
+ end
261
+ end
262
+
263
+ context 'Send once, Receive twice' do
264
+ Given(:ping_opts) { redis_ping_options }
265
+ When(:sub) do
266
+ Gilmour::RedisBackend.new({})
267
+ end
268
+ When (:response) do
269
+ waiter = Waiter.new
270
+
271
+ actual_ret = []
272
+
273
+ group_proc = sub.add_listener TestSubscriber::GroupReturn do
274
+ actual_ret.push(request.body)
275
+ waiter.signal if actual_ret.length == 4
276
+ end
277
+
278
+ sub.publish(ping_opts[:message], TestSubscriber::GroupTopic)
279
+ waiter.wait(5)
280
+
281
+ sub.remove_listener TestSubscriber::GroupReturn, group_proc
282
+ actual_ret
283
+ end
284
+ Then do
285
+ response.select { |e| e == ping_opts[:message] }.size.should == 2
286
+ response.select { |e| e == "2" }.size.should == 2
287
+ end
288
+ end
289
+
290
+ context 'Send once, Receive Once' do
291
+ Given(:ping_opts) { redis_ping_options }
292
+ When(:sub) do
293
+ Gilmour::RedisBackend.new({})
294
+ end
295
+ When (:response) do
296
+ waiter = Waiter.new
297
+ actual_ret = []
298
+
299
+ group_proc = sub.add_listener TestSubscriber::GroupReturn do
300
+ actual_ret.push(request.body)
301
+ waiter.signal if actual_ret.length == 1
302
+ end
303
+
304
+ sub.publish(ping_opts[:message], TestSubscriber::ExclusiveTopic)
305
+
306
+ waiter.wait(5)
307
+ sub.remove_listener TestSubscriber::GroupReturn, group_proc
308
+ actual_ret
309
+ end
310
+ Then do
311
+ response.size.should == 1
312
+ end
313
+ end
314
+
315
+ context 'Send message from subscriber' do
316
+ Given(:ping_opts) { redis_ping_options }
317
+ When(:sub) do
318
+ Gilmour::RedisBackend.new({})
319
+ end
320
+ When (:response) do
321
+ data = code = nil
322
+ waiter = Waiter.new
323
+ sub.publish(ping_opts[:message], 'test.republish') do |d, c|
324
+ data = d
325
+ code = c
326
+ waiter.signal
327
+ end
328
+ waiter.wait(5)
329
+ [data, code]
330
+ end
331
+ Then do
332
+ data, code = response
333
+ data.should be == ping_opts[:response]
334
+ code.should be == 200
335
+ end
336
+ And { expect(EM.reactor_thread.alive?).to be_truthy }
337
+ end
338
+ end
339
+ end
@@ -0,0 +1,370 @@
1
+ # encoding: utf-8
2
+ require 'rspec/given'
3
+ require 'securerandom'
4
+ require './testservice/test_service_base'
5
+
6
+ require_relative 'helpers/common'
7
+ require_relative 'helpers/connection'
8
+
9
+ describe 'TestSubscriberFork' do
10
+ opts = redis_connection_options
11
+ opts['health_check'] = false
12
+
13
+ test_subscriber_path = './testservice/subscribers/test_subscriber'
14
+ after(:all) do
15
+ EM.stop if EM.reactor_running?
16
+ end
17
+
18
+ Given(:subscriber) { TestServiceBase }
19
+ Given do
20
+ subscriber.load_subscriber(test_subscriber_path)
21
+ subscriber.subscribers.each do |topic, arr|
22
+ arr.each do |s|
23
+ s[:fork] = true
24
+ end
25
+ end
26
+ end
27
+ Then do
28
+ handlers = subscriber.subscribers(TestSubscriber::Topic)
29
+ module_present = handlers.find { |h| h[:subscriber] == TestSubscriber }
30
+ module_present.should be_truthy
31
+ end
32
+
33
+ context 'Running Service' do
34
+ before(:all) do
35
+ @service = TestServiceBase.new(opts, 'redis')
36
+ end
37
+ Given(:connection_opts) { opts }
38
+ before(:all) do
39
+ @service.registered_subscribers.each do |s|
40
+ s.backend = 'redis'
41
+ end
42
+
43
+ @service.start
44
+ end
45
+
46
+ context 'Fork not allowed to add dynamic listeners', :fork_dynamic do
47
+ Given(:ping_opts) do
48
+ redis_ping_options
49
+ end
50
+
51
+ When(:sub) do
52
+ Gilmour::RedisBackend.new({})
53
+ end
54
+ When(:code) do
55
+ waiter = Waiter.new
56
+ dynamicaly_subscribed = 0
57
+
58
+ sub.publish(1, TestSubscriber::ReListenTopic) do |d, c|
59
+ sub.confirm_subscriber("test.world") do |present|
60
+ dynamicaly_subscribed = present
61
+ waiter.signal
62
+ end
63
+ end
64
+
65
+ waiter.wait(5)
66
+ dynamicaly_subscribed
67
+ end
68
+ Then do
69
+ code.should be == false
70
+ end
71
+ end
72
+
73
+ context 'Publisher side timeout' do
74
+ Given(:ping_opts) do
75
+ redis_ping_options
76
+ end
77
+
78
+ When(:sub) do
79
+ Gilmour::RedisBackend.new({})
80
+ end
81
+ When(:code) do
82
+ code = nil
83
+ waiter_code = Waiter.new
84
+
85
+ sub.publish(3, TestSubscriber::TimeoutTopic, {:timeout => 1}) do |d, c|
86
+ code = c
87
+ waiter_code.signal
88
+ end
89
+
90
+ waiter_code.wait(5)
91
+ code
92
+ end
93
+ Then do
94
+ code.should be == 499
95
+ end
96
+ end
97
+
98
+ context 'Handler to Test exits' do
99
+ Given(:ping_opts) do
100
+ redis_ping_options
101
+ end
102
+
103
+ When(:sub) do
104
+ Gilmour::RedisBackend.new({})
105
+ end
106
+ When(:code) do
107
+ waiter_error = Waiter.new
108
+ waiter_code = Waiter.new
109
+ code = nil
110
+
111
+ error_listener_proc = sub.add_listener Gilmour::ErrorChannel do |d, c|
112
+ waiter_error.signal
113
+ end
114
+
115
+ sub.publish(1, TestSubscriber::ExitTopic) do |d, c|
116
+ code = c
117
+ waiter_code.signal
118
+ end
119
+
120
+ waiter_code.wait(5)
121
+ waiter_error.wait(5)
122
+
123
+ sub.remove_listener Gilmour::ErrorChannel, error_listener_proc
124
+ code
125
+ end
126
+ Then do
127
+ code.should be == 500
128
+ end
129
+ end
130
+
131
+ context 'Handler sleeps longer than the Timeout' do
132
+ Given(:ping_opts) do
133
+ redis_ping_options
134
+ end
135
+
136
+ When(:sub) do
137
+ Gilmour::RedisBackend.new({})
138
+ end
139
+ When(:code) do
140
+ waiter = Waiter.new
141
+ code = nil
142
+
143
+ sub.publish(3, TestSubscriber::TimeoutTopic) do |d, c|
144
+ code = c
145
+ waiter.signal
146
+ end
147
+
148
+ waiter.wait(5)
149
+ code
150
+ end
151
+ Then do
152
+ code.should be == 504
153
+ end
154
+ end
155
+
156
+ context 'Handler sleeps just enough to survive the timeout' do
157
+ Given(:ping_opts) do
158
+ redis_ping_options
159
+ end
160
+
161
+ When(:sub) do
162
+ Gilmour::RedisBackend.new({})
163
+ end
164
+ When(:code) do
165
+ waiter = Waiter.new
166
+ code = nil
167
+
168
+ sub.publish(1, TestSubscriber::TimeoutTopic) do |d, c|
169
+ code = c
170
+ waiter.signal
171
+ end
172
+
173
+ waiter.wait(5)
174
+ code
175
+ end
176
+ Then do
177
+ code.should be == 200
178
+ end
179
+ end
180
+
181
+ context 'Send and receive a message' do
182
+ Given(:ping_opts) { redis_ping_options }
183
+ When(:sub) do
184
+ Gilmour::RedisBackend.new({})
185
+ end
186
+ When(:response) do
187
+ waiter = Waiter.new
188
+ data = code = nil
189
+ sub.publish(ping_opts[:message], TestSubscriber::Topic, { confirm_subscriber: true }) do |d, c|
190
+ data = d
191
+ code = c
192
+ waiter.signal
193
+ end
194
+ waiter.wait(5)
195
+ [data, code]
196
+ end
197
+ Then do
198
+ data, code = response
199
+ data.should be == ping_opts[:response]
200
+ code.should be == 200
201
+ end
202
+ end
203
+
204
+ context 'Send & Recieve a message on a wildcard key' do
205
+ Given(:wildcard_opts) { redis_wildcard_options }
206
+ When(:sub) do
207
+ Gilmour::RedisBackend.new({})
208
+ end
209
+ When(:response) do
210
+ data = code = nil
211
+
212
+ waiter = Waiter.new
213
+
214
+ sub.publish(wildcard_opts[:message], wildcard_opts[:topic]) do |d,c|
215
+ data = d
216
+ code = 200
217
+ waiter.signal
218
+ end
219
+
220
+ waiter.wait(5)
221
+ [data, code]
222
+ end
223
+ Then do
224
+ data, code = response
225
+ data.should be == wildcard_opts[:message]
226
+ code.should be == 200
227
+ end
228
+ end
229
+
230
+ context 'Send once, Receive twice' do
231
+ Given(:ping_opts) { redis_ping_options }
232
+ When(:sub) do
233
+ Gilmour::RedisBackend.new({})
234
+ end
235
+ When (:response) do
236
+ waiter = Waiter.new
237
+
238
+ actual_ret = []
239
+
240
+ sub.add_listener TestSubscriber::GroupReturn do
241
+ actual_ret.push(request.body)
242
+ end
243
+
244
+ sub.publish(ping_opts[:message], TestSubscriber::GroupTopic)
245
+
246
+ waiter.wait(5)
247
+ actual_ret
248
+ end
249
+ Then do
250
+ response.select { |e| e == ping_opts[:message] }.size.should == 2
251
+ response.select { |e| e == "2" }.size.should == 2
252
+ end
253
+ end
254
+
255
+ context 'Check Exclusive Parallelism' do
256
+ Given(:ping_opts) { redis_ping_options }
257
+ When(:sub) do
258
+ Gilmour::RedisBackend.new({})
259
+ end
260
+ When (:response) do
261
+ waiter = Waiter.new
262
+
263
+ actual_ret = []
264
+
265
+ sub.add_listener TestSubscriber::ExclusiveTimeoutReturn do
266
+ actual_ret.push(request.body)
267
+ end
268
+
269
+ 3.times do
270
+ sub.publish(3, TestSubscriber::ExclusiveTimeoutTopic)
271
+ end
272
+
273
+ waiter.wait(5)
274
+ actual_ret
275
+ end
276
+ Then do
277
+ response.select { |e| e == "2" }.size.should == 3
278
+ end
279
+ end
280
+
281
+ context 'Check Parallelism' do
282
+ Given(:ping_opts) { redis_ping_options }
283
+ When(:sub) do
284
+ Gilmour::RedisBackend.new({})
285
+ end
286
+ When (:response) do
287
+ waiter = Waiter.new
288
+
289
+ actual_ret = []
290
+
291
+ sub.add_listener TestSubscriber::MultiTimeoutReturn do
292
+ actual_ret.push(request.body)
293
+ end
294
+
295
+ sub.publish(3, TestSubscriber::MultiTimeoutTopic)
296
+
297
+ waiter.wait(5)
298
+ actual_ret
299
+ end
300
+ Then do
301
+ response.select { |e| e == "2" }.size.should == 3
302
+ end
303
+ end
304
+
305
+ context 'Send once, Receive Once' do
306
+ Given(:ping_opts) { redis_ping_options }
307
+ When(:sub) do
308
+ Gilmour::RedisBackend.new({})
309
+ end
310
+ When (:response) do
311
+ waiter = Waiter.new
312
+
313
+ actual_ret = []
314
+
315
+ sub.add_listener TestSubscriber::GroupReturn do
316
+ actual_ret.push(request.body)
317
+ end
318
+
319
+ sub.publish(ping_opts[:message], TestSubscriber::ExclusiveTopic)
320
+
321
+ waiter.wait(5)
322
+ actual_ret
323
+ end
324
+ Then do
325
+ response.size.should == 1
326
+ end
327
+ end
328
+
329
+ context 'Handler to Test exits with LPush' do
330
+ Given(:ping_opts) do
331
+ redis_ping_options
332
+ end
333
+
334
+ When(:sub) do
335
+ Gilmour::RedisBackend.new({})
336
+ end
337
+ When(:code) do
338
+ code = nil
339
+
340
+ error_key = "hello.world"
341
+ backend = @service.get_backend("redis")
342
+ backend.report_errors = error_key
343
+
344
+ sub.publish(1, TestSubscriber::ExitTopic)
345
+
346
+ waiter = Waiter.new
347
+
348
+ Thread.new{
349
+ loop {
350
+ $stderr.puts "Checking values"
351
+ sub.publisher.lpop(error_key) do |val|
352
+ if val.is_a? String
353
+ code = 500
354
+ waiter.signal
355
+ end
356
+ end
357
+ sleep 1
358
+ }
359
+ }
360
+
361
+ waiter.wait(6)
362
+ code
363
+ end
364
+ Then do
365
+ code.should be == 500
366
+ end
367
+ end
368
+
369
+ end
370
+ end