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.
Files changed (65) hide show
  1. data/features/application.feature +1 -0
  2. data/features/lib/rhc_helper/app.rb +5 -3
  3. data/features/lib/rhc_helper/commandify.rb +2 -1
  4. data/features/step_definitions/application_steps.rb +2 -1
  5. data/features/support/env.rb +4 -1
  6. data/lib/rhc/auth/basic.rb +18 -13
  7. data/lib/rhc/auth/token.rb +98 -0
  8. data/lib/rhc/auth/token_store.rb +51 -0
  9. data/lib/rhc/auth.rb +3 -1
  10. data/lib/rhc/command_runner.rb +1 -0
  11. data/lib/rhc/commands/account.rb +47 -1
  12. data/lib/rhc/commands/alias.rb +2 -4
  13. data/lib/rhc/commands/app.rb +23 -18
  14. data/lib/rhc/commands/authorization.rb +93 -0
  15. data/lib/rhc/commands/base.rb +11 -3
  16. data/lib/rhc/commands/cartridge.rb +8 -16
  17. data/lib/rhc/commands/git_clone.rb +2 -3
  18. data/lib/rhc/commands/port_forward.rb +10 -11
  19. data/lib/rhc/commands/setup.rb +4 -1
  20. data/lib/rhc/commands/snapshot.rb +4 -3
  21. data/lib/rhc/commands/tail.rb +3 -4
  22. data/lib/rhc/commands/threaddump.rb +1 -2
  23. data/lib/rhc/commands.rb +37 -3
  24. data/lib/rhc/config.rb +10 -1
  25. data/lib/rhc/context_helper.rb +5 -1
  26. data/lib/rhc/core_ext.rb +10 -0
  27. data/lib/rhc/exceptions.rb +0 -12
  28. data/lib/rhc/git_helpers.rb +12 -0
  29. data/lib/rhc/helpers.rb +31 -1
  30. data/lib/rhc/output_helpers.rb +19 -3
  31. data/lib/rhc/rest/api.rb +2 -1
  32. data/lib/rhc/rest/application.rb +5 -4
  33. data/lib/rhc/rest/authorization.rb +10 -0
  34. data/lib/rhc/rest/base.rb +6 -1
  35. data/lib/rhc/rest/client.rb +243 -122
  36. data/lib/rhc/rest/domain.rb +0 -15
  37. data/lib/rhc/rest/gear_group.rb +0 -1
  38. data/lib/rhc/rest/mock.rb +118 -16
  39. data/lib/rhc/rest/user.rb +0 -1
  40. data/lib/rhc/rest.rb +28 -8
  41. data/lib/rhc/ssh_helpers.rb +5 -2
  42. data/lib/rhc/tar_gz.rb +16 -5
  43. data/lib/rhc/usage_templates/help.erb +1 -1
  44. data/lib/rhc/wizard.rb +54 -10
  45. data/spec/coverage_helper.rb +9 -0
  46. data/spec/rhc/auth_spec.rb +229 -22
  47. data/spec/rhc/cli_spec.rb +15 -0
  48. data/spec/rhc/command_spec.rb +100 -8
  49. data/spec/rhc/commands/account_spec.rb +75 -1
  50. data/spec/rhc/commands/app_spec.rb +23 -5
  51. data/spec/rhc/commands/authorization_spec.rb +120 -0
  52. data/spec/rhc/commands/domain_spec.rb +2 -2
  53. data/spec/rhc/commands/git_clone_spec.rb +24 -0
  54. data/spec/rhc/commands/port_forward_spec.rb +22 -23
  55. data/spec/rhc/commands/server_spec.rb +2 -2
  56. data/spec/rhc/commands/setup_spec.rb +12 -0
  57. data/spec/rhc/config_spec.rb +7 -3
  58. data/spec/rhc/helpers_spec.rb +62 -9
  59. data/spec/rhc/rest_application_spec.rb +24 -0
  60. data/spec/rhc/rest_client_spec.rb +66 -56
  61. data/spec/rhc/rest_spec.rb +11 -2
  62. data/spec/rhc/wizard_spec.rb +61 -12
  63. data/spec/spec_helper.rb +125 -42
  64. data/spec/wizard_spec_helper.rb +1 -0
  65. metadata +9 -3
@@ -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
- before{ base_config }
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(:auth){ mock }
194
- before{ RHC::Auth::Basic.should_receive(:new).once.with(subject.send(:options)).and_return(auth) }
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
- it do
197
- subject.should_receive(:client_from_options).with(:auth => auth)
198
- subject.send(:rest_client)
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.find_application("jenkins")
159
+ jenkins_app = rest_client.find_application(@domain.id,"jenkins")
154
160
  jenkins_app.cartridges[0].name.should == "jenkins-1.4"
155
- app = @domain.find_application("app1")
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.find_application("jenkins") }.should_not raise_error
194
- expect { @domain.find_application("jenkins2") }.should raise_error(RHC::ApplicationNotFoundException)
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("does not exist") }
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 does not exist") }
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
- if mac?
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
- if mac?
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
- if mac?
153
- forward.should_receive(:local).with(8080, haproxy_host_1, 8080)
154
- forward.should_receive(:local).with(8080, haproxy_host_2, 8080).and_raise(Errno::EADDRINUSE)
155
- forward.should_receive(:local).with(8081, haproxy_host_2, 8080)
156
- forward.should_receive(:local).with(35541, mongo_host, 35541)
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://person:@foo.com/broker/rest/api').with(&user_agent_header).to_raise(SocketError) }
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://person:@foo.com/broker/rest/api').with(&user_agent_header).to_return(:status => 404) }
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' }
@@ -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 => 'untruth'} }
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
- its(:to_options){ should == {:timeout => 'a'} }
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 => 'true', :timeout => '1', :ssl_ca_file => 'file2', :ssl_client_cert_file => 'file1', :rhlogin => 'user', :password => 'pass', :server => 'test.com'} }
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