rhc 1.4.8 → 1.5.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/features/application.feature +1 -0
- data/features/lib/rhc_helper/app.rb +5 -3
- data/features/lib/rhc_helper/commandify.rb +2 -1
- data/features/step_definitions/application_steps.rb +2 -1
- data/features/support/env.rb +4 -1
- data/lib/rhc/auth/basic.rb +18 -13
- data/lib/rhc/auth/token.rb +98 -0
- data/lib/rhc/auth/token_store.rb +51 -0
- data/lib/rhc/auth.rb +3 -1
- data/lib/rhc/command_runner.rb +1 -0
- data/lib/rhc/commands/account.rb +47 -1
- data/lib/rhc/commands/alias.rb +2 -4
- data/lib/rhc/commands/app.rb +23 -18
- data/lib/rhc/commands/authorization.rb +93 -0
- data/lib/rhc/commands/base.rb +11 -3
- data/lib/rhc/commands/cartridge.rb +8 -16
- data/lib/rhc/commands/git_clone.rb +2 -3
- data/lib/rhc/commands/port_forward.rb +10 -11
- data/lib/rhc/commands/setup.rb +4 -1
- data/lib/rhc/commands/snapshot.rb +4 -3
- data/lib/rhc/commands/tail.rb +3 -4
- data/lib/rhc/commands/threaddump.rb +1 -2
- data/lib/rhc/commands.rb +37 -3
- data/lib/rhc/config.rb +10 -1
- data/lib/rhc/context_helper.rb +5 -1
- data/lib/rhc/core_ext.rb +10 -0
- data/lib/rhc/exceptions.rb +0 -12
- data/lib/rhc/git_helpers.rb +12 -0
- data/lib/rhc/helpers.rb +31 -1
- data/lib/rhc/output_helpers.rb +19 -3
- data/lib/rhc/rest/api.rb +2 -1
- data/lib/rhc/rest/application.rb +5 -4
- data/lib/rhc/rest/authorization.rb +10 -0
- data/lib/rhc/rest/base.rb +6 -1
- data/lib/rhc/rest/client.rb +243 -122
- data/lib/rhc/rest/domain.rb +0 -15
- data/lib/rhc/rest/gear_group.rb +0 -1
- data/lib/rhc/rest/mock.rb +118 -16
- data/lib/rhc/rest/user.rb +0 -1
- data/lib/rhc/rest.rb +28 -8
- data/lib/rhc/ssh_helpers.rb +5 -2
- data/lib/rhc/tar_gz.rb +16 -5
- data/lib/rhc/usage_templates/help.erb +1 -1
- data/lib/rhc/wizard.rb +54 -10
- data/spec/coverage_helper.rb +9 -0
- data/spec/rhc/auth_spec.rb +229 -22
- data/spec/rhc/cli_spec.rb +15 -0
- data/spec/rhc/command_spec.rb +100 -8
- data/spec/rhc/commands/account_spec.rb +75 -1
- data/spec/rhc/commands/app_spec.rb +23 -5
- data/spec/rhc/commands/authorization_spec.rb +120 -0
- data/spec/rhc/commands/domain_spec.rb +2 -2
- data/spec/rhc/commands/git_clone_spec.rb +24 -0
- data/spec/rhc/commands/port_forward_spec.rb +22 -23
- data/spec/rhc/commands/server_spec.rb +2 -2
- data/spec/rhc/commands/setup_spec.rb +12 -0
- data/spec/rhc/config_spec.rb +7 -3
- data/spec/rhc/helpers_spec.rb +62 -9
- data/spec/rhc/rest_application_spec.rb +24 -0
- data/spec/rhc/rest_client_spec.rb +66 -56
- data/spec/rhc/rest_spec.rb +11 -2
- data/spec/rhc/wizard_spec.rb +61 -12
- data/spec/spec_helper.rb +125 -42
- data/spec/wizard_spec_helper.rb +1 -0
- metadata +9 -3
data/spec/rhc/command_spec.rb
CHANGED
@@ -1,10 +1,17 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rhc/commands/base'
|
3
3
|
require 'rhc/exceptions'
|
4
|
+
require 'rest_spec_helper'
|
4
5
|
|
5
6
|
describe RHC::Commands::Base do
|
6
7
|
|
7
|
-
|
8
|
+
let!(:config){ base_config }
|
9
|
+
|
10
|
+
before{ c = RHC::Commands.instance_variable_get(:@commands); @saved_commands = c && c.dup || nil }
|
11
|
+
after do
|
12
|
+
(Kernel.send(:remove_const, subject) if subject.is_a?(Class)) rescue nil
|
13
|
+
RHC::Commands.instance_variable_set(:@commands, @saved_commands)
|
14
|
+
end
|
8
15
|
|
9
16
|
describe '#object_name' do
|
10
17
|
subject { described_class }
|
@@ -190,25 +197,110 @@ describe RHC::Commands::Base do
|
|
190
197
|
end
|
191
198
|
|
192
199
|
describe "rest_client" do
|
193
|
-
let(:
|
194
|
-
|
200
|
+
let(:instance){ subject }
|
201
|
+
|
202
|
+
context "when initializing the object" do
|
203
|
+
let(:auth){ mock }
|
204
|
+
let(:basic_auth){ mock }
|
205
|
+
before{ RHC::Auth::Basic.should_receive(:new).once.with{ |arg| arg.should == instance.send(:options) }.and_return(basic_auth) }
|
206
|
+
before{ RHC::Auth::Token.should_receive(:new).once.with{ |arg, arg2, arg3| [arg, arg2, arg3].should == [instance.send(:options), basic_auth, instance.send(:token_store)] }.and_return(auth) }
|
207
|
+
|
208
|
+
it "should create a new auth object" do
|
209
|
+
subject.should_receive(:client_from_options).with(:auth => auth)
|
210
|
+
subject.send(:rest_client)
|
211
|
+
end
|
212
|
+
it { subject.send(:rest_client).should be_a(RHC::Rest::Client) }
|
213
|
+
it { subject.send(:rest_client).should equal subject.send(:rest_client) }
|
214
|
+
end
|
195
215
|
|
196
|
-
|
197
|
-
subject.
|
198
|
-
|
216
|
+
context "from a command line" do
|
217
|
+
subject{ Class.new(RHC::Commands::Base){ object_name :test; def run; 0; end } }
|
218
|
+
let(:instance) { subject.new }
|
219
|
+
let(:rest_client){ command_for(*arguments).send(:rest_client) }
|
220
|
+
let(:basic_auth){ rest_client.send(:auth).send(:auth) }
|
221
|
+
let(:stored_token){ nil }
|
222
|
+
before{ instance.send(:token_store).stub(:get).and_return(nil) unless stored_token }
|
223
|
+
|
224
|
+
context "with credentials" do
|
225
|
+
let(:arguments){ ['test', '-l', 'foo', '-p', 'bar'] }
|
226
|
+
it { expect{ rest_client.user }.to call(:user).on(rest_client) }
|
227
|
+
end
|
228
|
+
|
229
|
+
context "without password" do
|
230
|
+
let(:username){ 'foo' }
|
231
|
+
let(:password){ 'bar' }
|
232
|
+
let(:arguments){ ['test', '-l', username, '--server', mock_uri] }
|
233
|
+
before{ stub_api(:user => username); stub_user(:user => username, :password => password) }
|
234
|
+
before{ basic_auth.should_receive(:ask).and_return(password) }
|
235
|
+
it("asks for password") { rest_client.user }
|
236
|
+
end
|
237
|
+
|
238
|
+
context "without name or password" do
|
239
|
+
let(:username){ 'foo' }
|
240
|
+
let(:password){ 'bar' }
|
241
|
+
let(:arguments){ ['test', '--server', mock_uri] }
|
242
|
+
before{ stub_api; stub_user(:user => username, :password => password) }
|
243
|
+
before{ basic_auth.should_receive(:ask).ordered.and_return(username) }
|
244
|
+
before{ basic_auth.should_receive(:ask).ordered.and_return(password) }
|
245
|
+
it("asks for password") { rest_client.user }
|
246
|
+
end
|
247
|
+
|
248
|
+
context "with token" do
|
249
|
+
let(:username){ 'foo' }
|
250
|
+
let(:token){ 'a_token' }
|
251
|
+
let(:arguments){ ['test', '--token', token, '--server', mock_uri] }
|
252
|
+
before{ stub_api(:token => token); stub_user(:token => token) }
|
253
|
+
it("calls the server") { rest_client.user }
|
254
|
+
end
|
255
|
+
|
256
|
+
context "with username and a stored token" do
|
257
|
+
let(:username){ 'foo' }
|
258
|
+
let(:stored_token){ 'a_token' }
|
259
|
+
let(:arguments){ ['test', '-l', username, '--server', mock_uri] }
|
260
|
+
before{ instance.send(:token_store).should_receive(:get).with{ |user, server| user.should == username; server.should == instance.send(:openshift_server) }.and_return(stored_token) }
|
261
|
+
before{ stub_api; stub_user(:token => stored_token) }
|
262
|
+
it("has token set") { command_for(*arguments).send(:options).token.should == stored_token }
|
263
|
+
it("calls the server") { rest_client.user }
|
264
|
+
end
|
265
|
+
|
266
|
+
context "with username and tokens enabled" do
|
267
|
+
let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'true') } }
|
268
|
+
let(:username){ 'foo' }
|
269
|
+
let(:auth_token){ stub(:token => 'a_token') }
|
270
|
+
let(:arguments){ ['test', '-l', username, '--server', mock_uri] }
|
271
|
+
before{ instance.send(:token_store).should_receive(:get).with{ |user, server| user.should == username; server.should == instance.send(:openshift_server) }.twice.and_return(nil) }
|
272
|
+
before{ stub_api(false, true); stub_api_request(:get, 'broker/rest/user', false).to_return{ |request| request.headers['Authorization'] =~ /Bearer/ ? simple_user(username) : {:status => 401} } }
|
273
|
+
it("should attempt to create a new token") do
|
274
|
+
rest_client.should_receive(:new_session).ordered.and_return(auth_token)
|
275
|
+
rest_client.user
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
context "with username and tokens enabled against a server without tokens" do
|
280
|
+
let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'true') } }
|
281
|
+
let(:username){ 'foo' }
|
282
|
+
let(:arguments){ ['test', '-l', username, '--server', mock_uri] }
|
283
|
+
before{ instance.send(:token_store).should_receive(:get).with{ |user, server| user.should == username; server.should == instance.send(:openshift_server) }.twice.and_return(nil) }
|
284
|
+
before{ stub_api(false, false); stub_api_request(:get, 'broker/rest/user', false).to_return{ |request| request.headers['Authorization'] =~ /Basic/ ? simple_user(username) : {:status => 401} } }
|
285
|
+
it("should prompt for password") do
|
286
|
+
basic_auth.should_receive(:ask).once.and_return('password')
|
287
|
+
rest_client.user
|
288
|
+
end
|
289
|
+
end
|
199
290
|
end
|
200
|
-
it { subject.send(:rest_client).should be_a(RHC::Rest::Client) }
|
201
|
-
it { subject.send(:rest_client).should equal subject.send(:rest_client) }
|
202
291
|
end
|
203
292
|
end
|
204
293
|
|
205
294
|
describe Commander::Command::Options do
|
206
295
|
it{ subject.foo = 'bar'; subject.foo.should == 'bar' }
|
296
|
+
it{ subject.foo = 'bar'; subject.respond_to?(:foo).should be_true }
|
207
297
|
it{ subject.foo = lambda{ 'bar' }; subject.foo.should == 'bar' }
|
208
298
|
it{ subject.foo = lambda{ 'bar' }; subject[:foo].should == 'bar' }
|
209
299
|
it{ subject.foo = lambda{ 'bar' }; subject['foo'].should == 'bar' }
|
210
300
|
it{ subject.foo = lambda{ 'bar' }; subject.__hash__[:foo].should be_a Proc }
|
211
301
|
it{ subject[:foo] = lambda{ 'bar' }; subject.foo.should == 'bar' }
|
212
302
|
it{ subject['foo'] = lambda{ 'bar' }; subject.foo.should == 'bar' }
|
303
|
+
it{ subject.is_a?(Commander::Command::Options).should be_true }
|
304
|
+
it{ expect{ subject.barf? }.to raise_error(NoMethodError) }
|
213
305
|
it{ Commander::Command::Options.new(:foo => 1).foo.should == 1 }
|
214
306
|
end
|
@@ -5,7 +5,7 @@ require 'rhc/commands/account'
|
|
5
5
|
|
6
6
|
describe RHC::Commands::Account do
|
7
7
|
|
8
|
-
describe 'run' do
|
8
|
+
describe '#run' do
|
9
9
|
let(:arguments) { ['account'] }
|
10
10
|
let(:username) { 'foo' }
|
11
11
|
let(:password) { 'pass' }
|
@@ -38,4 +38,78 @@ describe RHC::Commands::Account do
|
|
38
38
|
it('should show') { run_output.should =~ /Plan:\s*Other/ }
|
39
39
|
end
|
40
40
|
end
|
41
|
+
|
42
|
+
describe '#logout' do
|
43
|
+
let(:arguments) { ['account', 'logout'] }
|
44
|
+
let(:username) { 'foo' }
|
45
|
+
let(:password) { 'pass' }
|
46
|
+
let(:supports_auth) { false }
|
47
|
+
let(:server) { mock_uri }
|
48
|
+
let!(:token_store) { RHC::Auth::TokenStore.new(Dir.mktmpdir) }
|
49
|
+
before{ user_config }
|
50
|
+
before do
|
51
|
+
stub_api(mock_user_auth, supports_auth)
|
52
|
+
stub_user
|
53
|
+
RHC::Auth::TokenStore.should_receive(:new).at_least(1).and_return(token_store)
|
54
|
+
end
|
55
|
+
|
56
|
+
it("should clear the token cache"){ expect{ run }.should call(:clear).on(token_store) }
|
57
|
+
it("should exit with success"){ expect{ run }.should exit_with_code(0) }
|
58
|
+
it("should display a message"){ run_output.should match("All local sessions removed.") }
|
59
|
+
|
60
|
+
context "when --all is requested" do
|
61
|
+
let(:arguments) { ['account', 'logout', '--all'] }
|
62
|
+
|
63
|
+
context "if the server does not implement authorizations" do
|
64
|
+
it("should display a message"){ run_output.should match(/Deleting all authorizations associated with your account.*not supported/) }
|
65
|
+
it("should exit with success"){ expect{ run }.should exit_with_code(0) }
|
66
|
+
end
|
67
|
+
|
68
|
+
context "if the server implements authorizations" do
|
69
|
+
let(:supports_auth) { true }
|
70
|
+
before{ stub_delete_authorizations }
|
71
|
+
|
72
|
+
it("should display a message"){ run_output.should match(/Deleting all authorizations associated with your account.*done/) }
|
73
|
+
it("should exit with success"){ expect{ run }.should exit_with_code(0) }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when --token is provided" do
|
78
|
+
let(:arguments) { ['account', 'logout', '--token', 'foo'] }
|
79
|
+
def user_auth; { :token => 'foo' }; end
|
80
|
+
|
81
|
+
context "if the server does not implement authorizations" do
|
82
|
+
it("should display a message"){ run_output.should match(/Ending session on server.*not supported/) }
|
83
|
+
it("should exit with success"){ expect{ run }.should exit_with_code(0) }
|
84
|
+
end
|
85
|
+
|
86
|
+
context "if the server implements authorizations" do
|
87
|
+
let(:supports_auth) { true }
|
88
|
+
|
89
|
+
context "if the server returns successfully" do
|
90
|
+
before{ stub_delete_authorization('foo') }
|
91
|
+
|
92
|
+
it("should display a message"){ run_output.should match(/Ending session on server.*deleted/) }
|
93
|
+
it("should exit with success"){ expect{ run }.should exit_with_code(0) }
|
94
|
+
it("should clear the token cache"){ expect{ run }.should call(:clear).on(token_store) }
|
95
|
+
end
|
96
|
+
|
97
|
+
context "if the server rejects the token" do
|
98
|
+
before{ stub_request(:delete, mock_href('broker/rest/user/authorizations/foo', false)).to_return(:status => 401, :body => {}.to_json) }
|
99
|
+
|
100
|
+
it("should display a message"){ run_output.should match(/Ending session on server.*already closed/) }
|
101
|
+
it("should exit with success"){ expect{ run }.should exit_with_code(0) }
|
102
|
+
it("should clear the token cache"){ expect{ run }.should call(:clear).on(token_store) }
|
103
|
+
end
|
104
|
+
|
105
|
+
context "if the server returns an unexpected error" do
|
106
|
+
before{ stub_request(:delete, mock_href('broker/rest/user/authorizations/foo', false)).to_return(:status => 500, :body => {}.to_json) }
|
107
|
+
|
108
|
+
it("should display a message"){ run_output.should match(/Ending session on server.*The server did not respond/) }
|
109
|
+
it("should exit with success"){ expect{ run }.should exit_with_code(0) }
|
110
|
+
it("should clear the token cache"){ expect{ run }.should call(:clear).on(token_store) }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
41
115
|
end
|
@@ -43,6 +43,12 @@ describe RHC::Commands::App do
|
|
43
43
|
end
|
44
44
|
end
|
45
45
|
|
46
|
+
describe '#gear_group_state' do
|
47
|
+
it("shows single state"){ subject.send(:gear_group_state, ['started']).should == 'started' }
|
48
|
+
it("shows unique states"){ subject.send(:gear_group_state, ['idle', 'idle']).should == 'idle' }
|
49
|
+
it("shows number of started"){ subject.send(:gear_group_state, ['started', 'idle']).should == '1/2 started' }
|
50
|
+
end
|
51
|
+
|
46
52
|
describe 'app create' do
|
47
53
|
before(:each) do
|
48
54
|
domain = rest_client.add_domain("mockdomain")
|
@@ -150,9 +156,9 @@ describe RHC::Commands::App do
|
|
150
156
|
it "should create a jenkins app and a regular app with an embedded jenkins client" do
|
151
157
|
#puts run_output
|
152
158
|
expect { run }.should exit_with_code(0)
|
153
|
-
jenkins_app = @domain.
|
159
|
+
jenkins_app = rest_client.find_application(@domain.id,"jenkins")
|
154
160
|
jenkins_app.cartridges[0].name.should == "jenkins-1.4"
|
155
|
-
app = @domain.
|
161
|
+
app = rest_client.find_application(@domain.id,"app1")
|
156
162
|
app.find_cartridge("jenkins-client-1.4")
|
157
163
|
end
|
158
164
|
end
|
@@ -190,8 +196,8 @@ describe RHC::Commands::App do
|
|
190
196
|
end
|
191
197
|
it "should use existing jenkins" do
|
192
198
|
expect { run }.should exit_with_code(0)
|
193
|
-
expect { @domain.
|
194
|
-
expect { @domain.
|
199
|
+
expect { rest_client.find_application(@domain.id,"jenkins") }.should_not raise_error
|
200
|
+
expect { rest_client.find_application(@domain.id,"jenkins2") }.should raise_error(RHC::Rest::ApplicationNotFoundException)
|
195
201
|
end
|
196
202
|
end
|
197
203
|
end
|
@@ -328,7 +334,7 @@ describe RHC::Commands::App do
|
|
328
334
|
before{ @domain = rest_client.add_domain("mockdomain") }
|
329
335
|
|
330
336
|
it "should raise cartridge not found exception when no apps exist" do
|
331
|
-
expect { run }.should raise_error RHC::ApplicationNotFoundException
|
337
|
+
expect { run }.should raise_error RHC::Rest::ApplicationNotFoundException
|
332
338
|
end
|
333
339
|
|
334
340
|
context "with an app" do
|
@@ -416,6 +422,18 @@ describe RHC::Commands::App do
|
|
416
422
|
end
|
417
423
|
end
|
418
424
|
|
425
|
+
describe 'app show --gears' do
|
426
|
+
let(:arguments) { ['app', 'show', 'app1', '--gears', '--noprompt'] }
|
427
|
+
|
428
|
+
context 'when run' do
|
429
|
+
before(:each) do
|
430
|
+
@domain = rest_client.add_domain("mockdomain")
|
431
|
+
@domain.add_application("app1", "mock_type")
|
432
|
+
end
|
433
|
+
it { run_output.should match("fakegearid started fake_geargroup_cart-0.1") }
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
419
437
|
describe 'app ssh' do
|
420
438
|
let(:arguments) { ['app', 'ssh', 'app1'] }
|
421
439
|
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rest_spec_helper'
|
3
|
+
require 'rhc'
|
4
|
+
require 'rhc/commands/authorization'
|
5
|
+
|
6
|
+
describe RHC::Commands::Authorization do
|
7
|
+
|
8
|
+
def self.with_authorization
|
9
|
+
let(:username) { 'foo' }
|
10
|
+
let(:password) { 'pass' }
|
11
|
+
let(:server) { mock_uri }
|
12
|
+
before{ user_config }
|
13
|
+
before{ stub_api(true, true) }
|
14
|
+
end
|
15
|
+
def self.without_authorization
|
16
|
+
let(:username) { 'foo' }
|
17
|
+
let(:password) { 'pass' }
|
18
|
+
let(:server) { mock_uri }
|
19
|
+
before{ user_config }
|
20
|
+
before{ stub_api(true, false) }
|
21
|
+
end
|
22
|
+
def self.expect_an_unsupported_message
|
23
|
+
context "without authorizations" do
|
24
|
+
without_authorization
|
25
|
+
it('should warn that the server doesn\'t support auth'){ run_output.should =~ /The server does not support setting, retrieving, or authenticating with authorization tokens/ }
|
26
|
+
it{ expect{ run }.should exit_with_code(1) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#run' do
|
31
|
+
let(:arguments) { ['authorization'] }
|
32
|
+
context "with authorizations" do
|
33
|
+
with_authorization
|
34
|
+
before{ stub_authorizations }
|
35
|
+
it('should display the note') { run_output.should =~ /an_authorization/ }
|
36
|
+
it('should display the token') { run_output.should =~ /Token:\s+a_token_value/ }
|
37
|
+
it('should display the expiration') { run_output.should =~ /Expires In:\s+1 minute/ }
|
38
|
+
it('should display the creation date') { run_output.should =~ /Created:\s+#{RHC::Helpers.date('2013-02-21T01:00:01Z')}/ }
|
39
|
+
it('should display the scopes') { run_output.should =~ /Scopes:\s+session read/ }
|
40
|
+
it{ expect{ run }.should exit_with_code(0) }
|
41
|
+
end
|
42
|
+
|
43
|
+
expect_an_unsupported_message
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "#delete" do
|
47
|
+
let(:arguments) { ['authorization', 'delete', 'foo', 'bar'] }
|
48
|
+
|
49
|
+
context "with authorizations" do
|
50
|
+
with_authorization
|
51
|
+
before{ stub_delete_authorization('foo') }
|
52
|
+
before{ stub_delete_authorization('bar') }
|
53
|
+
it('should display success') { run_output.should =~ /Deleting auth.*done/ }
|
54
|
+
it{ expect{ run }.should exit_with_code(0) }
|
55
|
+
after{ a_request(:delete, mock_href('broker/rest/user/authorizations/foo', true)).should have_been_made }
|
56
|
+
after{ a_request(:delete, mock_href('broker/rest/user/authorizations/bar', true)).should have_been_made }
|
57
|
+
end
|
58
|
+
|
59
|
+
context "without a token in the command line" do
|
60
|
+
let(:arguments) { ['authorization', 'delete'] }
|
61
|
+
it('should display success') { run_output.should =~ /You must specify one or more tokens to delete/ }
|
62
|
+
it{ expect{ run }.should exit_with_code(1) }
|
63
|
+
end
|
64
|
+
|
65
|
+
expect_an_unsupported_message
|
66
|
+
end
|
67
|
+
|
68
|
+
describe "#delete_all" do
|
69
|
+
let(:arguments) { ['authorization', 'delete-all'] }
|
70
|
+
|
71
|
+
context "with authorizations" do
|
72
|
+
with_authorization
|
73
|
+
before{ stub_delete_authorizations }
|
74
|
+
it('should display success') { run_output.should =~ /Deleting all auth.*done/ }
|
75
|
+
it{ expect{ run }.should exit_with_code(0) }
|
76
|
+
after{ a_request(:delete, mock_href('broker/rest/user/authorizations', true)).should have_been_made }
|
77
|
+
end
|
78
|
+
|
79
|
+
expect_an_unsupported_message
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#scope_help" do
|
83
|
+
let(:rest_client){ stub(:authorization_scope_list => [['scope_1', 'A description'], ['scope_2', 'Another description']]) }
|
84
|
+
before{ subject.should_receive(:rest_client).and_return(rest_client) }
|
85
|
+
it{ capture{ subject.send(:scope_help) }.should =~ /scope_1.*A description/ }
|
86
|
+
it{ capture{ subject.send(:scope_help) }.should =~ /scope_2.*Another description/ }
|
87
|
+
it{ capture{ subject.send(:scope_help) }.should =~ /You may pass multiple scopes/ }
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#add" do
|
91
|
+
let(:arguments) { ['authorization', 'add'] }
|
92
|
+
|
93
|
+
context "with authorizations" do
|
94
|
+
using_command_instance
|
95
|
+
with_authorization
|
96
|
+
before{ instance.should_receive(:scope_help) }
|
97
|
+
|
98
|
+
it('should display the scope help') { command_output.should =~ /When adding an authorization.*to see more options/m }
|
99
|
+
it{ expect{ run_command }.should exit_with_code(0) }
|
100
|
+
end
|
101
|
+
|
102
|
+
expect_an_unsupported_message
|
103
|
+
|
104
|
+
context "with options" do
|
105
|
+
let(:arguments) { ['authorization', 'add', '--scope', 'foo,bar', '--note', 'a_note', '--expires-in', '300'] }
|
106
|
+
with_authorization
|
107
|
+
before{ stub_add_authorization(:note => 'a_note', :scope => 'foo,bar', :expires_in => '300') }
|
108
|
+
|
109
|
+
it('should display success') { run_output.should =~ /Adding authorization.*done/ }
|
110
|
+
it('should display the note') { run_output.should =~ /a_note/ }
|
111
|
+
it('should display the token') { run_output.should =~ /Token:\s+a_token_value/ }
|
112
|
+
it('should display the expiration') { run_output.should =~ /Expires In:\s+5 minutes/ }
|
113
|
+
it('should display the creation date') { run_output.should =~ /Created:\s+#{RHC::Helpers.date(mock_date_1)}/ }
|
114
|
+
it('should display the scopes') { run_output.should =~ /Scopes:\s+foo bar/ }
|
115
|
+
it{ expect{ run }.should exit_with_code(0) }
|
116
|
+
|
117
|
+
expect_an_unsupported_message
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -118,7 +118,7 @@ describe RHC::Commands::Domain do
|
|
118
118
|
expect { run }.should exit_with_code(127)
|
119
119
|
rest_client.domains.empty?.should be_true
|
120
120
|
end
|
121
|
-
it { run_output.should match("
|
121
|
+
it { run_output.should match("not found") }
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
@@ -155,7 +155,7 @@ describe RHC::Commands::Domain do
|
|
155
155
|
expect { run }.should exit_with_code(127)
|
156
156
|
rest_client.domains[0].id.should == 'dontdelete'
|
157
157
|
end
|
158
|
-
it { run_output.should match("Domain deleteme
|
158
|
+
it { run_output.should match("Domain deleteme not found") }
|
159
159
|
end
|
160
160
|
|
161
161
|
context 'when there are applications on the domain' do
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'rest_spec_helper'
|
3
3
|
require 'rhc/commands/git_clone'
|
4
|
+
require 'fileutils'
|
4
5
|
|
5
6
|
describe RHC::Commands::GitClone do
|
6
7
|
before(:each) do
|
@@ -45,6 +46,29 @@ describe RHC::Commands::GitClone do
|
|
45
46
|
it { run_output.should match("Cloned") }
|
46
47
|
end
|
47
48
|
|
49
|
+
context "testing git_clone_deploy_hooks" do
|
50
|
+
before do
|
51
|
+
@instance.stub(:git_clone_repo) do |git_url, repo_dir|
|
52
|
+
FileUtils.mkdir_p "#{repo_dir}/.git/hooks"
|
53
|
+
FileUtils.mkdir_p "#{repo_dir}/.openshift/git_hooks"
|
54
|
+
FileUtils.touch "#{repo_dir}/.openshift/git_hooks/pre_commit"
|
55
|
+
@instance.git_clone_deploy_hooks(repo_dir)
|
56
|
+
say "Copied" if File.exists?("#{repo_dir}/.git/hooks/pre_commit")
|
57
|
+
true
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get around the FakeFS bug (defunkt/fakefs#177) by
|
61
|
+
# stubbing the #cp call to inject a expected fs entry
|
62
|
+
FileUtils.stub(:cp) do |hook, dir|
|
63
|
+
FakeFS::FileSystem.add(
|
64
|
+
File.join(dir, File.basename(hook)),
|
65
|
+
FakeFS::FileSystem.find(hook))
|
66
|
+
end
|
67
|
+
end
|
68
|
+
it { expect { run }.should exit_with_code(0) }
|
69
|
+
it { run_output.should match("Copied") }
|
70
|
+
end
|
71
|
+
|
48
72
|
context "reports failure" do
|
49
73
|
before{ @instance.stub(:git_clone_repo).and_raise(RHC::GitException) }
|
50
74
|
|
@@ -65,11 +65,7 @@ describe RHC::Commands::PortForward do
|
|
65
65
|
@ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, 'mysql -> 127.0.0.1:3306')
|
66
66
|
forward = mock(Net::SSH::Service::Forward)
|
67
67
|
@ssh.should_receive(:forward).and_return(forward)
|
68
|
-
|
69
|
-
forward.should_receive(:local).with(3306, '127.0.0.1', 3306)
|
70
|
-
else
|
71
|
-
forward.should_receive(:local).with('127.0.0.1', 3306, '127.0.0.1', 3306)
|
72
|
-
end
|
68
|
+
forward.should_receive(:local).with(3306, '127.0.0.1', 3306)
|
73
69
|
@ssh.should_receive(:loop)
|
74
70
|
end
|
75
71
|
it "should run successfully" do
|
@@ -108,11 +104,7 @@ describe RHC::Commands::PortForward do
|
|
108
104
|
@ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, 'mysql -> 127.0.0.1:3306')
|
109
105
|
forward = mock(Net::SSH::Service::Forward)
|
110
106
|
@ssh.should_receive(:forward).and_return(forward)
|
111
|
-
|
112
|
-
forward.should_receive(:local).with(3306, '127.0.0.1', 3306)
|
113
|
-
else
|
114
|
-
forward.should_receive(:local).with('127.0.0.1', 3306, '127.0.0.1', 3306)
|
115
|
-
end
|
107
|
+
forward.should_receive(:local).with(3306, '127.0.0.1', 3306)
|
116
108
|
@ssh.should_receive(:loop).and_raise(Interrupt.new)
|
117
109
|
end
|
118
110
|
it "should exit when user interrupts" do
|
@@ -124,6 +116,21 @@ describe RHC::Commands::PortForward do
|
|
124
116
|
it { run_output.should include("Ending port forward") }
|
125
117
|
end
|
126
118
|
|
119
|
+
context 'when local port is already bound' do
|
120
|
+
before(:each) do
|
121
|
+
Net::SSH.should_receive(:start).with(@uri.host, @uri.user).and_yield(@ssh).twice
|
122
|
+
@ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, 'mysql -> 127.0.0.1:3306')
|
123
|
+
forward = mock(Net::SSH::Service::Forward)
|
124
|
+
@ssh.should_receive(:forward).at_least(2).and_return(forward)
|
125
|
+
forward.should_receive(:local).with(3306, '127.0.0.1', 3306).and_raise(Errno::EACCES)
|
126
|
+
forward.should_receive(:local).with(3307, '127.0.0.1', 3306)
|
127
|
+
@ssh.should_receive(:loop).and_raise(Interrupt.new)
|
128
|
+
end
|
129
|
+
it 'should bind to a higher port' do
|
130
|
+
run_output.should include("3307")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
127
134
|
context 'when host refuses connection' do
|
128
135
|
before(:each) do
|
129
136
|
Net::SSH.should_receive(:start).with(@uri.host, @uri.user).and_yield(@ssh).twice
|
@@ -149,19 +156,11 @@ describe RHC::Commands::PortForward do
|
|
149
156
|
and_yield(nil, :stderr, "httpd -> #{haproxy_host_1}:8080\nhttpd -> #{haproxy_host_2}:8080\nmongodb -> #{mongo_host}:35541\nmysqld -> #{ipv6_host}:3306")
|
150
157
|
forward = mock(Net::SSH::Service::Forward)
|
151
158
|
@ssh.should_receive(:forward).at_least(3).times.and_return(forward)
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
forward.should_receive(:local).with(3306, ipv6_host, 3306)
|
158
|
-
else
|
159
|
-
forward.should_receive(:local).with(haproxy_host_1, 8080, haproxy_host_1, 8080)
|
160
|
-
forward.should_receive(:local).with(haproxy_host_2, 8080, haproxy_host_2, 8080).and_raise(Errno::EADDRINUSE)
|
161
|
-
forward.should_receive(:local).with(haproxy_host_2, 8081, haproxy_host_2, 8080)
|
162
|
-
forward.should_receive(:local).with(mongo_host, 35541, mongo_host, 35541)
|
163
|
-
forward.should_receive(:local).with(ipv6_host, 3306, ipv6_host, 3306)
|
164
|
-
end
|
159
|
+
forward.should_receive(:local).with(8080, haproxy_host_1, 8080)
|
160
|
+
forward.should_receive(:local).with(8080, haproxy_host_2, 8080).and_raise(Errno::EADDRINUSE)
|
161
|
+
forward.should_receive(:local).with(8081, haproxy_host_2, 8080)
|
162
|
+
forward.should_receive(:local).with(35541, mongo_host, 35541)
|
163
|
+
forward.should_receive(:local).with(3306, ipv6_host, 3306)
|
165
164
|
@ssh.should_receive(:loop).and_raise(Interrupt.new)
|
166
165
|
end
|
167
166
|
it "should exit when user interrupts" do
|
@@ -11,13 +11,13 @@ describe RHC::Commands::Server do
|
|
11
11
|
let(:arguments) { ['server', '--server', 'foo.com', '-l', 'person', '-p', ''] }
|
12
12
|
|
13
13
|
context 'when server refuses connection' do
|
14
|
-
before { stub_request(:get, 'https://
|
14
|
+
before { stub_request(:get, 'https://foo.com/broker/rest/api').with(&user_agent_header).with(&expect_authorization(:user => 'person')).to_raise(SocketError) }
|
15
15
|
it('should output an error') { run_output.should =~ /Connected to foo.com.*Unable to connect to the server/m }
|
16
16
|
it { expect { run }.should exit_with_code(1) }
|
17
17
|
end
|
18
18
|
|
19
19
|
context 'when API is missing' do
|
20
|
-
before { stub_request(:get, 'https://
|
20
|
+
before { stub_request(:get, 'https://foo.com/broker/rest/api').with(&user_agent_header).with(&expect_authorization(:user => 'person')).to_return(:status => 404) }
|
21
21
|
it('should output an error') { run_output.should =~ /Connected to foo.com.*server is not responding correctly/m }
|
22
22
|
it { expect { run }.should exit_with_code(1) }
|
23
23
|
end
|
@@ -39,6 +39,18 @@ describe RHC::Commands::Setup do
|
|
39
39
|
|
40
40
|
it{ command_for('setup').options.server.should == 'openshift.redhat.com' }
|
41
41
|
it{ command_for('setup', '--server', 'foo.com').options.server.should == 'foo.com' }
|
42
|
+
it{ command_for('setup', '--no-create-token').options.create_token.should == false }
|
43
|
+
it{ command_for('setup', '--create-token').options.create_token.should == true }
|
44
|
+
|
45
|
+
context "when config has use_authorization_tokens=false" do
|
46
|
+
let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'false') } }
|
47
|
+
it{ command_for('setup').options.use_authorization_tokens.should == false }
|
48
|
+
end
|
49
|
+
context "when config has use_authorization_tokens=true" do
|
50
|
+
let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'true') } }
|
51
|
+
it{ command_for('setup').options.use_authorization_tokens.should == true }
|
52
|
+
end
|
53
|
+
|
42
54
|
=begin context 'when libra_server is set' do
|
43
55
|
before{ ENV.should_receive(:[]).any_number_of_times.with('LIBRA_SERVER').and_return('bar.com') }
|
44
56
|
it{ command_for('setup').config['libra_server'].should == 'bar.com' }
|
data/spec/rhc/config_spec.rb
CHANGED
@@ -6,6 +6,7 @@ describe RHC::Config do
|
|
6
6
|
subject{ RHC::Config }
|
7
7
|
before(:all) do
|
8
8
|
ENV['LIBRA_SERVER'] = nil
|
9
|
+
ENV['HTTP_PROXY'] = nil
|
9
10
|
ENV['http_proxy'] = nil
|
10
11
|
mock_terminal
|
11
12
|
RHC::Config.stub(:home_dir).and_return('/home/mock_user')
|
@@ -15,6 +16,8 @@ describe RHC::Config do
|
|
15
16
|
|
16
17
|
after(:all) do
|
17
18
|
FakeFS.deactivate!
|
19
|
+
ENV['HTTP_PROXY'] = nil
|
20
|
+
ENV['http_proxy'] = nil
|
18
21
|
end
|
19
22
|
|
20
23
|
describe "class" do
|
@@ -45,12 +48,12 @@ describe RHC::Config do
|
|
45
48
|
|
46
49
|
context "with an non true value for insecure" do
|
47
50
|
let(:values){ {'insecure' => 'untruth'} }
|
48
|
-
its(:to_options){ should == {:insecure =>
|
51
|
+
its(:to_options){ should == {:insecure => false} }
|
49
52
|
end
|
50
53
|
|
51
54
|
context "with an invalid timeout" do
|
52
55
|
let(:values){ {'timeout' => 'a'} }
|
53
|
-
|
56
|
+
it{ expect{ subject.to_options }.to raise_error(ArgumentError) }
|
54
57
|
end
|
55
58
|
|
56
59
|
context "with standard values" do
|
@@ -63,9 +66,10 @@ describe RHC::Config do
|
|
63
66
|
'ssl_client_cert_file' => 'file1',
|
64
67
|
'ssl_ca_file' => 'file2',
|
65
68
|
'timeout' => '1',
|
69
|
+
'use_authorization_tokens' => 'true',
|
66
70
|
}
|
67
71
|
end
|
68
|
-
its(:to_options){ should == {:insecure =>
|
72
|
+
its(:to_options){ should == {:insecure => true, :timeout => 1, :ssl_ca_file => 'file2', :ssl_client_cert_file => 'file1', :rhlogin => 'user', :password => 'pass', :server => 'test.com', :use_authorization_tokens => true} }
|
69
73
|
end
|
70
74
|
end
|
71
75
|
|