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,319 @@
|
|
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::AgentTagManager do
|
26
|
+
|
27
|
+
include FlexMock::ArgumentTypes
|
28
|
+
|
29
|
+
before(:each) do
|
30
|
+
@log = flexmock(RightScale::Log)
|
31
|
+
@log.should_receive(:error).by_default.and_return { |m| raise RightScale::Log.format(*m) }
|
32
|
+
@identity = "rs-agent-1-1"
|
33
|
+
@agent_href = "/api/clouds/1/instances/1"
|
34
|
+
@agent_href2 = "/api/clouds/2/instances/2"
|
35
|
+
@agent = flexmock("agent", :self_href => @agent_href, :identity => @identity)
|
36
|
+
@hrefs = [@agent_href, @agent_href2]
|
37
|
+
@manager = RightScale::AgentTagManager.instance
|
38
|
+
@manager.agent = @agent
|
39
|
+
@request = flexmock("request", :run => true)
|
40
|
+
@request.should_receive(:callback).and_yield("result").by_default
|
41
|
+
@request.should_receive(:errback).by_default
|
42
|
+
@request.should_receive(:raw_response).and_return("raw response").by_default
|
43
|
+
@retryable_request = flexmock(RightScale::RetryableRequest)
|
44
|
+
@tag = "some:tag=value"
|
45
|
+
@tag1 = "other:tag=value"
|
46
|
+
@tags = [@tag, @tag1]
|
47
|
+
@result = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
context :tags do
|
51
|
+
|
52
|
+
before(:each) do
|
53
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
54
|
+
{:agent_identity => @identity, :hrefs => [@agent_href]}, {}).and_return(@request).once.by_default
|
55
|
+
end
|
56
|
+
|
57
|
+
it "retrieves current agent tags" do
|
58
|
+
@request.should_receive(:callback).and_yield({@agent_href => {"tags" => [@tag]}}).once
|
59
|
+
@manager.tags { |r| @result = r }
|
60
|
+
@result.should == [@tag]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns empty array when there is no results hash" do
|
64
|
+
@request.should_receive(:callback).and_yield({}).once
|
65
|
+
@manager.tags { |r| @result = r }
|
66
|
+
@result.should == []
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns the raw result when result is not a hash" do
|
70
|
+
@request.should_receive(:callback).and_yield("result").once
|
71
|
+
@manager.tags { |r| @result = r }
|
72
|
+
@result.should == "result"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "returns raw result when :raw option specified" do
|
76
|
+
@request.should_receive(:callback).and_yield("result").once
|
77
|
+
@request.should_receive(:raw_response).and_return("raw response").once
|
78
|
+
@manager.tags(:raw => true) { |r| @result = r }
|
79
|
+
@result.should == "raw response"
|
80
|
+
end
|
81
|
+
|
82
|
+
it "forwards timeout option" do
|
83
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
84
|
+
{:agent_identity => @identity, :hrefs => [@agent_href]}, {:timeout => 9}).and_return(@request).once
|
85
|
+
@request.should_receive(:callback).and_yield({@agent_href => {"tags" => [@tag]}}).once
|
86
|
+
@manager.tags(:timeout => 9) { |r| @result = r }
|
87
|
+
@result.should == [@tag]
|
88
|
+
end
|
89
|
+
|
90
|
+
it "yields error result and logs error" do
|
91
|
+
@log.should_receive(:error).with(/Failed to query tags/).once
|
92
|
+
@request.should_receive(:errback).and_yield("error").once
|
93
|
+
@request.should_receive(:callback).once
|
94
|
+
@manager.tags { |r| @result = r }
|
95
|
+
@result.should == "error"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context :query_tags do
|
100
|
+
|
101
|
+
it "queries for agents having individual tag" do
|
102
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
103
|
+
{:agent_identity => @identity, :tags => [@tag]}, {}).and_return(@request).once
|
104
|
+
@request.should_receive(:callback).and_yield({@identity => {"tags" => [@tag]}, @agent_href => {"tags" => [@tag]}}).once
|
105
|
+
@manager.query_tags(@tag) { |r| @result = r }
|
106
|
+
@result.should == {@identity => {"tags" => [@tag]}, @agent_href => {"tags" => [@tag]}}
|
107
|
+
end
|
108
|
+
|
109
|
+
it "queries for agents having multiple tags" do
|
110
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
111
|
+
{:agent_identity => @identity, :tags => @tags}, {}).and_return(@request).once
|
112
|
+
@request.should_receive(:callback).and_yield({@agent_href => {"tags" => @tags}}).once
|
113
|
+
@manager.query_tags(@tags) { |r| @result = r }
|
114
|
+
@result.should == {@agent_href => {"tags" => @tags}}
|
115
|
+
end
|
116
|
+
|
117
|
+
it "forwards options" do
|
118
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
119
|
+
{:agent_identity => @identity, :tags => @tags}, {:timeout => 9}).and_return(@request).once
|
120
|
+
@request.should_receive(:callback).and_yield({@identity => {"tags" => [@tag]}}).once
|
121
|
+
@request.should_receive(:raw_response).and_return("raw response").once
|
122
|
+
@manager.query_tags(@tags, :raw => true, :timeout => 9) { |r| @result = r }
|
123
|
+
@result.should == "raw response"
|
124
|
+
end
|
125
|
+
|
126
|
+
it "yields error result and logs error" do
|
127
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
128
|
+
{:agent_identity => @identity, :tags => [@tag]}, {}).and_return(@request).once
|
129
|
+
@log.should_receive(:error).with(/Failed to query tags/).once
|
130
|
+
@request.should_receive(:errback).and_yield("error").once
|
131
|
+
@request.should_receive(:callback).once
|
132
|
+
@manager.query_tags(@tag) { |r| @result = r }
|
133
|
+
@result.should == "error"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context :query_tags_raw do
|
138
|
+
|
139
|
+
before(:each) do
|
140
|
+
@request.should_receive(:raw_response).and_return("raw response").once
|
141
|
+
end
|
142
|
+
|
143
|
+
it "always yields raw response" do
|
144
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
145
|
+
{:agent_identity => @identity, :tags => [@tag]}, {}).and_return(@request).once
|
146
|
+
@request.should_receive(:callback).and_yield({@identity => {"tags" => [@tag]}, @agent_href => {"tags" => [@tag]}}).once
|
147
|
+
@manager.query_tags_raw(@tag) { |r| @result = r }
|
148
|
+
@result.should == "raw response"
|
149
|
+
end
|
150
|
+
|
151
|
+
it "queries for agents having individual tag and always yields raw response" do
|
152
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
153
|
+
{:agent_identity => @identity, :tags => [@tag]}, {}).and_return(@request).once
|
154
|
+
@request.should_receive(:callback).and_yield({@identity => {"tags" => [@tag]}, @agent_href => {"tags" => [@tag]}}).once
|
155
|
+
@manager.query_tags_raw(@tag) { |r| @result = r }
|
156
|
+
@result.should == "raw response"
|
157
|
+
end
|
158
|
+
|
159
|
+
it "queries for agents having multiple tags always yields raw response" do
|
160
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
161
|
+
{:agent_identity => @identity, :tags => @tags}, {}).and_return(@request).once
|
162
|
+
@request.should_receive(:callback).and_yield({@agent_href => {"tags" => @tags}}).once
|
163
|
+
@manager.query_tags_raw(@tags) { |r| @result = r }
|
164
|
+
@result.should == "raw response"
|
165
|
+
end
|
166
|
+
|
167
|
+
it "queries for selected agents" do
|
168
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
169
|
+
{:agent_identity => @identity, :hrefs => @hrefs, :tags => @tags}, {}).and_return(@request).once
|
170
|
+
@request.should_receive(:callback).and_yield({@agent_href => {"tags" => @tags}}).once
|
171
|
+
@manager.query_tags_raw(@tags, @hrefs) { |r| @result = r }
|
172
|
+
@result.should == "raw response"
|
173
|
+
end
|
174
|
+
|
175
|
+
it "forwards timeout option" do
|
176
|
+
@retryable_request.should_receive(:new).with("/router/query_tags",
|
177
|
+
{:agent_identity => @identity, :tags => @tags}, {:timeout => 9}).and_return(@request).once
|
178
|
+
@request.should_receive(:callback).and_yield({@identity => {"tags" => [@tag]}}).once
|
179
|
+
@manager.query_tags_raw(@tags, nil, :timeout => 9) { |r| @result = r }
|
180
|
+
@result.should == "raw response"
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context :add_tags do
|
185
|
+
|
186
|
+
before(:each) do
|
187
|
+
@request.should_receive(:raw_response).and_return("raw response").once
|
188
|
+
@agent.should_receive(:tags).and_return([]).once.by_default
|
189
|
+
@agent.should_receive(:tags=).once.by_default
|
190
|
+
end
|
191
|
+
|
192
|
+
it "adds individual tag to agent" do
|
193
|
+
@retryable_request.should_receive(:new).with("/router/add_tags", {:tags => [@tag]}).and_return(@request).once
|
194
|
+
@manager.add_tags(@tag).should be_true
|
195
|
+
end
|
196
|
+
|
197
|
+
it "adds multiple tags to agent" do
|
198
|
+
@retryable_request.should_receive(:new).with("/router/add_tags", {:tags => @tags}).and_return(@request).once
|
199
|
+
@manager.add_tags(@tags).should be_true
|
200
|
+
end
|
201
|
+
|
202
|
+
it "optionally yields raw response" do
|
203
|
+
@retryable_request.should_receive(:new).with("/router/add_tags", {:tags => @tags}).and_return(@request).once
|
204
|
+
@request.should_receive(:callback).and_yield("result").once
|
205
|
+
@manager.add_tags(@tags) { |r| @result = r }
|
206
|
+
@result.should == "raw response"
|
207
|
+
end
|
208
|
+
|
209
|
+
it "updates local tags" do
|
210
|
+
@agent.should_receive(:tags).and_return([@tag1]).once
|
211
|
+
@agent.should_receive(:tags=).should_receive([@tag]).once
|
212
|
+
@retryable_request.should_receive(:new).with("/router/add_tags", {:tags => [@tag]}).and_return(@request).once
|
213
|
+
@manager.add_tags(@tag).should be_true
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
context :remove_tags do
|
218
|
+
|
219
|
+
before(:each) do
|
220
|
+
@request.should_receive(:raw_response).and_return("raw response").once
|
221
|
+
@agent.should_receive(:tags).and_return([@tag]).once.by_default
|
222
|
+
@agent.should_receive(:tags=).once.by_default
|
223
|
+
end
|
224
|
+
|
225
|
+
it "removes individual tag to agent" do
|
226
|
+
@retryable_request.should_receive(:new).with("/router/delete_tags", {:tags => [@tag]}).and_return(@request).once
|
227
|
+
@manager.remove_tags(@tag).should be_true
|
228
|
+
end
|
229
|
+
|
230
|
+
it "removes multiple tags to agent" do
|
231
|
+
@retryable_request.should_receive(:new).with("/router/delete_tags", {:tags => @tags}).and_return(@request).once
|
232
|
+
@manager.remove_tags(@tags).should be_true
|
233
|
+
end
|
234
|
+
|
235
|
+
it "optionally yields raw response" do
|
236
|
+
@retryable_request.should_receive(:new).with("/router/delete_tags", {:tags => @tags}).and_return(@request).once
|
237
|
+
@request.should_receive(:callback).and_yield("result").once
|
238
|
+
@manager.remove_tags(@tags) { |r| @result = r }
|
239
|
+
@result.should == "raw response"
|
240
|
+
end
|
241
|
+
|
242
|
+
it "updates local tags" do
|
243
|
+
@agent.should_receive(:tags).and_return([]).once
|
244
|
+
@agent.should_receive(:tags=).should_receive([@tag]).once
|
245
|
+
@retryable_request.should_receive(:new).with("/router/delete_tags", {:tags => [@tag]}).and_return(@request).once
|
246
|
+
@manager.remove_tags(@tag).should be_true
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
context :do_update do
|
251
|
+
|
252
|
+
before(:each) do
|
253
|
+
@agent.should_receive(:tags).and_return([]).once.by_default
|
254
|
+
end
|
255
|
+
|
256
|
+
it "checks that agent has been set" do
|
257
|
+
@manager.agent = nil
|
258
|
+
@agent.should_receive(:tags).never
|
259
|
+
lambda { @manager.send(:do_update, [@tag], []) }.should \
|
260
|
+
raise_error(ArgumentError, "Must set agent= before using tag manager")
|
261
|
+
end
|
262
|
+
|
263
|
+
it "does not allow both add and removal of tags in same request" do
|
264
|
+
@agent.should_receive(:tags).never
|
265
|
+
lambda { @manager.send(:do_update, [@tag], [@tag1]) }.should \
|
266
|
+
raise_error(ArgumentError, "Cannot add and remove tags in same update")
|
267
|
+
end
|
268
|
+
|
269
|
+
it "adds tags for agent" do
|
270
|
+
@retryable_request.should_receive(:new).with("/router/add_tags", {:tags => [@tag]}).and_return(@request).once
|
271
|
+
@agent.should_receive(:tags=).never
|
272
|
+
@manager.send(:do_update, [@tag], []).should be_true
|
273
|
+
end
|
274
|
+
|
275
|
+
it "removes tags for agent" do
|
276
|
+
@retryable_request.should_receive(:new).with("/router/delete_tags", {:tags => [@tag1]}).and_return(@request).once
|
277
|
+
@agent.should_receive(:tags=).never
|
278
|
+
@manager.send(:do_update, [], [@tag1]).should be_true
|
279
|
+
end
|
280
|
+
|
281
|
+
it "yields raw response if block given" do
|
282
|
+
@retryable_request.should_receive(:new).with("/router/add_tags", {:tags => [@tag]}).and_return(@request).once
|
283
|
+
@request.should_receive(:raw_response).and_return("raw response").once
|
284
|
+
@agent.should_receive(:tags=).once
|
285
|
+
@manager.send(:do_update, [@tag], []) { |r| @result = r }
|
286
|
+
@result.should == "raw response"
|
287
|
+
end
|
288
|
+
|
289
|
+
it "updates local tags if block given and successful" do
|
290
|
+
@retryable_request.should_receive(:new).with("/router/add_tags", {:tags => [@tag]}).and_return(@request).once
|
291
|
+
@request.should_receive(:raw_response).and_return("raw response").once
|
292
|
+
@agent.should_receive(:tags=).with([@tag]).once
|
293
|
+
@manager.send(:do_update, [@tag], []) { |r| @result = r }
|
294
|
+
@result.should == "raw response"
|
295
|
+
end
|
296
|
+
|
297
|
+
it "yields error result and does not update local tags" do
|
298
|
+
@retryable_request.should_receive(:new).with("/router/add_tags", {:tags => [@tag]}).and_return(@request).once
|
299
|
+
@request.should_receive(:raw_response).and_return("error").once
|
300
|
+
@request.should_receive(:errback).and_yield("error").once
|
301
|
+
@request.should_receive(:callback).once
|
302
|
+
@agent.should_receive(:tags=).never
|
303
|
+
@manager.send(:do_update, [@tag], []) { |r| @result = r }
|
304
|
+
@result.should == "error"
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
context :clear do
|
309
|
+
|
310
|
+
it "clears all agent tags" do
|
311
|
+
@request.should_receive(:raw_response).and_return("raw response").once
|
312
|
+
@agent.should_receive(:tags).and_return(@tags).twice
|
313
|
+
@agent.should_receive(:tags=).with([]).once
|
314
|
+
@retryable_request.should_receive(:new).with("/router/delete_tags", {:tags => @tags}).and_return(@request).once
|
315
|
+
@manager.clear { |r| @result = r }
|
316
|
+
@result.should == "raw response"
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
@@ -0,0 +1,423 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright (c) 2013 RightScale Inc
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
# a copy of this software and associated documentation files (the
|
8
|
+
# "Software"), to deal in the Software without restriction, including
|
9
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
# the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be
|
15
|
+
# included in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
#++
|
25
|
+
|
26
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
27
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'right_agent', 'clients', 'api_client'))
|
28
|
+
|
29
|
+
describe RightScale::ApiClient do
|
30
|
+
|
31
|
+
include FlexMock::ArgumentTypes
|
32
|
+
|
33
|
+
before(:each) do
|
34
|
+
@log = flexmock(RightScale::Log)
|
35
|
+
@log.should_receive(:error).by_default.and_return { |m| raise RightScale::Log.format(*m) }
|
36
|
+
@log.should_receive(:warning).by_default.and_return { |m| raise RightScale::Log.format(*m) }
|
37
|
+
@timer = flexmock("timer", :cancel => true, :interval= => 0).by_default
|
38
|
+
flexmock(EM::PeriodicTimer).should_receive(:new).and_return(@timer).and_yield.by_default
|
39
|
+
@account_id = 123
|
40
|
+
@agent_id = "rs-instance-1-1"
|
41
|
+
@agent_href = "/api/clouds/1/instances/1"
|
42
|
+
@agent_href2 = "/api/clouds/2/instances/2"
|
43
|
+
@links = {"links" => [{"rel" => "self", "href" => @agent_href}]}
|
44
|
+
@http_client = flexmock("http client", :get => @links, :check_health => true).by_default
|
45
|
+
flexmock(RightScale::BalancedHttpClient).should_receive(:new).and_return(@http_client).by_default
|
46
|
+
@url = "http://test.com"
|
47
|
+
@auth_header = {"Authorization" => "Bearer <session>"}
|
48
|
+
@auth_client = AuthClientMock.new(@url, @auth_header, :authorized, @account_id, @agent_id)
|
49
|
+
@options = {}
|
50
|
+
@client = RightScale::ApiClient.new(@auth_client, @options)
|
51
|
+
@version = RightScale::AgentConfig.protocol_version
|
52
|
+
@payload = {:agent_identity => @agent_id}
|
53
|
+
@target = nil
|
54
|
+
@token = "random token"
|
55
|
+
end
|
56
|
+
|
57
|
+
context :initialize do
|
58
|
+
it "initializes options" do
|
59
|
+
@options = {
|
60
|
+
:open_timeout => 1,
|
61
|
+
:request_timeout => 2,
|
62
|
+
:listen_timeout => 3,
|
63
|
+
:retry_timeout => 4,
|
64
|
+
:retry_intervals => [1, 2, 3],
|
65
|
+
:reconnect_interval => 5 }
|
66
|
+
@client = RightScale::ApiClient.new(@auth_client, @options)
|
67
|
+
options = @client.instance_variable_get(:@options)
|
68
|
+
options[:server_name] = "RightApi"
|
69
|
+
options[:api_version] = "1.5"
|
70
|
+
options[:open_timeout] = 1
|
71
|
+
options[:request_timeout] = 2
|
72
|
+
options[:retry_timeout] = 3
|
73
|
+
options[:retry_intervals] = [1, 2, 3]
|
74
|
+
options[:reconnect_interval] = 4
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context :push do
|
79
|
+
it "makes mapped request" do
|
80
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/audit_entries/111/append", {:detail => "details"},
|
81
|
+
"update_entry", @token, Hash).and_return(nil).once
|
82
|
+
@client.push("/auditor/update_entry", @payload.merge(:audit_id => 111, :detail => "details"), @target, @token).should be_nil
|
83
|
+
end
|
84
|
+
|
85
|
+
it "does not require token" do
|
86
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/audit_entries/111/append", {:detail => "details"},
|
87
|
+
"update_entry", nil, Hash).and_return(nil).once
|
88
|
+
@client.push("/auditor/update_entry", @payload.merge(:audit_id => 111, :detail => "details"), @target).should be_nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context :request do
|
93
|
+
it "makes mapped request" do
|
94
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/right_net/booter/declare", {:r_s_version => @version},
|
95
|
+
"declare", @token, Hash).and_return(nil).once
|
96
|
+
@client.push("/booter/declare", @payload.merge(:r_s_version => @version), @target, @token).should be_nil
|
97
|
+
end
|
98
|
+
|
99
|
+
it "maps query_tags request" do
|
100
|
+
flexmock(@client).should_receive(:map_query_tags).with(:post, {:tags => ["a:b=c"]}, "query_tags", @token, Hash).
|
101
|
+
and_return({}).once
|
102
|
+
@client.request("/router/query_tags", @payload.merge(:tags => ["a:b=c"]), @target, @token).should == {}
|
103
|
+
end
|
104
|
+
|
105
|
+
it "does not require token" do
|
106
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/right_net/booter/declare", {:r_s_version => @version},
|
107
|
+
"declare", nil, Hash).and_return(nil).once
|
108
|
+
@client.push("/booter/declare", @payload.merge(:r_s_version => @version), @target).should be_nil
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context :support? do
|
113
|
+
it "returns true if request type is supported" do
|
114
|
+
@client.support?("/booter/declare").should be_true
|
115
|
+
end
|
116
|
+
|
117
|
+
it "returns false if request type is not supported" do
|
118
|
+
@client.support?("/instance_scheduler/execute").should be_false
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
context :map_request do
|
123
|
+
it "raises if request type not supported" do
|
124
|
+
lambda { @client.send(:map_request, "/instance_scheduler/execute", @payload, @token) }.should \
|
125
|
+
raise_error(ArgumentError, "Unsupported request type: /instance_scheduler/execute")
|
126
|
+
end
|
127
|
+
|
128
|
+
it "makes request" do
|
129
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/right_net/booter/declare", {:r_s_version => @version},
|
130
|
+
"declare", @token, Hash).and_return(nil).once
|
131
|
+
@client.send(:map_request, "/booter/declare", @payload.merge(:r_s_version => @version), @token).should be_nil
|
132
|
+
end
|
133
|
+
|
134
|
+
it "returns mapped response" do
|
135
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/audit_entries",
|
136
|
+
{:audit_entry => {:auditee_href => @agent_href, :summary => "summary"}}, "create_entry", @token, Hash).
|
137
|
+
and_return("/api/audit_entries/111").once
|
138
|
+
@client.send(:map_request, "/auditor/create_entry", @payload.merge(:summary => "summary"), @token).should == "111"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context :map_response do
|
143
|
+
it "converts audit entry href in result to an audit ID" do
|
144
|
+
response = "/api/audit_entries/111"
|
145
|
+
@client.send(:map_response, response, "/audit_entries").should == "111"
|
146
|
+
end
|
147
|
+
|
148
|
+
it "converts tag query result to list of tags for resource" do
|
149
|
+
response = [
|
150
|
+
{ "actions" => [],
|
151
|
+
"links" => [{"rel" => "resource", "href" => "/api/clouds/6/instances/CUPVAL7KUP7TF"}],
|
152
|
+
"tags" => [{"name" => "rs_agent_dev:log_level=debug"},
|
153
|
+
{"name" => "rs_login:state=restricted"},
|
154
|
+
{"name" => "rs_monitoring:state=active"}] },
|
155
|
+
{ "actions" => [],
|
156
|
+
"links" => [{"rel" => "resource", "href" => "/api/servers/20"}],
|
157
|
+
"tags" => [{"name" => "server:ready=now"},
|
158
|
+
{"name" => "rs_agent_dev:log_level=debug"}] } ]
|
159
|
+
@client.send(:map_response, response, "/tags/by_resource").should ==
|
160
|
+
{ "/api/clouds/6/instances/CUPVAL7KUP7TF" => { "tags" => ["rs_agent_dev:log_level=debug",
|
161
|
+
"rs_login:state=restricted",
|
162
|
+
"rs_monitoring:state=active"] } }
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "query tags" do
|
167
|
+
before(:each) do
|
168
|
+
@action = "query_tags"
|
169
|
+
@options = {}
|
170
|
+
@tags = ["a:b=c"]
|
171
|
+
@hrefs = [@agent_href2]
|
172
|
+
@response = [
|
173
|
+
{ "actions" => [],
|
174
|
+
"links" => [{"rel" => "resource", "href" => @agent_href}],
|
175
|
+
"tags" => [{"name" => "a:b=c"}, {"name" => "x:y=z"}] } ]
|
176
|
+
end
|
177
|
+
|
178
|
+
context :map_query_tags do
|
179
|
+
it "retrieves resource hrefs for specified tags" do
|
180
|
+
params = {:tags => @tags}
|
181
|
+
params2 = params.merge(:match_all => false, :resource_type => "instances")
|
182
|
+
flexmock(@client).should_receive(:query_by_resource).never
|
183
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/tags/by_tag", params2, @action, @token, @options).and_return({}).once
|
184
|
+
@client.send(:map_query_tags, :post, params, @action, @token, @options).should == {}
|
185
|
+
end
|
186
|
+
|
187
|
+
it "appends retrieved hrefs to any specified resource hrefs" do
|
188
|
+
params = {:tags => @tags, :resource_hrefs => @hrefs}
|
189
|
+
params2 = {:resource_hrefs => [@agent_href2, @agent_href]}
|
190
|
+
flexmock(@client).should_receive(:query_by_tag).with(:post, @tags, @action, @token, @options).and_return([@agent_href]).once
|
191
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/tags/by_resource", params2, @action, @token, @options).and_return({}).once
|
192
|
+
@client.send(:map_query_tags, :post, params, @action, @token, @options).should == {}
|
193
|
+
end
|
194
|
+
|
195
|
+
it "queries for tags for each resource href" do
|
196
|
+
params = {:resource_hrefs => @hrefs}
|
197
|
+
flexmock(@client).should_receive(:query_by_tag).never
|
198
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/tags/by_resource", params, @action, @token, @options).and_return(@response).once
|
199
|
+
@client.send(:map_query_tags, :post, params, @action, @token, @options).should == {@agent_href => {"tags" => ["a:b=c", "x:y=z"]}}
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
context :query_by_tag do
|
204
|
+
before(:each) do
|
205
|
+
@params = {:tags => @tags}
|
206
|
+
@params2 = @params.merge(:match_all => false, :resource_type => "instances")
|
207
|
+
end
|
208
|
+
|
209
|
+
it "queries for tags using specified tags" do
|
210
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/tags/by_tag", @params2, @action, @token, @options).and_return({}).once
|
211
|
+
@client.send(:query_by_tag, :post, @tags, @action, @token, @options).should == []
|
212
|
+
end
|
213
|
+
|
214
|
+
it "maps response" do
|
215
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/tags/by_tag", @params2, @action, @token, @options).and_return(@response).once
|
216
|
+
@client.send(:query_by_tag, :post, @tags, @action, @token, @options).should == [@agent_href]
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context :query_by_resource do
|
221
|
+
before(:each) do
|
222
|
+
@params = {:resource_hrefs => @hrefs}
|
223
|
+
end
|
224
|
+
|
225
|
+
it "queries for tags using specified hrefs" do
|
226
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/tags/by_resource", @params, @action, @token, @options).and_return({}).once
|
227
|
+
@client.send(:query_by_resource, :post, @hrefs, @action, @token, @options).should == {}
|
228
|
+
end
|
229
|
+
|
230
|
+
it "maps response" do
|
231
|
+
flexmock(@client).should_receive(:make_request).with(:post, "/tags/by_resource", @params, @action, @token, @options).and_return(@response).once
|
232
|
+
@client.send(:query_by_resource, :post, @hrefs, @action, @token, @options).should == {@agent_href => {"tags" => ["a:b=c", "x:y=z"]}}
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context :parameterize do
|
238
|
+
|
239
|
+
context "for audits" do
|
240
|
+
before(:each) do
|
241
|
+
@path, @params, @options = @client.send(:parameterize, "auditor", "update_entry", @payload.merge(:audit_id => 111,
|
242
|
+
:detail => "details"), "/audit_entries/:id/append")
|
243
|
+
end
|
244
|
+
|
245
|
+
it "converts audit parameters" do
|
246
|
+
@params.should == {:detail => "details"}
|
247
|
+
end
|
248
|
+
|
249
|
+
it "substitutes audit ID into path" do
|
250
|
+
@path.should == "/audit_entries/111/append"
|
251
|
+
end
|
252
|
+
|
253
|
+
it "adds parameter filter to options" do
|
254
|
+
@options.should == {:filter_params => ["detail", "text"]}
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
context "for tags" do
|
259
|
+
before(:each) do
|
260
|
+
tags = ["a:b=c", nil, [nil, "x:y=z"]]
|
261
|
+
@path, @params, @options = @client.send(:parameterize, "router", "add_tags", @payload.merge(:tags => tags),
|
262
|
+
"/tags/multi_add")
|
263
|
+
end
|
264
|
+
|
265
|
+
it "adds default resource href to parameters" do
|
266
|
+
@params[:resource_hrefs].should == [@agent_href]
|
267
|
+
end
|
268
|
+
|
269
|
+
it "adds specified resource hrefs to parameters" do
|
270
|
+
hrefs = [@agent_href, @agent_href2]
|
271
|
+
_, @params, _ = @client.send(:parameterize, "router", "query_tags", @payload.merge(:hrefs => hrefs),
|
272
|
+
"/tags/by_resource")
|
273
|
+
@params[:resource_hrefs].should == hrefs
|
274
|
+
end
|
275
|
+
|
276
|
+
it "ensures that tags parameter is properly formed" do
|
277
|
+
@params[:tags].should == ["a:b=c", "x:y=z"]
|
278
|
+
end
|
279
|
+
|
280
|
+
it "does not add tags if not present" do
|
281
|
+
_, @params, _ = @client.send(:parameterize, "router", "query_tags", @payload, "/tags/multi_add")
|
282
|
+
@params.should_not have_key(:tags)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
context "otherwise" do
|
287
|
+
before(:each) do
|
288
|
+
@path, @params, @options = @client.send(:parameterize, "booter", "declare", @payload.merge(:r_s_version => @version),
|
289
|
+
"/right_net/booter/declare")
|
290
|
+
end
|
291
|
+
|
292
|
+
it "removes :agent_identity parameter" do
|
293
|
+
@params[:agent_identity].should be_nil
|
294
|
+
end
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
context :parameterize_audit do
|
299
|
+
|
300
|
+
context "create_entry" do
|
301
|
+
it "stores instance href" do
|
302
|
+
@client.send(:parameterize_audit, "create_entry", @payload)[:audit_entry][:auditee_href].should == @agent_href
|
303
|
+
end
|
304
|
+
|
305
|
+
context "summary" do
|
306
|
+
it "stores summary if non-blank" do
|
307
|
+
@client.send(:parameterize_audit, "create_entry", :summary => "hello")[:audit_entry][:summary].should == "hello"
|
308
|
+
@client.send(:parameterize_audit, "create_entry", :summary => "")[:audit_entry].should_not have_key(:summary)
|
309
|
+
@client.send(:parameterize_audit, "create_entry", {})[:audit_entry].should_not have_key(:summary)
|
310
|
+
end
|
311
|
+
|
312
|
+
it "truncates summary if too long" do
|
313
|
+
@client.send(:parameterize_audit, "create_entry", :summary => "hello " * 50)[:audit_entry][:summary].size.should == 255
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
it "stores detail if non-blank" do
|
318
|
+
@client.send(:parameterize_audit, "create_entry", :detail => "details")[:audit_entry][:detail].should == "details"
|
319
|
+
@client.send(:parameterize_audit, "create_entry", :detail => "")[:audit_entry].should_not have_key(:detail)
|
320
|
+
@client.send(:parameterize_audit, "create_entry", {})[:audit_entry].should_not have_key(:detail)
|
321
|
+
end
|
322
|
+
|
323
|
+
it "stores user email if non-blank" do
|
324
|
+
@client.send(:parameterize_audit, "create_entry", :user_email => "email")[:user_email].should == "email"
|
325
|
+
@client.send(:parameterize_audit, "create_entry", :user_email => "").should_not have_key(:user_email)
|
326
|
+
@client.send(:parameterize_audit, "create_entry", {}).should_not have_key(:user_email)
|
327
|
+
end
|
328
|
+
|
329
|
+
it "stores notify category if present" do
|
330
|
+
@client.send(:parameterize_audit, "create_entry", :category => "Notification")[:notify].should == "Notification"
|
331
|
+
@client.send(:parameterize_audit, "create_entry", {}).should_not have_key(:notify)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
context "update_entry" do
|
336
|
+
it "stores offset if present" do
|
337
|
+
@client.send(:parameterize_audit, "update_entry", :offset => 100)[:offset].should == 100
|
338
|
+
@client.send(:parameterize_audit, "update_entry", {}).should_not have_key(:offset)
|
339
|
+
end
|
340
|
+
|
341
|
+
context "summary" do
|
342
|
+
it "stores summary if non-blank" do
|
343
|
+
@client.send(:parameterize_audit, "update_entry", :summary => "hello")[:summary].should == "hello"
|
344
|
+
@client.send(:parameterize_audit, "update_entry", :summary => "").should_not have_key(:summary)
|
345
|
+
@client.send(:parameterize_audit, "update_entry", {}).should_not have_key(:summary)
|
346
|
+
end
|
347
|
+
|
348
|
+
it "truncates summary if too long" do
|
349
|
+
@client.send(:parameterize_audit, "update_entry", :summary => "hello " * 50)[:summary].size.should == 255
|
350
|
+
end
|
351
|
+
|
352
|
+
it "stores notify category if present and summary is non-blank" do
|
353
|
+
@client.send(:parameterize_audit, "update_entry", :summary => "hello", :category => "Notification")[:notify].should == "Notification"
|
354
|
+
@client.send(:parameterize_audit, "update_entry", :category => "Notification").should_not have_key(:notify)
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
it "stores detail if non-blank" do
|
359
|
+
@client.send(:parameterize_audit, "update_entry", :detail => "details")[:detail].should == "details"
|
360
|
+
@client.send(:parameterize_audit, "update_entry", :detail => "").should_not have_key(:detail)
|
361
|
+
@client.send(:parameterize_audit, "update_entry", {}).should_not have_key(:detail)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
context "otherwise" do
|
366
|
+
it "raises unknown audit" do
|
367
|
+
lambda { @client.send(:parameterize_audit, "bogus", {}) }.should raise_error(ArgumentError)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
context :truncate do
|
373
|
+
it "returns non-string as is" do
|
374
|
+
@client.send(:truncate, nil, 5).should == nil
|
375
|
+
end
|
376
|
+
|
377
|
+
it "returns strings shorter than limit as is" do
|
378
|
+
@client.send(:truncate, "hello", 5).should == "hello"
|
379
|
+
end
|
380
|
+
|
381
|
+
it "requires max length to be greater than 3" do
|
382
|
+
@client.send(:truncate, "hello", 4).should == "h..."
|
383
|
+
lambda { @client.send(:truncate, "hello", 3) }.should raise_error(ArgumentError)
|
384
|
+
end
|
385
|
+
|
386
|
+
it "truncates strings that are too long" do
|
387
|
+
@client.send(:truncate, "how you doing", 10).bytesize.should == 10
|
388
|
+
end
|
389
|
+
|
390
|
+
it "ends truncated string with an ellipsis" do
|
391
|
+
@client.send(:truncate, "how you doing", 10).should == "how you..."
|
392
|
+
end
|
393
|
+
|
394
|
+
it "accounts for multi-byte characters" do
|
395
|
+
@client.send(:truncate, "Schös Tägli wünschi", 20).should == "Schös Tägli wü..."
|
396
|
+
@client.send(:truncate, "Schös Tägli wünschi", 19).should == "Schös Tägli w..."
|
397
|
+
@client.send(:truncate, "Schös Tägli wünschi", 18).should == "Schös Tägli w..."
|
398
|
+
@client.send(:truncate, "Schös Tägli wünschi", 17).should == "Schös Tägli ..."
|
399
|
+
end
|
400
|
+
end
|
401
|
+
|
402
|
+
context :non_blank do
|
403
|
+
it "returns nil if value nil" do
|
404
|
+
@client.send(:non_blank, nil).should be_nil
|
405
|
+
end
|
406
|
+
|
407
|
+
it "returns nil if value is empty" do
|
408
|
+
@client.send(:non_blank, "").should be_nil
|
409
|
+
end
|
410
|
+
|
411
|
+
it "returns nil if value nil" do
|
412
|
+
@client.send(:non_blank, "hello").should == "hello"
|
413
|
+
end
|
414
|
+
end
|
415
|
+
|
416
|
+
context :enable_use do
|
417
|
+
it "makes API request to get links for setting instance href" do
|
418
|
+
flexmock(@client).should_receive(:make_request).with(:get, "/sessions/instance", {}, "instance").and_return(@links).once
|
419
|
+
@client.instance_variable_get(:@self_href).should == @agent_href
|
420
|
+
@client.send(:enable_use).should be_true
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|