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.
Files changed (59) hide show
  1. data/README.md +27 -1
  2. data/bin/rhc +15 -23
  3. data/bin/rhc-app +4 -1
  4. data/bin/rhc-chk +3 -0
  5. data/bin/rhc-create-app +3 -0
  6. data/bin/rhc-create-domain +3 -0
  7. data/bin/rhc-ctl-app +3 -0
  8. data/bin/rhc-ctl-domain +3 -0
  9. data/bin/rhc-domain +5 -2
  10. data/bin/rhc-domain-info +3 -0
  11. data/bin/rhc-port-forward +16 -18
  12. data/bin/rhc-snapshot +3 -0
  13. data/bin/rhc-sshkey +3 -0
  14. data/bin/rhc-tail-files +3 -0
  15. data/bin/rhc-user-info +1 -0
  16. data/features/README.md +70 -0
  17. data/features/lib/rhc_helper/app.rb +124 -0
  18. data/features/lib/rhc_helper/cartridge.rb +72 -0
  19. data/features/lib/rhc_helper/commandify.rb +154 -0
  20. data/features/lib/rhc_helper/domain.rb +50 -0
  21. data/features/lib/rhc_helper/httpify.rb +107 -0
  22. data/features/lib/rhc_helper/loggable.rb +39 -0
  23. data/features/lib/rhc_helper/persistable.rb +38 -0
  24. data/features/lib/rhc_helper/runnable.rb +41 -0
  25. data/features/lib/rhc_helper.rb +7 -0
  26. data/features/step_definitions/application_steps.rb +99 -0
  27. data/features/step_definitions/cartridge_steps.rb +42 -0
  28. data/features/step_definitions/client_steps.rb +32 -0
  29. data/features/step_definitions/domain_steps.rb +19 -0
  30. data/features/support/env.rb +99 -0
  31. data/features/verify.feature +123 -0
  32. data/lib/rhc/cli.rb +4 -1
  33. data/lib/rhc/commands/base.rb +28 -6
  34. data/lib/rhc/commands/server.rb +4 -1
  35. data/lib/rhc/commands/setup.rb +24 -0
  36. data/lib/rhc/commands.rb +10 -5
  37. data/lib/rhc/config.rb +90 -21
  38. data/lib/rhc/core_ext.rb +11 -2
  39. data/lib/rhc/coverage_helper.rb +35 -0
  40. data/lib/rhc/help_formatter.rb +30 -0
  41. data/lib/rhc/helpers.rb +41 -5
  42. data/lib/rhc/ssh_key_helpers.rb +72 -0
  43. data/lib/rhc/targz.rb +2 -8
  44. data/lib/rhc/wizard.rb +75 -58
  45. data/lib/rhc-common.rb +20 -13
  46. data/lib/rhc-rest.rb +3 -11
  47. data/spec/coverage_helper.rb +51 -0
  48. data/spec/rest_spec_helper.rb +86 -0
  49. data/spec/rhc/cli_spec.rb +19 -3
  50. data/spec/rhc/commands/server_spec.rb +2 -2
  51. data/spec/rhc/common_spec.rb +49 -0
  52. data/spec/rhc/config_spec.rb +328 -0
  53. data/spec/rhc/helpers_spec.rb +74 -1
  54. data/spec/rhc/rest_client_spec.rb +402 -0
  55. data/spec/rhc/rest_spec.rb +454 -0
  56. data/spec/rhc/targz_spec.rb +13 -0
  57. data/spec/rhc/wizard_spec.rb +305 -43
  58. data/spec/spec_helper.rb +30 -25
  59. 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