right_agent 1.0.1 → 2.0.7
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.
- data/README.rdoc +10 -8
- data/Rakefile +31 -5
- data/lib/right_agent.rb +6 -1
- data/lib/right_agent/actor.rb +4 -20
- data/lib/right_agent/actors/agent_manager.rb +1 -1
- data/lib/right_agent/agent.rb +357 -144
- data/lib/right_agent/agent_config.rb +7 -6
- data/lib/right_agent/agent_identity.rb +13 -11
- data/lib/right_agent/agent_tag_manager.rb +60 -64
- data/{spec/results_mock.rb → lib/right_agent/clients.rb} +10 -24
- data/lib/right_agent/clients/api_client.rb +383 -0
- data/lib/right_agent/clients/auth_client.rb +247 -0
- data/lib/right_agent/clients/balanced_http_client.rb +369 -0
- data/lib/right_agent/clients/base_retry_client.rb +495 -0
- data/lib/right_agent/clients/right_http_client.rb +279 -0
- data/lib/right_agent/clients/router_client.rb +493 -0
- data/lib/right_agent/command/command_io.rb +4 -4
- data/lib/right_agent/command/command_parser.rb +2 -2
- data/lib/right_agent/command/command_runner.rb +1 -1
- data/lib/right_agent/connectivity_checker.rb +179 -0
- data/lib/right_agent/core_payload_types/secure_document_location.rb +2 -2
- data/lib/right_agent/dispatcher.rb +12 -10
- data/lib/right_agent/enrollment_result.rb +16 -12
- data/lib/right_agent/exceptions.rb +34 -20
- data/lib/right_agent/history.rb +10 -5
- data/lib/right_agent/log.rb +5 -5
- data/lib/right_agent/minimal.rb +1 -0
- data/lib/right_agent/multiplexer.rb +1 -1
- data/lib/right_agent/offline_handler.rb +270 -0
- data/lib/right_agent/packets.rb +7 -7
- data/lib/right_agent/payload_formatter.rb +1 -1
- data/lib/right_agent/pending_requests.rb +128 -0
- data/lib/right_agent/platform.rb +1 -1
- data/lib/right_agent/protocol_version_mixin.rb +69 -0
- data/lib/right_agent/{idempotent_request.rb → retryable_request.rb} +7 -7
- data/lib/right_agent/scripts/agent_controller.rb +28 -26
- data/lib/right_agent/scripts/agent_deployer.rb +37 -22
- data/lib/right_agent/scripts/common_parser.rb +10 -3
- data/lib/right_agent/secure_identity.rb +1 -1
- data/lib/right_agent/sender.rb +299 -785
- data/lib/right_agent/serialize/secure_serializer.rb +3 -1
- data/lib/right_agent/serialize/secure_serializer_initializer.rb +2 -2
- data/lib/right_agent/serialize/serializable.rb +8 -3
- data/right_agent.gemspec +49 -18
- data/spec/agent_config_spec.rb +7 -7
- data/spec/agent_identity_spec.rb +7 -4
- data/spec/agent_spec.rb +43 -7
- data/spec/agent_tag_manager_spec.rb +72 -83
- data/spec/clients/api_client_spec.rb +423 -0
- data/spec/clients/auth_client_spec.rb +272 -0
- data/spec/clients/balanced_http_client_spec.rb +576 -0
- data/spec/clients/base_retry_client_spec.rb +635 -0
- data/spec/clients/router_client_spec.rb +594 -0
- data/spec/clients/spec_helper.rb +111 -0
- data/spec/command/command_io_spec.rb +1 -1
- data/spec/command/command_parser_spec.rb +1 -1
- data/spec/connectivity_checker_spec.rb +83 -0
- data/spec/dispatcher_spec.rb +3 -2
- data/spec/enrollment_result_spec.rb +2 -2
- data/spec/history_spec.rb +51 -39
- data/spec/offline_handler_spec.rb +340 -0
- data/spec/pending_requests_spec.rb +136 -0
- data/spec/{idempotent_request_spec.rb → retryable_request_spec.rb} +73 -73
- data/spec/sender_spec.rb +835 -1052
- data/spec/serialize/secure_serializer_spec.rb +3 -2
- data/spec/spec_helper.rb +54 -1
- metadata +71 -12
@@ -0,0 +1,340 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
24
|
+
|
25
|
+
describe RightScale::OfflineHandler do
|
26
|
+
|
27
|
+
include FlexMock::ArgumentTypes
|
28
|
+
|
29
|
+
before(:each) do
|
30
|
+
@vote = 0
|
31
|
+
@restart_callback = lambda { @vote += 1 }
|
32
|
+
@offline_stats = RightSupport::Stats::Activity.new
|
33
|
+
@handler = RightScale::OfflineHandler.new(@restart_callback, @offline_stats)
|
34
|
+
end
|
35
|
+
|
36
|
+
context :initialize do
|
37
|
+
it "sets initial state to created and mode to initializing" do
|
38
|
+
@handler.state == :created
|
39
|
+
@handler.mode == :initializing
|
40
|
+
@handler.queue.size.should == 0
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context :init do
|
45
|
+
it "advances state from created to initializing so that new requests get prepended to queue" do
|
46
|
+
@handler.state.should == :created
|
47
|
+
@handler.init.should be_true
|
48
|
+
@handler.state.should == :initializing
|
49
|
+
end
|
50
|
+
|
51
|
+
it "does nothing if not in the created state" do
|
52
|
+
@handler.init
|
53
|
+
@handler.start
|
54
|
+
state = @handler.state
|
55
|
+
state.should_not == :created
|
56
|
+
@handler.init.should be_true
|
57
|
+
@handler.state.should == state
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context :start do
|
62
|
+
it "sets state to running if in offline mode" do
|
63
|
+
@handler.init
|
64
|
+
flexmock(@handler).should_receive(:start_timer)
|
65
|
+
@handler.enable
|
66
|
+
@handler.start.should be_true
|
67
|
+
@handler.state.should == :running
|
68
|
+
@handler.mode.should == :offline
|
69
|
+
end
|
70
|
+
|
71
|
+
it "sets state to flushing and flushes if not in offline mode" do
|
72
|
+
@handler.init
|
73
|
+
flexmock(@handler).should_receive(:flush).once
|
74
|
+
@handler.start.should be_true
|
75
|
+
@handler.state.should == :flushing
|
76
|
+
@handler.mode.should == :online
|
77
|
+
end
|
78
|
+
|
79
|
+
it "does nothing if not in initializing state" do
|
80
|
+
@handler.state.should == :created
|
81
|
+
@handler.start.should be_true
|
82
|
+
@handler.state.should == :created
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context :offline? do
|
87
|
+
it "indicates that offline when initially created" do
|
88
|
+
@handler.offline?.should be_true
|
89
|
+
end
|
90
|
+
|
91
|
+
it "indicates that not offline after initialize offline queueing" do
|
92
|
+
@handler.init
|
93
|
+
@handler.offline?.should be_false
|
94
|
+
end
|
95
|
+
|
96
|
+
it "indicates that offline when offline has been enabled" do
|
97
|
+
@handler.init
|
98
|
+
flexmock(@handler).should_receive(:start_timer)
|
99
|
+
@handler.enable
|
100
|
+
@handler.offline?.should be_true
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context :queueing? do
|
105
|
+
it "indicates that should queue when initially created" do
|
106
|
+
@handler.queueing?.should be_true
|
107
|
+
end
|
108
|
+
|
109
|
+
it "indicates that should not queue once initialize offline queueing" do
|
110
|
+
@handler.init
|
111
|
+
@handler.queueing?.should be_false
|
112
|
+
end
|
113
|
+
|
114
|
+
it "indicates that should queue when offline has been enabled" do
|
115
|
+
@handler.init
|
116
|
+
flexmock(@handler).should_receive(:start_timer)
|
117
|
+
@handler.enable
|
118
|
+
@handler.queueing?.should be_true
|
119
|
+
end
|
120
|
+
|
121
|
+
it "indicates that should not queue if offline but currently flushing" do
|
122
|
+
@handler.init
|
123
|
+
@handler.queueing?.should be_false
|
124
|
+
@handler.start
|
125
|
+
@handler.queueing?.should be_false
|
126
|
+
flexmock(@handler).should_receive(:start_timer)
|
127
|
+
@handler.enable
|
128
|
+
@handler.queueing?.should be_true
|
129
|
+
flexmock(EM).should_receive(:add_timer)
|
130
|
+
@handler.disable
|
131
|
+
@handler.state.should == :flushing
|
132
|
+
@handler.mode.should == :offline
|
133
|
+
@handler.queueing?.should be_false
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context :enable do
|
138
|
+
it "goes into offline mode if not offline now" do
|
139
|
+
@handler.init
|
140
|
+
@handler.start
|
141
|
+
flexmock(@handler).should_receive(:start_timer)
|
142
|
+
@handler.enable.should be_true
|
143
|
+
@handler.state.should == :running
|
144
|
+
@handler.mode.should == :offline
|
145
|
+
end
|
146
|
+
|
147
|
+
it "starts restart vote timer when after going into offline mode" do
|
148
|
+
@handler.init
|
149
|
+
@handler.start
|
150
|
+
flexmock(EM::Timer).should_receive(:new).once
|
151
|
+
@handler.enable.should be_true
|
152
|
+
end
|
153
|
+
|
154
|
+
it "sets state to running if was offline and now in flushing state" do
|
155
|
+
@handler.init
|
156
|
+
@handler.start
|
157
|
+
flexmock(@handler).should_receive(:start_timer)
|
158
|
+
@handler.enable
|
159
|
+
flexmock(EM).should_receive(:add_timer)
|
160
|
+
@handler.disable
|
161
|
+
@handler.enable.should be_true
|
162
|
+
@handler.state.should == :running
|
163
|
+
@handler.mode.should == :offline
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context :disable do
|
168
|
+
it "sets state to flushing and starts timer to begin flushing" do
|
169
|
+
@handler.init
|
170
|
+
@handler.start
|
171
|
+
flexmock(@handler).should_receive(:start_timer)
|
172
|
+
@handler.enable
|
173
|
+
flexmock(@handler).should_receive(:cancel_timer).once
|
174
|
+
flexmock(EM).should_receive(:add_timer).once
|
175
|
+
@handler.disable.should be_true
|
176
|
+
@handler.state.should == :flushing
|
177
|
+
end
|
178
|
+
|
179
|
+
it "does nothing if in created state" do
|
180
|
+
@handler.disable.should be_true
|
181
|
+
end
|
182
|
+
|
183
|
+
it "does nothing if not offline" do
|
184
|
+
@handler.init
|
185
|
+
@handler.disable.should be_true
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context :queue_request do
|
190
|
+
before(:each) do
|
191
|
+
@kind = :send_request
|
192
|
+
@type = "/foo/bar"
|
193
|
+
@payload = {:pay => "load"}
|
194
|
+
@target = "target"
|
195
|
+
@callback = lambda { |_| }
|
196
|
+
end
|
197
|
+
|
198
|
+
it "queues request at head of queue if still initializing" do
|
199
|
+
@handler.init
|
200
|
+
@handler.queue_request(@kind, @type, @payload, "target1", @callback).should be_true
|
201
|
+
@handler.queue.size.should == 1
|
202
|
+
@handler.queue_request(@kind, @type, @payload, "target2", @callback).should be_true
|
203
|
+
@handler.queue.size.should == 2
|
204
|
+
@handler.queue.first[:target] == "target2"
|
205
|
+
end
|
206
|
+
|
207
|
+
it "queues request at end of queue if no longer initializing" do
|
208
|
+
@handler.init
|
209
|
+
@handler.start
|
210
|
+
@handler.queue_request(@kind, @type, @payload, "target1", @callback)
|
211
|
+
@handler.queue.size.should == 1
|
212
|
+
@handler.queue_request(@kind, @type, @payload, "target2", @callback)
|
213
|
+
@handler.queue.size.should == 2
|
214
|
+
@handler.queue.first[:target] == "target1"
|
215
|
+
end
|
216
|
+
|
217
|
+
it "votes to restart if restart vote count has exceeded max queue length" do
|
218
|
+
@handler.init
|
219
|
+
@handler.start
|
220
|
+
flexmock(@handler).should_receive(:vote_to_restart).once
|
221
|
+
RightScale::OfflineHandler::MAX_QUEUED_REQUESTS.times do |i|
|
222
|
+
@handler.queue_request(@kind, @type, @payload, @target, @callback)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
context :terminate do
|
228
|
+
it "sets state to terminating and cancels all timers" do
|
229
|
+
@handler.init
|
230
|
+
@handler.start
|
231
|
+
@handler.terminate
|
232
|
+
@handler.state.should == :terminating
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
context :flush do
|
237
|
+
before(:each) do
|
238
|
+
@sender = flexmock("sender")
|
239
|
+
flexmock(RightScale::Sender).should_receive(:instance).and_return(@sender)
|
240
|
+
@kind = :send_request
|
241
|
+
@type = "/foo/bar"
|
242
|
+
@payload = {:pay => "load"}
|
243
|
+
@target = "target"
|
244
|
+
@result = nil
|
245
|
+
@callback = lambda { |result| @result = result }
|
246
|
+
end
|
247
|
+
|
248
|
+
context "when in flushing state" do
|
249
|
+
before(:each) do
|
250
|
+
@handler.init
|
251
|
+
@handler.start
|
252
|
+
flexmock(@handler).should_receive(:start_timer)
|
253
|
+
@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
|
260
|
+
flexmock(EM).should_receive(:add_timer).and_yield.once
|
261
|
+
log = flexmock(RightScale::Log)
|
262
|
+
log.should_receive(:info).with(/Connection to RightNet re-established/).once.ordered
|
263
|
+
log.should_receive(:info).with(/Starting to flush request queue/).once.ordered
|
264
|
+
log.should_receive(:info).with(/Request queue flushed/).once.ordered
|
265
|
+
@handler.disable.should be_true
|
266
|
+
end
|
267
|
+
|
268
|
+
it "submits all queued messages to the sender" do
|
269
|
+
@handler.queue.size.should == 0
|
270
|
+
end
|
271
|
+
|
272
|
+
it "sets up for callback to be executed" do
|
273
|
+
@result.should == "result"
|
274
|
+
end
|
275
|
+
|
276
|
+
it "changes state to running and mode to online" do
|
277
|
+
@handler.state.should == :running
|
278
|
+
@handler.mode.should == :online
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
it "does nothing if not in flushing state" do
|
283
|
+
@handler.init
|
284
|
+
@handler.start
|
285
|
+
@sender.should_receive(:send_push).never
|
286
|
+
@sender.should_receive(:send_request).never
|
287
|
+
@handler.send(:flush).should be_true
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
context :vote_to_restart do
|
292
|
+
it "makes a restart vote callback" do
|
293
|
+
@handler.send(:vote_to_restart).should be_true
|
294
|
+
@vote.should == 1
|
295
|
+
@handler.instance_variable_get(:@restart_vote_count).should == 0
|
296
|
+
end
|
297
|
+
|
298
|
+
it "starts a vote timer if requested" do
|
299
|
+
flexmock(@handler).should_receive(:start_timer).once
|
300
|
+
@handler.send(:vote_to_restart, timer_trigger = true).should be_true
|
301
|
+
end
|
302
|
+
|
303
|
+
it "does nothing if there is no restart vote callback" do
|
304
|
+
@handler = RightScale::OfflineHandler.new(restart_callback = nil, @offline_stats)
|
305
|
+
flexmock(@handler).should_receive(:start_timer).never
|
306
|
+
@handler.send(:vote_to_restart, timer_trigger = true).should be_true
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
context :start_timer do
|
311
|
+
it "starts a re-vote timer" do
|
312
|
+
timer = flexmock("timer")
|
313
|
+
flexmock(EM::Timer).should_receive(:new).and_return(timer).once
|
314
|
+
@handler.send(:start_timer).should be_true
|
315
|
+
@handler.instance_variable_get(:@restart_vote_timer).should == timer
|
316
|
+
end
|
317
|
+
|
318
|
+
it "does nothing if there is not restart vote callback or if terminating" do
|
319
|
+
@handler = RightScale::OfflineHandler.new(restart_callback = nil, @offline_stats)
|
320
|
+
flexmock(EM::Timer).should_receive(:new).never
|
321
|
+
@handler.send(:start_timer).should be_true
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
context :cancel_timer do
|
326
|
+
it "cancels restart vote timer and resets the vote count" do
|
327
|
+
timer = flexmock("timer")
|
328
|
+
timer.should_receive(:cancel).once
|
329
|
+
flexmock(EM::Timer).should_receive(:new).and_return(timer)
|
330
|
+
@handler.send(:start_timer)
|
331
|
+
@handler.send(:cancel_timer).should be_true
|
332
|
+
@handler.instance_variable_get(:@restart_vote_timer).should be_nil
|
333
|
+
@handler.instance_variable_get(:@restart_vote_count).should == 0
|
334
|
+
end
|
335
|
+
|
336
|
+
it "does nothing if the restart vote timer is not running" do
|
337
|
+
@handler.send(:cancel_timer).should be_true
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2013 RightScale Inc
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
|
23
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
24
|
+
|
25
|
+
describe RightScale::PendingRequest do
|
26
|
+
|
27
|
+
context :initialize do
|
28
|
+
it "creates pending request" do
|
29
|
+
now = Time.now
|
30
|
+
response_handler = lambda { |_| }
|
31
|
+
pending_request = RightScale::PendingRequest.new(:send_request, now, response_handler)
|
32
|
+
pending_request.kind.should == :send_request
|
33
|
+
pending_request.receive_time.should == now
|
34
|
+
pending_request.response_handler.should == response_handler
|
35
|
+
pending_request.retry_parent_token.should be_nil
|
36
|
+
pending_request.non_delivery.should be_nil
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context :retry_parent_token do
|
41
|
+
it "can be set" do
|
42
|
+
pending_request = RightScale::PendingRequest.new(:send_request, Time.now, lambda { |_| })
|
43
|
+
pending_request.retry_parent_token = "retry token"
|
44
|
+
pending_request.retry_parent_token.should == "retry token"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context :non_delivery do
|
49
|
+
it "can be set" do
|
50
|
+
pending_request = RightScale::PendingRequest.new(:send_request, Time.now, lambda { |_| })
|
51
|
+
pending_request.non_delivery = "because"
|
52
|
+
pending_request.non_delivery.should == "because"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe RightScale::PendingRequests do
|
58
|
+
|
59
|
+
# Add specified kinds of pending requests to pending_requests hash
|
60
|
+
def add_requests(pending_requests, kinds)
|
61
|
+
i = 0
|
62
|
+
kinds.each do |kind|
|
63
|
+
i += 1
|
64
|
+
pending_requests["token#{i}"] = RightScale::PendingRequest.new(kind, Time.now, lambda { |_| })
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
before(:all) do
|
69
|
+
@push = :send_push
|
70
|
+
@request = :send_request
|
71
|
+
end
|
72
|
+
|
73
|
+
context :initialize do
|
74
|
+
it "is a hash" do
|
75
|
+
pending_requests = RightScale::PendingRequests.new
|
76
|
+
pending_requests.should be_a(Hash)
|
77
|
+
pending_requests.size.should == 0
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context :[]= do
|
82
|
+
it "stores pending request" do
|
83
|
+
pending_requests = RightScale::PendingRequests.new
|
84
|
+
pending_request = RightScale::PendingRequest.new(:send_request, Time.now, lambda { |_| })
|
85
|
+
pending_requests["token"] = pending_request
|
86
|
+
pending_requests["token"].should == pending_request
|
87
|
+
end
|
88
|
+
|
89
|
+
it "deletes old pending send_push requests" do
|
90
|
+
now = Time.now
|
91
|
+
age = RightScale::PendingRequests::MAX_PUSH_AGE + 21
|
92
|
+
flexmock(Time).should_receive(:now).and_return(now, now + 10, now + 10, now + 20, now + 20, now + age, now + age)
|
93
|
+
pending_requests = RightScale::PendingRequests.new
|
94
|
+
add_requests(pending_requests, [@request, @push, @push])
|
95
|
+
pending_requests.size.should == 2
|
96
|
+
pending_requests["token1"].should_not be_nil
|
97
|
+
pending_requests["token2"].should be_nil
|
98
|
+
pending_requests["token3"].should_not be_nil
|
99
|
+
pending_requests.instance_variable_get(:@last_cleanup).should == now + age
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context :kind do
|
104
|
+
it "returns pending requests of specified kind" do
|
105
|
+
pending_requests = RightScale::PendingRequests.new
|
106
|
+
add_requests(pending_requests, [@request, @push, @push])
|
107
|
+
requests = pending_requests.kind(:send_request)
|
108
|
+
requests.size.should == 1
|
109
|
+
requests["token1"].should_not be_nil
|
110
|
+
requests = pending_requests.kind(:send_push)
|
111
|
+
requests.size.should == 2
|
112
|
+
requests["token2"].should_not be_nil
|
113
|
+
requests["token3"].should_not be_nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context :youngest_age do
|
118
|
+
it "returns age of youngest pending request" do
|
119
|
+
now = Time.now
|
120
|
+
flexmock(Time).should_receive(:now).and_return(now, now + 10, now + 10, now + 20, now + 20, now + 30)
|
121
|
+
pending_requests = RightScale::PendingRequests.new
|
122
|
+
add_requests(pending_requests, [@request, @push])
|
123
|
+
pending_requests.youngest_age.should == 10
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context :oldest_age do
|
128
|
+
it "returns age of oldest pending request" do
|
129
|
+
now = Time.now
|
130
|
+
flexmock(Time).should_receive(:now).and_return(now, now + 10, now + 10, now + 20, now + 20, now + 30)
|
131
|
+
pending_requests = RightScale::PendingRequests.new
|
132
|
+
add_requests(pending_requests, [@request, @push])
|
133
|
+
pending_requests.oldest_age.should == 20
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|