rhc 0.94.8 → 0.95.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +27 -1
- data/bin/rhc +15 -23
- data/bin/rhc-app +4 -1
- data/bin/rhc-chk +3 -0
- data/bin/rhc-create-app +3 -0
- data/bin/rhc-create-domain +3 -0
- data/bin/rhc-ctl-app +3 -0
- data/bin/rhc-ctl-domain +3 -0
- data/bin/rhc-domain +5 -2
- data/bin/rhc-domain-info +3 -0
- data/bin/rhc-port-forward +16 -18
- data/bin/rhc-snapshot +3 -0
- data/bin/rhc-sshkey +3 -0
- data/bin/rhc-tail-files +3 -0
- data/bin/rhc-user-info +1 -0
- data/features/README.md +70 -0
- data/features/lib/rhc_helper/app.rb +124 -0
- data/features/lib/rhc_helper/cartridge.rb +72 -0
- data/features/lib/rhc_helper/commandify.rb +154 -0
- data/features/lib/rhc_helper/domain.rb +50 -0
- data/features/lib/rhc_helper/httpify.rb +107 -0
- data/features/lib/rhc_helper/loggable.rb +39 -0
- data/features/lib/rhc_helper/persistable.rb +38 -0
- data/features/lib/rhc_helper/runnable.rb +41 -0
- data/features/lib/rhc_helper.rb +7 -0
- data/features/step_definitions/application_steps.rb +99 -0
- data/features/step_definitions/cartridge_steps.rb +42 -0
- data/features/step_definitions/client_steps.rb +32 -0
- data/features/step_definitions/domain_steps.rb +19 -0
- data/features/support/env.rb +99 -0
- data/features/verify.feature +123 -0
- data/lib/rhc/cli.rb +4 -1
- data/lib/rhc/commands/base.rb +28 -6
- data/lib/rhc/commands/server.rb +4 -1
- data/lib/rhc/commands/setup.rb +24 -0
- data/lib/rhc/commands.rb +10 -5
- data/lib/rhc/config.rb +90 -21
- data/lib/rhc/core_ext.rb +11 -2
- data/lib/rhc/coverage_helper.rb +35 -0
- data/lib/rhc/help_formatter.rb +30 -0
- data/lib/rhc/helpers.rb +41 -5
- data/lib/rhc/ssh_key_helpers.rb +72 -0
- data/lib/rhc/targz.rb +2 -8
- data/lib/rhc/wizard.rb +75 -58
- data/lib/rhc-common.rb +20 -13
- data/lib/rhc-rest.rb +3 -11
- data/spec/coverage_helper.rb +51 -0
- data/spec/rest_spec_helper.rb +86 -0
- data/spec/rhc/cli_spec.rb +19 -3
- data/spec/rhc/commands/server_spec.rb +2 -2
- data/spec/rhc/common_spec.rb +49 -0
- data/spec/rhc/config_spec.rb +328 -0
- data/spec/rhc/helpers_spec.rb +74 -1
- data/spec/rhc/rest_client_spec.rb +402 -0
- data/spec/rhc/rest_spec.rb +454 -0
- data/spec/rhc/targz_spec.rb +13 -0
- data/spec/rhc/wizard_spec.rb +305 -43
- data/spec/spec_helper.rb +30 -25
- metadata +124 -5
@@ -0,0 +1,402 @@
|
|
1
|
+
require 'base64'
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'stringio'
|
4
|
+
require 'rest_spec_helper'
|
5
|
+
require 'rhc-rest/client'
|
6
|
+
|
7
|
+
Spec::Runner.configure do |configuration|
|
8
|
+
include(RestSpecHelper)
|
9
|
+
end
|
10
|
+
|
11
|
+
# This object is used in a few cases where we need to inspect
|
12
|
+
# the logged output.
|
13
|
+
class MockClient < Rhc::Rest::Client
|
14
|
+
def logger
|
15
|
+
Logger.new((@output = StringIO.new))
|
16
|
+
end
|
17
|
+
def debug
|
18
|
+
@mydebug = true
|
19
|
+
end
|
20
|
+
def logged
|
21
|
+
@output.string
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module Rhc
|
26
|
+
module Rest
|
27
|
+
describe Client do
|
28
|
+
let(:client_links) { mock_response_links(mock_client_links) }
|
29
|
+
let(:domain_0_links) { mock_response_links(mock_domain_links('mock_domain_0')) }
|
30
|
+
let(:domain_1_links) { mock_response_links(mock_domain_links('mock_domain_1')) }
|
31
|
+
let(:user_links) { mock_response_links(mock_user_links) }
|
32
|
+
|
33
|
+
context "#new" do
|
34
|
+
before do
|
35
|
+
stub_request(:get, mock_href('', true)).
|
36
|
+
to_return({ :body => { :data => client_links }.to_json,
|
37
|
+
:status => 200
|
38
|
+
})
|
39
|
+
stub_request(:get, mock_href('api_error', true)).
|
40
|
+
to_raise(RestClient::ExceptionWithResponse.new('API Error'))
|
41
|
+
stub_request(:get, mock_href('other_error', true)).
|
42
|
+
to_raise(Exception.new('Other Error'))
|
43
|
+
end
|
44
|
+
it "returns a client object from the required arguments" do
|
45
|
+
credentials = Base64.encode64(mock_user + ":" + mock_pass)
|
46
|
+
client = Rhc::Rest::Client.new(mock_href, mock_user, mock_pass)
|
47
|
+
@@headers['Authorization'].should == "Basic #{credentials}"
|
48
|
+
client.instance_variable_get(:@links).should == client_links
|
49
|
+
end
|
50
|
+
it "logs an error message if the API cannot be connected" do
|
51
|
+
client = MockClient.new(mock_href('api_error'), mock_user, mock_pass)
|
52
|
+
client.logged.should =~ /API Error$/
|
53
|
+
end
|
54
|
+
it "raises a generic error for any other error condition" do
|
55
|
+
lambda{ Rhc::Rest::Client.new(mock_href('other_error'), mock_user, mock_pass) }.
|
56
|
+
should raise_error("Resource could not be accessed:Other Error")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "with an instantiated client " do
|
61
|
+
before(:each) do
|
62
|
+
stub_request(:get, mock_href('', true)).
|
63
|
+
to_return({ :body => { :data => client_links }.to_json,
|
64
|
+
:status => 200
|
65
|
+
})
|
66
|
+
@client = Rhc::Rest::Client.new(mock_href, mock_user, mock_pass)
|
67
|
+
end
|
68
|
+
|
69
|
+
context "#add_domain" do
|
70
|
+
before do
|
71
|
+
stub_request(:any, mock_href(client_links['ADD_DOMAIN']['relative'], true)).
|
72
|
+
to_return({ :body => {
|
73
|
+
:type => 'domain',
|
74
|
+
:data => {
|
75
|
+
:id => 'mock_domain',
|
76
|
+
:links => mock_response_links(mock_domain_links('mock_domain')),
|
77
|
+
}
|
78
|
+
}.to_json,
|
79
|
+
:status => 200
|
80
|
+
})
|
81
|
+
end
|
82
|
+
it "returns a domain object" do
|
83
|
+
domain = @client.add_domain('mock_domain')
|
84
|
+
domain.class.should == Rhc::Rest::Domain
|
85
|
+
domain.instance_variable_get(:@id).should == 'mock_domain'
|
86
|
+
domain.instance_variable_get(:@links).should ==
|
87
|
+
mock_response_links(mock_domain_links('mock_domain'))
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
context "#domains" do
|
92
|
+
before(:each) do
|
93
|
+
stub_request(:any, mock_href(client_links['LIST_DOMAINS']['relative'], true)).
|
94
|
+
to_return({ :body => {
|
95
|
+
:type => 'domains',
|
96
|
+
:data =>
|
97
|
+
[{ :id => 'mock_domain_0',
|
98
|
+
:links => mock_response_links(mock_domain_links('mock_domain_0')),
|
99
|
+
},
|
100
|
+
{ :id => 'mock_domain_1',
|
101
|
+
:links => mock_response_links(mock_domain_links('mock_domain_1')),
|
102
|
+
}]
|
103
|
+
}.to_json,
|
104
|
+
:status => 200
|
105
|
+
}).
|
106
|
+
to_return({ :body => {
|
107
|
+
:type => 'domains',
|
108
|
+
:data => []
|
109
|
+
}.to_json,
|
110
|
+
:status => 200
|
111
|
+
})
|
112
|
+
end
|
113
|
+
it "returns a list of existing domains" do
|
114
|
+
domains = @client.domains
|
115
|
+
domains.length.should equal(2)
|
116
|
+
(0..1).each do |idx|
|
117
|
+
domains[idx].class.should == Rhc::Rest::Domain
|
118
|
+
domains[idx].instance_variable_get(:@id).should == "mock_domain_#{idx}"
|
119
|
+
domains[idx].instance_variable_get(:@links).should ==
|
120
|
+
mock_response_links(mock_domain_links("mock_domain_#{idx}"))
|
121
|
+
end
|
122
|
+
end
|
123
|
+
it "returns an empty list when no domains exist" do
|
124
|
+
# Disregard the first response; this is for the previous expectiation.
|
125
|
+
domains = @client.domains
|
126
|
+
domains = @client.domains
|
127
|
+
domains.length.should equal(0)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
context "#find_domain" do
|
132
|
+
before(:each) do
|
133
|
+
stub_request(:any, mock_href(client_links['LIST_DOMAINS']['relative'], true)).
|
134
|
+
to_return({ :body => {
|
135
|
+
:type => 'domains',
|
136
|
+
:data =>
|
137
|
+
[{ :id => 'mock_domain_0',
|
138
|
+
:links => mock_response_links(mock_domain_links('mock_domain_0')),
|
139
|
+
},
|
140
|
+
{ :id => 'mock_domain_1',
|
141
|
+
:links => mock_response_links(mock_domain_links('mock_domain_1')),
|
142
|
+
}]
|
143
|
+
}.to_json,
|
144
|
+
:status => 200
|
145
|
+
})
|
146
|
+
end
|
147
|
+
it "returns a list of domain objects for matching domain IDs" do
|
148
|
+
matches = @client.find_domain('mock_domain_0')
|
149
|
+
matches.length.should equal(1)
|
150
|
+
matches[0].class.should == Rhc::Rest::Domain
|
151
|
+
end
|
152
|
+
it "returns an empty list when no matching domain IDs can be found" do
|
153
|
+
matches = @client.find_domain('mock_domain_2')
|
154
|
+
matches.length.should equal(0)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "#find_application" do
|
159
|
+
before(:each) do
|
160
|
+
stub_request(:any, mock_href(client_links['LIST_DOMAINS']['relative'], true)).
|
161
|
+
to_return({ :body => {
|
162
|
+
:type => 'domains',
|
163
|
+
:data =>
|
164
|
+
[{ :id => 'mock_domain_0',
|
165
|
+
:links => mock_response_links(mock_domain_links('mock_domain_0')),
|
166
|
+
},
|
167
|
+
{ :id => 'mock_domain_1',
|
168
|
+
:links => mock_response_links(mock_domain_links('mock_domain_1')),
|
169
|
+
}]
|
170
|
+
}.to_json,
|
171
|
+
:status => 200
|
172
|
+
})
|
173
|
+
stub_request(:any, mock_href(domain_0_links['LIST_APPLICATIONS']['relative'], true)).
|
174
|
+
to_return({ :body => {
|
175
|
+
:type => 'applications',
|
176
|
+
:data =>
|
177
|
+
[{ :domain_id => 'mock_domain_0',
|
178
|
+
:name => 'mock_app',
|
179
|
+
:creation_time => Time.new.to_s,
|
180
|
+
:uuid => 1234,
|
181
|
+
:aliases => ['alias_1', 'alias_2'],
|
182
|
+
:server_identity => 'mock_server_identity',
|
183
|
+
:links => mock_response_links(mock_app_links('mock_domain_0','mock_app')),
|
184
|
+
}]
|
185
|
+
}.to_json,
|
186
|
+
:status => 200
|
187
|
+
})
|
188
|
+
stub_request(:any, mock_href(domain_1_links['LIST_APPLICATIONS']['relative'], true)).
|
189
|
+
to_return({ :body => {
|
190
|
+
:type => 'applications',
|
191
|
+
:data =>
|
192
|
+
[{ :domain_id => 'mock_domain_1',
|
193
|
+
:name => 'mock_app',
|
194
|
+
:creation_time => Time.new.to_s,
|
195
|
+
:uuid => 1234,
|
196
|
+
:aliases => ['alias_1', 'alias_2'],
|
197
|
+
:server_identity => 'mock_server_identity',
|
198
|
+
:links => mock_response_links(mock_app_links('mock_domain_1','mock_app')),
|
199
|
+
}]
|
200
|
+
}.to_json,
|
201
|
+
:status => 200
|
202
|
+
})
|
203
|
+
end
|
204
|
+
it "returns a list of application objects for matching application IDs" do
|
205
|
+
matches = @client.find_application('mock_app')
|
206
|
+
matches.length.should equal(2)
|
207
|
+
(0..1).each do |idx|
|
208
|
+
matches[idx].class.should == Rhc::Rest::Application
|
209
|
+
matches[idx].instance_variable_get(:@name).should == 'mock_app'
|
210
|
+
matches[idx].instance_variable_get(:@domain_id).should == "mock_domain_#{idx}"
|
211
|
+
matches[idx].instance_variable_get(:@links).should ==
|
212
|
+
mock_response_links(mock_app_links("mock_domain_#{idx}",'mock_app'))
|
213
|
+
end
|
214
|
+
end
|
215
|
+
it "returns an empty list when no matching applications can be found" do
|
216
|
+
matches = @client.find_application('no_match')
|
217
|
+
matches.length.should equal(0)
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
context "#cartridges" do
|
222
|
+
before(:each) do
|
223
|
+
stub_request(:any, mock_href(client_links['LIST_CARTRIDGES']['relative'], true)).
|
224
|
+
to_return({ :body => {
|
225
|
+
:type => 'cartridges',
|
226
|
+
:data =>
|
227
|
+
[{ :name => 'mock_cart_0',
|
228
|
+
:type => 'mock_cart_0_type',
|
229
|
+
:links => mock_response_links(mock_cart_links('mock_cart_0')),
|
230
|
+
},
|
231
|
+
{ :name => 'mock_cart_1',
|
232
|
+
:type => 'mock_cart_1_type',
|
233
|
+
:links => mock_response_links(mock_cart_links('mock_cart_1')),
|
234
|
+
}]
|
235
|
+
}.to_json,
|
236
|
+
:status => 200
|
237
|
+
}).
|
238
|
+
to_return({ :body => {
|
239
|
+
:type => 'cartridges',
|
240
|
+
:data => []
|
241
|
+
}.to_json,
|
242
|
+
:status => 200
|
243
|
+
})
|
244
|
+
end
|
245
|
+
it "returns a list of existing cartridges" do
|
246
|
+
carts = @client.cartridges
|
247
|
+
carts.length.should equal(2)
|
248
|
+
(0..1).each do |idx|
|
249
|
+
carts[idx].class.should == Rhc::Rest::Cartridge
|
250
|
+
carts[idx].instance_variable_get(:@name).should == "mock_cart_#{idx}"
|
251
|
+
carts[idx].instance_variable_get(:@type).should == "mock_cart_#{idx}_type"
|
252
|
+
carts[idx].instance_variable_get(:@links).should ==
|
253
|
+
mock_response_links(mock_cart_links("mock_cart_#{idx}"))
|
254
|
+
end
|
255
|
+
end
|
256
|
+
it "returns an empty list when no cartridges exist" do
|
257
|
+
# Disregard the first response; this is for the previous expectiation.
|
258
|
+
carts = @client.cartridges
|
259
|
+
carts = @client.cartridges
|
260
|
+
carts.length.should equal(0)
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
context "#find_cartridge" do
|
265
|
+
before(:each) do
|
266
|
+
stub_request(:any, mock_href(client_links['LIST_CARTRIDGES']['relative'], true)).
|
267
|
+
to_return({ :body => {
|
268
|
+
:type => 'cartridges',
|
269
|
+
:data =>
|
270
|
+
[{ :name => 'mock_cart_0',
|
271
|
+
:type => 'mock_cart_0_type',
|
272
|
+
:links => mock_response_links(mock_cart_links('mock_cart_0')),
|
273
|
+
},
|
274
|
+
{ :name => 'mock_cart_1',
|
275
|
+
:type => 'mock_cart_1_type',
|
276
|
+
:links => mock_response_links(mock_cart_links('mock_cart_1')),
|
277
|
+
}]
|
278
|
+
}.to_json,
|
279
|
+
:status => 200
|
280
|
+
})
|
281
|
+
end
|
282
|
+
it "returns a list of cartridge objects for matching cartridges" do
|
283
|
+
matches = @client.find_cartridge('mock_cart_0')
|
284
|
+
matches.length.should equal(1)
|
285
|
+
matches[0].class.should == Rhc::Rest::Cartridge
|
286
|
+
matches[0].instance_variable_get(:@name).should == 'mock_cart_0'
|
287
|
+
matches[0].instance_variable_get(:@type).should == 'mock_cart_0_type'
|
288
|
+
matches[0].instance_variable_get(:@links).should ==
|
289
|
+
mock_response_links(mock_cart_links('mock_cart_0'))
|
290
|
+
end
|
291
|
+
it "returns an empty list when no matching cartridges can be found" do
|
292
|
+
matches = @client.find_cartridge('no_match')
|
293
|
+
matches.length.should equal(0)
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
context "#user" do
|
298
|
+
before(:each) do
|
299
|
+
stub_request(:any, mock_href(client_links['GET_USER']['relative'], true)).
|
300
|
+
to_return({ :body => {
|
301
|
+
:type => 'user',
|
302
|
+
:data =>
|
303
|
+
{ :login => mock_user,
|
304
|
+
:links => mock_response_links(mock_user_links)
|
305
|
+
}
|
306
|
+
}.to_json,
|
307
|
+
:status => 200
|
308
|
+
})
|
309
|
+
end
|
310
|
+
it "returns the user object associated with this client connection" do
|
311
|
+
user = @client.user
|
312
|
+
user.class.should == Rhc::Rest::User
|
313
|
+
user.instance_variable_get(:@login).should == mock_user
|
314
|
+
user.instance_variable_get(:@links).should == mock_response_links(mock_user_links)
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
context "#find_key" do
|
319
|
+
before(:each) do
|
320
|
+
stub_request(:any, mock_href(client_links['GET_USER']['relative'], true)).
|
321
|
+
to_return({ :body => {
|
322
|
+
:type => 'user',
|
323
|
+
:data =>
|
324
|
+
{ :login => mock_user,
|
325
|
+
:links => mock_response_links(mock_user_links)
|
326
|
+
}
|
327
|
+
}.to_json,
|
328
|
+
:status => 200
|
329
|
+
})
|
330
|
+
stub_request(:any, mock_href(user_links['LIST_KEYS']['relative'], true)).
|
331
|
+
to_return({ :body => {
|
332
|
+
:type => 'keys',
|
333
|
+
:data =>
|
334
|
+
[{ :name => 'mock_key_0',
|
335
|
+
:type => 'mock_key_0_type',
|
336
|
+
:content => '123456789:0',
|
337
|
+
:links => mock_response_links(mock_key_links('mock_key_0'))
|
338
|
+
},
|
339
|
+
{ :name => 'mock_key_1',
|
340
|
+
:type => 'mock_key_1_type',
|
341
|
+
:content => '123456789:1',
|
342
|
+
:links => mock_response_links(mock_key_links('mock_key_1'))
|
343
|
+
}]
|
344
|
+
}.to_json,
|
345
|
+
:status => 200
|
346
|
+
})
|
347
|
+
end
|
348
|
+
it "returns a list of key objects for matching keys" do
|
349
|
+
keys = @client.find_key('mock_key_0')
|
350
|
+
keys.length.should equal(1)
|
351
|
+
keys[0].class.should == Rhc::Rest::Key
|
352
|
+
keys[0].instance_variable_get(:@name).should == 'mock_key_0'
|
353
|
+
keys[0].instance_variable_get(:@type).should == 'mock_key_0_type'
|
354
|
+
keys[0].instance_variable_get(:@content).should == '123456789:0'
|
355
|
+
keys[0].instance_variable_get(:@links).should ==
|
356
|
+
mock_response_links(mock_key_links('mock_key_0'))
|
357
|
+
end
|
358
|
+
it "returns an empty list when no matching keys can be found" do
|
359
|
+
keys = @client.find_key('no_match')
|
360
|
+
keys.length.should equal(0)
|
361
|
+
end
|
362
|
+
end
|
363
|
+
|
364
|
+
shared_examples_for "a logout method" do
|
365
|
+
before(:each) do
|
366
|
+
stub_request(:get, mock_href('', true)).
|
367
|
+
to_return({ :body => { :data => client_links }.to_json,
|
368
|
+
:status => 200
|
369
|
+
})
|
370
|
+
@client = MockClient.new(mock_href, mock_user, mock_pass)
|
371
|
+
end
|
372
|
+
context "debug mode is on" do
|
373
|
+
it "writes a message to the logger" do
|
374
|
+
@client.debug
|
375
|
+
@client.logger # starts our mock logger
|
376
|
+
eval '@client.' + logout_method.to_s
|
377
|
+
@client.logged.should =~ /Logout\/Close client$/
|
378
|
+
end
|
379
|
+
end
|
380
|
+
context "debug mode is off" do
|
381
|
+
it "does nothing" do
|
382
|
+
@client = MockClient.new(mock_href, mock_user, mock_pass)
|
383
|
+
@client.logger # starts our mock logger
|
384
|
+
eval '@client.' + logout_method.to_s
|
385
|
+
@client.logged.should == ''
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
context "#logout" do
|
391
|
+
let(:logout_method) { :logout }
|
392
|
+
it_should_behave_like "a logout method"
|
393
|
+
end
|
394
|
+
|
395
|
+
context "#close" do
|
396
|
+
let(:logout_method) { :close }
|
397
|
+
it_should_behave_like "a logout method"
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|