startapp 0.1.6
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.
- checksums.yaml +7 -0
- data/COPYRIGHT +1 -0
- data/LICENSE +11 -0
- data/README.md +95 -0
- data/Rakefile +6 -0
- data/autocomplete/rhc_bash +1672 -0
- data/bin/app +37 -0
- data/conf/express.conf +8 -0
- data/features/assets/deploy.tar.gz +0 -0
- data/features/core_feature.rb +191 -0
- data/features/deployments_feature.rb +129 -0
- data/features/domains_feature.rb +58 -0
- data/features/keys_feature.rb +37 -0
- data/features/members_feature.rb +166 -0
- data/lib/rhc/auth/basic.rb +64 -0
- data/lib/rhc/auth/token.rb +102 -0
- data/lib/rhc/auth/token_store.rb +53 -0
- data/lib/rhc/auth.rb +5 -0
- data/lib/rhc/autocomplete.rb +66 -0
- data/lib/rhc/autocomplete_templates/bash.erb +39 -0
- data/lib/rhc/cartridge_helpers.rb +118 -0
- data/lib/rhc/cli.rb +40 -0
- data/lib/rhc/command_runner.rb +185 -0
- data/lib/rhc/commands/account.rb +25 -0
- data/lib/rhc/commands/alias.rb +124 -0
- data/lib/rhc/commands/app.rb +726 -0
- data/lib/rhc/commands/apps.rb +20 -0
- data/lib/rhc/commands/authorization.rb +115 -0
- data/lib/rhc/commands/base.rb +174 -0
- data/lib/rhc/commands/cartridge.rb +329 -0
- data/lib/rhc/commands/clone.rb +66 -0
- data/lib/rhc/commands/configure.rb +20 -0
- data/lib/rhc/commands/create.rb +100 -0
- data/lib/rhc/commands/delete.rb +19 -0
- data/lib/rhc/commands/deploy.rb +32 -0
- data/lib/rhc/commands/deployment.rb +82 -0
- data/lib/rhc/commands/domain.rb +172 -0
- data/lib/rhc/commands/env.rb +142 -0
- data/lib/rhc/commands/force_stop.rb +17 -0
- data/lib/rhc/commands/git_clone.rb +34 -0
- data/lib/rhc/commands/logout.rb +51 -0
- data/lib/rhc/commands/logs.rb +21 -0
- data/lib/rhc/commands/member.rb +148 -0
- data/lib/rhc/commands/port_forward.rb +197 -0
- data/lib/rhc/commands/reload.rb +17 -0
- data/lib/rhc/commands/restart.rb +17 -0
- data/lib/rhc/commands/scp.rb +54 -0
- data/lib/rhc/commands/server.rb +40 -0
- data/lib/rhc/commands/setup.rb +60 -0
- data/lib/rhc/commands/show.rb +43 -0
- data/lib/rhc/commands/snapshot.rb +137 -0
- data/lib/rhc/commands/ssh.rb +51 -0
- data/lib/rhc/commands/sshkey.rb +97 -0
- data/lib/rhc/commands/start.rb +17 -0
- data/lib/rhc/commands/stop.rb +17 -0
- data/lib/rhc/commands/tail.rb +47 -0
- data/lib/rhc/commands/threaddump.rb +14 -0
- data/lib/rhc/commands/tidy.rb +17 -0
- data/lib/rhc/commands.rb +396 -0
- data/lib/rhc/config.rb +321 -0
- data/lib/rhc/context_helper.rb +121 -0
- data/lib/rhc/core_ext.rb +202 -0
- data/lib/rhc/coverage_helper.rb +33 -0
- data/lib/rhc/deployment_helpers.rb +111 -0
- data/lib/rhc/exceptions.rb +256 -0
- data/lib/rhc/git_helpers.rb +106 -0
- data/lib/rhc/help_formatter.rb +55 -0
- data/lib/rhc/helpers.rb +481 -0
- data/lib/rhc/highline_extensions.rb +479 -0
- data/lib/rhc/json.rb +51 -0
- data/lib/rhc/output_helpers.rb +260 -0
- data/lib/rhc/rest/activation.rb +11 -0
- data/lib/rhc/rest/alias.rb +42 -0
- data/lib/rhc/rest/api.rb +87 -0
- data/lib/rhc/rest/application.rb +348 -0
- data/lib/rhc/rest/attributes.rb +36 -0
- data/lib/rhc/rest/authorization.rb +8 -0
- data/lib/rhc/rest/base.rb +79 -0
- data/lib/rhc/rest/cartridge.rb +162 -0
- data/lib/rhc/rest/client.rb +650 -0
- data/lib/rhc/rest/deployment.rb +18 -0
- data/lib/rhc/rest/domain.rb +98 -0
- data/lib/rhc/rest/environment_variable.rb +15 -0
- data/lib/rhc/rest/gear_group.rb +16 -0
- data/lib/rhc/rest/httpclient.rb +145 -0
- data/lib/rhc/rest/key.rb +44 -0
- data/lib/rhc/rest/membership.rb +105 -0
- data/lib/rhc/rest/mock.rb +1042 -0
- data/lib/rhc/rest/user.rb +32 -0
- data/lib/rhc/rest.rb +148 -0
- data/lib/rhc/scp_helpers.rb +27 -0
- data/lib/rhc/ssh_helpers.rb +380 -0
- data/lib/rhc/tar_gz.rb +51 -0
- data/lib/rhc/usage_templates/command_help.erb +51 -0
- data/lib/rhc/usage_templates/command_syntax_help.erb +11 -0
- data/lib/rhc/usage_templates/help.erb +61 -0
- data/lib/rhc/usage_templates/missing_help.erb +1 -0
- data/lib/rhc/usage_templates/options_help.erb +12 -0
- data/lib/rhc/vendor/okjson.rb +600 -0
- data/lib/rhc/vendor/parseconfig.rb +178 -0
- data/lib/rhc/vendor/sshkey.rb +253 -0
- data/lib/rhc/vendor/zliby.rb +628 -0
- data/lib/rhc/version.rb +5 -0
- data/lib/rhc/wizard.rb +637 -0
- data/lib/rhc.rb +34 -0
- data/spec/coverage_helper.rb +82 -0
- data/spec/direct_execution_helper.rb +339 -0
- data/spec/keys/example.pem +23 -0
- data/spec/keys/example_private.pem +27 -0
- data/spec/keys/server.pem +19 -0
- data/spec/rest_spec_helper.rb +31 -0
- data/spec/rhc/assets/cert.crt +22 -0
- data/spec/rhc/assets/cert_key_rsa +27 -0
- data/spec/rhc/assets/empty.txt +0 -0
- data/spec/rhc/assets/env_vars.txt +7 -0
- data/spec/rhc/assets/env_vars_2.txt +1 -0
- data/spec/rhc/assets/foo.txt +1 -0
- data/spec/rhc/assets/targz_corrupted.tar.gz +1 -0
- data/spec/rhc/assets/targz_sample.tar.gz +0 -0
- data/spec/rhc/auth_spec.rb +442 -0
- data/spec/rhc/cli_spec.rb +186 -0
- data/spec/rhc/command_spec.rb +435 -0
- data/spec/rhc/commands/account_spec.rb +42 -0
- data/spec/rhc/commands/alias_spec.rb +333 -0
- data/spec/rhc/commands/app_spec.rb +777 -0
- data/spec/rhc/commands/apps_spec.rb +39 -0
- data/spec/rhc/commands/authorization_spec.rb +157 -0
- data/spec/rhc/commands/cartridge_spec.rb +665 -0
- data/spec/rhc/commands/clone_spec.rb +41 -0
- data/spec/rhc/commands/deployment_spec.rb +327 -0
- data/spec/rhc/commands/domain_spec.rb +401 -0
- data/spec/rhc/commands/env_spec.rb +493 -0
- data/spec/rhc/commands/git_clone_spec.rb +102 -0
- data/spec/rhc/commands/logout_spec.rb +86 -0
- data/spec/rhc/commands/member_spec.rb +247 -0
- data/spec/rhc/commands/port_forward_spec.rb +217 -0
- data/spec/rhc/commands/scp_spec.rb +77 -0
- data/spec/rhc/commands/server_spec.rb +69 -0
- data/spec/rhc/commands/setup_spec.rb +118 -0
- data/spec/rhc/commands/snapshot_spec.rb +179 -0
- data/spec/rhc/commands/ssh_spec.rb +163 -0
- data/spec/rhc/commands/sshkey_spec.rb +188 -0
- data/spec/rhc/commands/tail_spec.rb +81 -0
- data/spec/rhc/commands/threaddump_spec.rb +84 -0
- data/spec/rhc/config_spec.rb +407 -0
- data/spec/rhc/helpers_spec.rb +531 -0
- data/spec/rhc/highline_extensions_spec.rb +314 -0
- data/spec/rhc/json_spec.rb +30 -0
- data/spec/rhc/rest_application_spec.rb +258 -0
- data/spec/rhc/rest_client_spec.rb +752 -0
- data/spec/rhc/rest_spec.rb +740 -0
- data/spec/rhc/targz_spec.rb +55 -0
- data/spec/rhc/wizard_spec.rb +756 -0
- data/spec/spec_helper.rb +575 -0
- data/spec/wizard_spec_helper.rb +330 -0
- metadata +469 -0
|
@@ -0,0 +1,740 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rest_spec_helper'
|
|
3
|
+
require 'rhc/rest'
|
|
4
|
+
|
|
5
|
+
module MockRestResponse
|
|
6
|
+
attr_accessor :code, :read
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
describe RHC::Rest::Cartridge do
|
|
11
|
+
context 'with a name' do
|
|
12
|
+
before{ subject.name = 'foo' }
|
|
13
|
+
its(:display_name){ should == 'foo' }
|
|
14
|
+
|
|
15
|
+
context 'when display name is present' do
|
|
16
|
+
before{ subject.display_name = 'bar' }
|
|
17
|
+
its(:display_name){ should == 'bar' }
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe RHC::Rest::Domain do
|
|
23
|
+
subject{ RHC::Rest::Client.new(:server => mock_uri) }
|
|
24
|
+
let(:user_auth){ nil }
|
|
25
|
+
let(:domain) { subject.domains.first }
|
|
26
|
+
context "against a 1.2 server" do
|
|
27
|
+
before{ stub_api_v12; stub_one_domain('bar') }
|
|
28
|
+
before do
|
|
29
|
+
stub_api_request(:post, 'broker/rest/domains/bar/applications', false).
|
|
30
|
+
with(:body => {:name => 'foo', :cartridge => 'bar'}.to_json).
|
|
31
|
+
to_return(:status => 201, :body => {:type => 'application', :data => {:id => '1'}}.to_json)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
it{ domain.add_application('foo', :cartridges => ['bar']).should be_true }
|
|
35
|
+
it{ expect{ domain.add_application('foo', :cartridges => ['bar', 'other']) }.to raise_error(RHC::Rest::MultipleCartridgeCreationNotSupported) }
|
|
36
|
+
it{ expect{ domain.add_application('foo', :initial_git_url => 'a_url') }.to raise_error(RHC::Rest::InitialGitUrlNotSupported) }
|
|
37
|
+
it{ expect{ domain.add_application('foo', :cartridges => [{:url => 'a_url'}]) }.to raise_error(RHC::Rest::DownloadingCartridgesNotSupported) }
|
|
38
|
+
it{ domain.add_application('foo', :cartridges => 'bar').should be_true }
|
|
39
|
+
it{ domain.add_application('foo', :cartridge => 'bar').should be_true }
|
|
40
|
+
it{ domain.add_application('foo', :cartridge => ['bar']).should be_true }
|
|
41
|
+
end
|
|
42
|
+
context "against a server that supports initial git urls and downloaded carts" do
|
|
43
|
+
let(:cartridges){ ['bar'] }
|
|
44
|
+
before{ stub_api; stub_one_domain('bar', [{:name => 'initial_git_url'},{:name => 'cartridges[][url]'}]) }
|
|
45
|
+
before do
|
|
46
|
+
stub_api_request(:post, 'broker/rest/domains/bar/applications', false).
|
|
47
|
+
with(:body => {:name => 'foo', :cartridges => cartridges}.to_json).
|
|
48
|
+
to_return(:status => 201, :body => {:type => 'application', :data => {:id => '1'}}.to_json)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it{ domain.add_application('foo', :cartridges => ['bar']).should be_true }
|
|
52
|
+
it{ domain.add_application('foo', :cartridges => 'bar').should be_true }
|
|
53
|
+
it{ domain.add_application('foo', :cartridge => 'bar').should be_true }
|
|
54
|
+
it{ domain.add_application('foo', :cartridge => ['bar']).should be_true }
|
|
55
|
+
|
|
56
|
+
context "with multiple cartridges" do
|
|
57
|
+
let(:cartridges){ ['bar'] }
|
|
58
|
+
it{ domain.add_application('foo', :cartridges => cartridges).should be_true }
|
|
59
|
+
it{ domain.add_application('foo', :cartridge => cartridges).should be_true }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context "with a url" do
|
|
63
|
+
before do
|
|
64
|
+
stub_api_request(:post, 'broker/rest/domains/bar/applications', false).
|
|
65
|
+
with(:body => {:name => 'foo', :initial_git_url => 'a_url', :cartridges => []}.to_json).
|
|
66
|
+
to_return(:status => 201, :body => {:type => 'application', :data => {:id => '1'}}.to_json)
|
|
67
|
+
end
|
|
68
|
+
it{ domain.add_application('foo', :initial_git_url => 'a_url').should be_true }
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
context "with a cartridge url" do
|
|
72
|
+
before do
|
|
73
|
+
stub_api_request(:post, 'broker/rest/domains/bar/applications', false).
|
|
74
|
+
with(:body => {:name => 'foo', :cartridges => [{:url => 'a_url'}]}.to_json).
|
|
75
|
+
to_return(:status => 201, :body => {:type => 'application', :data => {:id => '1'}}.to_json)
|
|
76
|
+
end
|
|
77
|
+
it{ domain.add_application('foo', :cartridges => [{:url => 'a_url'}]).should be_true }
|
|
78
|
+
it{ domain.add_application('foo', :cartridge => RHC::Rest::Cartridge.for_url('a_url')).should be_true }
|
|
79
|
+
it{ domain.add_application('foo', :cartridge => [{'url' => 'a_url'}]).should be_true }
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
module RHC
|
|
85
|
+
|
|
86
|
+
describe Rest do
|
|
87
|
+
subject{ RHC::Rest::Client.new }
|
|
88
|
+
|
|
89
|
+
describe "#default_verify_callback" do
|
|
90
|
+
def invoked_with(is_ok, ctx)
|
|
91
|
+
subject.send(:default_verify_callback).call(is_ok, ctx)
|
|
92
|
+
end
|
|
93
|
+
it{ invoked_with(true, nil).should be_true }
|
|
94
|
+
|
|
95
|
+
it{ expect{ invoked_with(false, nil) }.to raise_error(NoMethodError) }
|
|
96
|
+
|
|
97
|
+
context "with a self signed cert" do
|
|
98
|
+
it{ invoked_with(false, double(:current_cert => double(:issuer => '1', :subject => double(:cmp => 0)))).should be_false }
|
|
99
|
+
after{ subject.send(:self_signed?).should be_true }
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
context "with an intermediate signed cert" do
|
|
103
|
+
it{ invoked_with(false, double(:current_cert => double(:issuer => '2', :subject => double(:cmp => 1)), :error => 1, :error_string => 'a')).should be_false }
|
|
104
|
+
after{ subject.send(:self_signed?).should be_false }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# parse_response function
|
|
110
|
+
describe "#parse_response" do
|
|
111
|
+
context "with no response type" do
|
|
112
|
+
let(:object) {{ :links => { :foo => 'bar' } }}
|
|
113
|
+
it "deserializes to the encapsulated data" do
|
|
114
|
+
json_response = { :data => object }.to_json
|
|
115
|
+
subject.send(:parse_response, json_response).should have_same_attributes_as(object)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
context "with an application" do
|
|
120
|
+
let(:object) {{
|
|
121
|
+
:domain_id => 'test_domain',
|
|
122
|
+
:name => 'test_app',
|
|
123
|
+
:creation_time => '0000-00-00 00:00:00 -0000',
|
|
124
|
+
:uuid => 'test_app_1234',
|
|
125
|
+
:aliases => ['app_alias_1', 'app_alias_2'],
|
|
126
|
+
:server_identity => 'test_server',
|
|
127
|
+
:links => { :foo => 'bar' }
|
|
128
|
+
}}
|
|
129
|
+
it "deserializes to an application" do
|
|
130
|
+
json_response = { :type => 'application', :data => object, :messages => [{'text' => 'test message'}]}.to_json
|
|
131
|
+
app_obj = RHC::Rest::Application.new(object)
|
|
132
|
+
subject.send(:parse_response, json_response).should have_same_attributes_as(app_obj)
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context "with two applications" do
|
|
137
|
+
let(:object) {[{ :domain_id => 'test_domain',
|
|
138
|
+
:name => 'test_app',
|
|
139
|
+
:creation_time => '0000-00-00 00:00:00 -0000',
|
|
140
|
+
:uuid => 'test_app_1234',
|
|
141
|
+
:aliases => ['app_alias_1', 'app_alias_2'],
|
|
142
|
+
:server_identity => 'test_server',
|
|
143
|
+
:links => { :foo => 'bar' }
|
|
144
|
+
},
|
|
145
|
+
{ :domain_id => 'test_domain_2',
|
|
146
|
+
:name => 'test_app_2',
|
|
147
|
+
:creation_time => '0000-00-00 00:00:00 -0000',
|
|
148
|
+
:uuid => 'test_app_2_1234',
|
|
149
|
+
:aliases => ['app_alias_3', 'app_alias_4'],
|
|
150
|
+
:server_identity => 'test_server_2',
|
|
151
|
+
:links => { :foo => 'bar' }
|
|
152
|
+
}]
|
|
153
|
+
}
|
|
154
|
+
it "deserializes to a list of applications" do
|
|
155
|
+
json_response = { :type => 'applications', :data => object }.to_json
|
|
156
|
+
app_obj_1 = RHC::Rest::Application.new(object[0])
|
|
157
|
+
app_obj_2 = RHC::Rest::Application.new(object[1])
|
|
158
|
+
subject.send(:parse_response, json_response).length.should equal(2)
|
|
159
|
+
subject.send(:parse_response, json_response)[0].should have_same_attributes_as(app_obj_1)
|
|
160
|
+
subject.send(:parse_response, json_response)[1].should have_same_attributes_as(app_obj_2)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
context "with a cartridge" do
|
|
165
|
+
let(:object) {{
|
|
166
|
+
:name => 'test_cartridge',
|
|
167
|
+
:type => 'test_cartridge_type',
|
|
168
|
+
:links => { :foo => 'bar' }
|
|
169
|
+
}}
|
|
170
|
+
|
|
171
|
+
it "deserializes to a cartridge" do
|
|
172
|
+
json_response = { :type => 'cartridge', :data => object }.to_json
|
|
173
|
+
cart_obj = RHC::Rest::Cartridge.new(object)
|
|
174
|
+
subject.send(:parse_response, json_response).should have_same_attributes_as(cart_obj)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
context "with two cartridges" do
|
|
179
|
+
let(:object) {[{ :name => 'test_cartridge',
|
|
180
|
+
:type => 'test_cartridge_type',
|
|
181
|
+
:links => { :foo => 'bar' }
|
|
182
|
+
},
|
|
183
|
+
{ :name => 'test_cartridge_2',
|
|
184
|
+
:type => 'test_cartridge_type_2',
|
|
185
|
+
:links => { :foo => 'bar' }
|
|
186
|
+
}
|
|
187
|
+
]}
|
|
188
|
+
|
|
189
|
+
it "deserializes to a list of cartridges" do
|
|
190
|
+
json_response = { :type => 'cartridges', :data => object }.to_json
|
|
191
|
+
cart_obj_1 = RHC::Rest::Cartridge.new(object[0])
|
|
192
|
+
cart_obj_2 = RHC::Rest::Cartridge.new(object[1])
|
|
193
|
+
subject.send(:parse_response, json_response).length.should equal(2)
|
|
194
|
+
subject.send(:parse_response, json_response)[0].should have_same_attributes_as(cart_obj_1)
|
|
195
|
+
subject.send(:parse_response, json_response)[1].should have_same_attributes_as(cart_obj_2)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
context "with a domain" do
|
|
200
|
+
let(:object) {{
|
|
201
|
+
:id => 'test_domain',
|
|
202
|
+
:links => { :foo => 'bar' }
|
|
203
|
+
}}
|
|
204
|
+
|
|
205
|
+
it "deserializes to a domain" do
|
|
206
|
+
json_response = { :type => 'domain', :data => object }.to_json
|
|
207
|
+
dom_obj = RHC::Rest::Domain.new(object)
|
|
208
|
+
subject.send(:parse_response, json_response).should have_same_attributes_as(dom_obj)
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
context "with two domains" do
|
|
213
|
+
let(:object) {[{ :id => 'test_domain',
|
|
214
|
+
:links => { :foo => 'bar' }
|
|
215
|
+
},
|
|
216
|
+
{ :id => 'test_domain_2',
|
|
217
|
+
:links => { :foo => 'bar' }
|
|
218
|
+
}
|
|
219
|
+
]}
|
|
220
|
+
|
|
221
|
+
it "deserializes to a list of domains" do
|
|
222
|
+
json_response = { :type => 'domains', :data => object }.to_json
|
|
223
|
+
dom_obj_1 = RHC::Rest::Domain.new(object[0])
|
|
224
|
+
dom_obj_2 = RHC::Rest::Domain.new(object[1])
|
|
225
|
+
subject.send(:parse_response, json_response).length.should equal(2)
|
|
226
|
+
subject.send(:parse_response, json_response)[0].should have_same_attributes_as(dom_obj_1)
|
|
227
|
+
subject.send(:parse_response, json_response)[1].should have_same_attributes_as(dom_obj_2)
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
context "with a key" do
|
|
232
|
+
let(:object) {{
|
|
233
|
+
:name => 'test_key',
|
|
234
|
+
:type => 'test_key_type',
|
|
235
|
+
:content => 'test_key_content',
|
|
236
|
+
:links => { :foo => 'bar' }
|
|
237
|
+
}}
|
|
238
|
+
|
|
239
|
+
it "deserializes to a key" do
|
|
240
|
+
json_response = { :type => 'key', :data => object }.to_json
|
|
241
|
+
key_obj = RHC::Rest::Key.new(object)
|
|
242
|
+
subject.send(:parse_response, json_response).should have_same_attributes_as(key_obj)
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
context "with two keys" do
|
|
247
|
+
let(:object) {[{ :name => 'test_key',
|
|
248
|
+
:type => 'test_key_type',
|
|
249
|
+
:content => 'test_key_content',
|
|
250
|
+
:links => { :foo => 'bar' }
|
|
251
|
+
},
|
|
252
|
+
{ :name => 'test_key_2',
|
|
253
|
+
:type => 'test_key_type_2',
|
|
254
|
+
:content => 'test_key_content_2',
|
|
255
|
+
:links => { :foo => 'bar' }
|
|
256
|
+
}
|
|
257
|
+
]}
|
|
258
|
+
|
|
259
|
+
it "deserializes to a list of keys" do
|
|
260
|
+
json_response = { :type => 'keys', :data => object }.to_json
|
|
261
|
+
key_obj_1 = RHC::Rest::Key.new(object[0])
|
|
262
|
+
key_obj_2 = RHC::Rest::Key.new(object[1])
|
|
263
|
+
subject.send(:parse_response, json_response).length.should equal(2)
|
|
264
|
+
subject.send(:parse_response, json_response)[0].should have_same_attributes_as(key_obj_1)
|
|
265
|
+
subject.send(:parse_response, json_response)[1].should have_same_attributes_as(key_obj_2)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
context "with a user" do
|
|
270
|
+
let(:object) {{
|
|
271
|
+
:login => 'test_user',
|
|
272
|
+
:links => { :foo => 'bar' }
|
|
273
|
+
}}
|
|
274
|
+
|
|
275
|
+
it "deserializes to a user" do
|
|
276
|
+
json_response = { :type => 'user', :data => object }.to_json
|
|
277
|
+
user_obj = RHC::Rest::User.new(object)
|
|
278
|
+
subject.send(:parse_response, json_response).should have_same_attributes_as(user_obj)
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
context "with result messages" do
|
|
283
|
+
let(:object) do
|
|
284
|
+
{
|
|
285
|
+
:login => 'test_user',
|
|
286
|
+
:links => { :foo => 'bar' }
|
|
287
|
+
}
|
|
288
|
+
end
|
|
289
|
+
let(:messages) do
|
|
290
|
+
[
|
|
291
|
+
{:field => nil, :severity => 'info', :text => 'Nil field'},
|
|
292
|
+
{:field => 'result', :severity => 'info', :text => 'Result field'}, # < 1.5 API
|
|
293
|
+
{:field => 'base', :severity => 'result', :text => 'Result severity'}, # >= 1.5 API
|
|
294
|
+
{:field => 'base', :severity => 'info', :text => 'Non-result message' },
|
|
295
|
+
{:field => 'result', :severity => 'debug', :text => 'Debug message' },
|
|
296
|
+
{:field => 'base', :severity => 'warning', :text => 'Warning message' },
|
|
297
|
+
]
|
|
298
|
+
end
|
|
299
|
+
let(:response) do
|
|
300
|
+
{ :type => 'user', :data => object, :messages => messages }.to_json
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
it "copies all non-warning and non-info messages to the object" do
|
|
304
|
+
subject.stub(:debug?).and_return(false)
|
|
305
|
+
subject.send(:parse_response, response).messages.should == ['Result field', 'Result severity']
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it "includes debug and info when debug true" do
|
|
309
|
+
subject.stub(:debug?).and_return(true)
|
|
310
|
+
subject.send(:parse_response, response).messages.should == ['Nil field', 'Result field', 'Result severity', 'Non-result message', 'Debug message']
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
describe "#new_request" do
|
|
316
|
+
it{ subject.send(:new_request, :api_version => 2.0).last[4]['accept'].should == 'application/json;version=2.0' }
|
|
317
|
+
it{ subject.send(:new_request, :headers => {:accept => :xml}, :api_version => 2.0).last[4]['accept'].should == 'application/xml;version=2.0' }
|
|
318
|
+
context "with the default api version" do
|
|
319
|
+
before{ subject.should_receive(:current_api_version).and_return('1.0') }
|
|
320
|
+
it{ subject.send(:new_request, {}).last[4]['accept'].should == 'application/json;version=1.0' }
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# request function
|
|
325
|
+
describe "#request" do
|
|
326
|
+
let(:response){ lambda { subject.request(request) } }
|
|
327
|
+
let(:request){ {:url => mock_href, :method => method, :headers => {:accept => :json} } }
|
|
328
|
+
let(:method){ :get }
|
|
329
|
+
|
|
330
|
+
if HTTPClient::SSLConfig.method_defined? :ssl_version
|
|
331
|
+
context "when an invalid ssl version is passed, OpenSSL should reject us" do
|
|
332
|
+
let(:request){ {:url => "https://openshift.redhat.com", :method => :get, :ssl_version => :SSLv3_server} }
|
|
333
|
+
before{ WebMock.allow_net_connect! }
|
|
334
|
+
it("fails to call openssl"){ response.should raise_error(RHC::Rest::SSLConnectionFailed, /called a function you should not call/) }
|
|
335
|
+
after{ WebMock.disable_net_connect! }
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
context "with a successful request" do
|
|
340
|
+
let(:object) {{
|
|
341
|
+
:type => 'domain',
|
|
342
|
+
:data => {
|
|
343
|
+
:id => 'test_domain',
|
|
344
|
+
:links => { :foo => 'bar' }
|
|
345
|
+
}}}
|
|
346
|
+
before do
|
|
347
|
+
return_data = {
|
|
348
|
+
:body => object.to_json,
|
|
349
|
+
:status => 200,
|
|
350
|
+
:headers => { 'Set-Cookie' => "rh_sso=test_ssh_cookie" }
|
|
351
|
+
}
|
|
352
|
+
stub_request(:get, mock_href).with{ |req| req.headers['Accept'].should == 'application/json;version=1.0' }.to_return(return_data)
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it "sends the response to be deserialized" do
|
|
356
|
+
dom_obj = RHC::Rest::Domain.new(object)
|
|
357
|
+
subject.request(request.merge(:payload => {}, :api_version => '1.0', :timeout => 300)).should have_same_attributes_as(dom_obj)
|
|
358
|
+
end
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
context "with a nil response" do
|
|
362
|
+
before do
|
|
363
|
+
return_data = {
|
|
364
|
+
:body => nil,
|
|
365
|
+
:status => 200,
|
|
366
|
+
:headers => { 'Set-Cookie' => "rh_sso=test_ssh_cookie" }
|
|
367
|
+
}
|
|
368
|
+
stub_request(:get, mock_href).to_return(return_data)
|
|
369
|
+
end
|
|
370
|
+
it "throws an error" do
|
|
371
|
+
response.should raise_error(RHC::Rest::ConnectionException, 'An unexpected error occured: unexpected nil')
|
|
372
|
+
end
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
context "with a 204 (No Content) response" do
|
|
376
|
+
before do
|
|
377
|
+
return_data = {
|
|
378
|
+
:body => nil,
|
|
379
|
+
:status => 204,
|
|
380
|
+
:headers => { 'Set-Cookie' => "rh_sso=test_ssh_cookie" }
|
|
381
|
+
}
|
|
382
|
+
stub_request(:get, mock_href).to_return(return_data)
|
|
383
|
+
end
|
|
384
|
+
it "quietly exits" do
|
|
385
|
+
response.call.should equal(nil)
|
|
386
|
+
end
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
context "with a 502 (Bad Gateway) error" do
|
|
390
|
+
before{ stub_request(method, mock_href).to_return(:status => 502) }
|
|
391
|
+
|
|
392
|
+
context "on a GET request" do
|
|
393
|
+
it("repeats the call"){ response.should raise_error(RHC::Rest::ConnectionException, /communicating with the server.*temporary/i) }
|
|
394
|
+
after{ WebMock.should have_requested(method, mock_href).twice }
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
context "on a POST request" do
|
|
398
|
+
let(:method){ :post }
|
|
399
|
+
|
|
400
|
+
it("does not repeat the call"){ response.should raise_error(RHC::Rest::ConnectionException, /communicating with the server.*temporary/i) }
|
|
401
|
+
after{ WebMock.should have_requested(method, mock_href).once }
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
context "with a GET request" do
|
|
406
|
+
it "serializes payload as query parameters" do
|
|
407
|
+
stub_request(:get, mock_href).with(:query => {:test => '1', :bar => '2'}).to_return(:status => 204)
|
|
408
|
+
subject.request(request.merge(:payload => {:test => '1', :bar => '2'})).should be_nil
|
|
409
|
+
end
|
|
410
|
+
end
|
|
411
|
+
context "with a POST request" do
|
|
412
|
+
let(:method){ :post }
|
|
413
|
+
it "serializes payload as urlencoded body parameters" do
|
|
414
|
+
stub_request(method, mock_href).
|
|
415
|
+
with(:headers => {:accept => 'application/json', :content_type => 'application/json'},
|
|
416
|
+
:body => {:test => '1', :bar => 2}.to_json).
|
|
417
|
+
to_return(:status => 204)
|
|
418
|
+
subject.request(request.merge(:payload => {:test => '1', :bar => 2})).should be_nil
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
context "with a request timeout" do
|
|
423
|
+
before{ stub_request(:get, mock_href).to_timeout }
|
|
424
|
+
it{ response.should raise_error(RHC::Rest::TimeoutException, /Connection to server timed out. It is possible/) }
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
context "with a receive timeout" do
|
|
428
|
+
before{ stub_request(:get, mock_href).to_raise(HTTPClient::ReceiveTimeoutError) }
|
|
429
|
+
it{ response.should raise_error{ |e| e.on_receive?.should be_true } }
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
context "with a send timeout" do
|
|
433
|
+
before{ stub_request(:get, mock_href).to_raise(HTTPClient::SendTimeoutError) }
|
|
434
|
+
it{ response.should raise_error{ |e| e.on_send?.should be_true } }
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
context "with a connect timeout" do
|
|
438
|
+
before{ stub_request(:get, mock_href).to_raise(HTTPClient::ConnectTimeoutError) }
|
|
439
|
+
it{ response.should raise_error{ |e| e.on_connect?.should be_true } }
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
context "with a reset server connection" do
|
|
443
|
+
before{ stub_request(:get, mock_href).to_raise(Errno::ECONNRESET.new('Lost Server Connection')) }
|
|
444
|
+
it{ response.should raise_error(RHC::Rest::ConnectionException, /The server has closed the connection unexpectedly \(Connection reset by peer - Lost Server Connection\)/) }
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
context "with a broken server connection" do
|
|
449
|
+
before{ stub_request(:get, mock_href).to_raise(EOFError.new('Lost Server Connection')) }
|
|
450
|
+
it{ response.should raise_error(RHC::Rest::ConnectionException, 'Connection to server got interrupted: Lost Server Connection') }
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
#FIXME: the type of this exception should be a subclass of CertificateValidationFailed
|
|
454
|
+
context "with a potentially missing cert store" do
|
|
455
|
+
before{ stub_request(:get, mock_href).to_raise(OpenSSL::SSL::SSLError.new('unable to get local issuer certificate')) }
|
|
456
|
+
it{ response.should raise_error(RHC::Rest::SSLConnectionFailed, /You may need to specify your system CA certificate file/) }
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
context "with a self-signed SSL certificate" do
|
|
460
|
+
before do
|
|
461
|
+
subject.should_receive(:self_signed?).and_return(true)
|
|
462
|
+
stub_request(:get, mock_href).to_raise(OpenSSL::SSL::SSLError.new('Unverified SSL Certificate'))
|
|
463
|
+
end
|
|
464
|
+
it{ response.should raise_error(RHC::Rest::CertificateVerificationFailed, /The server is using a self-signed certificate/) }
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
context "with an unverified SSL certificate" do
|
|
468
|
+
before{ stub_request(:get, mock_href).to_raise(OpenSSL::SSL::SSLError.new('self signed certificate')) }
|
|
469
|
+
it{ response.should raise_error(RHC::Rest::CertificateVerificationFailed, /The server is using a self-signed certificate/) }
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
context "with an failed SSL certificate verification" do
|
|
473
|
+
before{ stub_request(:get, mock_href).to_raise(OpenSSL::SSL::SSLError.new('certificate verify failed')) }
|
|
474
|
+
it{ response.should raise_error(RHC::Rest::CertificateVerificationFailed, /The server's certificate could not be verified.*test\.domain\.com/) }
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
context "with a socket error" do
|
|
478
|
+
before{ stub_request(:get, mock_href).to_raise(SocketError) }
|
|
479
|
+
it{ response.should raise_error(RHC::Rest::ConnectionException, /unable to connect to the server/i) }
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
context "with an SSL connection error" do
|
|
483
|
+
before{ stub_request(:get, mock_href).to_raise(OpenSSL::SSL::SSLError) }
|
|
484
|
+
it{ response.should raise_error(RHC::Rest::SSLConnectionFailed, /a secure connection could not be established/i) }
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
context "with an SSL certificate error" do
|
|
488
|
+
before{ stub_request(:get, mock_href).to_raise(OpenSSL::SSL::SSLError.new('certificate verify failed')) }
|
|
489
|
+
it{ response.should raise_error(RHC::Rest::CertificateVerificationFailed, /the server's certificate could not be verified/i) }
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
context "with an SSL version exception" do
|
|
493
|
+
before{ stub_request(:get, mock_href).to_raise(OpenSSL::SSL::SSLError.new('SSL_connect returned=1 errno=0 state=SSLv2/v3 read server hello A')) }
|
|
494
|
+
it{ response.should raise_error(RHC::Rest::SSLVersionRejected, /connection attempt with an older ssl protocol/i) }
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
context "with a generic exception error" do
|
|
498
|
+
before{ stub_request(:get, mock_href).to_raise(Exception.new('Generic Error')) }
|
|
499
|
+
it{ response.should raise_error(RHC::Rest::ConnectionException, "An unexpected error occured: Generic Error") }
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
context "with an unauthorized request" do
|
|
503
|
+
before do
|
|
504
|
+
return_data = {
|
|
505
|
+
:body => nil,
|
|
506
|
+
:status => 401,
|
|
507
|
+
:headers => { 'Set-Cookie' => "rh_sso=test_ssh_cookie" }
|
|
508
|
+
}
|
|
509
|
+
stub_request(:get, mock_href).to_return(return_data)
|
|
510
|
+
end
|
|
511
|
+
it("raises not authenticated"){ response.should raise_error(RHC::Rest::UnAuthorizedException, 'Not authenticated') }
|
|
512
|
+
|
|
513
|
+
context "when auth will retry forever" do
|
|
514
|
+
let(:auth){ double('auth', :to_request => nil) }
|
|
515
|
+
before{ subject.stub(:auth).and_return(auth); auth.should_receive(:retry_auth?).exactly(4).times.and_return(true) }
|
|
516
|
+
it("raises not authenticated"){ response.should raise_error(RHC::Rest::UnAuthorizedException, 'Not authenticated') }
|
|
517
|
+
after{ WebMock.should have_requested(:get, mock_href).times(RHC::Rest::Client::MAX_RETRIES) }
|
|
518
|
+
end
|
|
519
|
+
end
|
|
520
|
+
end
|
|
521
|
+
|
|
522
|
+
# handle_error! function
|
|
523
|
+
describe "#handle_error!" do
|
|
524
|
+
let(:json){ nil }
|
|
525
|
+
let(:body){ "<html><body>Something failed</body></html>" }
|
|
526
|
+
let(:code){ nil }
|
|
527
|
+
let(:client){ HTTPClient.new(:proxy => proxy) }
|
|
528
|
+
let(:url){ "http://fake.url" }
|
|
529
|
+
let(:proxy){ nil }
|
|
530
|
+
def response
|
|
531
|
+
double(:status => code, :content => json ? RHC::Json.encode(json) : body)
|
|
532
|
+
end
|
|
533
|
+
let(:method) { lambda{ subject.send(:handle_error!, response, url, client) } }
|
|
534
|
+
|
|
535
|
+
context "with a 400 response" do
|
|
536
|
+
let(:code){ 400 }
|
|
537
|
+
|
|
538
|
+
it{ method.should raise_error(RHC::Rest::ServerErrorException) }
|
|
539
|
+
|
|
540
|
+
context "with a formatted JSON response" do
|
|
541
|
+
let(:json){ {:messages => [{ :severity => 'error', :text => 'mock error message' }] } }
|
|
542
|
+
it "raises a client error" do
|
|
543
|
+
method.should raise_error(RHC::Rest::ClientErrorException, 'mock error message')
|
|
544
|
+
end
|
|
545
|
+
end
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
context "with a 401 response" do
|
|
549
|
+
let(:code){ 401 }
|
|
550
|
+
let(:json){ {} }
|
|
551
|
+
it "raises an 'unauthorized exception' error" do
|
|
552
|
+
method.should raise_error(RHC::Rest::UnAuthorizedException, 'Not authenticated')
|
|
553
|
+
end
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
context "with a 403 response" do
|
|
557
|
+
let(:code){ 403 }
|
|
558
|
+
|
|
559
|
+
it "raises a request denied error" do
|
|
560
|
+
method.should raise_error(RHC::Rest::RequestDeniedException)
|
|
561
|
+
end
|
|
562
|
+
|
|
563
|
+
context "with a formatted JSON response" do
|
|
564
|
+
let(:json){ { :messages => [{ :severity => 'error', :text => 'mock error message' }] } }
|
|
565
|
+
it "raises a 'request denied' error" do
|
|
566
|
+
method.should raise_error(RHC::Rest::RequestDeniedException, 'mock error message')
|
|
567
|
+
end
|
|
568
|
+
end
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
context "with a 404 response" do
|
|
572
|
+
let(:code){ 404 }
|
|
573
|
+
|
|
574
|
+
it "raises a Not Found error" do
|
|
575
|
+
method.should raise_error(RHC::Rest::ResourceNotFoundException)
|
|
576
|
+
end
|
|
577
|
+
|
|
578
|
+
context "with a formatted JSON response" do
|
|
579
|
+
let(:json){ { :messages => [{ :severity => 'error', :text => 'mock error message' }] } }
|
|
580
|
+
it "raises a 'resource not found' error" do
|
|
581
|
+
method.should raise_error(RHC::Rest::ResourceNotFoundException, 'mock error message')
|
|
582
|
+
end
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
context "with a 409 response" do
|
|
587
|
+
let(:code){ 409 }
|
|
588
|
+
|
|
589
|
+
it "raises a generic server error" do
|
|
590
|
+
method.should raise_error(RHC::Rest::ServerErrorException)
|
|
591
|
+
end
|
|
592
|
+
|
|
593
|
+
context "with a formatted JSON response" do
|
|
594
|
+
let(:json){ { :messages => [{ :severity => 'error', :text => 'mock error message' }] } }
|
|
595
|
+
it "raises a validation error" do
|
|
596
|
+
method.should raise_error(RHC::Rest::ValidationException, 'mock error message')
|
|
597
|
+
end
|
|
598
|
+
end
|
|
599
|
+
context "with multiple JSON messages" do
|
|
600
|
+
let(:json){ { :messages => [{ :field => 'error', :text => 'mock error message 1' },
|
|
601
|
+
{ :field => 'error', :text => 'mock error message 2' }] } }
|
|
602
|
+
it "raises a validation error with concatenated messages" do
|
|
603
|
+
method.should raise_error(RHC::Rest::ValidationException, "The operation did not complete successfully, but the server returned additional information:\n* mock error message 1\n* mock error message 2")
|
|
604
|
+
end
|
|
605
|
+
end
|
|
606
|
+
context "with multiple errors" do
|
|
607
|
+
let(:json){ { :messages => [
|
|
608
|
+
{ :severity => 'error', :field => 'error', :text => 'mock 1' },
|
|
609
|
+
{ :severity => 'error', :text => 'mock 2' },
|
|
610
|
+
] } }
|
|
611
|
+
it "raises a validation error with concatenated messages" do
|
|
612
|
+
method.should raise_error(RHC::Rest::ValidationException, "The server reported multiple errors:\n* mock 1\n* mock 2")
|
|
613
|
+
end
|
|
614
|
+
end
|
|
615
|
+
context "with multiple messages and one error" do
|
|
616
|
+
let(:json){ { :messages => [
|
|
617
|
+
{ :field => 'error', :text => 'mock 1' },
|
|
618
|
+
{ :text => 'mock 2' },
|
|
619
|
+
{ :severity => 'error', :text => 'mock 3' },
|
|
620
|
+
] } }
|
|
621
|
+
it "raises a validation error with concatenated messages" do
|
|
622
|
+
method.should raise_error(RHC::Rest::ValidationException, "mock 3")
|
|
623
|
+
end
|
|
624
|
+
end
|
|
625
|
+
context "with an empty JSON response" do
|
|
626
|
+
let(:json){ {} }
|
|
627
|
+
it "raises a validation error" do
|
|
628
|
+
method.should raise_error(RHC::Rest::ServerErrorException)
|
|
629
|
+
end
|
|
630
|
+
end
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
context "with a 422 response" do
|
|
634
|
+
let(:code){ 422 }
|
|
635
|
+
|
|
636
|
+
it "raises a generic server error" do
|
|
637
|
+
method.should raise_error(RHC::Rest::ServerErrorException)
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
context "with a single JSON message" do
|
|
641
|
+
let(:json){ { :messages => [{ :severity => 'error', :text => 'mock error message' }] } }
|
|
642
|
+
it "raises a validation error" do
|
|
643
|
+
method.should raise_error(RHC::Rest::ValidationException, 'mock error message')
|
|
644
|
+
end
|
|
645
|
+
end
|
|
646
|
+
|
|
647
|
+
context "with an empty JSON response" do
|
|
648
|
+
let(:json){ {} }
|
|
649
|
+
it "raises a validation error" do
|
|
650
|
+
method.should raise_error(RHC::Rest::ServerErrorException)
|
|
651
|
+
end
|
|
652
|
+
end
|
|
653
|
+
|
|
654
|
+
context "with multiple JSON messages" do
|
|
655
|
+
let(:json){ { :messages => [{ :field => 'error', :text => 'mock error message 1' },
|
|
656
|
+
{ :field => 'error', :text => 'mock error message 2' }] } }
|
|
657
|
+
it "raises a validation error with concatenated messages" do
|
|
658
|
+
method.should raise_error(RHC::Rest::ValidationException, "The operation did not complete successfully, but the server returned additional information:\n* mock error message 1\n* mock error message 2")
|
|
659
|
+
end
|
|
660
|
+
end
|
|
661
|
+
context "with multiple errors" do
|
|
662
|
+
let(:json){ { :messages => [
|
|
663
|
+
{ :severity => 'error', :field => 'error', :text => 'mock 1' },
|
|
664
|
+
{ :severity => 'error', :text => 'mock 2' },
|
|
665
|
+
] } }
|
|
666
|
+
it "raises a validation error with concatenated messages" do
|
|
667
|
+
method.should raise_error(RHC::Rest::ValidationException, "The server reported multiple errors:\n* mock 1\n* mock 2")
|
|
668
|
+
end
|
|
669
|
+
end
|
|
670
|
+
context "with multiple messages and one error" do
|
|
671
|
+
let(:json){ { :messages => [
|
|
672
|
+
{ :field => 'error', :text => 'mock 1' },
|
|
673
|
+
{ :text => 'mock 2' },
|
|
674
|
+
{ :severity => 'error', :text => 'mock 3' },
|
|
675
|
+
] } }
|
|
676
|
+
it "raises a validation error with concatenated messages" do
|
|
677
|
+
method.should raise_error(RHC::Rest::ValidationException, "mock 3")
|
|
678
|
+
end
|
|
679
|
+
end
|
|
680
|
+
end
|
|
681
|
+
|
|
682
|
+
context "with a 500 response" do
|
|
683
|
+
let(:code){ 500 }
|
|
684
|
+
|
|
685
|
+
it "raises a generic server error" do
|
|
686
|
+
method.should raise_error(RHC::Rest::ServerErrorException, /server did not respond correctly.*verify that you can access the OpenShift server/i)
|
|
687
|
+
end
|
|
688
|
+
|
|
689
|
+
context "when proxy is set" do
|
|
690
|
+
let(:proxy) { 'http://foo.com' }
|
|
691
|
+
it "raises a generic server error with the proxy URL" do
|
|
692
|
+
method.should raise_error(RHC::Rest::ServerErrorException, /foo\.com/i)
|
|
693
|
+
end
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
context "when request url is present" do
|
|
697
|
+
let(:url){ 'foo.bar' }
|
|
698
|
+
it "raises a generic server error with the request URL" do
|
|
699
|
+
method.should raise_error(RHC::Rest::ServerErrorException, /foo\.bar/i)
|
|
700
|
+
end
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
context "with a formatted JSON response" do
|
|
704
|
+
let(:json){ { :messages => [{ :severity => 'error', :text => 'mock error message' }] } }
|
|
705
|
+
it "raises a server error" do
|
|
706
|
+
method.should raise_error(RHC::Rest::ServerErrorException, 'mock error message')
|
|
707
|
+
end
|
|
708
|
+
end
|
|
709
|
+
end
|
|
710
|
+
|
|
711
|
+
context "with a 503 response" do
|
|
712
|
+
let(:code){ 503 }
|
|
713
|
+
|
|
714
|
+
it "raises a 'service unavailable' error" do
|
|
715
|
+
method.should raise_error(RHC::Rest::ServiceUnavailableException)
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
context "with a formatted JSON response" do
|
|
719
|
+
let(:json){ { :messages => [{ :severity => 'error', :text => 'mock error message' }] } }
|
|
720
|
+
it "raises a 'service unavailable' error" do
|
|
721
|
+
method.should raise_error(RHC::Rest::ServiceUnavailableException, 'mock error message')
|
|
722
|
+
end
|
|
723
|
+
end
|
|
724
|
+
end
|
|
725
|
+
|
|
726
|
+
context "with an unhandled response code" do
|
|
727
|
+
let(:code){ 999 }
|
|
728
|
+
|
|
729
|
+
it{ method.should raise_error(RHC::Rest::ServerErrorException) }
|
|
730
|
+
|
|
731
|
+
context "with a formatted JSON response" do
|
|
732
|
+
let(:json){ { :messages => [{ :severity => 'error', :text => 'mock error message' }] } }
|
|
733
|
+
it "raises a resource access error" do
|
|
734
|
+
method.should raise_error(RHC::Rest::ServerErrorException, 'mock error message')
|
|
735
|
+
end
|
|
736
|
+
end
|
|
737
|
+
end
|
|
738
|
+
end
|
|
739
|
+
end
|
|
740
|
+
end
|