rhc 1.4.8 → 1.5.13

Sign up to get free protection for your applications and to get access to all the features.
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