gilmour 0.2.4

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.
@@ -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