startapp 0.1.6
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/COPYRIGHT +1 -0
- data/LICENSE +11 -0
- data/README.md +95 -0
- data/Rakefile +6 -0
- data/autocomplete/rhc_bash +1672 -0
- data/bin/app +37 -0
- data/conf/express.conf +8 -0
- data/features/assets/deploy.tar.gz +0 -0
- data/features/core_feature.rb +191 -0
- data/features/deployments_feature.rb +129 -0
- data/features/domains_feature.rb +58 -0
- data/features/keys_feature.rb +37 -0
- data/features/members_feature.rb +166 -0
- data/lib/rhc/auth/basic.rb +64 -0
- data/lib/rhc/auth/token.rb +102 -0
- data/lib/rhc/auth/token_store.rb +53 -0
- data/lib/rhc/auth.rb +5 -0
- data/lib/rhc/autocomplete.rb +66 -0
- data/lib/rhc/autocomplete_templates/bash.erb +39 -0
- data/lib/rhc/cartridge_helpers.rb +118 -0
- data/lib/rhc/cli.rb +40 -0
- data/lib/rhc/command_runner.rb +185 -0
- data/lib/rhc/commands/account.rb +25 -0
- data/lib/rhc/commands/alias.rb +124 -0
- data/lib/rhc/commands/app.rb +726 -0
- data/lib/rhc/commands/apps.rb +20 -0
- data/lib/rhc/commands/authorization.rb +115 -0
- data/lib/rhc/commands/base.rb +174 -0
- data/lib/rhc/commands/cartridge.rb +329 -0
- data/lib/rhc/commands/clone.rb +66 -0
- data/lib/rhc/commands/configure.rb +20 -0
- data/lib/rhc/commands/create.rb +100 -0
- data/lib/rhc/commands/delete.rb +19 -0
- data/lib/rhc/commands/deploy.rb +32 -0
- data/lib/rhc/commands/deployment.rb +82 -0
- data/lib/rhc/commands/domain.rb +172 -0
- data/lib/rhc/commands/env.rb +142 -0
- data/lib/rhc/commands/force_stop.rb +17 -0
- data/lib/rhc/commands/git_clone.rb +34 -0
- data/lib/rhc/commands/logout.rb +51 -0
- data/lib/rhc/commands/logs.rb +21 -0
- data/lib/rhc/commands/member.rb +148 -0
- data/lib/rhc/commands/port_forward.rb +197 -0
- data/lib/rhc/commands/reload.rb +17 -0
- data/lib/rhc/commands/restart.rb +17 -0
- data/lib/rhc/commands/scp.rb +54 -0
- data/lib/rhc/commands/server.rb +40 -0
- data/lib/rhc/commands/setup.rb +60 -0
- data/lib/rhc/commands/show.rb +43 -0
- data/lib/rhc/commands/snapshot.rb +137 -0
- data/lib/rhc/commands/ssh.rb +51 -0
- data/lib/rhc/commands/sshkey.rb +97 -0
- data/lib/rhc/commands/start.rb +17 -0
- data/lib/rhc/commands/stop.rb +17 -0
- data/lib/rhc/commands/tail.rb +47 -0
- data/lib/rhc/commands/threaddump.rb +14 -0
- data/lib/rhc/commands/tidy.rb +17 -0
- data/lib/rhc/commands.rb +396 -0
- data/lib/rhc/config.rb +321 -0
- data/lib/rhc/context_helper.rb +121 -0
- data/lib/rhc/core_ext.rb +202 -0
- data/lib/rhc/coverage_helper.rb +33 -0
- data/lib/rhc/deployment_helpers.rb +111 -0
- data/lib/rhc/exceptions.rb +256 -0
- data/lib/rhc/git_helpers.rb +106 -0
- data/lib/rhc/help_formatter.rb +55 -0
- data/lib/rhc/helpers.rb +481 -0
- data/lib/rhc/highline_extensions.rb +479 -0
- data/lib/rhc/json.rb +51 -0
- data/lib/rhc/output_helpers.rb +260 -0
- data/lib/rhc/rest/activation.rb +11 -0
- data/lib/rhc/rest/alias.rb +42 -0
- data/lib/rhc/rest/api.rb +87 -0
- data/lib/rhc/rest/application.rb +348 -0
- data/lib/rhc/rest/attributes.rb +36 -0
- data/lib/rhc/rest/authorization.rb +8 -0
- data/lib/rhc/rest/base.rb +79 -0
- data/lib/rhc/rest/cartridge.rb +162 -0
- data/lib/rhc/rest/client.rb +650 -0
- data/lib/rhc/rest/deployment.rb +18 -0
- data/lib/rhc/rest/domain.rb +98 -0
- data/lib/rhc/rest/environment_variable.rb +15 -0
- data/lib/rhc/rest/gear_group.rb +16 -0
- data/lib/rhc/rest/httpclient.rb +145 -0
- data/lib/rhc/rest/key.rb +44 -0
- data/lib/rhc/rest/membership.rb +105 -0
- data/lib/rhc/rest/mock.rb +1042 -0
- data/lib/rhc/rest/user.rb +32 -0
- data/lib/rhc/rest.rb +148 -0
- data/lib/rhc/scp_helpers.rb +27 -0
- data/lib/rhc/ssh_helpers.rb +380 -0
- data/lib/rhc/tar_gz.rb +51 -0
- data/lib/rhc/usage_templates/command_help.erb +51 -0
- data/lib/rhc/usage_templates/command_syntax_help.erb +11 -0
- data/lib/rhc/usage_templates/help.erb +61 -0
- data/lib/rhc/usage_templates/missing_help.erb +1 -0
- data/lib/rhc/usage_templates/options_help.erb +12 -0
- data/lib/rhc/vendor/okjson.rb +600 -0
- data/lib/rhc/vendor/parseconfig.rb +178 -0
- data/lib/rhc/vendor/sshkey.rb +253 -0
- data/lib/rhc/vendor/zliby.rb +628 -0
- data/lib/rhc/version.rb +5 -0
- data/lib/rhc/wizard.rb +637 -0
- data/lib/rhc.rb +34 -0
- data/spec/coverage_helper.rb +82 -0
- data/spec/direct_execution_helper.rb +339 -0
- data/spec/keys/example.pem +23 -0
- data/spec/keys/example_private.pem +27 -0
- data/spec/keys/server.pem +19 -0
- data/spec/rest_spec_helper.rb +31 -0
- data/spec/rhc/assets/cert.crt +22 -0
- data/spec/rhc/assets/cert_key_rsa +27 -0
- data/spec/rhc/assets/empty.txt +0 -0
- data/spec/rhc/assets/env_vars.txt +7 -0
- data/spec/rhc/assets/env_vars_2.txt +1 -0
- data/spec/rhc/assets/foo.txt +1 -0
- data/spec/rhc/assets/targz_corrupted.tar.gz +1 -0
- data/spec/rhc/assets/targz_sample.tar.gz +0 -0
- data/spec/rhc/auth_spec.rb +442 -0
- data/spec/rhc/cli_spec.rb +186 -0
- data/spec/rhc/command_spec.rb +435 -0
- data/spec/rhc/commands/account_spec.rb +42 -0
- data/spec/rhc/commands/alias_spec.rb +333 -0
- data/spec/rhc/commands/app_spec.rb +777 -0
- data/spec/rhc/commands/apps_spec.rb +39 -0
- data/spec/rhc/commands/authorization_spec.rb +157 -0
- data/spec/rhc/commands/cartridge_spec.rb +665 -0
- data/spec/rhc/commands/clone_spec.rb +41 -0
- data/spec/rhc/commands/deployment_spec.rb +327 -0
- data/spec/rhc/commands/domain_spec.rb +401 -0
- data/spec/rhc/commands/env_spec.rb +493 -0
- data/spec/rhc/commands/git_clone_spec.rb +102 -0
- data/spec/rhc/commands/logout_spec.rb +86 -0
- data/spec/rhc/commands/member_spec.rb +247 -0
- data/spec/rhc/commands/port_forward_spec.rb +217 -0
- data/spec/rhc/commands/scp_spec.rb +77 -0
- data/spec/rhc/commands/server_spec.rb +69 -0
- data/spec/rhc/commands/setup_spec.rb +118 -0
- data/spec/rhc/commands/snapshot_spec.rb +179 -0
- data/spec/rhc/commands/ssh_spec.rb +163 -0
- data/spec/rhc/commands/sshkey_spec.rb +188 -0
- data/spec/rhc/commands/tail_spec.rb +81 -0
- data/spec/rhc/commands/threaddump_spec.rb +84 -0
- data/spec/rhc/config_spec.rb +407 -0
- data/spec/rhc/helpers_spec.rb +531 -0
- data/spec/rhc/highline_extensions_spec.rb +314 -0
- data/spec/rhc/json_spec.rb +30 -0
- data/spec/rhc/rest_application_spec.rb +258 -0
- data/spec/rhc/rest_client_spec.rb +752 -0
- data/spec/rhc/rest_spec.rb +740 -0
- data/spec/rhc/targz_spec.rb +55 -0
- data/spec/rhc/wizard_spec.rb +756 -0
- data/spec/spec_helper.rb +575 -0
- data/spec/wizard_spec_helper.rb +330 -0
- metadata +469 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rest_spec_helper'
|
|
3
|
+
require 'rhc/commands/server'
|
|
4
|
+
require 'rhc/config'
|
|
5
|
+
|
|
6
|
+
describe RHC::Commands::Server do
|
|
7
|
+
before(:each){ user_config }
|
|
8
|
+
let(:rest_client) { MockRestClient.new }
|
|
9
|
+
|
|
10
|
+
describe 'run against a different server' do
|
|
11
|
+
let(:arguments) { ['server', '--server', 'foo.com', '-l', 'person', '-p', ''] }
|
|
12
|
+
|
|
13
|
+
context 'when server refuses connection' do
|
|
14
|
+
before { stub_request(:get, 'https://foo.com/broker/rest/api').with(&user_agent_header).to_raise(SocketError) }
|
|
15
|
+
it('should output an error') { run_output.should =~ /Connected to foo.com.*Unable to connect to the server/m }
|
|
16
|
+
it { expect { run }.to exit_with_code(1) }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
context 'when API is missing' do
|
|
20
|
+
before { stub_request(:get, 'https://foo.com/broker/rest/api').with(&user_agent_header).to_return(:status => 404) }
|
|
21
|
+
it('should output an error') { run_output.should =~ /Connected to foo.com.*server is not responding correctly/m }
|
|
22
|
+
it { expect { run }.to exit_with_code(1) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context 'when API is at version 1.2' do
|
|
26
|
+
before do
|
|
27
|
+
rest_client.stub(:api_version_negotiated).and_return('1.2')
|
|
28
|
+
end
|
|
29
|
+
it('should output an error') { run_output.should =~ /Connected to foo.com.*Using API version 1.2/m }
|
|
30
|
+
it { expect { run }.to exit_with_code(0) }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe 'run against an invalid server url' do
|
|
35
|
+
let(:arguments) { ['server', '--server', 'invalid_uri', '-l', 'person', '-p', ''] }
|
|
36
|
+
it('should output an invalid URI error') { run_output.should match('Invalid URI specified: invalid_uri') }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe 'run' do
|
|
40
|
+
let(:arguments) { ['server'] }
|
|
41
|
+
before{ rest_client.stub(:auth).and_return(nil) }
|
|
42
|
+
|
|
43
|
+
context 'when no issues' do
|
|
44
|
+
before { stub_request(:get, 'https://broker.startapp.bg/app/status/status.json').with(&user_agent_header).to_return(:body => {'issues' => []}.to_json) }
|
|
45
|
+
it('should output success') { run_output.should =~ /All systems running fine/ }
|
|
46
|
+
it { expect { run }.to exit_with_code(0) }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
context 'when 1 issue' do
|
|
50
|
+
before do
|
|
51
|
+
stub_request(:get, 'https://broker.startapp.bg/app/status/status.json').with(&user_agent_header).to_return(:body =>
|
|
52
|
+
{'open' => [
|
|
53
|
+
{'issue' => {
|
|
54
|
+
'created_at' => '2011-05-22T17:31:32-04:00',
|
|
55
|
+
'id' => 11,
|
|
56
|
+
'title' => 'Root cause',
|
|
57
|
+
'updates' => [{
|
|
58
|
+
'created_at' => '2012-05-22T13:48:20-04:00',
|
|
59
|
+
'description' => 'Working on update'
|
|
60
|
+
}]
|
|
61
|
+
}}]}.to_json)
|
|
62
|
+
end
|
|
63
|
+
it { expect { run }.to exit_with_code(1) }
|
|
64
|
+
it('should output message') { run_output.should =~ /1 open issue/ }
|
|
65
|
+
it('should output title') { run_output.should =~ /Root cause/ }
|
|
66
|
+
it('should contain update') { run_output.should =~ /Working on update/ }
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rest_spec_helper'
|
|
3
|
+
require 'rhc/commands/setup'
|
|
4
|
+
|
|
5
|
+
# just test the command runner as we already have extensive wizard tests
|
|
6
|
+
describe RHC::Commands::Setup do
|
|
7
|
+
subject{ RHC::Commands::Setup }
|
|
8
|
+
let(:instance){ subject.new }
|
|
9
|
+
let!(:config){ base_config }
|
|
10
|
+
before{ described_class.send(:public, *described_class.protected_instance_methods) }
|
|
11
|
+
before{ FakeFS::FileSystem.clear }
|
|
12
|
+
before{ RHC::Config.stub(:home_dir).and_return('/home/mock_user') }
|
|
13
|
+
|
|
14
|
+
describe '#run' do
|
|
15
|
+
it{ expects_running('setup').should call(:run).on(instance).with(no_args) }
|
|
16
|
+
|
|
17
|
+
let(:arguments) { ['setup', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'] }
|
|
18
|
+
|
|
19
|
+
before(:each) do
|
|
20
|
+
@wizard = double('wizard')
|
|
21
|
+
@wizard.stub(:run).and_return(true)
|
|
22
|
+
RHC::RerunWizard.stub(:new){ @wizard }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
context 'when no issues' do
|
|
26
|
+
it "should exit 0" do
|
|
27
|
+
expect { run }.to exit_with_code(0)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'when there is an issue' do
|
|
32
|
+
it "should exit 1" do
|
|
33
|
+
@wizard.stub(:run).and_return(false)
|
|
34
|
+
expect { run }.to exit_with_code(1)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it{ expects_running('setup').should call(:run).on(instance).with(no_args) }
|
|
40
|
+
it{ command_for('setup', '--clean').options.clean.should be_true }
|
|
41
|
+
|
|
42
|
+
it{ command_for('setup').options.server.should == 'broker.startapp.bg' }
|
|
43
|
+
it{ command_for('setup', '--server', 'foo.com').options.server.should == 'foo.com' }
|
|
44
|
+
it{ command_for('setup', '--no-create-token').options.create_token.should == false }
|
|
45
|
+
it{ command_for('setup', '--create-token').options.create_token.should == true }
|
|
46
|
+
|
|
47
|
+
context "when config has use_authorization_tokens=false" do
|
|
48
|
+
let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'false') } }
|
|
49
|
+
it{ command_for('setup').options.use_authorization_tokens.should == false }
|
|
50
|
+
end
|
|
51
|
+
context "when config has use_authorization_tokens=true" do
|
|
52
|
+
let!(:config){ base_config{ |c, d| d.add('use_authorization_tokens', 'true') } }
|
|
53
|
+
it{ command_for('setup').options.use_authorization_tokens.should == true }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
=begin context 'when libra_server is set' do
|
|
57
|
+
before{ ENV.stub(:[]).with('LIBRA_SERVER').and_return('bar.com') }
|
|
58
|
+
it{ command_for('setup').config['libra_server'].should == 'bar.com' }
|
|
59
|
+
it{ command_for('setup').options.server.should == 'bar.com' }
|
|
60
|
+
it{ command_for('setup', '--server', 'foo.com').options.server.should == 'foo.com' }
|
|
61
|
+
=end end
|
|
62
|
+
|
|
63
|
+
context 'when --clean is used' do
|
|
64
|
+
let!(:config){ base_config{ |config, defaults| defaults.add 'libra_server', 'test.com' } }
|
|
65
|
+
|
|
66
|
+
it("should ignore a config value"){ command_for('setup', '--clean').options.server.should == 'broker.startapp.bg' }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context 'when -d is passed' do
|
|
70
|
+
let(:arguments) { ['setup', '-d', '-l', 'test@test.foo'] }
|
|
71
|
+
# 'y' for the password prompt
|
|
72
|
+
let(:input) { ['', 'y', '', ''] }
|
|
73
|
+
let!(:rest_client){ MockRestClient.new }
|
|
74
|
+
|
|
75
|
+
it("succeeds"){ FakeFS{ expect { run input }.to exit_with_code 0 } }
|
|
76
|
+
it("the output includes debug output") do
|
|
77
|
+
FakeFS{ run_output( input ).should match 'DEBUG' }
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
context 'when -l is used to specify the user name' do
|
|
82
|
+
let(:arguments) { ['setup', '-l', 'test@test.foo'] }
|
|
83
|
+
# 'y' for the password prompt
|
|
84
|
+
let(:input) { ['', 'y', '', ''] }
|
|
85
|
+
let!(:rest_client){ MockRestClient.new }
|
|
86
|
+
|
|
87
|
+
it("succeeds"){ FakeFS{ expect { run input }.to exit_with_code 0 } }
|
|
88
|
+
it("sets the user name to the value given by the command line") do
|
|
89
|
+
FakeFS{ run_output( input ).should match 'test@test.foo' }
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe 'help' do
|
|
94
|
+
let(:arguments) { ['setup', '--help'] }
|
|
95
|
+
|
|
96
|
+
context 'help is run' do
|
|
97
|
+
it "should display help" do
|
|
98
|
+
@wizard.stub(:run).and_return(true)
|
|
99
|
+
expect { run }.to exit_with_code(0)
|
|
100
|
+
end
|
|
101
|
+
it('should output usage') { run_output.should match("Connects to an StartApp server to get you started. Will") }
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
describe '--autocomplete' do
|
|
106
|
+
let(:arguments) { ['setup', '--autocomplete'] }
|
|
107
|
+
before do
|
|
108
|
+
path = File.join(Gem.loaded_specs['app'].full_gem_path, "autocomplete")
|
|
109
|
+
FakeFS::FileUtils.mkdir_p(path)
|
|
110
|
+
FakeFS::FileUtils.touch(File.join(path, "rhc_bash"))
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
context 'is passed' do
|
|
114
|
+
it('should output information') { FakeFS{ run_output.should match("To enable tab-completion") } }
|
|
115
|
+
it('should output the gem path') { FakeFS{ run_output.should match File.join(RHC::Config.home_conf_dir, 'bash_autocomplete') } }
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rest_spec_helper'
|
|
3
|
+
require 'rhc/commands/snapshot'
|
|
4
|
+
require 'rhc/config'
|
|
5
|
+
require 'rhc/tar_gz'
|
|
6
|
+
|
|
7
|
+
describe RHC::Commands::Snapshot do
|
|
8
|
+
|
|
9
|
+
APP_NAME = 'mockapp'
|
|
10
|
+
|
|
11
|
+
let!(:rest_client) { MockRestClient.new }
|
|
12
|
+
before do
|
|
13
|
+
user_config
|
|
14
|
+
@app = rest_client.add_domain("mockdomain").add_application APP_NAME, 'mock-1.0'
|
|
15
|
+
@ssh_uri = URI.parse @app.ssh_url
|
|
16
|
+
@targz_filename = APP_NAME + '.tar.gz'
|
|
17
|
+
FileUtils.cp(File.expand_path('../../assets/targz_sample.tar.gz', __FILE__), @targz_filename)
|
|
18
|
+
File.chmod 0644, @targz_filename unless File.executable? @targz_filename
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
after do
|
|
22
|
+
File.delete @targz_filename if File.exist? @targz_filename
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe 'snapshot without an action' do
|
|
26
|
+
let(:arguments) {['snapshot', '--trace', '--noprompt']}
|
|
27
|
+
it('should raise') { expect{ run }.to raise_error(ArgumentError, /Please specify an action to take/) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'snapshot save' do
|
|
31
|
+
let(:arguments) {['snapshot', 'save', '--app', 'mockapp', '-d']}
|
|
32
|
+
|
|
33
|
+
context 'when saving a snapshot' do
|
|
34
|
+
before do
|
|
35
|
+
subject.class.any_instance.should_receive(:exec).with("ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'snapshot' > #{@app.name}.tar.gz").and_return([0, 'some save output'])
|
|
36
|
+
end
|
|
37
|
+
it { expect { run }.to exit_with_code(0) }
|
|
38
|
+
it { run_output.should_not match 'some save output' }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
context 'when failing to save a snapshot' do
|
|
42
|
+
before do
|
|
43
|
+
subject.class.any_instance.should_receive(:has_ssh?).and_return(true)
|
|
44
|
+
subject.class.any_instance.should_receive(:exec).with("ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'snapshot' > #{@app.name}.tar.gz").and_return([1, 'some save failures'])
|
|
45
|
+
end
|
|
46
|
+
it { expect { run }.to exit_with_code(130) }
|
|
47
|
+
it { run_output.should match 'some save failures' }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context 'when saving a snapshot on windows' do
|
|
51
|
+
before do
|
|
52
|
+
RHC::Helpers.stub(:windows?) do ; true; end
|
|
53
|
+
RHC::Helpers.stub(:jruby?) do ; false ; end
|
|
54
|
+
RHC::Helpers.stub(:linux?) do ; false ; end
|
|
55
|
+
ssh = double(Net::SSH)
|
|
56
|
+
Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_yield(ssh)
|
|
57
|
+
ssh.should_receive(:exec!).with("snapshot").and_yield(nil, :stdout, 'foo').and_yield(nil, :stderr, 'foo')
|
|
58
|
+
end
|
|
59
|
+
it { expect { run }.to exit_with_code(0) }
|
|
60
|
+
it { run_output.should match("Success") }
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
context 'when timing out on windows' do
|
|
64
|
+
before do
|
|
65
|
+
RHC::Helpers.stub(:windows?) do ; true; end
|
|
66
|
+
RHC::Helpers.stub(:jruby?) do ; false ; end
|
|
67
|
+
RHC::Helpers.stub(:linux?) do ; false ; end
|
|
68
|
+
ssh = double(Net::SSH)
|
|
69
|
+
Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_raise(Timeout::Error)
|
|
70
|
+
end
|
|
71
|
+
it { expect { run }.to exit_with_code(130) }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe 'snapshot save deployment' do
|
|
75
|
+
let(:arguments) {['snapshot', 'save', '--app', 'mockapp', '--deployment', '-d']}
|
|
76
|
+
|
|
77
|
+
context 'when saving a deployment snapshot' do
|
|
78
|
+
before do
|
|
79
|
+
subject.class.any_instance.should_receive(:exec).with("ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'gear archive-deployment' > #{@app.name}.tar.gz").and_return([0, 'some save output'])
|
|
80
|
+
end
|
|
81
|
+
it { expect { run }.to exit_with_code(0) }
|
|
82
|
+
it { run_output.should_not match 'some save output' }
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe 'snapshot save with invalid ssh executable' do
|
|
89
|
+
let(:arguments) {['snapshot', 'save', '--trace', '--noprompt', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp', '--ssh', 'path_to_ssh']}
|
|
90
|
+
it('should raise') { expect{ run }.to raise_error(RHC::InvalidSSHExecutableException, /SSH executable 'path_to_ssh' does not exist./) }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
describe 'snapshot save when ssh is not executable' do
|
|
94
|
+
let(:arguments) {['snapshot', 'save', '--trace', '--noprompt', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp', '--ssh', @targz_filename]}
|
|
95
|
+
it('should raise') { expect{ run }.to raise_error(RHC::InvalidSSHExecutableException, /SSH executable '#{@targz_filename}' is not executable./) }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe 'snapshot restore' do
|
|
99
|
+
let(:arguments) {['snapshot', 'restore', '--app', 'mockapp', '-d']}
|
|
100
|
+
|
|
101
|
+
context 'when restoring a snapshot' do
|
|
102
|
+
before do
|
|
103
|
+
File.stub(:exists?).and_return(true)
|
|
104
|
+
RHC::TarGz.stub(:contains).and_return(true)
|
|
105
|
+
subject.class.any_instance.should_receive(:exec).with("cat '#{@app.name}.tar.gz' | ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'restore INCLUDE_GIT'").and_return([0, 'some restore output'])
|
|
106
|
+
end
|
|
107
|
+
it('should succeed') { expect { run }.to exit_with_code(0) }
|
|
108
|
+
it { run_output.should_not match 'some restore output' }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
context 'when restoring a snapshot and failing to ssh' do
|
|
112
|
+
before do
|
|
113
|
+
File.stub(:exists?).and_return(true)
|
|
114
|
+
RHC::TarGz.stub(:contains).and_return(true)
|
|
115
|
+
subject.class.any_instance.should_receive(:has_ssh?).and_return(true)
|
|
116
|
+
subject.class.any_instance.should_receive(:exec).with("cat '#{@app.name}.tar.gz' | ssh #{@ssh_uri.user}@#{@ssh_uri.host} 'restore INCLUDE_GIT'").and_return([1, 'some restore failures'])
|
|
117
|
+
end
|
|
118
|
+
it { expect { run }.to exit_with_code(130) }
|
|
119
|
+
it { run_output.should match 'some restore failures' }
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
context 'when restoring a snapshot on windows' do
|
|
123
|
+
before do
|
|
124
|
+
RHC::Helpers.stub(:windows?) do ; true; end
|
|
125
|
+
RHC::Helpers.stub(:jruby?) do ; false ; end
|
|
126
|
+
RHC::Helpers.stub(:linux?) do ; false ; end
|
|
127
|
+
ssh = double(Net::SSH)
|
|
128
|
+
session = double(Net::SSH::Connection::Session)
|
|
129
|
+
channel = double(Net::SSH::Connection::Channel)
|
|
130
|
+
Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_return(session)
|
|
131
|
+
session.should_receive(:open_channel).and_yield(channel)
|
|
132
|
+
channel.should_receive(:exec).with("restore INCLUDE_GIT").and_yield(nil, nil)
|
|
133
|
+
channel.should_receive(:on_data).and_yield(nil, 'foo')
|
|
134
|
+
channel.should_receive(:on_extended_data).and_yield(nil, nil, 'foo')
|
|
135
|
+
channel.should_receive(:on_close).and_yield(nil)
|
|
136
|
+
lines = ''
|
|
137
|
+
File.open(File.expand_path('../../assets/targz_sample.tar.gz', __FILE__), 'rb') do |file|
|
|
138
|
+
file.chunk(1024) do |chunk|
|
|
139
|
+
lines << chunk
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
channel.should_receive(:send_data).with(lines)
|
|
143
|
+
channel.should_receive(:eof!)
|
|
144
|
+
session.should_receive(:loop)
|
|
145
|
+
end
|
|
146
|
+
it { expect { run }.to exit_with_code(0) }
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
context 'when timing out on windows' do
|
|
150
|
+
before do
|
|
151
|
+
RHC::Helpers.stub(:windows?) do ; true; end
|
|
152
|
+
RHC::Helpers.stub(:jruby?) do ; false ; end
|
|
153
|
+
RHC::Helpers.stub(:linux?) do ; false ; end
|
|
154
|
+
ssh = double(Net::SSH)
|
|
155
|
+
Net::SSH.should_receive(:start).with(@ssh_uri.host, @ssh_uri.user).and_raise(Timeout::Error)
|
|
156
|
+
end
|
|
157
|
+
it { expect { run }.to exit_with_code(130) }
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
describe 'snapshot restore file not found' do
|
|
163
|
+
let(:arguments) {['snapshot', 'restore', 'mockapp', '-f', 'foo.tar.gz']}
|
|
164
|
+
context 'when restoring a snapshot' do
|
|
165
|
+
it { expect { run }.to exit_with_code(130) }
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
describe 'snapshot restore with invalid ssh executable' do
|
|
170
|
+
let(:arguments) {['snapshot', 'restore', '--trace', '--noprompt', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp', '--ssh', 'path_to_ssh']}
|
|
171
|
+
it('should raise') { expect{ run }.to raise_error(RHC::InvalidSSHExecutableException, /SSH executable 'path_to_ssh' does not exist./) }
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
describe 'snapshot save when ssh is not executable' do
|
|
175
|
+
let(:arguments) {['snapshot', 'restore', '--trace', '--noprompt', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp', '--ssh', @targz_filename]}
|
|
176
|
+
it('should raise') { expect{ run }.to raise_error(RHC::InvalidSSHExecutableException, /SSH executable '#{@targz_filename}' is not executable./) }
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
@@ -0,0 +1,163 @@
|
|
|
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 an implicit app name' do
|
|
61
|
+
before{ subject.class.any_instance.stub(:git_config_get){ |key| 'app1' if key == "rhc.app-name" } }
|
|
62
|
+
let(:arguments) { ['app', 'ssh', '--gears', '--', 'command', '--trace'] }
|
|
63
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => 'foo', 'fakegearid1@fakesshurl.com' => 'bar') }
|
|
64
|
+
it('should print the ssh output') { run_output.should == "[fakegearid0 ] foo\n[fakegearid1 ] bar\n\n" }
|
|
65
|
+
it('should return successfully') { expect{ run }.to exit_with_code(0) }
|
|
66
|
+
end
|
|
67
|
+
context 'with an application id' do
|
|
68
|
+
let(:arguments) { ['app', 'ssh', '--application-id', rest_client.domains.first.applications.first.id, '--gears', 'command', '--trace'] }
|
|
69
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => 'foo', 'fakegearid1@fakesshurl.com' => 'bar') }
|
|
70
|
+
it('should print the ssh output') { run_output.should == "[fakegearid0 ] foo\n[fakegearid1 ] bar\n\n" }
|
|
71
|
+
it('should return successfully') { expect{ run }.to exit_with_code(0) }
|
|
72
|
+
end
|
|
73
|
+
context 'with --raw' do
|
|
74
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command', '--raw'] }
|
|
75
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => 'foo', 'fakegearid1@fakesshurl.com' => 'bar') }
|
|
76
|
+
it('should print the ssh output') { run_output.should == "foo\nbar\n\n" }
|
|
77
|
+
end
|
|
78
|
+
context 'with --limit' do
|
|
79
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command', '--limit', '1'] }
|
|
80
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => 'foo', 'fakegearid1@fakesshurl.com' => 'bar') }
|
|
81
|
+
it('should print the ssh output') { run_output.should == "[fakegearid0 ] foo\n[fakegearid1 ] bar\n\n" }
|
|
82
|
+
end
|
|
83
|
+
context 'with invalid --limit value' do
|
|
84
|
+
['0','-10'].each do |value|
|
|
85
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command', '--limit', value] }
|
|
86
|
+
it { run_output.should match('--limit must be an integer greater than zero') }
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
context 'with multiline output and --always-prefix' do
|
|
90
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command', '--always-prefix'] }
|
|
91
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => "foo\ntest", 'fakegearid1@fakesshurl.com' => "bar\ntest") }
|
|
92
|
+
it('should print the ssh output') { run_output.should == "[fakegearid0 ] foo\n[fakegearid0 ] test\n[fakegearid1 ] bar\n[fakegearid1 ] test\n\n" }
|
|
93
|
+
end
|
|
94
|
+
context 'with multiline output' do
|
|
95
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--gears', 'command'] }
|
|
96
|
+
before{ expect_multi_ssh('command', 'fakegearid0@fakesshurl.com' => "foo\ntest", 'fakegearid1@fakesshurl.com' => "bar\ntest") }
|
|
97
|
+
it('should print the ssh output') { run_output.should == "=== fakegearid0 \nfoo\ntest\n=== fakegearid1 \nbar\ntest\n\n" }
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
describe 'app ssh no system ssh' do
|
|
102
|
+
let(:arguments) { ['app', 'ssh', 'app1'] }
|
|
103
|
+
|
|
104
|
+
context 'when run' do
|
|
105
|
+
before(:each) do
|
|
106
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
107
|
+
@domain.add_application("app1", "mock_type")
|
|
108
|
+
RHC::Commands::Ssh.any_instance.should_receive(:has_ssh?).and_return(false)
|
|
109
|
+
end
|
|
110
|
+
it { run_output.should match("No system SSH available. Please use the --ssh option to specify the path to your SSH executable, or install SSH.") }
|
|
111
|
+
it { expect { run }.to exit_with_code(1) }
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
describe 'app ssh custom ssh' do
|
|
116
|
+
let(:arguments) { ['app', 'ssh', 'app1', '--ssh', 'path_to_ssh'] }
|
|
117
|
+
|
|
118
|
+
context 'when custom ssh does not exist' do
|
|
119
|
+
before(:each) do
|
|
120
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
121
|
+
@domain.add_application("app1", "mock_type")
|
|
122
|
+
RHC::Commands::Ssh.any_instance.should_not_receive(:has_ssh?)
|
|
123
|
+
File.should_receive(:exist?).with("path_to_ssh").once.and_return(false)
|
|
124
|
+
end
|
|
125
|
+
it { run_output.should match("SSH executable 'path_to_ssh' does not exist.") }
|
|
126
|
+
it { expect { run }.to exit_with_code(1) }
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
context 'when custom ssh is not executable' do
|
|
130
|
+
before(:each) do
|
|
131
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
132
|
+
@domain.add_application("app1", "mock_type")
|
|
133
|
+
RHC::Commands::Ssh.any_instance.should_not_receive(:has_ssh?)
|
|
134
|
+
File.should_receive(:exist?).with("path_to_ssh").once.and_return(true)
|
|
135
|
+
File.should_receive(:executable?).with(/.*path_to_ssh/).at_least(1).and_return(false)
|
|
136
|
+
end
|
|
137
|
+
it { run_output.should match("SSH executable 'path_to_ssh' is not executable.") }
|
|
138
|
+
it { expect { run }.to exit_with_code(1) }
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
context 'when custom ssh exists' do
|
|
142
|
+
before(:each) do
|
|
143
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
144
|
+
@domain.add_application("app1", "mock_type")
|
|
145
|
+
RHC::Commands::Ssh.any_instance.should_not_receive(:has_ssh?)
|
|
146
|
+
File.should_receive(:exist?).with("path_to_ssh").once.and_return(true)
|
|
147
|
+
File.should_receive(:executable?).with("path_to_ssh").once.and_return(true)
|
|
148
|
+
Kernel.should_receive(:exec).with("path_to_ssh", "fakeuuidfortestsapp1@127.0.0.1").once.times.and_return(0)
|
|
149
|
+
end
|
|
150
|
+
it { run_output.should match("Connecting to fakeuuidfortestsapp") }
|
|
151
|
+
it { expect { run }.to exit_with_code(0) }
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
describe 'ssh tests' do
|
|
156
|
+
let(:arguments) { ['app', 'ssh', 'app1', '-s /bin/blah'] }
|
|
157
|
+
|
|
158
|
+
context 'has_ssh?' do
|
|
159
|
+
before{ RHC::Commands::Ssh.any_instance.stub(:ssh_version){ raise "Fake Exception" } }
|
|
160
|
+
its(:has_ssh?) { should be_false }
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|