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.
Files changed (176) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +82 -0
  3. data/Rakefile +113 -0
  4. data/lib/right_agent.rb +59 -0
  5. data/lib/right_agent/actor.rb +182 -0
  6. data/lib/right_agent/actor_registry.rb +76 -0
  7. data/lib/right_agent/actors/agent_manager.rb +232 -0
  8. data/lib/right_agent/agent.rb +1149 -0
  9. data/lib/right_agent/agent_config.rb +480 -0
  10. data/lib/right_agent/agent_identity.rb +210 -0
  11. data/lib/right_agent/agent_tag_manager.rb +237 -0
  12. data/lib/right_agent/audit_formatter.rb +107 -0
  13. data/lib/right_agent/clients.rb +31 -0
  14. data/lib/right_agent/clients/api_client.rb +383 -0
  15. data/lib/right_agent/clients/auth_client.rb +247 -0
  16. data/lib/right_agent/clients/balanced_http_client.rb +369 -0
  17. data/lib/right_agent/clients/base_retry_client.rb +495 -0
  18. data/lib/right_agent/clients/right_http_client.rb +279 -0
  19. data/lib/right_agent/clients/router_client.rb +493 -0
  20. data/lib/right_agent/command.rb +30 -0
  21. data/lib/right_agent/command/agent_manager_commands.rb +150 -0
  22. data/lib/right_agent/command/command_client.rb +136 -0
  23. data/lib/right_agent/command/command_constants.rb +33 -0
  24. data/lib/right_agent/command/command_io.rb +126 -0
  25. data/lib/right_agent/command/command_parser.rb +87 -0
  26. data/lib/right_agent/command/command_runner.rb +118 -0
  27. data/lib/right_agent/command/command_serializer.rb +63 -0
  28. data/lib/right_agent/connectivity_checker.rb +179 -0
  29. data/lib/right_agent/console.rb +65 -0
  30. data/lib/right_agent/core_payload_types.rb +44 -0
  31. data/lib/right_agent/core_payload_types/cookbook.rb +61 -0
  32. data/lib/right_agent/core_payload_types/cookbook_position.rb +46 -0
  33. data/lib/right_agent/core_payload_types/cookbook_repository.rb +116 -0
  34. data/lib/right_agent/core_payload_types/cookbook_sequence.rb +70 -0
  35. data/lib/right_agent/core_payload_types/dev_repositories.rb +100 -0
  36. data/lib/right_agent/core_payload_types/dev_repository.rb +76 -0
  37. data/lib/right_agent/core_payload_types/event_categories.rb +38 -0
  38. data/lib/right_agent/core_payload_types/executable_bundle.rb +130 -0
  39. data/lib/right_agent/core_payload_types/login_policy.rb +72 -0
  40. data/lib/right_agent/core_payload_types/login_user.rb +79 -0
  41. data/lib/right_agent/core_payload_types/planned_volume.rb +94 -0
  42. data/lib/right_agent/core_payload_types/recipe_instantiation.rb +73 -0
  43. data/lib/right_agent/core_payload_types/repositories_bundle.rb +50 -0
  44. data/lib/right_agent/core_payload_types/right_script_attachment.rb +95 -0
  45. data/lib/right_agent/core_payload_types/right_script_instantiation.rb +94 -0
  46. data/lib/right_agent/core_payload_types/runlist_policy.rb +44 -0
  47. data/lib/right_agent/core_payload_types/secure_document.rb +66 -0
  48. data/lib/right_agent/core_payload_types/secure_document_location.rb +63 -0
  49. data/lib/right_agent/core_payload_types/software_repository_instantiation.rb +61 -0
  50. data/lib/right_agent/daemonize.rb +35 -0
  51. data/lib/right_agent/dispatched_cache.rb +109 -0
  52. data/lib/right_agent/dispatcher.rb +272 -0
  53. data/lib/right_agent/enrollment_result.rb +221 -0
  54. data/lib/right_agent/exceptions.rb +87 -0
  55. data/lib/right_agent/history.rb +145 -0
  56. data/lib/right_agent/log.rb +460 -0
  57. data/lib/right_agent/minimal.rb +46 -0
  58. data/lib/right_agent/monkey_patches.rb +30 -0
  59. data/lib/right_agent/monkey_patches/ruby_patch.rb +55 -0
  60. data/lib/right_agent/monkey_patches/ruby_patch/array_patch.rb +29 -0
  61. data/lib/right_agent/monkey_patches/ruby_patch/darwin_patch.rb +24 -0
  62. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch.rb +24 -0
  63. data/lib/right_agent/monkey_patches/ruby_patch/linux_patch/file_patch.rb +30 -0
  64. data/lib/right_agent/monkey_patches/ruby_patch/object_patch.rb +49 -0
  65. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch.rb +32 -0
  66. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/file_patch.rb +60 -0
  67. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/process_patch.rb +63 -0
  68. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/stdio_patch.rb +27 -0
  69. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/time_patch.rb +55 -0
  70. data/lib/right_agent/monkey_patches/ruby_patch/windows_patch/win32ole_patch.rb +34 -0
  71. data/lib/right_agent/multiplexer.rb +102 -0
  72. data/lib/right_agent/offline_handler.rb +270 -0
  73. data/lib/right_agent/operation_result.rb +300 -0
  74. data/lib/right_agent/packets.rb +673 -0
  75. data/lib/right_agent/payload_formatter.rb +104 -0
  76. data/lib/right_agent/pending_requests.rb +128 -0
  77. data/lib/right_agent/pid_file.rb +159 -0
  78. data/lib/right_agent/platform.rb +770 -0
  79. data/lib/right_agent/platform/unix/darwin/platform.rb +102 -0
  80. data/lib/right_agent/platform/unix/linux/platform.rb +305 -0
  81. data/lib/right_agent/platform/unix/platform.rb +226 -0
  82. data/lib/right_agent/platform/windows/mingw/platform.rb +447 -0
  83. data/lib/right_agent/platform/windows/mswin/platform.rb +236 -0
  84. data/lib/right_agent/platform/windows/platform.rb +1808 -0
  85. data/lib/right_agent/protocol_version_mixin.rb +69 -0
  86. data/lib/right_agent/retryable_request.rb +195 -0
  87. data/lib/right_agent/scripts/agent_controller.rb +543 -0
  88. data/lib/right_agent/scripts/agent_deployer.rb +400 -0
  89. data/lib/right_agent/scripts/common_parser.rb +160 -0
  90. data/lib/right_agent/scripts/log_level_manager.rb +192 -0
  91. data/lib/right_agent/scripts/stats_manager.rb +268 -0
  92. data/lib/right_agent/scripts/usage.rb +58 -0
  93. data/lib/right_agent/secure_identity.rb +92 -0
  94. data/lib/right_agent/security.rb +32 -0
  95. data/lib/right_agent/security/cached_certificate_store_proxy.rb +77 -0
  96. data/lib/right_agent/security/certificate.rb +102 -0
  97. data/lib/right_agent/security/certificate_cache.rb +89 -0
  98. data/lib/right_agent/security/distinguished_name.rb +56 -0
  99. data/lib/right_agent/security/encrypted_document.rb +83 -0
  100. data/lib/right_agent/security/rsa_key_pair.rb +76 -0
  101. data/lib/right_agent/security/signature.rb +86 -0
  102. data/lib/right_agent/security/static_certificate_store.rb +85 -0
  103. data/lib/right_agent/sender.rb +792 -0
  104. data/lib/right_agent/serialize.rb +29 -0
  105. data/lib/right_agent/serialize/message_pack.rb +107 -0
  106. data/lib/right_agent/serialize/secure_serializer.rb +151 -0
  107. data/lib/right_agent/serialize/secure_serializer_initializer.rb +47 -0
  108. data/lib/right_agent/serialize/serializable.rb +151 -0
  109. data/lib/right_agent/serialize/serializer.rb +159 -0
  110. data/lib/right_agent/subprocess.rb +38 -0
  111. data/lib/right_agent/tracer.rb +124 -0
  112. data/right_agent.gemspec +101 -0
  113. data/spec/actor_registry_spec.rb +80 -0
  114. data/spec/actor_spec.rb +162 -0
  115. data/spec/agent_config_spec.rb +235 -0
  116. data/spec/agent_identity_spec.rb +78 -0
  117. data/spec/agent_spec.rb +734 -0
  118. data/spec/agent_tag_manager_spec.rb +319 -0
  119. data/spec/clients/api_client_spec.rb +423 -0
  120. data/spec/clients/auth_client_spec.rb +272 -0
  121. data/spec/clients/balanced_http_client_spec.rb +576 -0
  122. data/spec/clients/base_retry_client_spec.rb +635 -0
  123. data/spec/clients/router_client_spec.rb +594 -0
  124. data/spec/clients/spec_helper.rb +111 -0
  125. data/spec/command/agent_manager_commands_spec.rb +51 -0
  126. data/spec/command/command_io_spec.rb +93 -0
  127. data/spec/command/command_parser_spec.rb +79 -0
  128. data/spec/command/command_runner_spec.rb +107 -0
  129. data/spec/command/command_serializer_spec.rb +51 -0
  130. data/spec/connectivity_checker_spec.rb +83 -0
  131. data/spec/core_payload_types/dev_repositories_spec.rb +64 -0
  132. data/spec/core_payload_types/dev_repository_spec.rb +33 -0
  133. data/spec/core_payload_types/executable_bundle_spec.rb +67 -0
  134. data/spec/core_payload_types/login_user_spec.rb +102 -0
  135. data/spec/core_payload_types/recipe_instantiation_spec.rb +81 -0
  136. data/spec/core_payload_types/right_script_attachment_spec.rb +65 -0
  137. data/spec/core_payload_types/right_script_instantiation_spec.rb +79 -0
  138. data/spec/core_payload_types/spec_helper.rb +23 -0
  139. data/spec/dispatched_cache_spec.rb +136 -0
  140. data/spec/dispatcher_spec.rb +324 -0
  141. data/spec/enrollment_result_spec.rb +53 -0
  142. data/spec/history_spec.rb +246 -0
  143. data/spec/log_spec.rb +192 -0
  144. data/spec/monkey_patches/eventmachine_spec.rb +62 -0
  145. data/spec/multiplexer_spec.rb +48 -0
  146. data/spec/offline_handler_spec.rb +340 -0
  147. data/spec/operation_result_spec.rb +208 -0
  148. data/spec/packets_spec.rb +461 -0
  149. data/spec/pending_requests_spec.rb +136 -0
  150. data/spec/platform/spec_helper.rb +216 -0
  151. data/spec/platform/unix/darwin/platform_spec.rb +181 -0
  152. data/spec/platform/unix/linux/platform_spec.rb +540 -0
  153. data/spec/platform/unix/spec_helper.rb +149 -0
  154. data/spec/platform/windows/mingw/platform_spec.rb +222 -0
  155. data/spec/platform/windows/mswin/platform_spec.rb +259 -0
  156. data/spec/platform/windows/spec_helper.rb +720 -0
  157. data/spec/retryable_request_spec.rb +306 -0
  158. data/spec/secure_identity_spec.rb +50 -0
  159. data/spec/security/cached_certificate_store_proxy_spec.rb +62 -0
  160. data/spec/security/certificate_cache_spec.rb +71 -0
  161. data/spec/security/certificate_spec.rb +49 -0
  162. data/spec/security/distinguished_name_spec.rb +46 -0
  163. data/spec/security/encrypted_document_spec.rb +55 -0
  164. data/spec/security/rsa_key_pair_spec.rb +55 -0
  165. data/spec/security/signature_spec.rb +66 -0
  166. data/spec/security/static_certificate_store_spec.rb +58 -0
  167. data/spec/sender_spec.rb +1045 -0
  168. data/spec/serialize/message_pack_spec.rb +131 -0
  169. data/spec/serialize/secure_serializer_spec.rb +132 -0
  170. data/spec/serialize/serializable_spec.rb +90 -0
  171. data/spec/serialize/serializer_spec.rb +197 -0
  172. data/spec/spec.opts +2 -0
  173. data/spec/spec.win32.opts +1 -0
  174. data/spec/spec_helper.rb +130 -0
  175. data/spec/tracer_spec.rb +114 -0
  176. 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