gilmour 0.3.4 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,207 @@
1
+ require 'rspec/given'
2
+
3
+ require_relative '../../lib/gilmour'
4
+ require_relative 'helpers/common'
5
+
6
+ class Server
7
+ include Gilmour::Base
8
+ end
9
+
10
+ describe 'Pipelines' do
11
+ after(:all) do
12
+ EM.stop
13
+ end
14
+ Given(:gilmour) {
15
+ Server.new.enable_backend('redis')
16
+ }
17
+ When {
18
+ gilmour.reply_to 'one' do
19
+ respond request.body.merge({'one' => 'foo'})
20
+ end
21
+ }
22
+ When {
23
+ gilmour.reply_to 'two' do
24
+ respond request.body.merge({'two' => 'foo'})
25
+ end
26
+ }
27
+ When {
28
+ gilmour.reply_to 'badtwo' do
29
+ respond request.body.merge({'badtwo' => 'foo'}), 500
30
+ end
31
+ }
32
+ When {
33
+ gilmour.reply_to 'three' do
34
+ respond request.body.merge({'three' => 'foo'})
35
+ end
36
+ }
37
+ When {
38
+ # Make sure all subscribers are active
39
+ sleep 1
40
+ }
41
+ context 'Compose' do
42
+ Given(:composed) {
43
+ gilmour.compose([{topic: 'one'}, {topic: 'two'},
44
+ {topic: 'three', message: {'anotherthree' => 'anotherthree'}}])
45
+ }
46
+ Then {
47
+ waiter = Waiter.new
48
+ code = data = nil
49
+ composed.execute({zero: 'foo'}) do |d, c|
50
+ data = d
51
+ code = c
52
+ waiter.signal
53
+ end
54
+ waiter.wait
55
+ ['zero', 'one', 'two', 'three', 'anotherthree'].each do |k|
56
+ expect(data.has_key?(k)).to be_truthy
57
+ end
58
+ expect(code).to eq(200)
59
+ }
60
+ end
61
+
62
+ context 'AndAnd' do
63
+ context 'All successful' do
64
+ Given(:andand) {
65
+ gilmour.andand([{topic: 'one'}, {topic: 'two'},
66
+ {topic: 'three', message: {'anotherthree' => 'anotherthree'}}])
67
+ }
68
+ Then {
69
+ waiter = Waiter.new
70
+ code = data = nil
71
+ andand.execute do |d, c|
72
+ data = d
73
+ code = c
74
+ waiter.signal
75
+ end
76
+ waiter.wait
77
+ expect(data.keys.size).to eq(2)
78
+ ['three', 'anotherthree'].each do |k|
79
+ expect(data.has_key?(k)).to be_truthy
80
+ end
81
+ expect(code).to eq(200)
82
+ }
83
+ end
84
+
85
+ context 'Interrupted' do
86
+ Given(:interupted) {
87
+ gilmour.andand([{topic: 'one'}, {topic: 'badtwo'},
88
+ {topic: 'three', message: {'anotherthree' => 'anotherthree'}}])
89
+ }
90
+ Given(:firsttry) {
91
+ waiter = Waiter.new
92
+ cont = code = data = nil
93
+ interupted.execute do |d, c, continuation|
94
+ data = d
95
+ code = c
96
+ cont = continuation
97
+ waiter.signal
98
+ end
99
+ waiter.wait
100
+ {code: code, data: data, continuation: cont}
101
+ }
102
+ Given(:secondtry) {
103
+ waiter = Waiter.new
104
+ code = data = nil
105
+ firsttry[:continuation].execute do |d, c|
106
+ data = d
107
+ code = c
108
+ waiter.signal
109
+ end
110
+ waiter.wait
111
+ {code: code, data: data}
112
+ }
113
+ Then {
114
+ data = firsttry[:data]
115
+ code = firsttry[:code]
116
+ expect(data.keys.size).to eq(1)
117
+ ['badtwo'].each do |k|
118
+ expect(data.has_key?(k)).to be_truthy
119
+ end
120
+ expect(code).to eq(500)
121
+ }
122
+ And {
123
+ data = secondtry[:data]
124
+ code = secondtry[:code]
125
+ expect(data.keys.size).to eq(2)
126
+ ['three', 'anotherthree'].each do |k|
127
+ expect(data.has_key?(k)).to be_truthy
128
+ end
129
+ expect(code).to eq(200)
130
+ }
131
+ end
132
+ end
133
+
134
+ context 'Batch' do
135
+ context 'Without record' do
136
+ Given(:batch) {
137
+ gilmour.batch([{topic: 'one'}, {topic: 'badtwo'},
138
+ {topic: 'three', message: {'anotherthree' => 'anotherthree'}}])
139
+ }
140
+ Then {
141
+ waiter = Waiter.new
142
+ code = data = nil
143
+ batch.execute do |d, c|
144
+ data = d
145
+ code = c
146
+ waiter.signal
147
+ end
148
+ waiter.wait
149
+ expect(data).to be_kind_of(Hash)
150
+ expect(data.keys.size).to eq(2)
151
+ ['three', 'anotherthree'].each do |k|
152
+ expect(data.has_key?(k)).to be_truthy
153
+ end
154
+ expect(code).to eq(200)
155
+ }
156
+ end
157
+
158
+ context 'With record' do
159
+ Given(:batchrecord) {
160
+ gilmour.batch([{topic: 'one'}, {topic: 'badtwo'},
161
+ {topic: 'three', message: {'anotherthree' => 'anotherthree'}}],
162
+ true)
163
+ }
164
+ Then {
165
+ waiter = Waiter.new
166
+ code = data = nil
167
+ batchrecord.execute do |d, c|
168
+ data = d
169
+ code = c
170
+ waiter.signal
171
+ end
172
+ waiter.wait
173
+ expect(data).to be_kind_of(Array)
174
+ expect(data.size).to eq(3)
175
+ %w{one badtwo three anotherthree}.each do |k|
176
+ expect(data.find {|o| o[:data].has_key?(k)}).not_to be_nil
177
+ end
178
+ }
179
+ end
180
+ end
181
+ context 'Combinations' do
182
+ context 'Andand and compose' do
183
+ Given(:andand) {
184
+ gilmour.andand([{topic: 'one'}, {topic: 'two'}])
185
+ }
186
+ Given(:compose) {
187
+ gilmour.compose([andand, {topic: 'three'}])
188
+ }
189
+ Then {
190
+ waiter = Waiter.new
191
+ code = data = nil
192
+ compose.execute do |d, c|
193
+ data = d
194
+ code = c
195
+ waiter.signal
196
+ end
197
+ waiter.wait
198
+ expect(data.keys.size).to eq(2)
199
+ ['two', 'three'].each do |k|
200
+ expect(data.has_key?(k)).to be_truthy
201
+ end
202
+ expect(code).to eq(200)
203
+ }
204
+ end
205
+ end
206
+ end
207
+
@@ -264,7 +264,7 @@ describe 'TestSubscriber' do
264
264
 
265
265
  end
266
266
 
267
- context 'Send and receive a message' do
267
+ context 'Send and receive a message', :debug do
268
268
  Given(:ping_opts) { redis_ping_options }
269
269
  When(:sub) do
270
270
  Gilmour::RedisBackend.new({})
@@ -206,7 +206,7 @@ describe 'TestSubscriberFork' do
206
206
  end
207
207
  end
208
208
 
209
- context 'Send and receive a message' do
209
+ context 'Send and receive a message', :debug do
210
210
  Given(:ping_opts) { redis_ping_options }
211
211
  When(:sub) do
212
212
  Gilmour::RedisBackend.new({})
@@ -375,7 +375,6 @@ describe 'TestSubscriberFork' do
375
375
 
376
376
  Thread.new{
377
377
  loop {
378
- $stderr.puts "Checking values"
379
378
  sub.publisher.lpop(error_key) do |val|
380
379
  if val.is_a? String
381
380
  code = 500
@@ -0,0 +1,303 @@
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
10
+ waiter = Waiter.new
11
+ TestReplier.callback do |topic, data|
12
+ @topic = topic
13
+ @data = data
14
+ $stderr.puts "Got callback #{topic}, #{data}"
15
+ waiter.signal
16
+ end
17
+ waiter
18
+ end
19
+
20
+ describe 'TestReplier' do
21
+ opts = redis_connection_options
22
+ opts[:health_check] = true
23
+
24
+ test_subscriber_path = './testservice/subscribers/test_reply'
25
+ after(:all) do
26
+ EM.stop
27
+ end
28
+ Given(:subscriber) { TestServiceBase }
29
+ Given do
30
+ subscriber.load_subscriber(test_subscriber_path)
31
+ end
32
+ Then do
33
+ handlers = subscriber.subscribers(TestReplier::Topic)
34
+ module_present = handlers.find { |h| h[:subscriber] == TestReplier }
35
+ module_present.should be_truthy
36
+ end
37
+
38
+ context 'Running Service' do
39
+ before(:all) do
40
+ @service = TestServiceBase.new(opts, 'redis')
41
+ end
42
+ Given(:connection_opts) { opts }
43
+ before(:all) do
44
+ @service.registered_subscribers.each do |s|
45
+ s.backend = 'redis'
46
+ end
47
+ @service.start
48
+ end
49
+
50
+ context 'Handler Register' do
51
+ When { install_test_subscriber }
52
+ context 'Check registered handlers' do
53
+ When(:handlers) do
54
+ subscriber.subscribers(TestReplier::Simulation)
55
+ .map { |h| h[:handler] }
56
+ end
57
+ Then { handlers.each { |h| h.should be_kind_of Proc } }
58
+ Then do
59
+ arg1 = TestReplier::Simulation
60
+ handlers.each do |h|
61
+ arg2 = SecureRandom.hex
62
+ # simualate a handler call
63
+ h.call(arg1, arg2)
64
+ @topic.should be == arg1
65
+ @data.should be == arg2
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ context 'Receive messages' do
72
+ context 'Receive a message' do
73
+ Given(:ping_opts) { redis_ping_options }
74
+ When do
75
+ @data = @topic = nil
76
+ waiter = install_test_subscriber
77
+ g = Gilmour::RedisBackend.new({})
78
+ g.request!(ping_opts[:message], TestReplier::Topic)
79
+ waiter.wait(5)
80
+ end
81
+ Then do
82
+ @data.should be == ping_opts[:message]
83
+ @topic.should be == "gilmour.request.#{TestReplier::Topic}"
84
+ end
85
+ And { expect(EM.reactor_thread.alive?).to be_truthy }
86
+ end
87
+ end
88
+
89
+ context 'Non Fork can add dynamic listeners', :fork_dynamic do
90
+ Given(:ping_opts) do
91
+ redis_ping_options
92
+ end
93
+
94
+ When(:sub) do
95
+ Gilmour::RedisBackend.new({})
96
+ end
97
+ When(:code) do
98
+ waiter = Waiter.new
99
+ dynamicaly_subscribed = 0
100
+
101
+ sub.request!(1, TestReplier::ReListenTopic) do |d, c|
102
+ sub.confirm_subscriber(sub.request_destination("test.world")) do |present|
103
+ dynamicaly_subscribed = present
104
+ waiter.signal
105
+ end
106
+ end
107
+
108
+ waiter.wait(5)
109
+ dynamicaly_subscribed
110
+ end
111
+ Then do
112
+ code.should be == true
113
+ end
114
+ end
115
+
116
+ context 'Publisher side timeout' do
117
+ Given(:ping_opts) do
118
+ redis_ping_options
119
+ end
120
+
121
+ When(:sub) do
122
+ Gilmour::RedisBackend.new({})
123
+ end
124
+ When(:code) do
125
+ code = nil
126
+ waiter_code = Waiter.new
127
+
128
+ sub.request!(3, TestReplier::TimeoutTopic, {:timeout => 1}) do |d, c|
129
+ code = c
130
+ waiter_code.signal
131
+ end
132
+
133
+ waiter_code.wait(5)
134
+ code
135
+ end
136
+ Then do
137
+ code.should be == 499
138
+ end
139
+ end
140
+
141
+ context 'Handler sleeps longer than the Timeout' do
142
+ Given(:ping_opts) do
143
+ redis_ping_options
144
+ end
145
+
146
+ When(:sub) do
147
+ Gilmour::RedisBackend.new({})
148
+ end
149
+ When(:code) do
150
+ waiter_error = Waiter.new
151
+ waiter_code = Waiter.new
152
+ code = nil
153
+
154
+ backend = @service.get_backend("redis")
155
+ backend.broadcast_errors = true
156
+ sub.slot Gilmour::ErrorChannel do
157
+ waiter_error.signal
158
+ end
159
+
160
+ sub.request!(3, TestReplier::TimeoutTopic) do |d, c|
161
+ code = c
162
+ waiter_code.signal
163
+ end
164
+
165
+ waiter_code.wait(5)
166
+ waiter_error.wait(5)
167
+
168
+ backend.broadcast_errors = false
169
+ code
170
+ end
171
+ Then do
172
+ code.should be == 504
173
+ end
174
+ end
175
+
176
+ context 'Handler sleeps just enough to survive the timeout' do
177
+ Given(:ping_opts) do
178
+ redis_ping_options
179
+ end
180
+
181
+ When(:sub) do
182
+ Gilmour::RedisBackend.new({})
183
+ end
184
+ When(:code) do
185
+ waiter = Waiter.new
186
+ code = nil
187
+
188
+ sub.request!(1, TestReplier::TimeoutTopic) do |d, c|
189
+ code = c
190
+ waiter.signal
191
+ end
192
+
193
+ waiter.wait(5)
194
+ code
195
+ end
196
+ Then do
197
+ code.should be == 200
198
+ end
199
+ end
200
+
201
+
202
+ context 'Request! sans subscriber error' do
203
+ Given(:ping_opts) do
204
+ redis_ping_options
205
+ end
206
+
207
+ When(:sub) do
208
+ Gilmour::RedisBackend.new({})
209
+ end
210
+ When(:response) do
211
+ waiter = Waiter.new
212
+ data = code = nil
213
+ sub.request!(ping_opts[:message], "hello.world") do |d, c|
214
+ data = d
215
+ code = c
216
+ waiter.signal
217
+ end
218
+ waiter.wait(5)
219
+ [data, code]
220
+ end
221
+ Then do
222
+ data, code = response
223
+ data.should be == nil
224
+ code.should be == 404
225
+ end
226
+
227
+ end
228
+
229
+ context 'Send and receive a message' do
230
+ Given(:ping_opts) { redis_ping_options }
231
+ When(:sub) do
232
+ Gilmour::RedisBackend.new({})
233
+ end
234
+ When(:response) do
235
+ waiter = Waiter.new
236
+ data = code = nil
237
+ sub.request!(ping_opts[:message], TestReplier::Topic) do |d, c|
238
+ data = d
239
+ code = c
240
+ waiter.signal
241
+ end
242
+ waiter.wait(5)
243
+ [data, code]
244
+ end
245
+ Then do
246
+ data, code = response
247
+ data.should be == ping_opts[:response]
248
+ code.should be == 200
249
+ end
250
+ end
251
+
252
+ context 'Send once, Receive twice' do
253
+ Given(:ping_opts) { redis_ping_options }
254
+ When(:sub) do
255
+ Gilmour::RedisBackend.new({})
256
+ end
257
+ When (:response) do
258
+ waiter = Waiter.new
259
+
260
+ actual_ret = []
261
+
262
+ group_proc = sub.slot TestReplier::GroupReturn do
263
+ actual_ret.push(request.body)
264
+ waiter.signal if actual_ret.length == 4
265
+ end
266
+
267
+ sub.signal!(ping_opts[:message], TestReplier::GroupTopic)
268
+ waiter.wait(5)
269
+
270
+ sub.remove_slot TestReplier::GroupReturn, group_proc
271
+ actual_ret
272
+ end
273
+ Then do
274
+ response.select { |e| e == ping_opts[:message] }.size.should == 2
275
+ response.select { |e| e == "2" }.size.should == 2
276
+ end
277
+ end
278
+
279
+ context 'Send message from subscriber' do
280
+ Given(:ping_opts) { redis_ping_options }
281
+ When(:sub) do
282
+ Gilmour::RedisBackend.new({})
283
+ end
284
+ When (:response) do
285
+ data = code = nil
286
+ waiter = Waiter.new
287
+ sub.request!(ping_opts[:message], TestReplier::Republish) do |d, c|
288
+ data = d
289
+ code = c
290
+ waiter.signal
291
+ end
292
+ waiter.wait(5)
293
+ [data, code]
294
+ end
295
+ Then do
296
+ data, code = response
297
+ data.should be == ping_opts[:response]
298
+ code.should be == 200
299
+ end
300
+ And { expect(EM.reactor_thread.alive?).to be_truthy }
301
+ end
302
+ end
303
+ end