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,86 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rest_spec_helper'
|
|
3
|
+
require 'rhc'
|
|
4
|
+
require 'rhc/commands/logout'
|
|
5
|
+
|
|
6
|
+
describe RHC::Commands::Logout do
|
|
7
|
+
|
|
8
|
+
describe '#run' do
|
|
9
|
+
let(:arguments) { ['logout'] }
|
|
10
|
+
let(:username) { 'foo' }
|
|
11
|
+
let(:password) { nil }
|
|
12
|
+
let(:supports_auth) { false }
|
|
13
|
+
let(:server) { mock_uri }
|
|
14
|
+
let!(:token_store) { RHC::Auth::TokenStore.new(Dir.mktmpdir) }
|
|
15
|
+
before{ user_config }
|
|
16
|
+
before do
|
|
17
|
+
stub_api(false, supports_auth)
|
|
18
|
+
challenge{ stub_user }
|
|
19
|
+
RHC::Auth::TokenStore.stub(:new).and_return(token_store)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "when calling from the alias" do
|
|
23
|
+
let(:arguments){ ['account', 'logout', '-h'] }
|
|
24
|
+
it("should print usage"){ run_output.should match "Usage: app logout" }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it("should clear the token cache"){ expect{ run }.to call(:clear).on(token_store) }
|
|
28
|
+
it("should exit with success"){ expect{ run }.to exit_with_code(0) }
|
|
29
|
+
it("should display a message"){ run_output.should match("All local sessions removed.") }
|
|
30
|
+
|
|
31
|
+
context "when --all is requested" do
|
|
32
|
+
let(:arguments) { ['account', 'logout', '--all'] }
|
|
33
|
+
|
|
34
|
+
context "if the server does not implement authorizations" do
|
|
35
|
+
it("should display a message"){ run_output.should match(/Deleting all authorizations associated with your account.*not supported/) }
|
|
36
|
+
it("should exit with success"){ expect{ run }.to exit_with_code(0) }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context "if the server implements authorizations" do
|
|
40
|
+
let(:supports_auth) { true }
|
|
41
|
+
before{ stub_delete_authorizations }
|
|
42
|
+
|
|
43
|
+
it("should display a message"){ run_output.should match(/Deleting all authorizations associated with your account.*done/) }
|
|
44
|
+
it("should exit with success"){ expect{ run }.to exit_with_code(0) }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context "when --token is provided" do
|
|
49
|
+
let(:arguments) { ['account', 'logout', '--token', 'foo'] }
|
|
50
|
+
def user_auth; { :token => 'foo' }; end
|
|
51
|
+
|
|
52
|
+
context "if the server does not implement authorizations" do
|
|
53
|
+
it("should display a message"){ run_output.should match(/Ending session on server.*not supported/) }
|
|
54
|
+
it("should exit with success"){ expect{ run }.to exit_with_code(0) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
context "if the server implements authorizations" do
|
|
58
|
+
let(:supports_auth) { true }
|
|
59
|
+
|
|
60
|
+
context "if the server returns successfully" do
|
|
61
|
+
before{ stub_delete_authorization('foo') }
|
|
62
|
+
|
|
63
|
+
it("should display a message"){ run_output.should match(/Ending session on server.*deleted/) }
|
|
64
|
+
it("should exit with success"){ expect{ run }.to exit_with_code(0) }
|
|
65
|
+
it("should clear the token cache"){ expect{ run }.to call(:clear).on(token_store) }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context "if the server rejects the token" do
|
|
69
|
+
before{ stub_request(:delete, mock_href('broker/rest/user/authorizations/foo', false)).to_return(:status => 401, :body => {}.to_json) }
|
|
70
|
+
|
|
71
|
+
it("should display a message"){ run_output.should match(/Ending session on server.*already closed/) }
|
|
72
|
+
it("should exit with success"){ expect{ run }.to exit_with_code(0) }
|
|
73
|
+
it("should clear the token cache"){ expect{ run }.to call(:clear).on(token_store) }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
context "if the server returns an unexpected error" do
|
|
77
|
+
before{ stub_request(:delete, mock_href('broker/rest/user/authorizations/foo', false)).to_return(:status => 500, :body => {}.to_json) }
|
|
78
|
+
|
|
79
|
+
it("should display a message"){ run_output.should match(/Ending session on server.*The server did not respond/) }
|
|
80
|
+
it("should exit with success"){ expect{ run }.to exit_with_code(0) }
|
|
81
|
+
it("should clear the token cache"){ expect{ run }.to call(:clear).on(token_store) }
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rest_spec_helper'
|
|
3
|
+
require 'rhc/commands/member'
|
|
4
|
+
|
|
5
|
+
describe RHC::Commands::Member do
|
|
6
|
+
|
|
7
|
+
before{ user_config }
|
|
8
|
+
|
|
9
|
+
describe 'help' do
|
|
10
|
+
let(:arguments) { ['member', '--help'] }
|
|
11
|
+
|
|
12
|
+
it "should display help" do
|
|
13
|
+
expect { run }.to exit_with_code(0)
|
|
14
|
+
end
|
|
15
|
+
it('should output usage') { run_output.should match "Usage: app member" }
|
|
16
|
+
it('should output info about roles') { run_output.should match "Teams of developers can collaborate" }
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
let(:username){ 'test_user' }
|
|
20
|
+
let(:password){ 'test_password' }
|
|
21
|
+
let(:server){ 'test.domain.com' }
|
|
22
|
+
|
|
23
|
+
def with_mock_rest_client
|
|
24
|
+
@rest_client ||= MockRestClient.new
|
|
25
|
+
end
|
|
26
|
+
def with_mock_domain
|
|
27
|
+
@domain ||= with_mock_rest_client.add_domain("mock-domain-0")
|
|
28
|
+
end
|
|
29
|
+
def with_mock_app
|
|
30
|
+
@app ||= begin
|
|
31
|
+
app = with_mock_domain.add_application("mock-app-0", "ruby-1.8.7")
|
|
32
|
+
app.stub(:ssh_url).and_return("ssh://user@test.domain.com")
|
|
33
|
+
app.stub(:supports_members?).and_return(supports_members)
|
|
34
|
+
app
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
let(:owner){ RHC::Rest::Membership::Member.new(:id => '1', :role => 'admin', :owner => true, :login => 'alice') }
|
|
39
|
+
let(:other_admin){ RHC::Rest::Membership::Member.new(:id => '2', :role => 'admin', :login => 'Bob') }
|
|
40
|
+
let(:other_editor){ RHC::Rest::Membership::Member.new(:id => '3', :role => 'edit', :name => 'Carol', :login => 'carol') }
|
|
41
|
+
let(:other_viewer){ RHC::Rest::Membership::Member.new(:id => '4', :role => 'view', :name => 'Doug', :login => 'doug@doug.com') }
|
|
42
|
+
let(:other_viewer2){ RHC::Rest::Membership::Member.new(:id => '5', :role => 'view', :name => 'ViewerC', :login => 'viewerc@viewer.com') }
|
|
43
|
+
let(:other_viewer3){ RHC::Rest::Membership::Member.new(:id => '6', :role => 'view', :name => 'ViewerB', :login => 'viewerb@viewer.com') }
|
|
44
|
+
let(:other_viewer4){ RHC::Rest::Membership::Member.new(:id => '7', :role => 'view', :name => 'ViewerA', :login => 'viewera@viewer.com') }
|
|
45
|
+
|
|
46
|
+
describe 'show-domain' do
|
|
47
|
+
context 'with members' do
|
|
48
|
+
let(:arguments) { ['domain', 'show', 'mock-domain-0'] }
|
|
49
|
+
let(:supports_members){ true }
|
|
50
|
+
|
|
51
|
+
before{ with_mock_domain.add_member(owner).add_member(other_editor).add_member(other_admin).add_member(other_viewer).add_member(other_viewer2).add_member(other_viewer3).add_member(other_viewer4) }
|
|
52
|
+
it { expect { run }.to exit_with_code(0) }
|
|
53
|
+
it { run_output.should =~ /owned by alice/ }
|
|
54
|
+
it { run_output.should =~ /Bob\s+\(admin\)/ }
|
|
55
|
+
it { run_output.should =~ /<carol>\s+\(edit\)/ }
|
|
56
|
+
it { run_output.should =~ /<doug@doug\.com>\s+\(view\)/ }
|
|
57
|
+
it("should order the members by role then by name") { run_output.should =~ /Bob.*admin.*Admins.*Carol.*Editors.*ViewerA.*ViewerB.*ViewerC.*Viewers/m }
|
|
58
|
+
it("should include the login value") { run_output.should =~ /alice.*Bob.*carol.*doug@doug\.com/m }
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe 'list-member' do
|
|
63
|
+
context 'on a domain' do
|
|
64
|
+
let(:arguments) { ['members', '-n', 'mock-domain-0'] }
|
|
65
|
+
let(:supports_members){ true }
|
|
66
|
+
before{ with_mock_domain.add_member(owner) }
|
|
67
|
+
it { expect { run }.to exit_with_code(0) }
|
|
68
|
+
it { run_output.should =~ /alice\s+admin \(owner\)/ }
|
|
69
|
+
it("should not show the name column") { run_output.should =~ /^Login\s+Role$/ }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
context 'on an application' do
|
|
73
|
+
let(:arguments) { ['members', 'mock-domain-0/mock-app-0'] }
|
|
74
|
+
let(:supports_members){ false }
|
|
75
|
+
before{ with_mock_app }
|
|
76
|
+
|
|
77
|
+
it { expect { run }.to exit_with_code(1) }
|
|
78
|
+
it { run_output.should =~ /The server does not support adding or removing members/ }
|
|
79
|
+
|
|
80
|
+
context "with only owner" do
|
|
81
|
+
let(:supports_members){ true }
|
|
82
|
+
before{ with_mock_app.add_member(owner) }
|
|
83
|
+
it { expect { run }.to exit_with_code(0) }
|
|
84
|
+
it { run_output.should =~ /alice\s+admin \(owner\)/ }
|
|
85
|
+
it("should not show the name column") { run_output.should =~ /^Login\s+Role$/ }
|
|
86
|
+
|
|
87
|
+
context "with ids" do
|
|
88
|
+
let(:arguments) { ['members', 'mock-domain-0/mock-app-0', '--ids'] }
|
|
89
|
+
it { expect { run }.to exit_with_code(0) }
|
|
90
|
+
it { run_output.should =~ /alice\s+admin \(owner\) 1/ }
|
|
91
|
+
it("should not show the name column") { run_output.should =~ /^Login\s+Role\s+ID$/ }
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context "with several members" do
|
|
96
|
+
let(:supports_members){ true }
|
|
97
|
+
before{ with_mock_app.add_member(owner).add_member(other_editor).add_member(other_admin).add_member(other_viewer) }
|
|
98
|
+
it { expect { run }.to exit_with_code(0) }
|
|
99
|
+
it { run_output.should =~ /alice\s+admin \(owner\)/ }
|
|
100
|
+
it { run_output.should =~ /Bob\s+admin/ }
|
|
101
|
+
it { run_output.should =~ /carol\s+edit/ }
|
|
102
|
+
it { run_output.should =~ /doug\.com\s+view/ }
|
|
103
|
+
it("should order the members by role") { run_output.should =~ /admin.*owner.*admin.*edit.*view/m }
|
|
104
|
+
it("should include the login value") { run_output.should =~ /alice.*Bob.*carol.*doug@doug\.com/m }
|
|
105
|
+
it("should show the name column") { run_output.should =~ /^Name\s+Login\s+Role$/ }
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
describe 'add-member' do
|
|
111
|
+
before do
|
|
112
|
+
stub_api
|
|
113
|
+
challenge{ stub_one_domain('test', nil, mock_user_auth) }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
context "when the resource doesn't support membership changes" do
|
|
117
|
+
let(:arguments) { ['add-member', 'testuser', '-n', 'test'] }
|
|
118
|
+
it { expect { run }.to exit_with_code(1) }
|
|
119
|
+
it { run_output.should =~ /Adding 1 editor to domain .*The server does not support adding or removing members/ }
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
context "with supported membership" do
|
|
123
|
+
let(:supports_members?){ true }
|
|
124
|
+
|
|
125
|
+
context 'with a valid user' do
|
|
126
|
+
let(:arguments) { ['add-member', 'testuser', '-n', 'test'] }
|
|
127
|
+
before do
|
|
128
|
+
stub_api_request(:patch, "broker/rest/domains/test/members").
|
|
129
|
+
with(:body => {:members => [{'login' => 'testuser', 'role' => 'edit'}]}).
|
|
130
|
+
to_return({:body => {:type => 'members', :data => [], :messages => [{:exit_code => 0, :field => 'login', :index => 0, :severity => 'info', :text => 'Added 1 member'},]}.to_json, :status => 200})
|
|
131
|
+
end
|
|
132
|
+
it { expect { run }.to exit_with_code(0) }
|
|
133
|
+
it { run_output.should =~ /Adding 1 editor to domain .*done/ }
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
context 'with an invalid role' do
|
|
137
|
+
let(:arguments) { ['add-member', 'testuser', '-n', 'test', '--role', 'missing'] }
|
|
138
|
+
it { expect { run }.to exit_with_code(1) }
|
|
139
|
+
it { run_output.should =~ /The provided role 'missing' is not valid\. Supported values: .*admin/ }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
context 'with a missing user' do
|
|
143
|
+
let(:arguments) { ['add-member', 'testuser', '-n', 'test'] }
|
|
144
|
+
before do
|
|
145
|
+
stub_api_request(:patch, "broker/rest/domains/test/members").
|
|
146
|
+
with(:body => {:members => [{'login' => 'testuser', 'role' => 'edit'}]}).
|
|
147
|
+
to_return({:body => {:messages => [{:exit_code => 132, :field => 'login', :index => 0, :severity => 'error', :text => 'There is no user with a login testuser'},]}.to_json, :status => 422})
|
|
148
|
+
end
|
|
149
|
+
it { expect { run }.to exit_with_code(1) }
|
|
150
|
+
it { run_output.should =~ /Adding 1 editor to domain.*There is no user with a login testuser/ }
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
context 'with a missing user id and role' do
|
|
154
|
+
let(:arguments) { ['add-member', '123', '-n', 'test', '--ids', '--role', 'admin'] }
|
|
155
|
+
before do
|
|
156
|
+
stub_api_request(:patch, "broker/rest/domains/test/members").
|
|
157
|
+
with(:body => {:members => [{'id' => '123', 'role' => 'admin'}]}).
|
|
158
|
+
to_return({:body => {:messages => [{:exit_code => 132, :field => 'id', :index => 0, :severity => 'error', :text => 'There is no user with the id 123'},]}.to_json, :status => 422})
|
|
159
|
+
end
|
|
160
|
+
it { expect { run }.to exit_with_code(1) }
|
|
161
|
+
it { run_output.should =~ /Adding 1 administrator to domain.*There is no user with the id 123/ }
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
describe 'remove-member' do
|
|
167
|
+
context "when the resource doesn't support membership changes" do
|
|
168
|
+
before{ stub_api }
|
|
169
|
+
|
|
170
|
+
context "when adjusting a domain" do
|
|
171
|
+
let(:arguments) { ['remove-member', 'testuser', '-n', 'test'] }
|
|
172
|
+
before{ challenge{ stub_one_domain('test', nil, mock_user_auth) } }
|
|
173
|
+
it { expect { run }.to exit_with_code(1) }
|
|
174
|
+
it { run_output.should =~ /Removing 1 member from domain .*The server does not support adding or removing members/ }
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
context "with supported membership" do
|
|
179
|
+
let(:supports_members?){ true }
|
|
180
|
+
before do
|
|
181
|
+
stub_api
|
|
182
|
+
challenge{ stub_one_domain('test', nil, mock_user_auth) }
|
|
183
|
+
end
|
|
184
|
+
=begin Scenario removed
|
|
185
|
+
context "when adjusting an app" do
|
|
186
|
+
let(:arguments) { ['remove-member', 'testuser', '-n', 'test', '-a', 'app'] }
|
|
187
|
+
before{ challenge{ stub_one_application('test', 'app') } }
|
|
188
|
+
it { expect { run }.to exit_with_code(1) }
|
|
189
|
+
it { run_output.should =~ /You can only add or remove members on a domain/ }
|
|
190
|
+
end
|
|
191
|
+
=end
|
|
192
|
+
context 'with a valid member' do
|
|
193
|
+
let(:arguments) { ['remove-member', 'testuser', '-n', 'test'] }
|
|
194
|
+
before do
|
|
195
|
+
stub_api_request(:patch, "broker/rest/domains/test/members").
|
|
196
|
+
with(:body => {:members => [{'login' => 'testuser', 'role' => 'none'}]}).
|
|
197
|
+
to_return({:body => {:type => 'members', :data => [], :messages => [{:exit_code => 0, :field => 'login', :index => 0, :severity => 'info', :text => 'Removed 1 member'},]}.to_json, :status => 200})
|
|
198
|
+
end
|
|
199
|
+
it { expect { run }.to exit_with_code(0) }
|
|
200
|
+
it { run_output.should =~ /Removing 1 member from domain .*done/ }
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
context 'with --all' do
|
|
204
|
+
let(:arguments) { ['remove-member', '--all', '-n', 'test'] }
|
|
205
|
+
before do
|
|
206
|
+
stub_api_request(:delete, "broker/rest/domains/test/members").
|
|
207
|
+
to_return({:body => {:type => 'members', :data => [], :messages => [{:exit_code => 0, :field => 'login', :index => 0, :severity => 'info', :text => 'Removed everyone except owner.'},]}.to_json, :status => 200})
|
|
208
|
+
end
|
|
209
|
+
it { expect { run }.to exit_with_code(0) }
|
|
210
|
+
it { run_output.should =~ /Removing all members from domain .*done/ }
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
context 'with a missing user' do
|
|
214
|
+
let(:arguments) { ['remove-member', 'testuser', '-n', 'test'] }
|
|
215
|
+
before do
|
|
216
|
+
stub_api_request(:patch, "broker/rest/domains/test/members").
|
|
217
|
+
with(:body => {:members => [{'login' => 'testuser', 'role' => 'none'}]}).
|
|
218
|
+
to_return({:body => {:messages => [{:exit_code => 132, :field => 'login', :index => 0, :severity => 'error', :text => 'There is no user with a login testuser'},]}.to_json, :status => 422})
|
|
219
|
+
end
|
|
220
|
+
it { expect { run }.to exit_with_code(1) }
|
|
221
|
+
it { run_output.should =~ /Removing 1 member from domain.*There is no user with a login testuser/ }
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
context 'with a missing user id and role' do
|
|
225
|
+
let(:arguments) { ['remove-member', '123', '-n', 'test', '--ids'] }
|
|
226
|
+
before do
|
|
227
|
+
stub_api_request(:patch, "broker/rest/domains/test/members").
|
|
228
|
+
with(:body => {:members => [{'id' => '123', 'role' => 'none'}]}).
|
|
229
|
+
to_return({:body => {:messages => [{:exit_code => 132, :field => 'id', :index => 0, :severity => 'error', :text => 'There is no user with the id 123'},]}.to_json, :status => 422})
|
|
230
|
+
end
|
|
231
|
+
it { expect { run }.to exit_with_code(1) }
|
|
232
|
+
it { run_output.should =~ /Removing 1 member from domain.*There is no user with the id 123/ }
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
context 'when the user isn''t a member' do
|
|
236
|
+
let(:arguments) { ['remove-member', 'testuser', '-n', 'test'] }
|
|
237
|
+
before do
|
|
238
|
+
stub_api_request(:patch, "broker/rest/domains/test/members").
|
|
239
|
+
with(:body => {:members => [{'login' => 'testuser', 'role' => 'none'}]}).
|
|
240
|
+
to_return({:body => {:type => 'members', :data => [], :messages => [{:exit_code => 0, :field => 'login', :index => 0, :severity => 'warning', :text => 'testuser is not a member of this domain.'},]}.to_json, :status => 200})
|
|
241
|
+
end
|
|
242
|
+
it { expect { run }.to exit_with_code(0) }
|
|
243
|
+
it { run_output.should =~ /Removing 1 member from domain.*testuser is not a member of this domain.*done/m }
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rest_spec_helper'
|
|
3
|
+
require 'rhc/commands/port_forward'
|
|
4
|
+
|
|
5
|
+
describe RHC::Commands::PortForward do
|
|
6
|
+
|
|
7
|
+
let!(:rest_client){ MockRestClient.new }
|
|
8
|
+
before{ user_config }
|
|
9
|
+
|
|
10
|
+
describe 'run' do
|
|
11
|
+
let(:arguments) { ['port-forward', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp'] }
|
|
12
|
+
|
|
13
|
+
before :each do
|
|
14
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
15
|
+
@app = @domain.add_application 'mockapp', 'mock-1.0'
|
|
16
|
+
@uri = URI.parse @app.ssh_url
|
|
17
|
+
@ssh = double(Net::SSH)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context 'when port forwarding for a down appl' do
|
|
21
|
+
before(:each) do
|
|
22
|
+
Net::SSH.should_receive(:start).with(@uri.host, @uri.user).and_yield(@ssh)
|
|
23
|
+
@ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, '127.0.0.1:3306')
|
|
24
|
+
@gg = MockRestGearGroup.new(rest_client)
|
|
25
|
+
@app.should_receive(:gear_groups).and_return([@gg])
|
|
26
|
+
@gg.should_receive(:gears).and_return([{'state' => 'stopped', 'id' => 'fakegearid'}])
|
|
27
|
+
end
|
|
28
|
+
it "should error out and suggest restarting the application" do
|
|
29
|
+
expect { run }.to exit_with_code(1)
|
|
30
|
+
end
|
|
31
|
+
it { run_output.should match(/none.*The application is stopped\..*restart/m) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context 'when port forwarding an app without ports to forward' do
|
|
35
|
+
before(:each) do
|
|
36
|
+
Net::SSH.should_receive(:start).with(@uri.host, @uri.user).and_yield(@ssh)
|
|
37
|
+
@ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, '127.0.0.1:3306')
|
|
38
|
+
end
|
|
39
|
+
it "should error out as no ports to forward" do
|
|
40
|
+
expect { run }.to exit_with_code(102)
|
|
41
|
+
rest_client.domains[0].name.should == 'mockdomain'
|
|
42
|
+
rest_client.domains[0].applications.size.should == 1
|
|
43
|
+
rest_client.domains[0].applications[0].name.should == 'mockapp'
|
|
44
|
+
end
|
|
45
|
+
it("should report no ports") { run_output.should match("no available ports to forward.") }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
context 'when port forwarding an app with permission denied ports' do
|
|
49
|
+
before(:each) do
|
|
50
|
+
Net::SSH.should_receive(:start).with(@uri.host, @uri.user).and_yield(@ssh)
|
|
51
|
+
@ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, 'permission denied')
|
|
52
|
+
end
|
|
53
|
+
it "should error out as permission denied" do
|
|
54
|
+
expect { run }.to exit_with_code(129)
|
|
55
|
+
rest_client.domains[0].name.should == 'mockdomain'
|
|
56
|
+
rest_client.domains[0].applications.size.should == 1
|
|
57
|
+
rest_client.domains[0].applications[0].name.should == 'mockapp'
|
|
58
|
+
end
|
|
59
|
+
it { run_output.should match("Permission denied") }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
context 'when port forwarding an app with ports to forward' do
|
|
63
|
+
before(:each) do
|
|
64
|
+
Net::SSH.should_receive(:start).with(@uri.host, @uri.user).and_yield(@ssh).twice
|
|
65
|
+
@ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, 'mysql -> 127.0.0.1:3306')
|
|
66
|
+
forward = double(Net::SSH::Service::Forward)
|
|
67
|
+
@ssh.should_receive(:forward).and_return(forward)
|
|
68
|
+
forward.should_receive(:local).with(3306, '127.0.0.1', 3306)
|
|
69
|
+
@ssh.should_receive(:loop)
|
|
70
|
+
end
|
|
71
|
+
it "should run successfully" do
|
|
72
|
+
expect { run }.to exit_with_code(0)
|
|
73
|
+
rest_client.domains[0].name.should == 'mockdomain'
|
|
74
|
+
rest_client.domains[0].applications.size.should == 1
|
|
75
|
+
rest_client.domains[0].applications[0].name.should == 'mockapp'
|
|
76
|
+
end
|
|
77
|
+
it { run_output.should match(/Forwarding ports.*Press CTRL-C/m) }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
context 'when host is unreachable' do
|
|
81
|
+
before(:each) do
|
|
82
|
+
Net::SSH.should_receive(:start).and_raise(Errno::EHOSTUNREACH)
|
|
83
|
+
end
|
|
84
|
+
it "should error out" do
|
|
85
|
+
expect { run }.to exit_with_code(1)
|
|
86
|
+
rest_client.domains[0].name.should == 'mockdomain'
|
|
87
|
+
rest_client.domains[0].applications.size.should == 1
|
|
88
|
+
rest_client.domains[0].applications[0].name.should == 'mockapp'
|
|
89
|
+
end
|
|
90
|
+
it { run_output.should include("Error trying to forward ports.") }
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
context 'when REST client connection times out' do
|
|
94
|
+
before(:each) do
|
|
95
|
+
rest_client.should_receive(:find_domain).and_raise(RHC::Rest::ConnectionException)
|
|
96
|
+
end
|
|
97
|
+
it("should error out") { expect { run }.to exit_with_code(1) }
|
|
98
|
+
it{ run_output.should match("Connection.*failed:") }
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
context 'when port forwarding an app with ports to forward' do
|
|
102
|
+
before(:each) do
|
|
103
|
+
Net::SSH.should_receive(:start).with(@uri.host, @uri.user).and_yield(@ssh).twice
|
|
104
|
+
@ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, 'mysql -> 127.0.0.1:3306')
|
|
105
|
+
forward = double(Net::SSH::Service::Forward)
|
|
106
|
+
@ssh.should_receive(:forward).and_return(forward)
|
|
107
|
+
forward.should_receive(:local).with(3306, '127.0.0.1', 3306)
|
|
108
|
+
@ssh.should_receive(:loop).and_raise(Interrupt.new)
|
|
109
|
+
end
|
|
110
|
+
it "should exit when user interrupts" do
|
|
111
|
+
expect { run }.to exit_with_code(0)
|
|
112
|
+
rest_client.domains[0].name.should == 'mockdomain'
|
|
113
|
+
rest_client.domains[0].applications.size.should == 1
|
|
114
|
+
rest_client.domains[0].applications[0].name.should == 'mockapp'
|
|
115
|
+
end
|
|
116
|
+
it { run_output.should include("Ending port forward") }
|
|
117
|
+
end
|
|
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 = double(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
|
+
|
|
134
|
+
context 'when host refuses connection' do
|
|
135
|
+
before(:each) do
|
|
136
|
+
Net::SSH.should_receive(:start).with(@uri.host, @uri.user).and_yield(@ssh).twice
|
|
137
|
+
@ssh.should_receive(:exec!).with("rhc-list-ports").and_yield(nil, :stderr, 'mysql -> 127.0.0.1:3306')
|
|
138
|
+
forward = double(Net::SSH::Service::Forward)
|
|
139
|
+
@ssh.should_receive(:forward).and_raise(Errno::ECONNREFUSED)
|
|
140
|
+
end
|
|
141
|
+
it "should error out" do
|
|
142
|
+
expect { run }.to exit_with_code(0)
|
|
143
|
+
end
|
|
144
|
+
it { run_output.should include("ssh -N") }
|
|
145
|
+
it { run_output.should include("Error forwarding") }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context 'when port forwarding a scaled app with ports to forward' do
|
|
149
|
+
let(:haproxy_host_1) { '127.0.0.1' }
|
|
150
|
+
let(:haproxy_host_2) { '127.0.0.2' }
|
|
151
|
+
let(:mongo_host) { '51125bb94a-test907742.dev.rhcloud.com' }
|
|
152
|
+
let(:ipv6_host) { '::1' }
|
|
153
|
+
before(:each) do
|
|
154
|
+
Net::SSH.should_receive(:start).with(@uri.host, @uri.user).and_yield(@ssh).twice
|
|
155
|
+
@ssh.should_receive(:exec!).with("rhc-list-ports").
|
|
156
|
+
and_yield(nil, :stderr, "httpd -> #{haproxy_host_1}:8080\nhttpd -> #{haproxy_host_2}:8080\nmongodb -> #{mongo_host}:35541\nmysqld -> #{ipv6_host}:3306")
|
|
157
|
+
forward = double(Net::SSH::Service::Forward)
|
|
158
|
+
@ssh.should_receive(:forward).at_least(3).times.and_return(forward)
|
|
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)
|
|
164
|
+
@ssh.should_receive(:loop).and_raise(Interrupt.new)
|
|
165
|
+
end
|
|
166
|
+
it "should exit when user interrupts" do
|
|
167
|
+
expect { run }.to exit_with_code(0)
|
|
168
|
+
rest_client.domains[0].name.should == 'mockdomain'
|
|
169
|
+
rest_client.domains[0].applications.size.should == 1
|
|
170
|
+
rest_client.domains[0].applications[0].name.should == 'mockapp'
|
|
171
|
+
end
|
|
172
|
+
it { run_output.should include("Ending port forward") }
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
context 'when port forwarding a single gear on a scaled app' do
|
|
176
|
+
let(:gear_host) { 'fakesshurl.com' }
|
|
177
|
+
let(:gear_user) { 'fakegearid0' }
|
|
178
|
+
let(:arguments) { ['port-forward', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password', '--app', 'mockapp', '--gear', @gear_id] }
|
|
179
|
+
|
|
180
|
+
it 'should run successfully' do
|
|
181
|
+
@gear_id = 'fakegearid0'
|
|
182
|
+
Net::SSH.should_receive(:start).with(gear_host, gear_user).and_yield(@ssh).twice
|
|
183
|
+
|
|
184
|
+
@ssh.should_receive(:exec!).with("rhc-list-ports --exclude-remote").
|
|
185
|
+
and_yield(nil, :stderr, "mongodb -> #{gear_host}:35541")
|
|
186
|
+
forward = double(Net::SSH::Service::Forward)
|
|
187
|
+
@ssh.should_receive(:forward).and_return(forward)
|
|
188
|
+
forward.should_receive(:local).with(35541, gear_host, 35541)
|
|
189
|
+
@ssh.should_receive(:loop).and_raise(Interrupt.new)
|
|
190
|
+
|
|
191
|
+
expect { run }.to exit_with_code(0)
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
it 'should fail if the specified gear is missing' do
|
|
195
|
+
@gear_id = 'notarealgearxxxxx'
|
|
196
|
+
|
|
197
|
+
expect { run }.to exit_with_code(1)
|
|
198
|
+
run_output.should include('Gear notarealgearxxxxx not found')
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
it 'should fail if the specified gear has no ssh info' do
|
|
202
|
+
@gear_id = 'fakegearid0'
|
|
203
|
+
|
|
204
|
+
# Given - gears in gear group should not have ssh info
|
|
205
|
+
gg = MockRestGearGroup.new(rest_client)
|
|
206
|
+
@app.stub(:gear_groups).and_return([gg])
|
|
207
|
+
gg.stub(:gears).and_return([{'state' => 'started', 'id' => 'fakegearid0'}])
|
|
208
|
+
|
|
209
|
+
expect { run }.to exit_with_code(1)
|
|
210
|
+
run_output.should match('The server does not support operations on individual gears.')
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rest_spec_helper'
|
|
3
|
+
require 'rhc/commands/scp'
|
|
4
|
+
|
|
5
|
+
describe RHC::Commands::Scp 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 'scp default' do
|
|
12
|
+
context 'scp' do
|
|
13
|
+
let(:arguments) { ['scp'] }
|
|
14
|
+
it { run_output.should match('Usage:') }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
describe 'scp with invalid option' do
|
|
19
|
+
let (:arguments) {['app', 'scp', 'app1', 'invalid_command', 'file.txt', 'app-root/data']}
|
|
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
|
+
end
|
|
26
|
+
it { run_output.should match("'invalid_command' is not a valid argument for this command. Please use upload or download.") }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe 'local file or path does not exist' do
|
|
31
|
+
let (:arguments) {['app', 'scp', 'app1', 'upload', 'file.txt', 'app-root/data']}
|
|
32
|
+
|
|
33
|
+
context 'when run' do
|
|
34
|
+
before(:each) do
|
|
35
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
36
|
+
@domain.add_application("app1", "mock_type")
|
|
37
|
+
File.should_receive(:exist?).with("file.txt").once.and_return(false)
|
|
38
|
+
end
|
|
39
|
+
it { run_output.should match("Local file, file_path, or directory could not be found.") }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe 'scp connections' do
|
|
44
|
+
let (:arguments) {['app', 'scp', 'app1', 'upload', 'file.txt', 'app-root/data']}
|
|
45
|
+
|
|
46
|
+
context 'connection refused' do
|
|
47
|
+
before(:each) do
|
|
48
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
49
|
+
@domain.add_application("app1", "mock_type")
|
|
50
|
+
File.should_receive(:exist?).with("file.txt").once.and_return(true)
|
|
51
|
+
Net::SCP.should_receive("upload!".to_sym).with("127.0.0.1", "fakeuuidfortestsapp1","file.txt","app-root/data").and_raise(Errno::ECONNREFUSED)
|
|
52
|
+
end
|
|
53
|
+
it { run_output.should match("The server fakeuuidfortestsapp1 refused a connection with user 127.0.0.1. The application may be unavailable.") }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context 'socket error' do
|
|
57
|
+
before(:each) do
|
|
58
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
59
|
+
@domain.add_application("app1", "mock_type")
|
|
60
|
+
File.should_receive(:exist?).with("file.txt").once.and_return(true)
|
|
61
|
+
Net::SCP.should_receive("upload!".to_sym).with("127.0.0.1", "fakeuuidfortestsapp1","file.txt","app-root/data").and_raise(SocketError)
|
|
62
|
+
end
|
|
63
|
+
it { run_output.should match("The connection to 127.0.0.1 failed: SocketError") }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context 'remote file not found' do
|
|
67
|
+
before(:each) do
|
|
68
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
69
|
+
@domain.add_application("app1", "mock_type")
|
|
70
|
+
File.should_receive(:exist?).with("file.txt").once.and_return(true)
|
|
71
|
+
Net::SCP.should_receive("upload!".to_sym).with("127.0.0.1", "fakeuuidfortestsapp1","file.txt","app-root/data").and_raise(Net::SCP::Error)
|
|
72
|
+
end
|
|
73
|
+
it { run_output.should match("Remote file, file_path, or directory could not be found.") }
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|