right_agent 2.0.7-x86-mingw32
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/LICENSE +20 -0
- data/README.rdoc +82 -0
- data/Rakefile +113 -0
- data/lib/right_agent.rb +59 -0
- data/lib/right_agent/actor.rb +182 -0
- data/lib/right_agent/actor_registry.rb +76 -0
- data/lib/right_agent/actors/agent_manager.rb +232 -0
- data/lib/right_agent/agent.rb +1149 -0
- data/lib/right_agent/agent_config.rb +480 -0
- data/lib/right_agent/agent_identity.rb +210 -0
- data/lib/right_agent/agent_tag_manager.rb +237 -0
- data/lib/right_agent/audit_formatter.rb +107 -0
- data/lib/right_agent/clients.rb +31 -0
- 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.rb +30 -0
- data/lib/right_agent/command/agent_manager_commands.rb +150 -0
- data/lib/right_agent/command/command_client.rb +136 -0
- data/lib/right_agent/command/command_constants.rb +33 -0
- data/lib/right_agent/command/command_io.rb +126 -0
- data/lib/right_agent/command/command_parser.rb +87 -0
- data/lib/right_agent/command/command_runner.rb +118 -0
- data/lib/right_agent/command/command_serializer.rb +63 -0
- data/lib/right_agent/connectivity_checker.rb +179 -0
- data/lib/right_agent/console.rb +65 -0
- data/lib/right_agent/core_payload_types.rb +44 -0
- data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
- data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
- data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
- data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
- data/lib/right_agent/core_payload_types/dev_repositories.rb +100 -0
- data/lib/right_agent/core_payload_types/dev_repository.rb +76 -0
- data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
- data/lib/right_agent/core_payload_types/executable_bundle.rb +130 -0
- data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
- data/lib/right_agent/core_payload_types/login_user.rb +79 -0
- data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
- data/lib/right_agent/core_payload_types/recipe_instantiation.rb +73 -0
- data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
- data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
- data/lib/right_agent/core_payload_types/right_script_instantiation.rb +94 -0
- data/lib/right_agent/core_payload_types/runlist_policy.rb +44 -0
- data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
- data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
- data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
- data/lib/right_agent/daemonize.rb +35 -0
- data/lib/right_agent/dispatched_cache.rb +109 -0
- data/lib/right_agent/dispatcher.rb +272 -0
- data/lib/right_agent/enrollment_result.rb +221 -0
- data/lib/right_agent/exceptions.rb +87 -0
- data/lib/right_agent/history.rb +145 -0
- data/lib/right_agent/log.rb +460 -0
- data/lib/right_agent/minimal.rb +46 -0
- data/lib/right_agent/monkey_patches.rb +30 -0
- data/lib/right_agent/monkey_patches/ruby_patch.rb +55 -0
- data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
- data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
- data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
- data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
- data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +60 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
- data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
- data/lib/right_agent/multiplexer.rb +102 -0
- data/lib/right_agent/offline_handler.rb +270 -0
- data/lib/right_agent/operation_result.rb +300 -0
- data/lib/right_agent/packets.rb +673 -0
- data/lib/right_agent/payload_formatter.rb +104 -0
- data/lib/right_agent/pending_requests.rb +128 -0
- data/lib/right_agent/pid_file.rb +159 -0
- data/lib/right_agent/platform.rb +770 -0
- data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
- data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
- data/lib/right_agent/platform/unix/platform.rb +226 -0
- data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
- data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
- data/lib/right_agent/platform/windows/platform.rb +1808 -0
- data/lib/right_agent/protocol_version_mixin.rb +69 -0
- data/lib/right_agent/retryable_request.rb +195 -0
- data/lib/right_agent/scripts/agent_controller.rb +543 -0
- data/lib/right_agent/scripts/agent_deployer.rb +400 -0
- data/lib/right_agent/scripts/common_parser.rb +160 -0
- data/lib/right_agent/scripts/log_level_manager.rb +192 -0
- data/lib/right_agent/scripts/stats_manager.rb +268 -0
- data/lib/right_agent/scripts/usage.rb +58 -0
- data/lib/right_agent/secure_identity.rb +92 -0
- data/lib/right_agent/security.rb +32 -0
- data/lib/right_agent/security/cached_certificate_store_proxy.rb +77 -0
- data/lib/right_agent/security/certificate.rb +102 -0
- data/lib/right_agent/security/certificate_cache.rb +89 -0
- data/lib/right_agent/security/distinguished_name.rb +56 -0
- data/lib/right_agent/security/encrypted_document.rb +83 -0
- data/lib/right_agent/security/rsa_key_pair.rb +76 -0
- data/lib/right_agent/security/signature.rb +86 -0
- data/lib/right_agent/security/static_certificate_store.rb +85 -0
- data/lib/right_agent/sender.rb +792 -0
- data/lib/right_agent/serialize.rb +29 -0
- data/lib/right_agent/serialize/message_pack.rb +107 -0
- data/lib/right_agent/serialize/secure_serializer.rb +151 -0
- data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
- data/lib/right_agent/serialize/serializable.rb +151 -0
- data/lib/right_agent/serialize/serializer.rb +159 -0
- data/lib/right_agent/subprocess.rb +38 -0
- data/lib/right_agent/tracer.rb +124 -0
- data/right_agent.gemspec +101 -0
- data/spec/actor_registry_spec.rb +80 -0
- data/spec/actor_spec.rb +162 -0
- data/spec/agent_config_spec.rb +235 -0
- data/spec/agent_identity_spec.rb +78 -0
- data/spec/agent_spec.rb +734 -0
- data/spec/agent_tag_manager_spec.rb +319 -0
- 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/agent_manager_commands_spec.rb +51 -0
- data/spec/command/command_io_spec.rb +93 -0
- data/spec/command/command_parser_spec.rb +79 -0
- data/spec/command/command_runner_spec.rb +107 -0
- data/spec/command/command_serializer_spec.rb +51 -0
- data/spec/connectivity_checker_spec.rb +83 -0
- data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
- data/spec/core_payload_types/dev_repository_spec.rb +33 -0
- data/spec/core_payload_types/executable_bundle_spec.rb +67 -0
- data/spec/core_payload_types/login_user_spec.rb +102 -0
- data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
- data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
- data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
- data/spec/core_payload_types/spec_helper.rb +23 -0
- data/spec/dispatched_cache_spec.rb +136 -0
- data/spec/dispatcher_spec.rb +324 -0
- data/spec/enrollment_result_spec.rb +53 -0
- data/spec/history_spec.rb +246 -0
- data/spec/log_spec.rb +192 -0
- data/spec/monkey_patches/eventmachine_spec.rb +62 -0
- data/spec/multiplexer_spec.rb +48 -0
- data/spec/offline_handler_spec.rb +340 -0
- data/spec/operation_result_spec.rb +208 -0
- data/spec/packets_spec.rb +461 -0
- data/spec/pending_requests_spec.rb +136 -0
- data/spec/platform/spec_helper.rb +216 -0
- data/spec/platform/unix/darwin/platform_spec.rb +181 -0
- data/spec/platform/unix/linux/platform_spec.rb +540 -0
- data/spec/platform/unix/spec_helper.rb +149 -0
- data/spec/platform/windows/mingw/platform_spec.rb +222 -0
- data/spec/platform/windows/mswin/platform_spec.rb +259 -0
- data/spec/platform/windows/spec_helper.rb +720 -0
- data/spec/retryable_request_spec.rb +306 -0
- data/spec/secure_identity_spec.rb +50 -0
- data/spec/security/cached_certificate_store_proxy_spec.rb +62 -0
- data/spec/security/certificate_cache_spec.rb +71 -0
- data/spec/security/certificate_spec.rb +49 -0
- data/spec/security/distinguished_name_spec.rb +46 -0
- data/spec/security/encrypted_document_spec.rb +55 -0
- data/spec/security/rsa_key_pair_spec.rb +55 -0
- data/spec/security/signature_spec.rb +66 -0
- data/spec/security/static_certificate_store_spec.rb +58 -0
- data/spec/sender_spec.rb +1045 -0
- data/spec/serialize/message_pack_spec.rb +131 -0
- data/spec/serialize/secure_serializer_spec.rb +132 -0
- data/spec/serialize/serializable_spec.rb +90 -0
- data/spec/serialize/serializer_spec.rb +197 -0
- data/spec/spec.opts +2 -0
- data/spec/spec.win32.opts +1 -0
- data/spec/spec_helper.rb +130 -0
- data/spec/tracer_spec.rb +114 -0
- metadata +447 -0
@@ -0,0 +1,306 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2011 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.join(File.dirname(__FILE__), 'spec_helper')
|
24
|
+
|
25
|
+
describe RightScale::RetryableRequest do
|
26
|
+
|
27
|
+
module RightScale
|
28
|
+
class SenderMock
|
29
|
+
include RightSupport::Ruby::EasySingleton
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
before(:all) do
|
34
|
+
if @sender_exists = RightScale.const_defined?(:Sender)
|
35
|
+
RightScale.module_eval('OldSender = Sender')
|
36
|
+
end
|
37
|
+
RightScale.module_eval('Sender = SenderMock')
|
38
|
+
end
|
39
|
+
|
40
|
+
after(:all) do
|
41
|
+
if @sender_exists
|
42
|
+
RightScale.module_eval('Sender = OldSender')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context ':targets option' do
|
47
|
+
|
48
|
+
context 'when :targets => nil' do
|
49
|
+
it 'should send target-less requests' do
|
50
|
+
request = RightScale::RetryableRequest.new('type', 'payload')
|
51
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
52
|
+
and_yield(RightScale::OperationResult.non_delivery('test')).once
|
53
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
54
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
55
|
+
request.run
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when one target is specified' do
|
60
|
+
it 'should send a targeted request' do
|
61
|
+
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
|
+
and_yield(RightScale::OperationResult.non_delivery('test')).once
|
64
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
65
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
66
|
+
request.run
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context 'when many targets are specified' do
|
71
|
+
it 'should choose a random target' do
|
72
|
+
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
|
+
type.should == 'type'
|
75
|
+
payload.should == 'payload'
|
76
|
+
["rs-agent-1-1", "rs-agent-2-2", "rs-agent-3-3"].should include(target[:agent_id])
|
77
|
+
block.call(RightScale::OperationResult.non_delivery('test'))
|
78
|
+
end
|
79
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
80
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
81
|
+
request.run
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
context ':retry_on_error option' do
|
88
|
+
|
89
|
+
context 'when not specified' do
|
90
|
+
it 'should fail if receives error response' do
|
91
|
+
request = RightScale::RetryableRequest.new('type', 'payload')
|
92
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
93
|
+
and_yield(RightScale::OperationResult.error('test')).once
|
94
|
+
flexmock(request).should_receive(:fail).once
|
95
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
96
|
+
request.run
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'when specified as true' do
|
101
|
+
it 'should retry if receives error response' do
|
102
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :retry_on_error => true)
|
103
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
104
|
+
and_yield(RightScale::OperationResult.error('test')).once
|
105
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
106
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
107
|
+
request.run
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should ignore duplicate responses' do
|
111
|
+
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|
|
113
|
+
5.times { b.call(RightScale::OperationResult.success('test')) }
|
114
|
+
end
|
115
|
+
flexmock(request).should_receive(:fail).never
|
116
|
+
flexmock(request).should_receive(:succeed).once
|
117
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).never
|
118
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
119
|
+
request.run
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should never retry after cancel response' do
|
123
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :retry_on_error => true)
|
124
|
+
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).
|
126
|
+
and_yield(RightScale::OperationResult.cancel('enough already')).once
|
127
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).never
|
128
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
129
|
+
request.run
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
context ':retry_delay options' do
|
136
|
+
|
137
|
+
context 'when using default settings' do
|
138
|
+
it 'should retry non-delivery responses' do
|
139
|
+
request = RightScale::RetryableRequest.new('type', 'payload')
|
140
|
+
flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
|
141
|
+
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).
|
143
|
+
and_yield(RightScale::OperationResult.non_delivery('test')).once
|
144
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
145
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
146
|
+
request.run
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'should retry retry responses' do
|
150
|
+
request = RightScale::RetryableRequest.new('type', 'payload')
|
151
|
+
flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
|
152
|
+
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).
|
154
|
+
and_yield(RightScale::OperationResult.retry('test')).once
|
155
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
156
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
157
|
+
request.run
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should log default retry reason if none given' do
|
161
|
+
request = RightScale::RetryableRequest.new('type', 'payload')
|
162
|
+
flexmock(RightScale::Log).should_receive(:info).with(/Retrying in 5 seconds/).once
|
163
|
+
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).
|
165
|
+
and_yield(RightScale::OperationResult.retry).once
|
166
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).once
|
167
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
168
|
+
request.run
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'should ignore responses that arrive post-cancel' do
|
172
|
+
request = RightScale::RetryableRequest.new('type', 'payload')
|
173
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
174
|
+
and_yield(RightScale::OperationResult.success('test')).once
|
175
|
+
flexmock(request).should_receive(:fail).once
|
176
|
+
flexmock(request).should_receive(:succeed).never
|
177
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).never
|
178
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
179
|
+
request.cancel('test')
|
180
|
+
request.run
|
181
|
+
end
|
182
|
+
|
183
|
+
it 'should never retry after cancel response' do
|
184
|
+
request = RightScale::RetryableRequest.new('type', 'payload')
|
185
|
+
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).
|
187
|
+
and_yield(RightScale::OperationResult.cancel('enough already')).once
|
188
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_RETRY_DELAY, Proc).never
|
189
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
190
|
+
request.run
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
context 'when a :retry_delay is specified' do
|
195
|
+
it 'should control the initial retry delay' do
|
196
|
+
retry_delay = 10
|
197
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay)
|
198
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
199
|
+
and_yield(RightScale::OperationResult.retry('test')).once
|
200
|
+
flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).once
|
201
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
202
|
+
flexmock(EM).should_receive(:next_tick).never
|
203
|
+
request.run
|
204
|
+
end
|
205
|
+
|
206
|
+
it 'should treat -1 as meaning no delay' do
|
207
|
+
retry_delay = -1
|
208
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay)
|
209
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
210
|
+
and_yield(RightScale::OperationResult.retry('test')).once
|
211
|
+
flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).never
|
212
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
213
|
+
flexmock(EM).should_receive(:next_tick).once
|
214
|
+
request.run
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context 'when a :retry_delay_count is specified' do
|
219
|
+
it 'should limit the number of retries using the :retry_delay value' do
|
220
|
+
retry_delay = 10
|
221
|
+
retry_delay_count = 1
|
222
|
+
backoff_factor = RightScale::RetryableRequest::RETRY_BACKOFF_FACTOR
|
223
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay,
|
224
|
+
:retry_delay_count => retry_delay_count)
|
225
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
226
|
+
and_yield(RightScale::OperationResult.retry('test')).twice
|
227
|
+
flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.once
|
228
|
+
flexmock(EM).should_receive(:add_timer).with(retry_delay * backoff_factor, Proc).once
|
229
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
230
|
+
flexmock(EM).should_receive(:next_tick).never
|
231
|
+
request.run
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'should backoff as delay time increases' do
|
235
|
+
retry_delay = 10
|
236
|
+
retry_delay_count = 2
|
237
|
+
max_retry_delay = 30
|
238
|
+
backoff_factor = RightScale::RetryableRequest::RETRY_BACKOFF_FACTOR
|
239
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay,
|
240
|
+
:retry_delay_count => retry_delay_count,
|
241
|
+
:max_retry_delay => max_retry_delay)
|
242
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
243
|
+
and_yield(RightScale::OperationResult.retry('test')).times(4)
|
244
|
+
flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.twice
|
245
|
+
flexmock(EM).should_receive(:add_timer).with(retry_delay * backoff_factor, Proc).and_yield.once
|
246
|
+
flexmock(EM).should_receive(:add_timer).with(max_retry_delay, Proc).once
|
247
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
248
|
+
flexmock(EM).should_receive(:next_tick).never
|
249
|
+
request.run
|
250
|
+
request.instance_variable_get(:@retry_delay_count).should == retry_delay_count / 2
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context 'when a :max_retry_delay is specified' do
|
255
|
+
it 'should limit the retry delay total backoff' do
|
256
|
+
retry_delay = 10
|
257
|
+
retry_delay_count = 1
|
258
|
+
max_retry_delay = 30
|
259
|
+
backoff_factor = RightScale::RetryableRequest::RETRY_BACKOFF_FACTOR
|
260
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :retry_delay => retry_delay,
|
261
|
+
:retry_delay_count => retry_delay_count,
|
262
|
+
:max_retry_delay => max_retry_delay)
|
263
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).
|
264
|
+
and_yield(RightScale::OperationResult.retry('test')).times(3)
|
265
|
+
flexmock(EM).should_receive(:add_timer).with(retry_delay, Proc).and_yield.once
|
266
|
+
flexmock(EM).should_receive(:add_timer).with(retry_delay * backoff_factor, Proc).and_yield.once
|
267
|
+
flexmock(EM).should_receive(:add_timer).with(max_retry_delay, Proc).once
|
268
|
+
flexmock(EM).should_receive(:add_timer).with(RightScale::RetryableRequest::DEFAULT_TIMEOUT, Proc).once
|
269
|
+
flexmock(EM).should_receive(:next_tick).never
|
270
|
+
request.run
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
end
|
275
|
+
|
276
|
+
context ':timeout option' do
|
277
|
+
context 'when disable timeout' do
|
278
|
+
it 'should not timeout' do
|
279
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :timeout => -1)
|
280
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).once
|
281
|
+
flexmock(EM).should_receive(:add_timer).never
|
282
|
+
request.run
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
context 'when a timeout is specified' do
|
287
|
+
it 'should time the response' do
|
288
|
+
timeout = 10
|
289
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :timeout => timeout)
|
290
|
+
flexmock(RightScale::Sender.instance).should_receive(:send_request).with('type', 'payload', nil, Proc).once
|
291
|
+
flexmock(EM).should_receive(:add_timer).with(timeout, Proc).once
|
292
|
+
request.run
|
293
|
+
end
|
294
|
+
|
295
|
+
it 'should log a message when timeout' do
|
296
|
+
timeout = 10
|
297
|
+
request = RightScale::RetryableRequest.new('type', 'payload', :timeout => timeout)
|
298
|
+
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
|
300
|
+
flexmock(EM).should_receive(:add_timer).with(timeout, Proc).and_yield.once
|
301
|
+
request.run
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2011 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::SecureIdentity do
|
26
|
+
|
27
|
+
it 'should obscure the secret token when generating the agent identity' do
|
28
|
+
id = 12345
|
29
|
+
secret = "mum's the word"
|
30
|
+
identity = RightScale::SecureIdentity.derive(id, secret)
|
31
|
+
identity.should_not =~ /#{secret}/
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should detect tampering with verifiers' do
|
35
|
+
id = 12345
|
36
|
+
secret = "mum's the word"
|
37
|
+
ts = Time.now
|
38
|
+
|
39
|
+
identity = RightScale::SecureIdentity.derive(id, secret)
|
40
|
+
verifier = RightScale::SecureIdentity.create_verifier(id, secret, ts)
|
41
|
+
bad1 = RightScale::SecureIdentity.create_verifier(id+1, secret, ts)
|
42
|
+
bad2 = RightScale::SecureIdentity.create_verifier(id, secret, ts-1)
|
43
|
+
bad3 = RightScale::SecureIdentity.create_verifier(id, secret + "foom", ts)
|
44
|
+
|
45
|
+
verifier.should_not == bad1
|
46
|
+
verifier.should_not == bad2
|
47
|
+
verifier.should_not == bad3
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-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::CachedCertificateStoreProxy do
|
26
|
+
|
27
|
+
include RightScale::SpecHelper
|
28
|
+
|
29
|
+
before(:all) do
|
30
|
+
@cert, @key = issue_cert
|
31
|
+
@signer, key = issue_cert
|
32
|
+
@target, key = issue_cert
|
33
|
+
@store = flexmock("Store")
|
34
|
+
@proxy = RightScale::CachedCertificateStoreProxy.new(@store)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should not raise and return nil for non existent certificates' do
|
38
|
+
res = nil
|
39
|
+
@store.should_receive(:get_target).with(nil).and_return(nil)
|
40
|
+
lambda { res = @proxy.get_target(nil) }.should_not raise_error
|
41
|
+
res.should == nil
|
42
|
+
@store.should_receive(:get_signer).with(nil).and_return(nil)
|
43
|
+
lambda { res = @proxy.get_signer(nil) }.should_not raise_error
|
44
|
+
res.should == nil
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should return target certificates' do
|
48
|
+
@store.should_receive(:get_target).with('anything').and_return(@target)
|
49
|
+
@proxy.get_target('anything').should == @target
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should return signer certificates' do
|
53
|
+
@store.should_receive(:get_signer).with('anything').and_return(@signer)
|
54
|
+
@proxy.get_signer('anything').should == @signer
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should return receiver certificate and key' do
|
58
|
+
@store.should_receive(:get_receiver).with('anything').and_return([@cert, @key])
|
59
|
+
@proxy.get_receiver('anything').should == [@cert, @key]
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2011 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::CertificateCache do
|
26
|
+
|
27
|
+
before(:each) do
|
28
|
+
@cache = RightScale::CertificateCache.new(2)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should allow storing and retrieving objects' do
|
32
|
+
@cache['some_id'].should be_nil
|
33
|
+
@cache['some_id'] = 'some_value'
|
34
|
+
@cache['some_id'].should == 'some_value'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should not store more than required' do
|
38
|
+
@cache[1] = 'oldest'
|
39
|
+
@cache[2] = 'older'
|
40
|
+
@cache[1].should == 'oldest'
|
41
|
+
@cache[2].should == 'older'
|
42
|
+
|
43
|
+
@cache[3] = 'new'
|
44
|
+
@cache[3].should == 'new'
|
45
|
+
|
46
|
+
@cache[1].should be_nil
|
47
|
+
@cache[2].should == 'older'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'should use LRU to remove entries' do
|
51
|
+
@cache[1] = 'oldest'
|
52
|
+
@cache[2] = 'older'
|
53
|
+
@cache[1].should == 'oldest'
|
54
|
+
@cache[2].should == 'older'
|
55
|
+
|
56
|
+
@cache[1] = 'new'
|
57
|
+
@cache[3] = 'newer'
|
58
|
+
@cache[1].should == 'new'
|
59
|
+
@cache[3].should == 'newer'
|
60
|
+
|
61
|
+
@cache[2].should be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should store items returned by block' do
|
65
|
+
@cache[1].should be_nil
|
66
|
+
item = @cache.get(1) { 'item' }
|
67
|
+
item.should == 'item'
|
68
|
+
@cache[1].should == 'item'
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|