rhc 1.9.6 → 1.10.7
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.
- checksums.yaml +7 -0
- data/features/lib/rhc_helper.rb +0 -4
- data/features/lib/rhc_helper/app.rb +10 -10
- data/features/lib/rhc_helper/commandify.rb +6 -24
- data/features/support/before_hooks.rb +1 -1
- data/features/support/env.rb +9 -2
- data/features/support/platform_support.rb +11 -1
- data/lib/rhc/auth/basic.rb +4 -1
- data/lib/rhc/cartridge_helpers.rb +4 -8
- data/lib/rhc/commands.rb +6 -3
- data/lib/rhc/commands/alias.rb +1 -0
- data/lib/rhc/commands/app.rb +104 -67
- data/lib/rhc/commands/authorization.rb +2 -1
- data/lib/rhc/commands/base.rb +8 -1
- data/lib/rhc/commands/cartridge.rb +39 -16
- data/lib/rhc/commands/git_clone.rb +2 -1
- data/lib/rhc/commands/port_forward.rb +4 -6
- data/lib/rhc/commands/ssh.rb +54 -0
- data/lib/rhc/exceptions.rb +12 -7
- data/lib/rhc/git_helpers.rb +4 -5
- data/lib/rhc/help_formatter.rb +11 -6
- data/lib/rhc/helpers.rb +24 -3
- data/lib/rhc/highline_extensions.rb +31 -6
- data/lib/rhc/output_helpers.rb +0 -29
- data/lib/rhc/rest.rb +16 -1
- data/lib/rhc/rest/application.rb +7 -3
- data/lib/rhc/rest/base.rb +7 -2
- data/lib/rhc/rest/client.rb +7 -14
- data/lib/rhc/rest/gear_group.rb +10 -1
- data/lib/rhc/rest/mock.rb +34 -8
- data/lib/rhc/ssh_helpers.rb +144 -1
- data/lib/rhc/usage_templates/command_help.erb +16 -2
- data/spec/coverage_helper.rb +10 -7
- data/spec/rhc/commands/alias_spec.rb +28 -0
- data/spec/rhc/commands/app_spec.rb +64 -45
- data/spec/rhc/commands/authorization_spec.rb +16 -0
- data/spec/rhc/commands/cartridge_spec.rb +59 -3
- data/spec/rhc/commands/port_forward_spec.rb +6 -6
- data/spec/rhc/commands/ssh_spec.rb +125 -0
- data/spec/rhc/commands/tail_spec.rb +4 -3
- data/spec/rhc/helpers_spec.rb +70 -42
- data/spec/rhc/highline_extensions_spec.rb +23 -1
- data/spec/rhc/rest_client_spec.rb +6 -9
- data/spec/rhc/rest_spec.rb +41 -2
- data/spec/spec_helper.rb +38 -0
- metadata +336 -373
@@ -295,4 +295,32 @@ describe RHC::Commands::Alias do
|
|
295
295
|
end
|
296
296
|
end
|
297
297
|
|
298
|
+
describe 'aliases' do
|
299
|
+
before do
|
300
|
+
rest_client.stub(:api_version_negotiated).and_return(1.4)
|
301
|
+
end
|
302
|
+
context 'app with existing certificate' do
|
303
|
+
let(:arguments) { ['aliases', 'mock_app_0'] }
|
304
|
+
it { expect { run }.to exit_with_code(0) }
|
305
|
+
it { run_output.should =~ /Has Certificate?/m }
|
306
|
+
it { run_output.should =~ /Certificate Added/m }
|
307
|
+
it { run_output.should =~ /www.foo.bar/m }
|
308
|
+
end
|
309
|
+
context 'app without certificates' do
|
310
|
+
let(:arguments) { ['aliases', 'mock_app_1'] }
|
311
|
+
it { expect { run }.to exit_with_code(0) }
|
312
|
+
it { run_output.should =~ /No aliases associated with the application mock_app_1/m }
|
313
|
+
end
|
314
|
+
context 'simple list is server does not support ssl certs' do
|
315
|
+
let(:arguments) { ['aliases', 'mock_app_0'] }
|
316
|
+
before do
|
317
|
+
rest_client.stub(:api_version_negotiated).and_return(1.3)
|
318
|
+
end
|
319
|
+
it { expect { run }.to exit_with_code(0) }
|
320
|
+
it { run_output.should =~ /no/m }
|
321
|
+
it { run_output.should =~ /-/m }
|
322
|
+
it { run_output.should =~ /www.foo.bar/m }
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
298
326
|
end
|
@@ -19,8 +19,10 @@ describe RHC::Commands::App do
|
|
19
19
|
@instance.stub(:git_config_set) { "" }
|
20
20
|
Kernel.stub(:sleep) { }
|
21
21
|
@instance.stub(:git_clone_repo) do |git_url, repo_dir|
|
22
|
+
$terminal.instance_variable_get(:@output).puts "Cloning into..."
|
22
23
|
raise RHC::GitException, "Error in git clone" if repo_dir == "giterrorapp"
|
23
24
|
Dir::mkdir(repo_dir)
|
25
|
+
File.expand_path(repo_dir)
|
24
26
|
end
|
25
27
|
@instance.stub(:host_exists?) do |host|
|
26
28
|
host.match("dnserror") ? false : true
|
@@ -41,6 +43,8 @@ describe RHC::Commands::App do
|
|
41
43
|
context 'app' do
|
42
44
|
let(:arguments) { ['app'] }
|
43
45
|
it { run_output.should match('Usage:') }
|
46
|
+
it { run_output.should match('List of Actions') }
|
47
|
+
it { run_output.should_not match('Options') }
|
44
48
|
end
|
45
49
|
end
|
46
50
|
|
@@ -159,7 +163,7 @@ describe RHC::Commands::App do
|
|
159
163
|
before{ rest_client.domains.clear }
|
160
164
|
let(:arguments) { ['app', 'create', 'app1', 'mock_standalone_cart-1'] }
|
161
165
|
# skips login stage and insecure check because of mock rest client, doesn't check keys
|
162
|
-
it { run_output(['mydomain', 'y', 'mykey']).should match(/This wizard.*Checking your namespace.*Your domain name 'mydomain' has been successfully created.*Creating application.*Your public SSH key.*Uploading key 'mykey'
|
166
|
+
it { run_output(['mydomain', 'y', 'mykey']).should match(/This wizard.*Checking your namespace.*Your domain name 'mydomain' has been successfully created.*Creating application.*Your public SSH key.*Uploading key 'mykey'.*Your application 'app1' is now available.*Cloned to/m) }
|
163
167
|
end
|
164
168
|
|
165
169
|
context 'when run without a cart' do
|
@@ -207,8 +211,8 @@ describe RHC::Commands::App do
|
|
207
211
|
let(:arguments) { ['app', 'create', 'app1', 'mock_standalone_cart-1', '--from', 'git://url', '--noprompt', '-p', 'password'] }
|
208
212
|
it { expect { run }.to exit_with_code(0) }
|
209
213
|
it { run_output.should match("Success") }
|
214
|
+
it { run_output.should match("Git remote: git:fake.foo/git/app1.git\n") }
|
210
215
|
it { run_output.should match("Source Code: git://url\n") }
|
211
|
-
it { run_output.should match("Initial Git URL: git://url\n") }
|
212
216
|
after{ rest_client.domains.first.applications.first.initial_git_url.should == 'git://url' }
|
213
217
|
end
|
214
218
|
|
@@ -229,9 +233,7 @@ describe RHC::Commands::App do
|
|
229
233
|
end
|
230
234
|
|
231
235
|
describe 'cart matching behavior' do
|
232
|
-
before(
|
233
|
-
domain = rest_client.add_domain("mockdomain")
|
234
|
-
end
|
236
|
+
before{ rest_client.add_domain("mockdomain") }
|
235
237
|
|
236
238
|
context 'multiple web matches' do
|
237
239
|
let(:arguments) { ['app', 'create', 'app1', 'mock_standalone_cart', '--trace', '--noprompt'] }
|
@@ -246,8 +248,8 @@ describe RHC::Commands::App do
|
|
246
248
|
it('picks the non web cart') { run_output.should match('Using unique_mock_cart-1') }
|
247
249
|
end
|
248
250
|
context 'when I pick very ambiguous carts' do
|
249
|
-
let(:arguments) { ['app', 'create', 'app1', 'mock', '--noprompt'] }
|
250
|
-
it('shows only web carts') { run_output.
|
251
|
+
let(:arguments) { ['app', 'create', 'app1', 'mock', 'embcart-', '--noprompt'] }
|
252
|
+
it('shows only web carts') { run_output.should match("There are multiple cartridges matching 'mock'") }
|
251
253
|
end
|
252
254
|
context 'when I pick only embedded carts' do
|
253
255
|
let(:arguments) { ['app', 'create', 'app1', 'mock_cart', '--trace', '--noprompt'] }
|
@@ -259,7 +261,7 @@ describe RHC::Commands::App do
|
|
259
261
|
end
|
260
262
|
context 'when I pick multiple standalone carts' do
|
261
263
|
let(:arguments) { ['app', 'create', 'app1', 'unique_standalone', 'mock_standalone_cart', '--trace', '--noprompt'] }
|
262
|
-
it { expect { run }.to raise_error(RHC::MultipleCartridgesException, /
|
264
|
+
it { expect { run }.to raise_error(RHC::MultipleCartridgesException, /There are multiple cartridges matching 'mock_standalone_cart'/) }
|
263
265
|
end
|
264
266
|
context 'when I pick a custom URL cart' do
|
265
267
|
let(:arguments) { ['app', 'create', 'app1', 'http://foo.com', '--trace', '--noprompt'] }
|
@@ -267,9 +269,9 @@ describe RHC::Commands::App do
|
|
267
269
|
it('lists the cart using the short_name') { run_output.should match(%r(Cartridges:\s+http://foo.com$)) }
|
268
270
|
end
|
269
271
|
context 'when I pick a custom URL cart and a web cart' do
|
270
|
-
let(:arguments) { ['app', 'create', 'app1', 'http://foo.com', '
|
272
|
+
let(:arguments) { ['app', 'create', 'app1', 'http://foo.com', 'embcart-1', '--trace', '--noprompt'] }
|
271
273
|
it('tells me about custom carts') { run_output.should match("The cartridge 'http://foo.com' will be downloaded") }
|
272
|
-
it('lists the carts using the short_name') { run_output.should match(%r(Cartridges:\s+http://foo.com,
|
274
|
+
it('lists the carts using the short_name') { run_output.should match(%r(Cartridges:\s+http://foo.com, embcart-1$)) }
|
273
275
|
end
|
274
276
|
end
|
275
277
|
|
@@ -494,6 +496,37 @@ describe RHC::Commands::App do
|
|
494
496
|
end
|
495
497
|
end
|
496
498
|
end
|
499
|
+
|
500
|
+
context "against a 1.5 server" do
|
501
|
+
let!(:rest_client){ nil }
|
502
|
+
let(:username){ mock_user }
|
503
|
+
let(:password){ 'password' }
|
504
|
+
let(:server){ mock_uri }
|
505
|
+
let(:arguments){ ['delete-app', 'foo', '--confirm', '--trace'] }
|
506
|
+
before do
|
507
|
+
stub_api(true)
|
508
|
+
stub_one_domain('test')
|
509
|
+
stub_one_application('test', 'foo')
|
510
|
+
end
|
511
|
+
before do
|
512
|
+
stub_api_request(:delete, "broker/rest/domains/test/applications/foo").
|
513
|
+
to_return({
|
514
|
+
:body => {
|
515
|
+
:type => nil,
|
516
|
+
:data => nil,
|
517
|
+
:messages => [
|
518
|
+
{:exit_code => 0, :field => nil, :severity => 'info', :text => 'Removed foo'},
|
519
|
+
{:exit_code => 0, :field => nil, :severity => 'result', :text => 'Job URL changed'},
|
520
|
+
]
|
521
|
+
}.to_json,
|
522
|
+
:status => 200
|
523
|
+
})
|
524
|
+
end
|
525
|
+
|
526
|
+
it("should display info returned by the server"){ run_output.should match "Removed foo" }
|
527
|
+
it("should display results returned by the server"){ run_output.should match "Job URL changed" }
|
528
|
+
it('should exit successfully'){ expect{ run }.to exit_with_code(0) }
|
529
|
+
end
|
497
530
|
end
|
498
531
|
|
499
532
|
describe 'app show' do
|
@@ -564,66 +597,52 @@ describe RHC::Commands::App do
|
|
564
597
|
end
|
565
598
|
|
566
599
|
describe 'app show --gears' do
|
567
|
-
let(:arguments) { ['app', 'show', 'app1', '--gears'
|
600
|
+
let(:arguments) { ['app', 'show', 'app1', '--gears'] }
|
568
601
|
|
569
602
|
context 'when run' do
|
570
603
|
before(:each) do
|
571
604
|
@domain = rest_client.add_domain("mockdomain")
|
572
605
|
@domain.add_application("app1", "mock_type")
|
573
606
|
end
|
574
|
-
it { run_output.should match("
|
607
|
+
it { run_output.should match("fakegearid0 started mock_type small fakegearid0@fakesshurl.com") }
|
608
|
+
it { expect{ run }.to exit_with_code(0) }
|
575
609
|
end
|
576
610
|
end
|
577
611
|
|
578
|
-
describe 'app
|
579
|
-
let(:arguments) { ['app', '
|
612
|
+
describe 'app show --gears quota' do
|
613
|
+
let(:arguments) { ['app', 'show', 'app1', '--gears', 'quota'] }
|
580
614
|
|
581
615
|
context 'when run' do
|
582
|
-
before
|
616
|
+
before do
|
583
617
|
@domain = rest_client.add_domain("mockdomain")
|
584
|
-
@domain.add_application("app1", "mock_type")
|
585
|
-
|
618
|
+
@domain.add_application("app1", "mock_type", true)
|
619
|
+
expect_multi_ssh('echo "$(du -s 2>/dev/null | cut -f 1)"', 'fakegearid0@fakesshurl.com' => '1734934', 'fakegearid1@fakesshurl.com' => '1934234')
|
586
620
|
end
|
587
|
-
it { run_output.should match(
|
588
|
-
it { expect
|
621
|
+
it { run_output.should match(/Gear.*Cartridges.*Used.*fakegearid0.*1\.7 MB.*1 GB.*fakegearid1.*1\.9 MB/m) }
|
622
|
+
it { expect{ run }.to exit_with_code(0) }
|
589
623
|
end
|
590
624
|
end
|
591
625
|
|
592
|
-
describe 'app
|
593
|
-
let(:arguments) { ['app', '
|
626
|
+
describe 'app show --gears ssh' do
|
627
|
+
let(:arguments) { ['app', 'show', 'app1', '--gears', 'ssh'] }
|
594
628
|
|
595
629
|
context 'when run' do
|
596
|
-
before
|
630
|
+
before do
|
597
631
|
@domain = rest_client.add_domain("mockdomain")
|
598
|
-
@domain.add_application("app1", "mock_type")
|
599
|
-
@instance.should_receive(:has_ssh?).and_return(false)
|
632
|
+
@domain.add_application("app1", "mock_type", true)
|
600
633
|
end
|
601
|
-
it { run_output.should
|
602
|
-
it { expect
|
634
|
+
it { run_output.should == "fakegearid0@fakesshurl.com\nfakegearid1@fakesshurl.com\n\n" }
|
635
|
+
it { expect{ run }.to exit_with_code(0) }
|
603
636
|
end
|
604
637
|
end
|
605
638
|
|
606
|
-
describe 'app
|
607
|
-
let(:arguments) { ['app', '
|
639
|
+
describe 'app show --gears badcommand' do
|
640
|
+
let(:arguments) { ['app', 'show', 'app1', '--gears', 'badcommand'] }
|
608
641
|
|
609
642
|
context 'when run' do
|
610
|
-
before(
|
611
|
-
|
612
|
-
|
613
|
-
@instance.should_not_receive(:has_ssh?)
|
614
|
-
Kernel.should_receive(:system).with("path_to_ssh fakeuuidfortestsapp1@127.0.0.1").and_return(1)
|
615
|
-
end
|
616
|
-
it { run_output.should match("Connecting to fakeuuidfortestsapp") }
|
617
|
-
it { expect { run }.to exit_with_code(1) }
|
618
|
-
end
|
619
|
-
end
|
620
|
-
|
621
|
-
describe 'ssh tests' do
|
622
|
-
let(:arguments) { ['app', 'ssh', 'app1', '-s /bin/blah'] }
|
623
|
-
|
624
|
-
context 'has_ssh?' do
|
625
|
-
before{ @instance.stub(:ssh_version){ raise "Fake Exception" } }
|
626
|
-
its(:has_ssh?) { should be_false }
|
643
|
+
before{ rest_client.add_domain("mockdomain").add_application("app1", "mock_type", true) }
|
644
|
+
it { run_output.should match(/The operation badcommand is not supported/m) }
|
645
|
+
it { expect{ run }.to exit_with_code(1) }
|
627
646
|
end
|
628
647
|
end
|
629
648
|
|
@@ -52,6 +52,22 @@ describe RHC::Commands::Authorization do
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
+
describe '#list' do
|
56
|
+
let(:arguments) { ['authorization', 'list'] }
|
57
|
+
context "with authorizations" do
|
58
|
+
with_authorization
|
59
|
+
before{ stub_authorizations }
|
60
|
+
it('should display the note') { run_output.should =~ /an_authorization/ }
|
61
|
+
it('should display the token') { run_output.should =~ /Token:\s+a_token_value/ }
|
62
|
+
it('should display the expiration') { run_output.should =~ /Expires In:\s+1 minute/ }
|
63
|
+
it('should display the creation date') { run_output.should =~ /Created:\s+#{RHC::Helpers.date('2013-02-21T01:00:01Z')}/ }
|
64
|
+
it('should display the scopes') { run_output.should =~ /Scopes:\s+session read/ }
|
65
|
+
it{ expect{ run }.to exit_with_code(0) }
|
66
|
+
end
|
67
|
+
|
68
|
+
expect_an_unsupported_message
|
69
|
+
end
|
70
|
+
|
55
71
|
describe "#delete" do
|
56
72
|
let(:arguments) { ['authorization', 'delete', 'foo', 'bar'] }
|
57
73
|
|
@@ -59,6 +59,7 @@ describe RHC::Commands::Cartridge do
|
|
59
59
|
it{ run_output.should match "Mock2 description\n\n" }
|
60
60
|
it{ run_output.should match "Tagged with: scheduled" }
|
61
61
|
it{ run_output.should_not match("Tagged with: cartridge") }
|
62
|
+
it{ run_output.should match /Premium Cart.*\[premium_cart\-1\*\] \(web\)/ }
|
62
63
|
end
|
63
64
|
end
|
64
65
|
end
|
@@ -208,6 +209,38 @@ describe RHC::Commands::Cartridge do
|
|
208
209
|
expect { run }.to raise_error RHC::CartridgeNotFoundException
|
209
210
|
end
|
210
211
|
end
|
212
|
+
|
213
|
+
context "against a 1.5 server" do
|
214
|
+
let!(:rest_client){ nil }
|
215
|
+
let(:username){ mock_user }
|
216
|
+
let(:password){ 'password' }
|
217
|
+
let(:server){ mock_uri }
|
218
|
+
let(:arguments){ ['remove-cartridge', 'jenkins-1.4', '-a', 'foo', '--confirm', '--trace'] }
|
219
|
+
before do
|
220
|
+
stub_api(true)
|
221
|
+
stub_one_domain('test')
|
222
|
+
stub_one_application('test', 'foo').with(:query => {:include => 'cartridges'})
|
223
|
+
stub_application_cartridges('test', 'foo', [{:name => 'php-5.3'}, {:name => 'jenkins-1.4'}])
|
224
|
+
end
|
225
|
+
before do
|
226
|
+
stub_api_request(:delete, "broker/rest/domains/test/applications/foo/cartridges/jenkins-1.4").
|
227
|
+
to_return({
|
228
|
+
:body => {
|
229
|
+
:type => nil,
|
230
|
+
:data => nil,
|
231
|
+
:messages => [
|
232
|
+
{:exit_code => 0, :field => nil, :severity => 'info', :text => 'Removed Jenkins'},
|
233
|
+
{:exit_code => 0, :field => nil, :severity => 'result', :text => 'Job URL changed'},
|
234
|
+
]
|
235
|
+
}.to_json,
|
236
|
+
:status => 200
|
237
|
+
})
|
238
|
+
end
|
239
|
+
|
240
|
+
it("should display info returned by the server"){ run_output.should match "Removed Jenkins" }
|
241
|
+
it("should display results returned by the server"){ run_output.should match "Job URL changed" }
|
242
|
+
it('should exit successfully'){ expect{ run }.to exit_with_code(0) }
|
243
|
+
end
|
211
244
|
end
|
212
245
|
|
213
246
|
describe 'cartridge status' do
|
@@ -353,10 +386,10 @@ describe RHC::Commands::Cartridge do
|
|
353
386
|
let(:arguments) { ['cartridge', 'scale', @cart_type || 'mock_type', '-a', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] | (@extra_args || []) }
|
354
387
|
|
355
388
|
let(:current_scale) { 1 }
|
356
|
-
before
|
389
|
+
before do
|
357
390
|
domain = rest_client.add_domain("mock_domain")
|
358
|
-
app = domain.add_application("app1", "mock_type", scalable)
|
359
|
-
app.cartridges.first.stub(:current_scale).and_return(current_scale)
|
391
|
+
@app = domain.add_application("app1", "mock_type", scalable)
|
392
|
+
@app.cartridges.first.stub(:current_scale).and_return(current_scale)
|
360
393
|
end
|
361
394
|
|
362
395
|
context 'when run with scalable app' do
|
@@ -371,6 +404,21 @@ describe RHC::Commands::Cartridge do
|
|
371
404
|
succeed_with_message "minimum: 6"
|
372
405
|
end
|
373
406
|
|
407
|
+
it "with an explicit value" do
|
408
|
+
@extra_args = ["6"]
|
409
|
+
succeed_with_message "minimum: 6, maximum: 6"
|
410
|
+
end
|
411
|
+
|
412
|
+
it "with an invalid explicit value" do
|
413
|
+
@extra_args = ["a6"]
|
414
|
+
fail_with_message "Multiplier must be a positive integer"
|
415
|
+
end
|
416
|
+
|
417
|
+
it "with an explicit value and a different minimum" do
|
418
|
+
@extra_args = ["6", "--min", "5"]
|
419
|
+
succeed_with_message "minimum: 5, maximum: 6"
|
420
|
+
end
|
421
|
+
|
374
422
|
it "with a max value" do
|
375
423
|
@extra_args = ["--max","3"]
|
376
424
|
succeed_with_message 'maximum: 3'
|
@@ -385,6 +433,14 @@ describe RHC::Commands::Cartridge do
|
|
385
433
|
@extra_args = ["--max","a"]
|
386
434
|
fail_with_message "invalid argument: --max"
|
387
435
|
end
|
436
|
+
|
437
|
+
context "when the operation times out" do
|
438
|
+
before{ @app.cartridges.first.should_receive(:set_scales).twice.and_raise(RHC::Rest::TimeoutException.new('Timeout', HTTPClient::ReceiveTimeoutError.new)) }
|
439
|
+
it "displays an error" do
|
440
|
+
@extra_args = ["--min","2"]
|
441
|
+
fail_with_message "The server has closed the connection, but your scaling operation is still in progress"
|
442
|
+
end
|
443
|
+
end
|
388
444
|
end
|
389
445
|
|
390
446
|
context 'when run with a nonscalable app' do
|
@@ -28,7 +28,7 @@ describe RHC::Commands::PortForward do
|
|
28
28
|
it "should error out and suggest restarting the application" do
|
29
29
|
expect { run }.to exit_with_code(1)
|
30
30
|
end
|
31
|
-
it { run_output.should match(/
|
31
|
+
it { run_output.should match(/none.*The application is stopped\..*restart/m) }
|
32
32
|
end
|
33
33
|
|
34
34
|
context 'when port forwarding an app without ports to forward' do
|
@@ -174,11 +174,11 @@ describe RHC::Commands::PortForward do
|
|
174
174
|
|
175
175
|
context 'when port forwarding a single gear on a scaled app' do
|
176
176
|
let(:gear_host) { 'fakesshurl.com' }
|
177
|
-
let(:gear_user) { '
|
177
|
+
let(:gear_user) { 'fakegearid0' }
|
178
178
|
let(:arguments) { ['port-forward', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp', '--gear', @gear_id] }
|
179
179
|
|
180
180
|
it 'should run successfully' do
|
181
|
-
@gear_id = '
|
181
|
+
@gear_id = 'fakegearid0'
|
182
182
|
Net::SSH.should_receive(:start).with(gear_host, gear_user).and_yield(@ssh).twice
|
183
183
|
|
184
184
|
@ssh.should_receive(:exec!).with("rhc-list-ports --exclude-remote").
|
@@ -199,15 +199,15 @@ describe RHC::Commands::PortForward do
|
|
199
199
|
end
|
200
200
|
|
201
201
|
it 'should fail if the specified gear has no ssh info' do
|
202
|
-
@gear_id = '
|
202
|
+
@gear_id = 'fakegearid0'
|
203
203
|
|
204
204
|
# Given - gears in gear group should not have ssh info
|
205
205
|
gg = MockRestGearGroup.new(rest_client)
|
206
206
|
@app.stub(:gear_groups).and_return([gg])
|
207
|
-
gg.stub(:gears).and_return([{'state' => 'started', 'id' => '
|
207
|
+
gg.stub(:gears).and_return([{'state' => 'started', 'id' => 'fakegearid0'}])
|
208
208
|
|
209
209
|
expect { run }.to exit_with_code(1)
|
210
|
-
run_output.should
|
210
|
+
run_output.should match('The server does not support operations on individual gears.')
|
211
211
|
end
|
212
212
|
|
213
213
|
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'rest_spec_helper'
|
3
|
+
require 'rhc/commands/ssh'
|
4
|
+
|
5
|
+
describe RHC::Commands::Ssh do
|
6
|
+
let!(:rest_client){ MockRestClient.new }
|
7
|
+
let!(:config){ user_config }
|
8
|
+
before{ RHC::Config.stub(:home_dir).and_return('/home/mock_user') }
|
9
|
+
before{ Kernel.stub(:exec).and_raise(RuntimeError) }
|
10
|
+
|
11
|
+
describe 'ssh default' do
|
12
|
+
context 'ssh' do
|
13
|
+
let(:arguments) { ['ssh'] }
|
14
|
+
it { run_output.should match('Usage:') }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'ssh without command' do
|
19
|
+
let(:arguments) { ['app', 'ssh', 'app1'] }
|
20
|
+
|
21
|
+
context 'when run' do
|
22
|
+
before(:each) do
|
23
|
+
@domain = rest_client.add_domain("mockdomain")
|
24
|
+
@domain.add_application("app1", "mock_type")
|
25
|
+
Kernel.should_receive(:exec).with("ssh", "fakeuuidfortestsapp1@127.0.0.1").and_return(0)
|
26
|
+
end
|
27
|
+
it { run_output.should match("Connecting to fakeuuidfortestsapp") }
|
28
|
+
it { expect{ run }.to exit_with_code(0) }
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe 'app ssh with command' do
|
33
|
+
let(:arguments) { ['app', 'ssh', 'app1', 'ls', '/tmp'] }
|
34
|
+
|
35
|
+
context 'when run' do
|
36
|
+
before(:each) do
|
37
|
+
@domain = rest_client.add_domain("mockdomain")
|
38
|
+
@domain.add_application("app1", "mock_type")
|
39
|
+
Kernel.should_receive(:exec).with("ssh", "fakeuuidfortestsapp1@127.0.0.1", "ls", "/tmp").and_return(0)
|
40
|
+
end
|
41
|
+
it { run_output.should_not match("Connecting to fakeuuidfortestsapp") }
|
42
|
+
it { expect { run }.to exit_with_code(0) }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe 'app ssh with --gears' do
|
47
|
+
before{ rest_client.add_domain("mockdomain").add_application("app1", "mock_type", true) }
|
48
|
+
|
49
|
+
context 'with no command' do
|
50
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears'] }
|
51
|
+
it('should display usage info') { run_output.should match("Usage:") }
|
52
|
+
it { expect { run }.to exit_with_code(1) }
|
53
|
+
end
|
54
|
+
context 'with a command' do
|
55
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command', '--trace'] }
|
56
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => 'foo', 'fakegearid1@fakesshurl.com' => 'bar') }
|
57
|
+
it('should print the ssh output') { run_output.should == "[fakegearid0 ] foo\n[fakegearid1 ] bar\n\n" }
|
58
|
+
it('should return successfully') { expect{ run }.to exit_with_code(0) }
|
59
|
+
end
|
60
|
+
context 'with --raw' do
|
61
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command', '--raw'] }
|
62
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => 'foo', 'fakegearid1@fakesshurl.com' => 'bar') }
|
63
|
+
it('should print the ssh output') { run_output.should == "foo\nbar\n\n" }
|
64
|
+
end
|
65
|
+
context 'with --limit' do
|
66
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command', '--limit', '1'] }
|
67
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => 'foo', 'fakegearid1@fakesshurl.com' => 'bar') }
|
68
|
+
it('should print the ssh output') { run_output.should == "[fakegearid0 ] foo\n[fakegearid1 ] bar\n\n" }
|
69
|
+
end
|
70
|
+
context 'with invalid --limit value' do
|
71
|
+
['0','-10'].each do |value|
|
72
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command', '--limit', value] }
|
73
|
+
it { run_output.should match('--limit must be an integer greater than zero') }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
context 'with multiline output and --always-prefix' do
|
77
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command', '--always-prefix'] }
|
78
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => "foo\ntest", 'fakegearid1@fakesshurl.com' => "bar\ntest") }
|
79
|
+
it('should print the ssh output') { run_output.should == "[fakegearid0 ] foo\n[fakegearid0 ] test\n[fakegearid1 ] bar\n[fakegearid1 ] test\n\n" }
|
80
|
+
end
|
81
|
+
context 'with multiline output' do
|
82
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command'] }
|
83
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => "foo\ntest", 'fakegearid1@fakesshurl.com' => "bar\ntest") }
|
84
|
+
it('should print the ssh output') { run_output.should == "=== fakegearid0 \nfoo\ntest\n=== fakegearid1 \nbar\ntest\n\n" }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
describe 'app ssh no system ssh' do
|
89
|
+
let(:arguments) { ['app', 'ssh', 'app1'] }
|
90
|
+
|
91
|
+
context 'when run' do
|
92
|
+
before(:each) do
|
93
|
+
@domain = rest_client.add_domain("mockdomain")
|
94
|
+
@domain.add_application("app1", "mock_type")
|
95
|
+
RHC::Commands::Ssh.any_instance.should_receive(:has_ssh?).and_return(false)
|
96
|
+
end
|
97
|
+
it { run_output.should match("Please use the --ssh option to specify the path to your SSH executable, or install SSH.") }
|
98
|
+
it { expect { run }.to exit_with_code(1) }
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'app ssh custom ssh' do
|
103
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--ssh', 'path_to_ssh'] }
|
104
|
+
|
105
|
+
context 'when run' do
|
106
|
+
before(:each) do
|
107
|
+
@domain = rest_client.add_domain("mockdomain")
|
108
|
+
@domain.add_application("app1", "mock_type")
|
109
|
+
RHC::Commands::Ssh.any_instance.should_not_receive(:has_ssh?)
|
110
|
+
Kernel.should_receive(:exec).with("path_to_ssh", "fakeuuidfortestsapp1@127.0.0.1").once.times.and_return(0)
|
111
|
+
end
|
112
|
+
it { run_output.should match("Connecting to fakeuuidfortestsapp") }
|
113
|
+
it { expect { run }.to exit_with_code(0) }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe 'ssh tests' do
|
118
|
+
let(:arguments) { ['app', 'ssh', 'app1', '-s /bin/blah'] }
|
119
|
+
|
120
|
+
context 'has_ssh?' do
|
121
|
+
before{ RHC::Commands::Ssh.any_instance.stub(:ssh_version){ raise "Fake Exception" } }
|
122
|
+
its(:has_ssh?) { should be_false }
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|