right_agent 2.1.5 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/right_agent/agent_tag_manager.rb +17 -9
- data/lib/right_agent/clients/api_client.rb +28 -27
- data/lib/right_agent/clients/balanced_http_client.rb +25 -5
- data/lib/right_agent/clients/base_retry_client.rb +76 -42
- data/lib/right_agent/clients/blocking_client.rb +11 -1
- data/lib/right_agent/clients/non_blocking_client.rb +32 -9
- data/lib/right_agent/clients/right_http_client.rb +14 -8
- data/lib/right_agent/clients/router_client.rb +41 -14
- data/lib/right_agent/command/command_client.rb +1 -0
- data/lib/right_agent/http_exceptions.rb +6 -1
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +2 -2
- data/lib/right_agent/offline_handler.rb +22 -9
- data/lib/right_agent/retryable_request.rb +18 -12
- data/lib/right_agent/scripts/agent_controller.rb +9 -3
- data/lib/right_agent/sender.rb +94 -61
- data/right_agent.gemspec +2 -2
- data/spec/agent_tag_manager_spec.rb +59 -14
- data/spec/clients/api_client_spec.rb +48 -36
- data/spec/clients/balanced_http_client_spec.rb +46 -2
- data/spec/clients/base_retry_client_spec.rb +118 -48
- data/spec/clients/blocking_client_spec.rb +16 -0
- data/spec/clients/non_blocking_client_spec.rb +43 -6
- data/spec/clients/router_client_spec.rb +54 -49
- data/spec/http_exceptions_spec.rb +7 -0
- data/spec/offline_handler_spec.rb +22 -11
- data/spec/retryable_request_spec.rb +35 -20
- data/spec/sender_spec.rb +185 -122
- metadata +3 -3
data/spec/sender_spec.rb
CHANGED
@@ -63,11 +63,17 @@ describe RightScale::Sender do
|
|
63
63
|
@log.should_receive(:warning).by_default.and_return { |m| raise RightScale::Log.format(*m) }
|
64
64
|
@sender = create_sender(:http)
|
65
65
|
@token = "token"
|
66
|
+
@ttl = 30
|
66
67
|
@type = "/foo/bar"
|
67
68
|
@action = "bar"
|
68
69
|
@payload = {:pay => "load"}
|
69
70
|
@target = "target"
|
70
|
-
@
|
71
|
+
@options = {}
|
72
|
+
@response = nil
|
73
|
+
@callback = lambda { |response| @response = response }
|
74
|
+
@now = Time.now
|
75
|
+
flexmock(Time).should_receive(:now).and_return(@now).by_default
|
76
|
+
@received_at = @now
|
71
77
|
end
|
72
78
|
|
73
79
|
context :initialize do
|
@@ -137,24 +143,24 @@ describe RightScale::Sender do
|
|
137
143
|
flexmock(RightSupport::Data::UUID, :generate => "random token")
|
138
144
|
flexmock(@sender).should_receive(:http_send).with(:send_push, nil, on { |a| a.class == RightScale::Push &&
|
139
145
|
a.type == @type && a.from == @agent_id && a.target.nil? && a.persistent == true && a.confirm.nil? &&
|
140
|
-
a.token == "random token" && a.expires_at == 0 }, Time
|
146
|
+
a.token == "random token" && a.expires_at == 0 }, Time).once
|
141
147
|
@sender.send_push(@type).should be_true
|
142
148
|
end
|
143
149
|
|
144
150
|
it "stores payload" do
|
145
|
-
flexmock(@sender).should_receive(:http_send).with(:send_push, nil, on { |a| a.payload == @payload }, Time
|
151
|
+
flexmock(@sender).should_receive(:http_send).with(:send_push, nil, on { |a| a.payload == @payload }, Time).once
|
146
152
|
@sender.send_push(@type, @payload).should be_true
|
147
153
|
end
|
148
154
|
|
149
155
|
it "sets specific target using string" do
|
150
156
|
flexmock(@sender).should_receive(:http_send).with(:send_push, @target, on { |a| a.target == @target &&
|
151
|
-
a.selector == :any }, Time
|
157
|
+
a.selector == :any }, Time).once
|
152
158
|
@sender.send_push(@type, nil, @target).should be_true
|
153
159
|
end
|
154
160
|
|
155
161
|
it "sets specific target using :agent_id" do
|
156
162
|
target = {:agent_id => @agent_id}
|
157
|
-
flexmock(@sender).should_receive(:http_send).with(:send_push, target, on { |a| a.target == @agent_id }, Time
|
163
|
+
flexmock(@sender).should_receive(:http_send).with(:send_push, target, on { |a| a.target == @agent_id }, Time).once
|
158
164
|
@sender.send_push(@type, nil, target).should be_true
|
159
165
|
end
|
160
166
|
|
@@ -162,7 +168,7 @@ describe RightScale::Sender do
|
|
162
168
|
tags = ["a:b=c"]
|
163
169
|
target = {:tags => tags}
|
164
170
|
flexmock(@sender).should_receive(:http_send).with(:send_push, target, on { |a| a.tags == tags &&
|
165
|
-
a.selector == :any }, Time
|
171
|
+
a.selector == :any }, Time).once
|
166
172
|
@sender.send_push(@type, nil, target).should be_true
|
167
173
|
end
|
168
174
|
|
@@ -170,20 +176,31 @@ describe RightScale::Sender do
|
|
170
176
|
scope = {:shard => 1, :account => 123}
|
171
177
|
target = {:scope => scope}
|
172
178
|
flexmock(@sender).should_receive(:http_send).with(:send_push, target, on { |a| a.scope == scope &&
|
173
|
-
a.selector == :any }, Time
|
179
|
+
a.selector == :any }, Time).once
|
174
180
|
@sender.send_push(@type, nil, target).should be_true
|
175
181
|
end
|
176
182
|
|
177
183
|
it "sets target selector" do
|
178
184
|
tags = ["a:b=c"]
|
179
185
|
target = {:tags => tags, :selector => :all}
|
180
|
-
flexmock(@sender).should_receive(:http_send).with(:send_push, target, on { |a| a.selector == :all }, Time
|
186
|
+
flexmock(@sender).should_receive(:http_send).with(:send_push, target, on { |a| a.selector == :all }, Time).once
|
181
187
|
@sender.send_push(@type, nil, target).should be_true
|
182
188
|
end
|
183
189
|
|
184
190
|
it "sets token" do
|
185
|
-
flexmock(@sender).should_receive(:http_send).with(:send_push, @target, on { |a| a.token == "token2" }, Time
|
186
|
-
@sender.send_push(@type, nil, @target, "token2").should be_true
|
191
|
+
flexmock(@sender).should_receive(:http_send).with(:send_push, @target, on { |a| a.token == "token2" }, Time).once
|
192
|
+
@sender.send_push(@type, nil, @target, :token => "token2").should be_true
|
193
|
+
end
|
194
|
+
|
195
|
+
it "defaults to no expiration time" do
|
196
|
+
@sender = create_sender(:http, :time_to_live => 99)
|
197
|
+
flexmock(@sender).should_receive(:http_send).with(:send_push, nil, on { |a| a.expires_at == 0 }, Time).once
|
198
|
+
@sender.send_push(@type).should be_true
|
199
|
+
end
|
200
|
+
|
201
|
+
it "sets expiration time if time-to-live if specified" do
|
202
|
+
flexmock(@sender).should_receive(:http_send).with(:send_push, @target, on { |a| a.expires_at == (@now + @ttl).to_i }, Time).once
|
203
|
+
@sender.send_push(@type, nil, @target, :time_to_live => @ttl).should be_true
|
187
204
|
end
|
188
205
|
|
189
206
|
it "sets applies callback for returning response" do
|
@@ -236,15 +253,21 @@ describe RightScale::Sender do
|
|
236
253
|
|
237
254
|
it "sets token" do
|
238
255
|
flexmock(@sender).should_receive(:http_send).with(:send_request, @target, on { |a| a.token == "token2" }, Time, Proc).once
|
239
|
-
@sender.send_request(@type, nil, @target, "token2") { |_| }.should be_true
|
256
|
+
@sender.send_request(@type, nil, @target, :token => "token2") { |_| }.should be_true
|
240
257
|
end
|
241
258
|
|
242
|
-
it "sets expiration time if
|
243
|
-
@sender = create_sender(:http, :time_to_live =>
|
244
|
-
flexmock(@sender).should_receive(:http_send).with(:send_request, nil, on { |a| a.expires_at
|
259
|
+
it "sets expiration time if time-to-live configured" do
|
260
|
+
@sender = create_sender(:http, :time_to_live => 99)
|
261
|
+
flexmock(@sender).should_receive(:http_send).with(:send_request, nil, on { |a| a.expires_at == (@now + 99).to_i }, Time, Proc).once
|
245
262
|
@sender.send_request(@type) { |_| }.should be_true
|
246
263
|
end
|
247
264
|
|
265
|
+
it "overrides configured time-to-live with specified time-to-live" do
|
266
|
+
@sender = create_sender(:http, :time_to_live => 99)
|
267
|
+
flexmock(@sender).should_receive(:http_send).with(:send_request, @target, on { |a| a.expires_at == (@now + @ttl).to_i }, Time, Proc).once
|
268
|
+
@sender.send_request(@type, nil, @target, :time_to_live => @ttl) { |_| }.should be_true
|
269
|
+
end
|
270
|
+
|
248
271
|
it "does not allow fanout" do
|
249
272
|
lambda { @sender.send_request(@type, nil, :selector => :all) }.should raise_error(ArgumentError)
|
250
273
|
end
|
@@ -256,29 +279,32 @@ describe RightScale::Sender do
|
|
256
279
|
|
257
280
|
context :build_and_send_packet do
|
258
281
|
[:http, :amqp].each do |mode|
|
259
|
-
|
260
282
|
context "when #{mode}" do
|
261
283
|
before(:each) do
|
262
284
|
@sender = create_sender(mode)
|
263
285
|
end
|
264
286
|
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
287
|
+
[[:send_push, RightScale::Push, nil], [:send_request, RightScale::Request, @callback]].each do |kind, klass, callback|
|
288
|
+
it "builds packet" do
|
289
|
+
packet = flexmock("packet", :type => @type, :token => @token, :selector => :any)
|
290
|
+
flexmock(@sender).should_receive(:build_packet).
|
291
|
+
with(kind, @type, @payload, @target, @options, &callback).and_return(packet).once
|
292
|
+
flexmock(@sender).should_receive("#{mode}_send".to_sym)
|
293
|
+
@sender.build_and_send_packet(kind, @type, @payload, @target, @options, &callback).should be_true
|
294
|
+
end
|
271
295
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
296
|
+
it "sends packet" do
|
297
|
+
flexmock(@sender).should_receive("#{mode}_send".to_sym).
|
298
|
+
with(kind, @target, on { |a| a.class == klass }, Time, &callback).once
|
299
|
+
@sender.build_and_send_packet(kind, @type, @payload, @target, @options, &callback).should be_true
|
300
|
+
end
|
277
301
|
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
302
|
+
it "ignores nil packet result when queueing" do
|
303
|
+
flexmock(@sender).should_receive(:build_packet).
|
304
|
+
with(kind, @type, @payload, @target, @options, &callback).and_return(nil).once
|
305
|
+
flexmock(@sender).should_receive("#{mode}_send".to_sym).never
|
306
|
+
@sender.build_and_send_packet(kind, @type, @payload, @target, @options, &callback).should be_true
|
307
|
+
end
|
282
308
|
end
|
283
309
|
end
|
284
310
|
end
|
@@ -286,50 +312,55 @@ describe RightScale::Sender do
|
|
286
312
|
|
287
313
|
context :build_packet do
|
288
314
|
[:send_push, :send_request].each do |kind|
|
289
|
-
|
290
315
|
context "when #{kind}" do
|
291
316
|
it "validates target" do
|
292
317
|
flexmock(@sender).should_receive(:validate_target).with(@target, kind == :send_push).once
|
293
|
-
@sender.build_packet(kind, @type, nil, @target
|
318
|
+
@sender.build_packet(kind, @type, nil, @target).should_not be_nil
|
294
319
|
end
|
295
320
|
|
296
321
|
it "submits request to offline handler and returns nil if queueing" do
|
297
322
|
flexmock(@sender).should_receive(:queueing?).and_return(true).once
|
298
|
-
@sender.build_packet(kind, @type, nil, @target
|
323
|
+
@sender.build_packet(kind, @type, nil, @target).should be_nil
|
324
|
+
end
|
325
|
+
|
326
|
+
it "uses specified request token" do
|
327
|
+
flexmock(RightSupport::Data::UUID, :generate => "random token")
|
328
|
+
packet = @sender.build_packet(kind, @type, nil, @target, :token => @token)
|
329
|
+
packet.token.should == @token
|
299
330
|
end
|
300
331
|
|
301
332
|
it "generates a request token if none provided" do
|
302
333
|
flexmock(RightSupport::Data::UUID, :generate => "random token")
|
303
|
-
packet = @sender.build_packet(kind, @type, nil, @target
|
334
|
+
packet = @sender.build_packet(kind, @type, nil, @target)
|
304
335
|
packet.token.should == "random token"
|
305
336
|
end
|
306
337
|
|
307
338
|
it "sets payload" do
|
308
|
-
packet = @sender.build_packet(kind, @type, @payload, @target
|
339
|
+
packet = @sender.build_packet(kind, @type, @payload, @target)
|
309
340
|
packet.payload.should == @payload
|
310
341
|
end
|
311
342
|
|
312
343
|
it "sets the packet from this agent" do
|
313
|
-
packet = @sender.build_packet(kind, @type, nil, @target
|
344
|
+
packet = @sender.build_packet(kind, @type, nil, @target)
|
314
345
|
packet.from.should == @agent_id
|
315
346
|
end
|
316
347
|
|
317
348
|
it "sets target if target is not a hash" do
|
318
|
-
packet = @sender.build_packet(kind, @type, nil, @target
|
349
|
+
packet = @sender.build_packet(kind, @type, nil, @target)
|
319
350
|
packet.target.should == @target
|
320
351
|
end
|
321
352
|
|
322
353
|
context "when target is a hash" do
|
323
354
|
it "sets agent ID" do
|
324
355
|
target = {:agent_id => @agent_id}
|
325
|
-
packet = @sender.build_packet(kind, @type, nil, target
|
356
|
+
packet = @sender.build_packet(kind, @type, nil, target)
|
326
357
|
packet.target.should == @agent_id
|
327
358
|
end
|
328
359
|
|
329
360
|
it "sets tags" do
|
330
361
|
tags = ["a:b=c"]
|
331
362
|
target = {:tags => tags}
|
332
|
-
packet = @sender.build_packet(kind, @type, nil, target
|
363
|
+
packet = @sender.build_packet(kind, @type, nil, target)
|
333
364
|
packet.tags.should == tags
|
334
365
|
packet.scope.should be_nil
|
335
366
|
end
|
@@ -337,56 +368,68 @@ describe RightScale::Sender do
|
|
337
368
|
it "sets scope" do
|
338
369
|
scope = {:shard => 1, :account => 123}
|
339
370
|
target = {:scope => scope}
|
340
|
-
packet = @sender.build_packet(kind, @type, nil, target
|
371
|
+
packet = @sender.build_packet(kind, @type, nil, target)
|
341
372
|
packet.tags.should == []
|
342
373
|
end
|
343
374
|
end
|
344
375
|
|
345
376
|
if kind == :send_push
|
346
377
|
it "defaults selector to :any" do
|
347
|
-
packet = @sender.build_packet(kind, @type, nil, @target
|
378
|
+
packet = @sender.build_packet(kind, @type, nil, @target)
|
348
379
|
packet.selector.should == :any
|
349
380
|
end
|
350
381
|
|
351
382
|
it "sets selector" do
|
352
383
|
target = {:selector => :all}
|
353
|
-
packet = @sender.build_packet(kind, @type, nil, target
|
384
|
+
packet = @sender.build_packet(kind, @type, nil, target)
|
354
385
|
packet.selector.should == :all
|
355
386
|
end
|
356
387
|
|
357
388
|
it "sets persistent flag" do
|
358
|
-
packet = @sender.build_packet(kind, @type, nil, @target
|
389
|
+
packet = @sender.build_packet(kind, @type, nil, @target)
|
359
390
|
packet.persistent.should be_true
|
360
391
|
end
|
361
392
|
|
362
393
|
it "enables confirm if callback provided" do
|
363
|
-
packet = @sender.build_packet(kind, @type, nil, @target,
|
394
|
+
packet = @sender.build_packet(kind, @type, nil, @target, &@callback)
|
364
395
|
packet.confirm.should be_true
|
365
396
|
end
|
366
397
|
|
367
398
|
it "does not enable confirm if not callback provided" do
|
368
|
-
packet = @sender.build_packet(kind, @type, nil, @target
|
399
|
+
packet = @sender.build_packet(kind, @type, nil, @target)
|
369
400
|
packet.confirm.should be_false
|
370
401
|
end
|
371
402
|
|
372
|
-
it "does not set expiration time" do
|
373
|
-
|
403
|
+
it "does not set expiration time by default" do
|
404
|
+
@sender = create_sender(:http, :time_to_live => 99)
|
405
|
+
packet = @sender.build_packet(kind, @type, nil, @target)
|
374
406
|
packet.expires_at.should == 0
|
375
407
|
end
|
408
|
+
|
409
|
+
it "sets expiration time if specified" do
|
410
|
+
packet = @sender.build_packet(kind, @type, nil, @target, :time_to_live => @ttl)
|
411
|
+
packet.expires_at.should == (@now + @ttl).to_i
|
412
|
+
end
|
376
413
|
else
|
377
414
|
it "always sets selector to :any" do
|
378
|
-
packet = @sender.build_packet(kind, @type, nil, @target
|
415
|
+
packet = @sender.build_packet(kind, @type, nil, @target)
|
379
416
|
packet.selector.should == :any
|
380
417
|
end
|
381
418
|
|
382
|
-
it "sets expiration time to specified
|
383
|
-
|
384
|
-
now
|
385
|
-
flexmock(Time).should_receive(:now).and_return(now)
|
386
|
-
packet = @sender.build_packet(kind, @type, nil, @target, @token)
|
387
|
-
packet.expires_at.should == (now + 99).to_i
|
419
|
+
it "sets expiration time to specified time-to-live" do
|
420
|
+
packet = @sender.build_packet(kind, @type, nil, @target, :time_to_live => @ttl)
|
421
|
+
packet.expires_at.should == (@now + @ttl).to_i
|
388
422
|
end
|
389
423
|
end
|
424
|
+
|
425
|
+
it "queues request if currently queuing and returns nil" do
|
426
|
+
@options = {:token => @token, :time_to_live => @ttl}
|
427
|
+
@sender = create_sender(:http, :offline_queueing => true)
|
428
|
+
flexmock(@sender.offline_handler).should_receive(:queueing?).and_return(true)
|
429
|
+
flexmock(@sender.offline_handler).should_receive(:queue_request).
|
430
|
+
with(kind, @type, @payload, @target, @token, (@now + @ttl).to_i, @callback).once
|
431
|
+
@sender.build_packet(kind, @type, @payload, @target, @options, &@callback).should be nil
|
432
|
+
end
|
390
433
|
end
|
391
434
|
end
|
392
435
|
end
|
@@ -394,9 +437,6 @@ describe RightScale::Sender do
|
|
394
437
|
context :handle_response do
|
395
438
|
before(:each) do
|
396
439
|
flexmock(RightSupport::Data::UUID, :generate => @token)
|
397
|
-
@received_at = Time.now
|
398
|
-
flexmock(Time).should_receive(:now).and_return(@received_at)
|
399
|
-
@callback = lambda { |_| }
|
400
440
|
@pending_request = RightScale::PendingRequest.new(:send_request, @received_at, @callback)
|
401
441
|
@sender.pending_requests[@token] = @pending_request
|
402
442
|
end
|
@@ -657,18 +697,15 @@ describe RightScale::Sender do
|
|
657
697
|
|
658
698
|
context :http_send do
|
659
699
|
before(:each) do
|
660
|
-
@
|
661
|
-
flexmock(Time).should_receive(:now).and_return(@received_at)
|
700
|
+
@token = "random token"
|
662
701
|
flexmock(RightSupport::Data::UUID).should_receive(:generate).and_return(@token).by_default
|
663
|
-
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @
|
664
|
-
@response = nil
|
665
|
-
@callback = lambda { |response| @response = response }
|
702
|
+
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @options, &@callback)
|
666
703
|
end
|
667
704
|
|
668
705
|
it "sends request using configured client" do
|
669
|
-
@packet = @sender.build_packet(:send_push, @type, @payload, @target, @
|
670
|
-
@client.should_receive(:push).with(@type, @payload, @target, @token).and_return(nil).once
|
671
|
-
@sender.send(:http_send, :send_push, @target, @packet, @received_at,
|
706
|
+
@packet = @sender.build_packet(:send_push, @type, @payload, @target, @options, &@callback)
|
707
|
+
@client.should_receive(:push).with(@type, @payload, @target, :request_uuid => @token).and_return(nil).once
|
708
|
+
@sender.send(:http_send, :send_push, @target, @packet, @received_at, &@callback).should be_true
|
672
709
|
end
|
673
710
|
|
674
711
|
context "when :async_response enabled" do
|
@@ -678,40 +715,43 @@ describe RightScale::Sender do
|
|
678
715
|
end
|
679
716
|
|
680
717
|
it "sends in next_tick if :async_response option set" do
|
681
|
-
@packet = @sender.build_packet(:send_push, @type, @payload, @target, @
|
682
|
-
@client.should_receive(:push).with(@type, @payload, @target, @token).and_return(nil).once
|
683
|
-
@sender.send(:http_send, :send_push, @target, @packet, @received_at,
|
718
|
+
@packet = @sender.build_packet(:send_push, @type, @payload, @target, @options, &@callback)
|
719
|
+
@client.should_receive(:push).with(@type, @payload, @target, :request_uuid => @token).and_return(nil).once
|
720
|
+
@sender.send(:http_send, :send_push, @target, @packet, @received_at, &@callback).should be_true
|
684
721
|
end
|
685
722
|
|
686
723
|
it "logs unexpected exception" do
|
687
724
|
flexmock(@sender).should_receive(:handle_response).and_raise(RuntimeError).once
|
688
725
|
@log.should_receive(:error).with(/Failed sending or handling response/, RuntimeError, :trace).once
|
689
|
-
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @
|
690
|
-
@client.should_receive(:request).with(@type, @payload, @target, @token).and_return("result").once
|
691
|
-
@sender.send(:http_send, :send_request, @target, @packet, @received_at,
|
726
|
+
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @options, &@callback)
|
727
|
+
@client.should_receive(:request).with(@type, @payload, @target, :request_uuid => @token).and_return("result").once
|
728
|
+
@sender.send(:http_send, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
692
729
|
end
|
693
730
|
end
|
694
731
|
end
|
695
732
|
|
696
733
|
context :http_send_once do
|
697
734
|
before(:each) do
|
698
|
-
@
|
699
|
-
flexmock(Time).should_receive(:now).and_return(@received_at)
|
735
|
+
@token = "random token"
|
700
736
|
flexmock(RightSupport::Data::UUID).should_receive(:generate).and_return(@token).by_default
|
701
|
-
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @
|
702
|
-
@response = nil
|
703
|
-
@callback = lambda { |response| @response = response }
|
737
|
+
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @options, &@callback)
|
704
738
|
end
|
705
739
|
|
706
740
|
it "sends request using configured client" do
|
707
|
-
@packet = @sender.build_packet(:send_push, @type, @payload, @target
|
708
|
-
@client.should_receive(:push).with(@type, @payload, @target, @token).and_return(nil).once
|
709
|
-
@sender.send(:http_send_once, :send_push, @target, @packet, @received_at
|
741
|
+
@packet = @sender.build_packet(:send_push, @type, @payload, @target)
|
742
|
+
@client.should_receive(:push).with(@type, @payload, @target, :request_uuid => @token).and_return(nil).once
|
743
|
+
@sender.send(:http_send_once, :send_push, @target, @packet, @received_at).should be_true
|
744
|
+
end
|
745
|
+
|
746
|
+
it "sends request with time-to-live to configured client" do
|
747
|
+
@packet = @sender.build_packet(:send_push, @type, @payload, @target, @options, &@callback)
|
748
|
+
@client.should_receive(:push).with(@type, @payload, @target, :request_uuid => @token).and_return(nil).once
|
749
|
+
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
710
750
|
end
|
711
751
|
|
712
752
|
it "responds with success result containing response" do
|
713
|
-
@client.should_receive(:request).with(@type, @payload, @target, @token).and_return("result").once
|
714
|
-
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at,
|
753
|
+
@client.should_receive(:request).with(@type, @payload, @target, :request_uuid => @token).and_return("result").once
|
754
|
+
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
715
755
|
@response.token.should == @token
|
716
756
|
@response.results.success?.should be_true
|
717
757
|
@response.results.content.should == "result"
|
@@ -720,8 +760,8 @@ describe RightScale::Sender do
|
|
720
760
|
end
|
721
761
|
|
722
762
|
it "responds with success result when response is nil" do
|
723
|
-
@client.should_receive(:request).with(@type, @payload, @target, @token).and_return(nil).once
|
724
|
-
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at,
|
763
|
+
@client.should_receive(:request).with(@type, @payload, @target, :request_uuid => @token).and_return(nil).once
|
764
|
+
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
725
765
|
@response.token.should == @token
|
726
766
|
@response.results.success?.should be_true
|
727
767
|
@response.results.content.should be_nil
|
@@ -731,20 +771,35 @@ describe RightScale::Sender do
|
|
731
771
|
|
732
772
|
context "when fails" do
|
733
773
|
context "with connectivity error" do
|
774
|
+
it "queues push if queueing and does not respond" do
|
775
|
+
@options = {:time_to_live => @ttl}
|
776
|
+
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @options, &@callback)
|
777
|
+
@sender = create_sender(:http, :offline_queueing => true)
|
778
|
+
@sender.initialize_offline_queue
|
779
|
+
@sender.enable_offline_mode
|
780
|
+
@client.should_receive(:request).and_raise(RightScale::Exceptions::ConnectivityFailure, "disconnected").once
|
781
|
+
flexmock(@sender.offline_handler).should_receive(:queue_request).
|
782
|
+
with(:send_push, @type, @payload, @target, @token, (@now + @ttl).to_i).once
|
783
|
+
flexmock(@sender).should_receive(:handle_response).never
|
784
|
+
@sender.send(:http_send_once, :send_push, @target, @packet, @received_at).should be_true
|
785
|
+
end
|
786
|
+
|
734
787
|
it "queues request if queueing and does not respond" do
|
788
|
+
@options = {:time_to_live => @ttl}
|
789
|
+
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @options, &@callback)
|
735
790
|
@sender = create_sender(:http, :offline_queueing => true)
|
736
791
|
@sender.initialize_offline_queue
|
737
792
|
@sender.enable_offline_mode
|
738
793
|
@client.should_receive(:request).and_raise(RightScale::Exceptions::ConnectivityFailure, "disconnected").once
|
739
|
-
flexmock(@sender.offline_handler).should_receive(:queue_request).
|
740
|
-
@payload, @target, @callback).once
|
794
|
+
flexmock(@sender.offline_handler).should_receive(:queue_request).
|
795
|
+
with(:send_request, @type, @payload, @target, @token, (@now + @ttl).to_i, @callback).once
|
741
796
|
flexmock(@sender).should_receive(:handle_response).never
|
742
|
-
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at,
|
797
|
+
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
743
798
|
end
|
744
799
|
|
745
800
|
it "responds with retry result if not queueing" do
|
746
801
|
@client.should_receive(:request).and_raise(RightScale::Exceptions::ConnectivityFailure, "Server not responding").once
|
747
|
-
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at,
|
802
|
+
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
748
803
|
@response.results.retry?.should be_true
|
749
804
|
@response.results.content.should == "Server not responding"
|
750
805
|
end
|
@@ -752,14 +807,14 @@ describe RightScale::Sender do
|
|
752
807
|
|
753
808
|
it "responds with retry result if retryable error" do
|
754
809
|
@client.should_receive(:request).and_raise(RightScale::Exceptions::RetryableError, "try again").once
|
755
|
-
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at,
|
810
|
+
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
756
811
|
@response.results.retry?.should be_true
|
757
812
|
@response.results.content.should == "try again"
|
758
813
|
end
|
759
814
|
|
760
815
|
it "responds with error result if internal error" do
|
761
816
|
@client.should_receive(:request).and_raise(RightScale::Exceptions::InternalServerError.new("unprocessable", "Router")).once
|
762
|
-
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at,
|
817
|
+
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
763
818
|
@response.results.error?.should be_true
|
764
819
|
@response.results.content.should == "Router internal error"
|
765
820
|
end
|
@@ -767,12 +822,12 @@ describe RightScale::Sender do
|
|
767
822
|
it "does not respond to request if terminating" do
|
768
823
|
@client.should_receive(:request).and_raise(RightScale::Exceptions::Terminating, "going down").once
|
769
824
|
flexmock(@sender).should_receive(:handle_response).never
|
770
|
-
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at,
|
825
|
+
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
771
826
|
end
|
772
827
|
|
773
828
|
it "responds with error result if HTTP error" do
|
774
829
|
@client.should_receive(:request).and_raise(RightScale::HttpExceptions.create(400, "bad data")).once
|
775
|
-
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at,
|
830
|
+
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
776
831
|
@response.results.error?.should be_true
|
777
832
|
@response.results.content.should == "400 Bad Request: bad data"
|
778
833
|
end
|
@@ -780,7 +835,7 @@ describe RightScale::Sender do
|
|
780
835
|
it "responds with error result if unexpected error" do
|
781
836
|
@log.should_receive(:error).with(/Failed to send/, StandardError, :trace).once
|
782
837
|
@client.should_receive(:request).and_raise(StandardError, "unexpected").once
|
783
|
-
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at,
|
838
|
+
@sender.send(:http_send_once, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
784
839
|
@response.results.error?.should be_true
|
785
840
|
@response.results.content.should == "Agent agent internal error"
|
786
841
|
end
|
@@ -791,55 +846,55 @@ describe RightScale::Sender do
|
|
791
846
|
context :amqp do
|
792
847
|
before(:each) do
|
793
848
|
@sender = create_sender(:amqp)
|
849
|
+
@token = "random_token"
|
794
850
|
flexmock(RightSupport::Data::UUID).should_receive(:generate).and_return(@token).by_default
|
795
|
-
@packet = @sender.build_packet(:send_push, @type, @payload, @target, @
|
796
|
-
@received_at = Time.now
|
797
|
-
flexmock(Time).should_receive(:now).and_return(@received_at)
|
798
|
-
@response = nil
|
799
|
-
@callback = lambda { |response| @response = response }
|
851
|
+
@packet = @sender.build_packet(:send_push, @type, @payload, @target, @options)
|
800
852
|
end
|
801
853
|
|
802
854
|
context :amqp_send do
|
803
855
|
it "stores pending request for use in responding if callback specified" do
|
804
|
-
@packet = @sender.build_packet(:send_push, @type, @payload, @target, @
|
856
|
+
@packet = @sender.build_packet(:send_push, @type, @payload, @target, @options, &@callback)
|
805
857
|
flexmock(@sender).should_receive(:amqp_send_once)
|
806
|
-
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at,
|
858
|
+
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at, &@callback).should be_true
|
807
859
|
@sender.pending_requests[@token].should_not be_nil
|
808
860
|
end
|
809
861
|
|
810
862
|
it "does not store pending request if callback not specified" do
|
811
863
|
flexmock(@sender).should_receive(:amqp_send_once)
|
812
|
-
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at
|
864
|
+
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at).should be_true
|
813
865
|
@sender.pending_requests[@token].should be_nil
|
814
866
|
end
|
815
867
|
|
816
868
|
it "publishes without retry capability if send_push" do
|
817
869
|
flexmock(@sender).should_receive(:amqp_send_once).with(@packet).once
|
818
|
-
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at
|
870
|
+
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at).should be_true
|
819
871
|
end
|
820
872
|
|
821
873
|
it "publishes with retry capability if send_request" do
|
822
|
-
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @
|
874
|
+
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @options, &@callback)
|
823
875
|
flexmock(@sender).should_receive(:amqp_send_retry).with(@packet, @token).once
|
824
|
-
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at,
|
876
|
+
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
825
877
|
end
|
826
878
|
|
827
879
|
context "when fails" do
|
828
880
|
|
829
881
|
context "with offline error" do
|
830
882
|
it "submits request to offline handler if queuing" do
|
883
|
+
@options = {:time_to_live => @ttl}
|
884
|
+
@packet = @sender.build_packet(:send_push, @type, @payload, @target, @options)
|
831
885
|
@sender = create_sender(:amqp, :offline_queueing => true)
|
832
886
|
@sender.initialize_offline_queue
|
833
887
|
@sender.enable_offline_mode
|
888
|
+
flexmock(@sender.offline_handler).should_receive(:queue_request).
|
889
|
+
with(:send_push, @type, @payload, @target, @token, (@now + @ttl).to_i).once
|
834
890
|
flexmock(@sender).should_receive(:amqp_send_once).and_raise(RightScale::Sender::TemporarilyOffline).once
|
835
|
-
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at
|
836
|
-
@sender.offline_handler.queue.size.should == 1
|
891
|
+
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at).should be_true
|
837
892
|
@sender.pending_requests[@token].should be_nil
|
838
893
|
end
|
839
894
|
|
840
895
|
it "responds with retry result if not queueing" do
|
841
896
|
flexmock(@sender).should_receive(:amqp_send_once).and_raise(RightScale::Sender::TemporarilyOffline).once
|
842
|
-
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at,
|
897
|
+
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at, &@callback).should be_true
|
843
898
|
@sender.offline_handler.queue.size.should == 0
|
844
899
|
@sender.pending_requests[@token].should_not be_nil # because send_push does not get deleted when deliver
|
845
900
|
@response.results.retry?.should be_true
|
@@ -849,7 +904,7 @@ describe RightScale::Sender do
|
|
849
904
|
|
850
905
|
it "responds with non-delivery result if send failure" do
|
851
906
|
flexmock(@sender).should_receive(:amqp_send_once).and_raise(RightScale::Sender::SendFailure).once
|
852
|
-
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at,
|
907
|
+
@sender.send(:amqp_send, :send_push, @target, @packet, @received_at, &@callback).should be_true
|
853
908
|
@sender.pending_requests[@token].should_not be_nil # because send_push does not get deleted when deliver
|
854
909
|
@response.results.non_delivery?.should be_true
|
855
910
|
@response.results.content.should == "send failed unexpectedly"
|
@@ -882,7 +937,7 @@ describe RightScale::Sender do
|
|
882
937
|
context :amqp_send_retry do
|
883
938
|
before(:each) do
|
884
939
|
flexmock(RightSupport::Data::UUID).should_receive(:generate).and_return("retry token")
|
885
|
-
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @token,
|
940
|
+
@packet = @sender.build_packet(:send_request, @type, @payload, @target, :token => @token, &@callback)
|
886
941
|
end
|
887
942
|
|
888
943
|
it "publishes request to request queue" do
|
@@ -923,8 +978,23 @@ describe RightScale::Sender do
|
|
923
978
|
@sender = create_sender(:amqp, :retry_timeout => 0.3, :retry_interval => 0.1)
|
924
979
|
@client.should_receive(:publish).once
|
925
980
|
flexmock(EM).should_receive(:add_timer).and_yield.once
|
926
|
-
@sender.send(:amqp_send_retry, @packet, @token).should be_true
|
927
981
|
@sender.pending_requests[@token].should be_nil
|
982
|
+
@sender.send(:amqp_send_retry, @packet, @token).should be_true
|
983
|
+
end
|
984
|
+
|
985
|
+
it "stops retrying if request has expired" do
|
986
|
+
@options = {:time_to_live => @ttl}
|
987
|
+
flexmock(Time).should_receive(:now).and_return(@now, @now + @ttl)
|
988
|
+
@packet = @sender.build_packet(:send_request, @type, @payload, @target, @options, &@callback)
|
989
|
+
@sender = create_sender(:amqp, :retry_timeout => 0.3, :retry_interval => 0.1)
|
990
|
+
@client.should_receive(:publish).and_return(@broker_ids).once
|
991
|
+
flexmock(@sender.connectivity_checker).should_receive(:check).once
|
992
|
+
flexmock(EM).should_receive(:add_timer).and_yield.once
|
993
|
+
@log.should_receive(:warning).with(/RE-SEND TIMEOUT/).once
|
994
|
+
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
995
|
+
@response.results.non_delivery?.should be_true
|
996
|
+
@response.results.content.should == RightScale::OperationResult::RETRY_TIMEOUT
|
997
|
+
@sender.pending_requests.empty?.should be_true
|
928
998
|
end
|
929
999
|
|
930
1000
|
it "keeps retrying if has not exceeded retry timeout" do
|
@@ -932,7 +1002,7 @@ describe RightScale::Sender do
|
|
932
1002
|
@sender = create_sender(:amqp, :retry_timeout => 0.3, :retry_interval => 0.1)
|
933
1003
|
@client.should_receive(:publish).and_return(@broker_ids).twice
|
934
1004
|
flexmock(@sender.connectivity_checker).should_receive(:check).once
|
935
|
-
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at,
|
1005
|
+
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
936
1006
|
|
937
1007
|
EM.add_timer(0.15) do
|
938
1008
|
@sender.pending_requests.empty?.should be_false
|
@@ -952,9 +1022,9 @@ describe RightScale::Sender do
|
|
952
1022
|
EM.run do
|
953
1023
|
@sender = create_sender(:amqp, :retry_timeout => 0.1, :retry_interval => 0.1)
|
954
1024
|
@client.should_receive(:publish).and_return(@broker_ids).once
|
955
|
-
@log.should_receive(:warning).once
|
1025
|
+
@log.should_receive(:warning).with(/RE-SEND TIMEOUT/).once
|
956
1026
|
flexmock(@sender.connectivity_checker).should_receive(:check).once
|
957
|
-
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at,
|
1027
|
+
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
958
1028
|
|
959
1029
|
EM.add_timer(0.3) do
|
960
1030
|
EM.stop
|
@@ -972,7 +1042,7 @@ describe RightScale::Sender do
|
|
972
1042
|
flexmock(EM).should_receive(:add_timer).and_yield.once
|
973
1043
|
@log.should_receive(:error).with(/Failed to publish request/, RightAMQP::HABrokerClient::NoConnectedBrokers).once
|
974
1044
|
@log.should_receive(:error).with(/Failed retry.*temporarily offline/).once
|
975
|
-
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at,
|
1045
|
+
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
976
1046
|
@sender.pending_requests[@token].should_not be_nil
|
977
1047
|
@sender.pending_requests["retry token"].should_not be_nil
|
978
1048
|
end
|
@@ -984,7 +1054,7 @@ describe RightScale::Sender do
|
|
984
1054
|
flexmock(EM).should_receive(:add_timer).and_yield.once
|
985
1055
|
@log.should_receive(:error).with(/Failed to publish request/, StandardError, :trace).once
|
986
1056
|
@log.should_receive(:error).with(/Failed retry.*send failure/).once
|
987
|
-
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at,
|
1057
|
+
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
988
1058
|
@sender.pending_requests[@token].should_not be_nil
|
989
1059
|
@sender.pending_requests["retry token"].should_not be_nil
|
990
1060
|
end
|
@@ -996,7 +1066,7 @@ describe RightScale::Sender do
|
|
996
1066
|
@log.should_receive(:error).with(/Failed retry.*without responding/, StandardError, :trace).twice
|
997
1067
|
flexmock(EM).should_receive(:add_timer).and_yield
|
998
1068
|
flexmock(@sender.connectivity_checker).should_receive(:check).and_raise(StandardError).once
|
999
|
-
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at,
|
1069
|
+
@sender.send(:amqp_send, :send_request, @target, @packet, @received_at, &@callback).should be_true
|
1000
1070
|
@sender.pending_requests[@token].should_not be_nil
|
1001
1071
|
@sender.pending_requests["retry token"].should_not be_nil
|
1002
1072
|
end
|
@@ -1005,13 +1075,6 @@ describe RightScale::Sender do
|
|
1005
1075
|
end
|
1006
1076
|
|
1007
1077
|
context :deliver_response do
|
1008
|
-
before(:each) do
|
1009
|
-
@received_at = Time.now
|
1010
|
-
flexmock(Time).should_receive(:now).and_return(@received_at)
|
1011
|
-
@response = nil
|
1012
|
-
@callback = lambda { |response| @response = response }
|
1013
|
-
end
|
1014
|
-
|
1015
1078
|
it "calls the response handler" do
|
1016
1079
|
pending_request = RightScale::PendingRequest.new(:send_request, @received_at, @callback)
|
1017
1080
|
@sender.pending_requests[@token] = pending_request
|