right_agent 2.1.5-x86-mingw32 → 2.2.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -203,6 +203,12 @@ describe RightScale::BlockingClient do
203
203
  result.should == [@result, 200, @body, @headers]
204
204
  end
205
205
 
206
+ it "stores the connection" do
207
+ @http_client.should_receive(:get).with(@host + @path + @query, @request_options).and_return(@response).once
208
+ @client.request(:get, @path, @host, @connect_options, @request_options)
209
+ @client.connections[@path].should == {:host => @host, :path => @path, :expires_at => @later + 5}
210
+ end
211
+
206
212
  it "returns nil if response is nil" do
207
213
  @http_client.should_receive(:get).with(@host + @path + @query, @request_options).and_return(nil).once
208
214
  result = @client.request(:get, @path, @host, @connect_options, @request_options)
@@ -261,5 +267,15 @@ describe RightScale::BlockingClient do
261
267
  result.should == [nil, nil, nil, nil]
262
268
  end
263
269
  end
270
+
271
+ context :close do
272
+ it "deletes all persistent connections" do
273
+ @http_client.should_receive(:get).with(@host + @path + @query, @request_options).and_return(@response).once
274
+ @client.request(:get, @path, @host, @connect_options, @request_options)
275
+ @client.connections.should_not be_empty
276
+ @client.close("terminating").should be true
277
+ @client.connections.should be_empty
278
+ end
279
+ end
264
280
  end
265
281
  end
@@ -264,15 +264,15 @@ describe RightScale::NonBlockingClient do
264
264
  should raise_error(RightScale::HttpExceptions::InternalServerError)
265
265
  end
266
266
 
267
- it "converts Errno::ETIMEDOUT error to 504" do
268
- @headers.http_status = 504
267
+ it "converts Errno::ETIMEDOUT error to 408 RequestTimeout" do
268
+ @headers.http_status = 408
269
269
  @response.should_receive(:errback).and_yield.once
270
270
  @response.should_receive(:error).and_return(Errno::ETIMEDOUT)
271
- @fiber.should_receive(:resume).with(504, "Errno::ETIMEDOUT").once
272
- flexmock(Fiber).should_receive(:yield).and_return([504, "Errno::ETIMEDOUT"]).once
271
+ @fiber.should_receive(:resume).with(408, "Request timeout").once
272
+ flexmock(Fiber).should_receive(:yield).and_return([408, "Request timeout"]).once
273
273
  flexmock(EM::HttpRequest).should_receive(:new).with(@host, @connect_options).and_return(@request).once
274
274
  lambda { @client.request(:get, @path, @host, @connect_options, @request_options) }.
275
- should raise_error(RightScale::HttpExceptions::GatewayTimeout)
275
+ should raise_error(RightScale::HttpExceptions::RequestTimeout)
276
276
  end
277
277
 
278
278
  it "stores the connection if keepalive enabled" do
@@ -351,7 +351,7 @@ describe RightScale::NonBlockingClient do
351
351
  end
352
352
 
353
353
  it "stops polling if there is an error" do
354
- @response.should_receive(:error).and_return("some error").times(3)
354
+ @response.should_receive(:error).and_return("some error").once
355
355
  @response.should_receive(:errback).and_yield.once
356
356
  @fiber.should_receive(:resume).with(500, "some error").once
357
357
  @client.send(:poll_again, @fiber, @request, @request_options, @stop_at).should be true
@@ -374,6 +374,43 @@ describe RightScale::NonBlockingClient do
374
374
  end
375
375
  end
376
376
  end
377
+
378
+ context :close do
379
+ it "closes all persistent connections" do
380
+ @request_options.merge!(:keepalive => true)
381
+ flexmock(EM::HttpRequest).should_receive(:new).and_return(@request).once
382
+ @client.request(:get, @path, @host, @connect_options, @request_options)
383
+ @request.should_receive(:close).with("terminating").once
384
+ @client.connections.should_not be_empty
385
+ @client.close("terminating").should be true
386
+ @client.connections.should be_empty
387
+ end
388
+ end
389
+ end
390
+
391
+ context :handle_error do
392
+ before(:each) do
393
+ @options = {}
394
+ @client = RightScale::NonBlockingClient.new(@options)
395
+ end
396
+
397
+ ["terminating", "reconnecting"].each do |error|
398
+ it "converts #{error} error to a 200 OK" do
399
+ @client.send(:handle_error, :get, error).should == [200, nil]
400
+ end
401
+ end
402
+
403
+ it "converts Errno::ETIMEDOUT to 408 RequestTimeout" do
404
+ @client.send(:handle_error, :get, Errno::ETIMEDOUT).should == [408, "Request timeout"]
405
+ end
406
+
407
+ it "converts error to 500 InternalServerError by default" do
408
+ @client.send(:handle_error, :get, "failed").should == [500, "failed"]
409
+ end
410
+
411
+ it "generates error message for 500 InternalServerError if none specified" do
412
+ @client.send(:handle_error, :get, nil).should == [500, "HTTP connection failure for GET"]
413
+ end
377
414
  end
378
415
 
379
416
  context :beautify_headers do
@@ -34,7 +34,7 @@ describe RightScale::RouterClient do
34
34
  @log.should_receive(:warning).by_default.and_return { |m| raise RightScale::Log.format(*m) }
35
35
  @timer = flexmock("timer", :cancel => true).by_default
36
36
  flexmock(EM::Timer).should_receive(:new).and_return(@timer).by_default
37
- @http_client = flexmock("http client", :get => true, :check_health => true).by_default
37
+ @http_client = flexmock("http client", :get => true, :check_health => true, :close => true).by_default
38
38
  flexmock(RightScale::BalancedHttpClient).should_receive(:new).and_return(@http_client).by_default
39
39
  @websocket = WebSocketClientMock.new
40
40
  flexmock(Faye::WebSocket::Client).should_receive(:new).and_return(@websocket).by_default
@@ -83,44 +83,41 @@ describe RightScale::RouterClient do
83
83
  @action = "bar"
84
84
  @payload = {:some => "data"}
85
85
  @target = "rs-agent-2-2"
86
- @token = "random token"
87
86
  @params = {
88
87
  :type => @type,
89
88
  :payload => @payload,
90
89
  :target => @target }
91
90
  end
92
91
 
93
- context :push do
94
- it "makes post request to router" do
95
- flexmock(@client).should_receive(:make_request).with(:post, "/push", @params, @action, @token).
96
- and_return(nil).once
97
- @client.push(@type, @payload, @target, @token).should be nil
98
- end
99
-
100
- it "does not require token" do
101
- flexmock(@client).should_receive(:make_request).with(:post, "/push", @params, @action, nil).
102
- and_return(nil).once
103
- @client.push(@type, @payload, @target).should be nil
104
- end
105
- end
106
-
107
- context :request do
108
- it "makes post request to router" do
109
- flexmock(@client).should_receive(:make_request).with(:post, "/request", @params, @action, @token).
110
- and_return(nil).once
111
- @client.request(@type, @payload, @target, @token)
112
- end
92
+ [:push, :request].each do |kind|
93
+ context kind do
94
+ it "makes post request to router" do
95
+ flexmock(@client).should_receive(:make_request).with(:post, "/#{kind}", @params, @action, {}).and_return(nil).once
96
+ @client.send(kind, @type, @payload, @target).should be nil
97
+ end
113
98
 
114
- it "does not require token" do
115
- flexmock(@client).should_receive(:make_request).with(:post, "/request", @params, @action, nil).
116
- and_return(nil).once
117
- @client.request(@type, @payload, @target).should be nil
99
+ it "applies request options" do
100
+ options = {:request_uuid => "uuid", :time_to_live => 60}
101
+ flexmock(@client).should_receive(:make_request).with(:post, "/#{kind}", @params, @action, options).and_return(nil).once
102
+ @client.send(kind, @type, @payload, @target, options).should be nil
103
+ end
118
104
  end
119
105
  end
120
106
  end
121
107
 
122
108
  context "events" do
123
109
 
110
+ def when_in_listen_state(state, checks = nil, failures = 0)
111
+ flexmock(EM).should_receive(:next_tick).by_default
112
+ flexmock(EM::Timer).should_receive(:new).and_return(@timer).by_default
113
+ @client.send(:update_listen_state, state)
114
+ @client.instance_variable_set(:@listen_checks, checks) if checks
115
+ @client.instance_variable_set(:@listen_failures, failures)
116
+ @client.instance_variable_set(:@connect_interval, 30)
117
+ @client.instance_variable_set(:@reconnect_interval, 2)
118
+ state
119
+ end
120
+
124
121
  before(:each) do
125
122
  @handler = lambda { |_| }
126
123
  @later = Time.at(@now = Time.now)
@@ -143,8 +140,8 @@ describe RightScale::RouterClient do
143
140
  end
144
141
 
145
142
  it "makes post request by default" do
146
- flexmock(@client).should_receive(:make_request).with(:post, "/notify", @params, "notify", "uuid",
147
- {:filter_params => ["event"]}).once
143
+ flexmock(@client).should_receive(:make_request).with(:post, "/notify", @params, "notify",
144
+ {:request_uuid => "uuid", :filter_params => ["event"]}).once
148
145
  @client.notify(@event, @routing_keys).should be true
149
146
  end
150
147
  end
@@ -223,17 +220,6 @@ describe RightScale::RouterClient do
223
220
  end
224
221
 
225
222
  context :listen_loop do
226
- def when_in_listen_state(state, checks = nil, failures = 0)
227
- flexmock(EM).should_receive(:next_tick).by_default
228
- flexmock(EM::Timer).should_receive(:new).and_return(@timer).by_default
229
- @client.send(:update_listen_state, state)
230
- @client.instance_variable_set(:@listen_checks, checks) if checks
231
- @client.instance_variable_set(:@listen_failures, failures)
232
- @client.instance_variable_set(:@connect_interval, 30)
233
- @client.instance_variable_set(:@reconnect_interval, 2)
234
- state
235
- end
236
-
237
223
  context "in :choose state" do
238
224
  it "chooses listen method" do
239
225
  when_in_listen_state(:choose)
@@ -357,22 +343,41 @@ describe RightScale::RouterClient do
357
343
  end
358
344
  end
359
345
 
346
+ it "waits required amount of time before looping" do
347
+ when_in_listen_state(:choose)
348
+ flexmock(@client).should_receive(:listen_loop_wait).with(@later + 1, 0, @routing_keys, @handler).and_return(true).once
349
+ @client.send(:listen_loop, @routing_keys, &@handler).should be true
350
+ end
351
+ end
352
+
353
+ context :listen_loop_wait do
360
354
  it "uses next_tick for next loop if interval is 0" do
361
355
  when_in_listen_state(:choose)
362
356
  @client.instance_variable_get(:@listen_interval).should == 0
363
357
  flexmock(EM).should_receive(:next_tick).and_yield.once
364
- flexmock(EM::Timer).should_receive(:new).with(1, Proc).and_return(@timer).once
365
- @client.send(:listen_loop, @routing_keys, &@handler).should be true
366
- @client.instance_variable_get(:@listen_state).should == :check
358
+ flexmock(EM::Timer).should_receive(:new).never
359
+ flexmock(@client).should_receive(:listen_loop).with(@routing_keys, @handler).once
360
+ @client.send(:listen_loop_wait, 0, @later, @routing_keys, &@handler).should be true
367
361
  end
368
362
 
369
363
  it "otherwise uses timer for next loop" do
370
364
  when_in_listen_state(:long_poll)
371
- flexmock(@client).should_receive(:try_deferred_long_poll).once
372
- flexmock(EM::Timer).should_receive(:new).with(1, Proc).and_return(@timer).once
365
+ @client.instance_variable_set(:@listen_interval, 9)
366
+ flexmock(EM::Timer).should_receive(:new).with(9, Proc).and_return(@timer).and_yield.once
373
367
  flexmock(EM).should_receive(:next_tick).never
374
- @client.send(:listen_loop, @routing_keys, &@handler).should be true
375
- @client.instance_variable_get(:@listen_state).should == :wait
368
+ flexmock(@client).should_receive(:listen_loop).with(@routing_keys, @handler).once
369
+ @client.send(:listen_loop_wait, @later - 9, 9, @routing_keys, &@handler).should be true
370
+ end
371
+
372
+ it "waits some more if interval has changed while waiting" do
373
+ when_in_listen_state(:long_poll)
374
+ @client.instance_variable_set(:@listen_interval, 3)
375
+ flexmock(EM::Timer).should_receive(:new).with(1, Proc).and_return(@timer).and_yield.once.ordered
376
+ flexmock(EM::Timer).should_receive(:new).with(2, Proc).and_return(@timer).and_yield.once.ordered
377
+ flexmock(EM::Timer).should_receive(:new).with(1, Proc).and_return(@timer).and_yield.once.ordered
378
+ flexmock(EM).should_receive(:next_tick).never
379
+ flexmock(@client).should_receive(:listen_loop).with(@routing_keys, @handler).once
380
+ @client.send(:listen_loop_wait, @later, 1, @routing_keys, &@handler).should be true
376
381
  end
377
382
  end
378
383
 
@@ -429,7 +434,7 @@ describe RightScale::RouterClient do
429
434
  end
430
435
  end
431
436
 
432
- [502, 503].each do |code|
437
+ [408, 502, 503].each do |code|
433
438
  it "chooses to connect immediately if previous close code #{code} indicates router not responding" do
434
439
  @client.instance_variable_set(:@close_code, RightScale::RouterClient::PROTOCOL_ERROR_CLOSE)
435
440
  @client.instance_variable_set(:@close_reason, "Unexpected response code: #{code}")
@@ -676,13 +681,13 @@ describe RightScale::RouterClient do
676
681
  it "makes listen request to router" do
677
682
  flexmock(@client).should_receive(:make_request).with(:poll, "/listen",
678
683
  on { |a| a[:wait_time].should == 55 && !a.key?(:routing_keys) &&
679
- a[:timestamp] == @later.to_f }, "listen", nil, Hash).and_return([@event]).once
684
+ a[:timestamp] == @later.to_f }, "listen", Hash).and_return([@event]).once
680
685
  @client.send(:long_poll, @routing_keys, @ack, &@handler)
681
686
  end
682
687
 
683
688
  it "uses listen timeout for request poll timeout and connect interval for request timeout" do
684
689
  @client.instance_variable_set(:@connect_interval, 300)
685
- flexmock(@client).should_receive(:make_request).with(:poll, "/listen", Hash, "listen", nil,
690
+ flexmock(@client).should_receive(:make_request).with(:poll, "/listen", Hash, "listen",
686
691
  {:poll_timeout => 60, :request_timeout => 300}).and_return([@event]).once
687
692
  @client.send(:long_poll, @routing_keys, @ack, &@handler)
688
693
  end
@@ -101,6 +101,13 @@ describe RightScale::HttpExceptions do
101
101
  bad_request = RestClient::Exceptions::EXCEPTIONS_MAP[400].new(nil, 400)
102
102
  RightScale::HttpExceptions.convert(bad_request).should be_a RightScale::HttpExceptions::BadRequest
103
103
  end
104
+
105
+ it "assigns status code 408 to RequestTimeout" do
106
+ request_timeout = RestClient::Exceptions::EXCEPTIONS_MAP[408].new
107
+ exception = RightScale::HttpExceptions.convert(request_timeout)
108
+ exception.should be_a RightScale::HttpExceptions::RequestTimeout
109
+ exception.http_code.should == 408
110
+ end
104
111
  end
105
112
 
106
113
  end # RightScale::HttpExceptions
@@ -192,14 +192,18 @@ describe RightScale::OfflineHandler do
192
192
  @type = "/foo/bar"
193
193
  @payload = {:pay => "load"}
194
194
  @target = "target"
195
+ @token = "token"
196
+ @now = Time.now
197
+ flexmock(Time).should_receive(:now).and_return(@now)
198
+ @expires_at = @now + 25
195
199
  @callback = lambda { |_| }
196
200
  end
197
201
 
198
202
  it "queues request at head of queue if still initializing" do
199
203
  @handler.init
200
- @handler.queue_request(@kind, @type, @payload, "target1", @callback).should be_true
204
+ @handler.queue_request(@kind, @type, @payload, "target1", "token1", @expires_at, &@callback).should be_true
201
205
  @handler.queue.size.should == 1
202
- @handler.queue_request(@kind, @type, @payload, "target2", @callback).should be_true
206
+ @handler.queue_request(@kind, @type, @payload, "target2", "token2", @expires_at, &@callback).should be_true
203
207
  @handler.queue.size.should == 2
204
208
  @handler.queue.first[:target] == "target2"
205
209
  end
@@ -207,9 +211,9 @@ describe RightScale::OfflineHandler do
207
211
  it "queues request at end of queue if no longer initializing" do
208
212
  @handler.init
209
213
  @handler.start
210
- @handler.queue_request(@kind, @type, @payload, "target1", @callback)
214
+ @handler.queue_request(@kind, @type, @payload, "target1", "token1", @expires_at, &@callback)
211
215
  @handler.queue.size.should == 1
212
- @handler.queue_request(@kind, @type, @payload, "target2", @callback)
216
+ @handler.queue_request(@kind, @type, @payload, "target2", "token2", @expires_at, &@callback)
213
217
  @handler.queue.size.should == 2
214
218
  @handler.queue.first[:target] == "target1"
215
219
  end
@@ -219,7 +223,7 @@ describe RightScale::OfflineHandler do
219
223
  @handler.start
220
224
  flexmock(@handler).should_receive(:vote_to_restart).once
221
225
  RightScale::OfflineHandler::MAX_QUEUED_REQUESTS.times do |i|
222
- @handler.queue_request(@kind, @type, @payload, @target, @callback)
226
+ @handler.queue_request(@kind, @type, @payload, @target, @token, @expires_at, &@callback)
223
227
  end
224
228
  end
225
229
  end
@@ -241,6 +245,10 @@ describe RightScale::OfflineHandler do
241
245
  @type = "/foo/bar"
242
246
  @payload = {:pay => "load"}
243
247
  @target = "target"
248
+ @token = "token"
249
+ @now = Time.now
250
+ flexmock(Time).should_receive(:now).and_return(@now)
251
+ @expires_at = (@now + 25).to_i
244
252
  @result = nil
245
253
  @callback = lambda { |result| @result = result }
246
254
  end
@@ -251,16 +259,19 @@ describe RightScale::OfflineHandler do
251
259
  @handler.start
252
260
  flexmock(@handler).should_receive(:start_timer)
253
261
  @handler.enable
254
- @handler.queue_request(:send_push, @type, @payload, @target, nil)
255
- @handler.queue_request(:send_request, @type, @payload, @target, @callback)
256
- @handler.queue.size.should == 2
257
- flexmock(EM).should_receive(:next_tick).and_yield.once
258
- @sender.should_receive(:send_push).with(@type, @payload, @target).once.ordered
259
- @sender.should_receive(:send_request).with(@type, @payload, @target, Proc).and_yield("result").once.ordered
262
+ @handler.queue_request(:send_push, @type, @payload, @target, @token, 0)
263
+ @handler.queue_request(:send_request, @type, @payload, @target, @token, @expires_at, &@callback)
264
+ @handler.queue_request(:send_request, @type, @payload, @target, @token, @now.to_i, &@callback)
265
+ @handler.queue.size.should == 3
266
+ flexmock(EM).should_receive(:next_tick).and_yield.twice
267
+ @sender.should_receive(:send_push).with(@type, @payload, @target, {:token => @token}).once.ordered
268
+ @sender.should_receive(:send_request).
269
+ with(@type, @payload, @target, {:token => @token, :time_to_live => 25}, Proc).and_yield("result").once.ordered
260
270
  flexmock(EM).should_receive(:add_timer).and_yield.once
261
271
  log = flexmock(RightScale::Log)
262
272
  log.should_receive(:info).with(/Connection to RightNet re-established/).once.ordered
263
273
  log.should_receive(:info).with(/Starting to flush request queue/).once.ordered
274
+ log.should_receive(:info).with(/Dropping queued request/).once.ordered
264
275
  log.should_receive(:info).with(/Request queue flushed/).once.ordered
265
276
  @handler.disable.should be_true
266
277
  end
@@ -35,6 +35,7 @@ describe RightScale::RetryableRequest do
35
35
  RightScale.module_eval('OldSender = Sender')
36
36
  end
37
37
  RightScale.module_eval('Sender = SenderMock')
38
+ @options = {:time_to_live => RightScale::RetryableRequest::DEFAULT_TIMEOUT}
38
39
  end
39
40
 
40
41
  after(:all) do
@@ -48,7 +49,7 @@ describe RightScale::RetryableRequest do
48
49
  context 'when :targets => nil' do
49
50
  it 'should send target-less requests' do
50
51
  request = RightScale::RetryableRequest.new('type', 'payload')
51
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
52
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
52
53
  and_yield(RightScale::OperationResult.non_delivery('test')).once
53
54
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
54
55
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
@@ -59,7 +60,7 @@ describe RightScale::RetryableRequest do
59
60
  context 'when one target is specified' do
60
61
  it 'should send a targeted request' do
61
62
  request = RightScale::RetryableRequest.new('type', 'payload', :targets => ["rs-agent-1-1"])
62
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', {:agent_id => "rs-agent-1-1"}, Proc).
63
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', {:agent_id => "rs-agent-1-1"}, @options, Proc).
63
64
  and_yield(RightScale::OperationResult.non_delivery('test')).once
64
65
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
65
66
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
@@ -70,10 +71,12 @@ describe RightScale::RetryableRequest do
70
71
  context 'when many targets are specified' do
71
72
  it 'should choose a random target' do
72
73
  request = RightScale::RetryableRequest.new('type', 'payload', :targets => ["rs-agent-1-1", "rs-agent-2-2", "rs-agent-3-3"])
73
- flexmock(RightScale::Sender.instance).should_receive(:send_request).and_return do |type, payload, target, block|
74
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).and_return do |type, payload, target, options, block|
74
75
  type.should == 'type'
75
76
  payload.should == 'payload'
76
77
  ["rs-agent-1-1", "rs-agent-2-2", "rs-agent-3-3"].should include(target[:agent_id])
78
+ options[:token].should == nil
79
+ options[:time_to_live].should == @options[:time_to_live]
77
80
  block.call(RightScale::OperationResult.non_delivery('test'))
78
81
  end
79
82
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
@@ -89,7 +92,7 @@ describe RightScale::RetryableRequest do
89
92
  context 'when not specified' do
90
93
  it 'should fail if receives error response' do
91
94
  request = RightScale::RetryableRequest.new('type', 'payload')
92
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
95
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
93
96
  and_yield(RightScale::OperationResult.error('test')).once
94
97
  flexmock(request).should_receive(:fail).once
95
98
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
@@ -100,7 +103,7 @@ describe RightScale::RetryableRequest do
100
103
  context 'when specified as true' do
101
104
  it 'should retry if receives error response' do
102
105
  request = RightScale::RetryableRequest.new('type', 'payload', :retry_on_error => true)
103
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
106
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
104
107
  and_yield(RightScale::OperationResult.error('test')).once
105
108
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
106
109
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
@@ -109,7 +112,7 @@ describe RightScale::RetryableRequest do
109
112
 
110
113
  it 'should ignore duplicate responses' do
111
114
  request = RightScale::RetryableRequest.new('type', 'payload', :retry_on_error => true)
112
- flexmock(RightScale::Sender.instance).should_receive(:send_request).and_return do |t, p, tgt, b|
115
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).and_return do |t, p, tgt, opts, b|
113
116
  5.times { b.call(RightScale::OperationResult.success('test')) }
114
117
  end
115
118
  flexmock(request).should_receive(:fail).never
@@ -122,7 +125,7 @@ describe RightScale::RetryableRequest do
122
125
  it 'should never retry after cancel response' do
123
126
  request = RightScale::RetryableRequest.new('type', 'payload', :retry_on_error => true)
124
127
  flexmock(RightScale::Log).should_receive(:info).with("Request type canceled (enough already)").once
125
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
128
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
126
129
  and_yield(RightScale::OperationResult.cancel('enough already')).once
127
130
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
128
131
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).never
@@ -139,7 +142,7 @@ describe RightScale::RetryableRequest do
139
142
  request = RightScale::RetryableRequest.new('type', 'payload')
140
143
  flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
141
144
  flexmock(RightScale::Log).should_receive(:info).with("Request non-delivery (test) for type").once
142
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
145
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
143
146
  and_yield(RightScale::OperationResult.non_delivery('test')).once
144
147
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
145
148
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
@@ -150,7 +153,7 @@ describe RightScale::RetryableRequest do
150
153
  request = RightScale::RetryableRequest.new('type', 'payload')
151
154
  flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
152
155
  flexmock(RightScale::Log).should_receive(:info).with("Request type failed (test) and should be retried").once
153
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
156
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
154
157
  and_yield(RightScale::OperationResult.retry('test')).once
155
158
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
156
159
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
@@ -161,7 +164,7 @@ describe RightScale::RetryableRequest do
161
164
  request = RightScale::RetryableRequest.new('type', 'payload')
162
165
  flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
163
166
  flexmock(RightScale::Log).should_receive(:info).with("Request type failed (RightScale not ready) and should be retried").once
164
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
167
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
165
168
  and_yield(RightScale::OperationResult.retry).once
166
169
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
167
170
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
@@ -170,7 +173,7 @@ describe RightScale::RetryableRequest do
170
173
 
171
174
  it 'should ignore responses that arrive post-cancel' do
172
175
  request = RightScale::RetryableRequest.new('type', 'payload')
173
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
176
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
174
177
  and_yield(RightScale::OperationResult.success('test')).once
175
178
  flexmock(request).should_receive(:fail).once
176
179
  flexmock(request).should_receive(:succeed).never
@@ -183,7 +186,7 @@ describe RightScale::RetryableRequest do
183
186
  it 'should never retry after cancel response' do
184
187
  request = RightScale::RetryableRequest.new('type', 'payload')
185
188
  flexmock(RightScale::Log).should_receive(:info).with("Request type canceled (enough already)").once
186
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
189
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
187
190
  and_yield(RightScale::OperationResult.cancel('enough already')).once
188
191
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
189
192
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).never
@@ -195,7 +198,7 @@ describe RightScale::RetryableRequest do
195
198
  it 'should control the initial retry delay' do
196
199
  retry_delay = 10
197
200
  request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay)
198
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
201
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
199
202
  and_yield(RightScale::OperationResult.retry('test')).once
200
203
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
201
204
  flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).once
@@ -206,7 +209,7 @@ describe RightScale::RetryableRequest do
206
209
  it 'should treat -1 as meaning no delay' do
207
210
  retry_delay = -1
208
211
  request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay)
209
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
212
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
210
213
  and_yield(RightScale::OperationResult.retry('test')).once
211
214
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
212
215
  flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).never
@@ -222,7 +225,7 @@ describe RightScale::RetryableRequest do
222
225
  backoff_factor = RightScale::RetryableRequest::RETRY_BACKOFF_FACTOR
223
226
  request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay,
224
227
  :retry_delay_count => retry_delay_count)
225
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
228
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
226
229
  and_yield(RightScale::OperationResult.retry('test')).twice
227
230
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
228
231
  flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.once
@@ -239,7 +242,7 @@ describe RightScale::RetryableRequest do
239
242
  request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay,
240
243
  :retry_delay_count => retry_delay_count,
241
244
  :max_retry_delay => max_retry_delay)
242
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
245
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
243
246
  and_yield(RightScale::OperationResult.retry('test')).times(4)
244
247
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
245
248
  flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.twice
@@ -260,7 +263,7 @@ describe RightScale::RetryableRequest do
260
263
  request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay,
261
264
  :retry_delay_count => retry_delay_count,
262
265
  :max_retry_delay => max_retry_delay)
263
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
266
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, @options, Proc).
264
267
  and_yield(RightScale::OperationResult.retry('test')).times(3)
265
268
  flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
266
269
  flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.once
@@ -277,7 +280,7 @@ describe RightScale::RetryableRequest do
277
280
  context 'when disable timeout' do
278
281
  it 'should not timeout' do
279
282
  request = RightScale::RetryableRequest.new('type', 'payload', :timeout => -1)
280
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).once
283
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, {}, Proc).once
281
284
  flexmock(EM).should_receive(:add_timer).never
282
285
  request.run
283
286
  end
@@ -287,7 +290,8 @@ describe RightScale::RetryableRequest do
287
290
  it 'should time the response' do
288
291
  timeout = 10
289
292
  request = RightScale::RetryableRequest.new('type', 'payload', :timeout => timeout)
290
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).once
293
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).
294
+ with('type', 'payload', nil, {:time_to_live => timeout}, Proc).once
291
295
  flexmock(EM).should_receive(:add_timer).with(timeout, Proc).once
292
296
  request.run
293
297
  end
@@ -296,10 +300,21 @@ describe RightScale::RetryableRequest do
296
300
  timeout = 10
297
301
  request = RightScale::RetryableRequest.new('type', 'payload', :timeout => timeout)
298
302
  flexmock(RightScale::Log).should_receive(:info).with("Request type timed out after 10 seconds").once
299
- flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).once
303
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).
304
+ with('type', 'payload', nil, {:time_to_live => timeout}, Proc).once
300
305
  flexmock(EM).should_receive(:add_timer).with(timeout, Proc).and_yield.once
301
306
  request.run
302
307
  end
308
+
309
+ it "should cancel request if time has expired" do
310
+ timeout = 10
311
+ now = Time.now
312
+ flexmock(Time).should_receive(:now).and_return(now, now + 10)
313
+ request = RightScale::RetryableRequest.new('type', 'payload', :timeout => timeout)
314
+ flexmock(request).should_receive(:fail).once
315
+ flexmock(RightScale::Sender.instance).should_receive(:send_request).never
316
+ request.run
317
+ end
303
318
  end
304
319
  end
305
320