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,665 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'rest_spec_helper'
|
|
3
|
+
require 'rhc/commands/cartridge'
|
|
4
|
+
require 'rhc/config'
|
|
5
|
+
|
|
6
|
+
describe RHC::Commands::Cartridge do
|
|
7
|
+
|
|
8
|
+
def exit_with_code_and_message(code, message = nil)
|
|
9
|
+
run_output.should match(message) if message
|
|
10
|
+
expect{ run }.to exit_with_code(code)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def succeed_with_message(message = "done")
|
|
14
|
+
exit_with_code_and_message(0,message)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def fail_with_message(message,code = 1)
|
|
18
|
+
exit_with_code_and_message(code, message)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def fail_with_code(code = 1)
|
|
22
|
+
exit_with_code_and_message(code)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
before{ user_config }
|
|
26
|
+
|
|
27
|
+
describe 'run' do
|
|
28
|
+
let!(:rest_client){ MockRestClient.new }
|
|
29
|
+
context "with all arguments" do
|
|
30
|
+
let(:arguments) { ['cartridges', '--trace'] }
|
|
31
|
+
it { succeed_with_message /mock_cart-1.*mock_cart-2.*unique_mock_cart-1/m }
|
|
32
|
+
end
|
|
33
|
+
context "without password" do
|
|
34
|
+
let(:arguments) { ['cartridges', '--trace'] }
|
|
35
|
+
it { succeed_with_message /mock_cart-1.*mock_cart-2.*unique_mock_cart-1/m }
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
describe 'cartridge list' do
|
|
40
|
+
let(:arguments){ ['cartridge', 'list'] }
|
|
41
|
+
let(:username){ nil }
|
|
42
|
+
let(:password){ nil }
|
|
43
|
+
let(:server){ mock_uri }
|
|
44
|
+
let(:user_auth){ false }
|
|
45
|
+
|
|
46
|
+
context 'with valid carts' do
|
|
47
|
+
before{ stub_api; stub_simple_carts }
|
|
48
|
+
|
|
49
|
+
it{ run_output.should match /mock_standalone_cart\-1\s+Mock1 Cart\s+web/ }
|
|
50
|
+
it{ run_output.should match /mock_standalone_cart\-2\s+web/ }
|
|
51
|
+
it{ run_output.should match /mock_embedded_cart\-1\s+Mock1 Embedded Cart\s+addon/ }
|
|
52
|
+
it{ run_output.should match /premium_cart\-1 \(\*\)\s+Premium Cart\s+web/ }
|
|
53
|
+
it{ expect{ run }.to exit_with_code(0) }
|
|
54
|
+
|
|
55
|
+
context 'with verbose list' do
|
|
56
|
+
let(:arguments){ ['cartridge', 'list', '--verbose', '--trace'] }
|
|
57
|
+
it{ run_output.should match /Mock1 Cart.*\[mock_standalone_cart\-1\] \(web\)/ }
|
|
58
|
+
it{ run_output.should match /mock_standalone_cart\-2 \(web\)/ }
|
|
59
|
+
it{ run_output.should match "Mock2 description\n\n" }
|
|
60
|
+
it{ run_output.should match "Tagged with: scheduled" }
|
|
61
|
+
it{ run_output.should_not match("Tagged with: cartridge") }
|
|
62
|
+
it{ run_output.should match /Premium Cart.*\[premium_cart\-1\*\] \(web\)/ }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
describe 'alias app cartridge' do
|
|
68
|
+
let!(:rest_client){ MockRestClient.new }
|
|
69
|
+
let(:arguments) { ['app', 'cartridge', 'list'] }
|
|
70
|
+
|
|
71
|
+
context 'when run' do
|
|
72
|
+
it { succeed_with_message /mock_cart-1.*mock_cart-2.*unique_mock_cart-1/m }
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
describe 'cartridge add' do
|
|
77
|
+
let!(:rest_client){ MockRestClient.new }
|
|
78
|
+
let(:arguments) { ['cartridge', 'add', 'mock_cart-1', '--app', 'app1'] }
|
|
79
|
+
|
|
80
|
+
context 'when run' do
|
|
81
|
+
before do
|
|
82
|
+
domain = rest_client.add_domain("mock_domain")
|
|
83
|
+
app = domain.add_application("app1", "mock_type")
|
|
84
|
+
end
|
|
85
|
+
it { succeed_with_message /Adding mock_cart-1 to application 'app1' \.\.\. / }
|
|
86
|
+
it { succeed_with_message /Connection URL:\s+http\:\/\/fake\.url/ }
|
|
87
|
+
it { succeed_with_message /Prop1:\s+value1/ }
|
|
88
|
+
it { succeed_with_message /Cartridge added with properties/ }
|
|
89
|
+
it "should not contain env var info" do
|
|
90
|
+
run_output.should_not match(/Environment Variables/)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
describe 'cartridge add' do
|
|
96
|
+
let!(:rest_client){ MockRestClient.new }
|
|
97
|
+
let(:arguments) { ['cartridge', 'add', 'mock_cart-1', '--app', 'app1', '--gear-size', 'small'] }
|
|
98
|
+
|
|
99
|
+
context 'with gear size' do
|
|
100
|
+
before do
|
|
101
|
+
domain = rest_client.add_domain("mock_domain")
|
|
102
|
+
app = domain.add_application("app1", "mock_type", true)
|
|
103
|
+
end
|
|
104
|
+
it { succeed_with_message /Adding mock_cart-1 to application 'app1' \.\.\. / }
|
|
105
|
+
it { succeed_with_message /Connection URL:\s+http\:\/\/fake\.url/ }
|
|
106
|
+
it { succeed_with_message /Prop1:\s+value1/ }
|
|
107
|
+
it { succeed_with_message /Cartridge added with properties/ }
|
|
108
|
+
it "should not contain env var info" do
|
|
109
|
+
run_output.should_not match(/Environment Variables/)
|
|
110
|
+
end
|
|
111
|
+
it { succeed_with_message /Gears:\s+1 small/ }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
context 'with gear size on unsupported server' do
|
|
115
|
+
let(:arguments) { ['cartridge', 'add', 'mock_cart-1', '--app', 'app1', '--gear-size', 'small'] }
|
|
116
|
+
before do
|
|
117
|
+
domain = rest_client.add_domain("mock_domain")
|
|
118
|
+
app = domain.add_application("app1", "mock_type", true)
|
|
119
|
+
@app.stub(:has_param?).with('ADD_CARTRIDGE','environment_variables').and_return(true)
|
|
120
|
+
@app.stub(:has_param?).with('ADD_CARTRIDGE','gear_size').and_return(false)
|
|
121
|
+
end
|
|
122
|
+
it { expect { run }.to exit_with_code(0) }
|
|
123
|
+
it { run_output.should match(/Server does not support gear sizes for cartridges/) }
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
describe 'cartridge add' do
|
|
128
|
+
let!(:rest_client){ MockRestClient.new }
|
|
129
|
+
let(:instance) do
|
|
130
|
+
domain = rest_client.add_domain("mock_domain")
|
|
131
|
+
@app = domain.add_application("app1", "mock_type")
|
|
132
|
+
instance = RHC::Commands::Cartridge.new
|
|
133
|
+
RHC::Commands::Cartridge.stub(:new) { instance }
|
|
134
|
+
instance
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
context 'with app context' do
|
|
138
|
+
let(:arguments) { ['cartridge', 'add', 'mock_cart-1'] }
|
|
139
|
+
before do
|
|
140
|
+
instance.stub(:git_config_get) { |key| @app.id if key == "rhc.app-id" }
|
|
141
|
+
end
|
|
142
|
+
it{ succeed_with_message }
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
context 'with named app context' do
|
|
146
|
+
let(:arguments) { ['cartridge', 'add', 'mock_cart-1'] }
|
|
147
|
+
before do
|
|
148
|
+
instance.stub(:git_config_get) { |key| @app.name if key == "rhc.app-name" }
|
|
149
|
+
end
|
|
150
|
+
it{ succeed_with_message }
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
context 'without app context' do
|
|
154
|
+
let(:arguments) { ['cartridge', 'add', 'mock_cart-1'] }
|
|
155
|
+
before do
|
|
156
|
+
instance.should_receive(:git_config_get).with('rhc.domain-name').and_return(nil)
|
|
157
|
+
instance.should_receive(:git_config_get).with('rhc.app-name').and_return(nil)
|
|
158
|
+
instance.should_receive(:git_config_get).with('rhc.app-id').and_return('')
|
|
159
|
+
end
|
|
160
|
+
it{ fail_with_code }
|
|
161
|
+
end
|
|
162
|
+
context 'with unrecognized app context' do
|
|
163
|
+
let(:arguments) { ['cartridge', 'add', 'mock_cart-1'] }
|
|
164
|
+
before do
|
|
165
|
+
instance.should_receive(:git_config_get).with('rhc.domain-name').and_return(nil)
|
|
166
|
+
instance.should_receive(:git_config_get).with('rhc.app-name').and_return(nil)
|
|
167
|
+
instance.should_receive(:git_config_get).with('rhc.app-id').and_return('find')
|
|
168
|
+
end
|
|
169
|
+
it{ fail_with_code(101) }
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
describe 'cartridge add' do
|
|
174
|
+
let!(:rest_client){ MockRestClient.new }
|
|
175
|
+
|
|
176
|
+
context 'when invoked through an alias' do
|
|
177
|
+
let(:arguments) { ['app', 'cartridge', 'add', 'unique_mock_cart', '--app', 'app1'] }
|
|
178
|
+
before do
|
|
179
|
+
domain = rest_client.add_domain("mock_domain")
|
|
180
|
+
app = domain.add_application("app1", "mock_type")
|
|
181
|
+
end
|
|
182
|
+
it {
|
|
183
|
+
succeed_with_message
|
|
184
|
+
}
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
context 'when cartridge with regex breaking name does not exist' do
|
|
188
|
+
let(:arguments) { ['cartridge', 'add', '*##', '--app', 'app1'] }
|
|
189
|
+
before do
|
|
190
|
+
domain = rest_client.add_domain("mock_domain")
|
|
191
|
+
app = domain.add_application("app1", "mock_type")
|
|
192
|
+
end
|
|
193
|
+
it{ fail_with_code 154 }
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
context 'when cartridge does not exist' do
|
|
197
|
+
let(:arguments) { ['cartridge', 'add', 'nomatch_cart', '--app', 'app1'] }
|
|
198
|
+
before do
|
|
199
|
+
domain = rest_client.add_domain("mock_domain")
|
|
200
|
+
app = domain.add_application("app1", "mock_type")
|
|
201
|
+
end
|
|
202
|
+
it{ fail_with_code 154 }
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
context 'when multiple carts match' do
|
|
206
|
+
let(:arguments) { ['cartridge', 'add', 'mock_cart', '-a', 'app1'] }
|
|
207
|
+
before do
|
|
208
|
+
domain = rest_client.add_domain("mock_domain")
|
|
209
|
+
app = domain.add_application("app1", "mock_type")
|
|
210
|
+
end
|
|
211
|
+
it {
|
|
212
|
+
fail_with_code 155
|
|
213
|
+
}
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
context 'when cart is premium' do
|
|
217
|
+
let(:arguments) { ['cartridge', 'add', 'premium_cart', '-a', 'app1'] }
|
|
218
|
+
before do
|
|
219
|
+
domain = rest_client.add_domain("mock_domain")
|
|
220
|
+
app = domain.add_application("app1", "mock_type")
|
|
221
|
+
end
|
|
222
|
+
it {
|
|
223
|
+
succeed_with_message /This gear costs an additional \$0\.05 per gear after the first 3 gears\./
|
|
224
|
+
}
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
describe 'cartridge remove' do
|
|
229
|
+
let!(:rest_client){ MockRestClient.new }
|
|
230
|
+
|
|
231
|
+
context 'when run with --noprompt and without --confirm' do
|
|
232
|
+
let(:arguments) { ['cartridge', 'remove', 'mock_cart-1', '-a', 'app1', '--noprompt'] }
|
|
233
|
+
before do
|
|
234
|
+
domain = rest_client.add_domain("mock_domain")
|
|
235
|
+
app = domain.add_application("app1", "mock_type")
|
|
236
|
+
app.add_cartridge('mock_cart-1')
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
it{ fail_with_message "This action requires the --confirm option" }
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
context 'when run with confirmation' do
|
|
243
|
+
let(:arguments) { ['cartridge', 'remove', 'mock_cart-1', '--confirm', '--trace', '-a', 'app1'] }
|
|
244
|
+
before do
|
|
245
|
+
domain = rest_client.add_domain("mock_domain")
|
|
246
|
+
@app = domain.add_application("app1", "mock_type")
|
|
247
|
+
end
|
|
248
|
+
it "should remove cartridge" do
|
|
249
|
+
@app.add_cartridge('mock_cart-1')
|
|
250
|
+
expect { run }.to exit_with_code(0)
|
|
251
|
+
# framework cart should be the only one listed
|
|
252
|
+
@app.cartridges.length.should == 1
|
|
253
|
+
end
|
|
254
|
+
it "should raise cartridge not found exception" do
|
|
255
|
+
expect { run }.to raise_error RHC::CartridgeNotFoundException
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
context 'when run with custom cart url' do
|
|
260
|
+
let(:arguments) { ['cartridge', 'remove', 'https://foo.bar.com', '--confirm', '-a', 'app1'] }
|
|
261
|
+
before do
|
|
262
|
+
@domain = rest_client.add_domain("mockdomain")
|
|
263
|
+
@app = @domain.add_application("app1", "mock_type")
|
|
264
|
+
cart1 = @app.add_cartridge('mock_cart-1')
|
|
265
|
+
cart1.url = 'https://foo.bar.com'
|
|
266
|
+
end
|
|
267
|
+
it "should remove cartridge" do
|
|
268
|
+
expect { run }.to exit_with_code(0)
|
|
269
|
+
# framework cart should be the only one listed
|
|
270
|
+
@app.cartridges.length.should == 1
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
context "against a 1.5 server" do
|
|
275
|
+
let!(:rest_client){ nil }
|
|
276
|
+
let(:username){ mock_user }
|
|
277
|
+
let(:password){ 'password' }
|
|
278
|
+
let(:server){ mock_uri }
|
|
279
|
+
let(:arguments){ ['remove-cartridge', 'jenkins-1', '-a', 'foo', '--confirm', '--trace'] }
|
|
280
|
+
before do
|
|
281
|
+
stub_api(false)
|
|
282
|
+
challenge{ stub_one_domain('test') }
|
|
283
|
+
stub_one_application('test', 'foo').with(:query => {:include => 'cartridges'})
|
|
284
|
+
stub_application_cartridges('test', 'foo', [{:name => 'php-5.3'}, {:name => 'jenkins-1'}])
|
|
285
|
+
end
|
|
286
|
+
before do
|
|
287
|
+
stub_api_request(:delete, "broker/rest/domains/test/applications/foo/cartridges/jenkins-1").
|
|
288
|
+
to_return({
|
|
289
|
+
:body => {
|
|
290
|
+
:type => nil,
|
|
291
|
+
:data => nil,
|
|
292
|
+
:messages => [
|
|
293
|
+
{:exit_code => 0, :field => nil, :severity => 'info', :text => 'Removed Jenkins'},
|
|
294
|
+
{:exit_code => 0, :field => nil, :severity => 'result', :text => 'Job URL changed'},
|
|
295
|
+
]
|
|
296
|
+
}.to_json,
|
|
297
|
+
:status => 200
|
|
298
|
+
})
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it("should not display info returned by the server"){ run_output.should_not match "Removed Jenkins" }
|
|
302
|
+
it("should display prefix returned by the server"){ run_output.should match "Removing jenkins-1" }
|
|
303
|
+
it("should display results returned by the server"){ run_output.should match "Job URL changed" }
|
|
304
|
+
it('should exit successfully'){ expect{ run }.to exit_with_code(0) }
|
|
305
|
+
end
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
describe 'cartridge status' do
|
|
309
|
+
let!(:rest_client){ MockRestClient.new }
|
|
310
|
+
let(:arguments) { ['cartridge', 'status', 'mock_cart-1', '-a', 'app1'] }
|
|
311
|
+
|
|
312
|
+
before do
|
|
313
|
+
@domain = rest_client.add_domain("mock_domain")
|
|
314
|
+
@app = @domain.add_application("app1", "mock_type")
|
|
315
|
+
@app.add_cartridge('mock_cart-1')
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
context 'when run' do
|
|
319
|
+
it { run_output.should match('started') }
|
|
320
|
+
end
|
|
321
|
+
|
|
322
|
+
context 'when run with cart stopped' do
|
|
323
|
+
before { @app.find_cartridge('mock_cart-1').stop }
|
|
324
|
+
it { run_output.should match('stopped') }
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
describe 'cartridge start' do
|
|
329
|
+
let!(:rest_client){ MockRestClient.new }
|
|
330
|
+
let(:arguments) { ['cartridge', 'start', 'mock_cart-1', '-a', 'app1'] }
|
|
331
|
+
|
|
332
|
+
context 'when run' do
|
|
333
|
+
before do
|
|
334
|
+
domain = rest_client.add_domain("mock_domain")
|
|
335
|
+
app = domain.add_application("app1", "mock_type")
|
|
336
|
+
app.add_cartridge('mock_cart-1')
|
|
337
|
+
end
|
|
338
|
+
it { run_output.should match(/Starting mock_cart-1 .*done/) }
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
describe 'cartridge stop' do
|
|
343
|
+
let!(:rest_client){ MockRestClient.new }
|
|
344
|
+
let(:arguments) { ['cartridge', 'stop', 'mock_cart-1', '-a', 'app1'] }
|
|
345
|
+
|
|
346
|
+
context 'when run' do
|
|
347
|
+
before do
|
|
348
|
+
domain = rest_client.add_domain("mock_domain")
|
|
349
|
+
app = domain.add_application("app1", "mock_type")
|
|
350
|
+
app.add_cartridge('mock_cart-1')
|
|
351
|
+
end
|
|
352
|
+
it { run_output.should match(/Stopping mock_cart-1 .*done/) }
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
describe 'cartridge restart' do
|
|
357
|
+
let!(:rest_client){ MockRestClient.new }
|
|
358
|
+
let(:arguments) { ['cartridge', 'restart', 'mock_cart-1', '-a', 'app1'] }
|
|
359
|
+
|
|
360
|
+
context 'when run' do
|
|
361
|
+
before do
|
|
362
|
+
domain = rest_client.add_domain("mock_domain")
|
|
363
|
+
app = domain.add_application("app1", "mock_type")
|
|
364
|
+
app.add_cartridge('mock_cart-1')
|
|
365
|
+
end
|
|
366
|
+
it { run_output.should match(/Restarting mock_cart-1 .*done/) }
|
|
367
|
+
end
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
describe 'cartridge reload' do
|
|
371
|
+
let!(:rest_client){ MockRestClient.new }
|
|
372
|
+
let(:arguments) { ['cartridge', 'reload', 'mock_cart-1', '-a', 'app1'] }
|
|
373
|
+
|
|
374
|
+
context 'when run' do
|
|
375
|
+
before do
|
|
376
|
+
domain = rest_client.add_domain("mock_domain")
|
|
377
|
+
app = domain.add_application("app1", "mock_type")
|
|
378
|
+
app.add_cartridge('mock_cart-1')
|
|
379
|
+
end
|
|
380
|
+
it { run_output.should match(/Reloading mock_cart-1 .*done/) }
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
describe 'cartridge show' do
|
|
385
|
+
let!(:rest_client){ MockRestClient.new }
|
|
386
|
+
let(:arguments) { ['cartridge', 'show', 'mock_cart-1', '-a', 'app1'] }
|
|
387
|
+
|
|
388
|
+
before do
|
|
389
|
+
domain = rest_client.add_domain("mock_domain")
|
|
390
|
+
app = domain.add_application("app1", "mock_type")
|
|
391
|
+
app.add_cartridge('mock_cart-1')
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
context 'when run with exactly the same case as how cartridge was created' do
|
|
395
|
+
it { run_output.should match('Connection URL: http://fake.url') }
|
|
396
|
+
it { run_output.should match(/Prop1:\s+value1/) }
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
describe 'cartridge show' do
|
|
401
|
+
let(:arguments) { ['cartridge', 'show', 'Mock_Cart-1', '-a', 'app1'] }
|
|
402
|
+
|
|
403
|
+
before do
|
|
404
|
+
@rc = MockRestClient.new
|
|
405
|
+
domain = @rc.add_domain("mock_domain")
|
|
406
|
+
app = domain.add_application("app1", "mock_type")
|
|
407
|
+
app.add_cartridge('mock_cart-1')
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
context 'when run with different case from how cartrige was created' do
|
|
411
|
+
it { run_output.should match('Connection URL: http://fake.url') }
|
|
412
|
+
it { run_output.should match(/Prop1:\s+value1/) }
|
|
413
|
+
end
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
describe 'cartridge show' do
|
|
417
|
+
let(:arguments) { ['cartridge', 'show', 'premium_cart', '-a', 'app1'] }
|
|
418
|
+
|
|
419
|
+
before do
|
|
420
|
+
@rc = MockRestClient.new
|
|
421
|
+
domain = @rc.add_domain("mock_domain")
|
|
422
|
+
app = domain.add_application("app1", "mock_type")
|
|
423
|
+
app.cartridges << @rc.cartridges.find {|c| c.name == 'premium_cart'}
|
|
424
|
+
end
|
|
425
|
+
|
|
426
|
+
context 'when run with a premium cartridge' do
|
|
427
|
+
it { run_output.should match(/This gear costs an additional \$0\.05 per gear after the first 3 gears./) }
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
|
|
431
|
+
describe 'cartridge show scaled' do
|
|
432
|
+
let!(:rest_client){ MockRestClient.new }
|
|
433
|
+
let(:arguments) { ['cartridge', 'show', 'mock_type', '-a', 'app1'] }
|
|
434
|
+
|
|
435
|
+
context 'when run' do
|
|
436
|
+
before do
|
|
437
|
+
domain = rest_client.add_domain("mock_domain")
|
|
438
|
+
app = domain.add_application("app1", "mock_type", true)
|
|
439
|
+
end
|
|
440
|
+
it { run_output.should match(/Scaling: .*x2 \(minimum/) }
|
|
441
|
+
it { run_output.should match('minimum: 2') }
|
|
442
|
+
it { run_output.should match('maximum: available') }
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
describe 'cartridge scale' do
|
|
447
|
+
let!(:rest_client){ MockRestClient.new }
|
|
448
|
+
let(:arguments) { ['cartridge', 'scale', @cart_type || 'mock_type', '-a', 'app1'] | (@extra_args || []) }
|
|
449
|
+
|
|
450
|
+
let(:current_scale) { 1 }
|
|
451
|
+
before do
|
|
452
|
+
domain = rest_client.add_domain("mock_domain")
|
|
453
|
+
@app = domain.add_application("app1", "mock_type", scalable)
|
|
454
|
+
@app.cartridges.first.stub(:current_scale).and_return(current_scale)
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
context 'when run with scalable app' do
|
|
458
|
+
let(:scalable){ true }
|
|
459
|
+
|
|
460
|
+
it "with no values" do
|
|
461
|
+
fail_with_message "Must provide either a min or max"
|
|
462
|
+
end
|
|
463
|
+
|
|
464
|
+
it "with a min value" do
|
|
465
|
+
@extra_args = ["--min","6"]
|
|
466
|
+
succeed_with_message "minimum: 6"
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
it "with an explicit value" do
|
|
470
|
+
@extra_args = ["6"]
|
|
471
|
+
succeed_with_message "minimum: 6, maximum: 6"
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
it "with an invalid explicit value" do
|
|
475
|
+
@extra_args = ["a6"]
|
|
476
|
+
fail_with_message "Multiplier must be a positive integer"
|
|
477
|
+
end
|
|
478
|
+
|
|
479
|
+
it "with an explicit value and a different minimum" do
|
|
480
|
+
@extra_args = ["6", "--min", "5"]
|
|
481
|
+
succeed_with_message "minimum: 5, maximum: 6"
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
it "with a max value" do
|
|
485
|
+
@extra_args = ["--max","3"]
|
|
486
|
+
succeed_with_message 'maximum: 3'
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
it "with an invalid min value" do
|
|
490
|
+
@extra_args = ["--min","a"]
|
|
491
|
+
fail_with_message "invalid argument: --min"
|
|
492
|
+
end
|
|
493
|
+
|
|
494
|
+
it "with an invalid max value" do
|
|
495
|
+
@extra_args = ["--max","a"]
|
|
496
|
+
fail_with_message "invalid argument: --max"
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
context "when the operation times out" do
|
|
500
|
+
before{ @app.cartridges.first.should_receive(:set_scales).twice.and_raise(RHC::Rest::TimeoutException.new('Timeout', HTTPClient::ReceiveTimeoutError.new)) }
|
|
501
|
+
it "displays an error" do
|
|
502
|
+
@extra_args = ["--min","2"]
|
|
503
|
+
fail_with_message "The server has closed the connection, but your scaling operation is still in progress"
|
|
504
|
+
end
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
context 'when run with a nonscalable app' do
|
|
509
|
+
let(:scalable){ false }
|
|
510
|
+
|
|
511
|
+
it "with a min value" do
|
|
512
|
+
@extra_args = ["--min","6"]
|
|
513
|
+
fail_with_message "Cartridge is not scalable"
|
|
514
|
+
end
|
|
515
|
+
end
|
|
516
|
+
end
|
|
517
|
+
|
|
518
|
+
describe 'cartridge storage' do
|
|
519
|
+
let!(:rest_client){ MockRestClient.new(RHC::Config, 1.3) }
|
|
520
|
+
let(:cmd_base) { ['cartridge', 'storage'] }
|
|
521
|
+
let(:std_args) { ['-a', 'app1'] | (@extra_args || []) }
|
|
522
|
+
let(:cart_type) { ['mock_cart-1'] }
|
|
523
|
+
|
|
524
|
+
before do
|
|
525
|
+
domain = rest_client.add_domain("mock_domain")
|
|
526
|
+
app = domain.add_application("app1", "mock_type", false)
|
|
527
|
+
app.add_cartridge('mock_cart-1', true)
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
context 'when run with no arguments' do
|
|
531
|
+
let(:arguments) { cmd_base | std_args }
|
|
532
|
+
it ("should show the mock_type"){ run_output.should match('mock_type') }
|
|
533
|
+
it ('should show mock_cart-1'){ run_output.should match('mock_cart-1') }
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
context 'when run for a non-existent cartridge' do
|
|
537
|
+
let(:arguments) { cmd_base | ['bogus_cart'] | std_args }
|
|
538
|
+
it { fail_with_message("There are no cartridges that match 'bogus_cart'.", 154) }
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
context 'when run with -c flag' do
|
|
542
|
+
let(:arguments) { cmd_base | ['-c', 'mock_cart-1'] | std_args}
|
|
543
|
+
it "should show storage info for the indicated app and cart" do
|
|
544
|
+
run_output.should match('mock_cart-1')
|
|
545
|
+
run_output.should_not match('mock_type')
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
it "should set storage for the indicated app and cart" do
|
|
549
|
+
@extra_args = ["--set", "6GB"]
|
|
550
|
+
run_output.should match('6GB')
|
|
551
|
+
end
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
context 'when run with valid arguments' do
|
|
555
|
+
let(:arguments) { cmd_base | cart_type | std_args }
|
|
556
|
+
it "should show storage info for the indicated app and cart" do
|
|
557
|
+
@extra_args = ["--show"]
|
|
558
|
+
run_output.should match('mock_cart-1')
|
|
559
|
+
run_output.should_not match('mock_type')
|
|
560
|
+
end
|
|
561
|
+
it "should add storage for the indicated app and cart" do
|
|
562
|
+
@extra_args = ["--add", "5GB"]
|
|
563
|
+
run_output.should match('10GB')
|
|
564
|
+
end
|
|
565
|
+
it "should remove storage for the indicated app and cart" do
|
|
566
|
+
@extra_args = ["--remove", "5GB"]
|
|
567
|
+
run_output.should match('None')
|
|
568
|
+
end
|
|
569
|
+
it "should warn when told to remove more storage than the indicated app and cart have" do
|
|
570
|
+
@extra_args = ["--remove", "70GB"]
|
|
571
|
+
fail_with_message('The amount of additional storage to be removed exceeds the total amount in use')
|
|
572
|
+
end
|
|
573
|
+
it "should not warn when told to remove more storage than the indicated app and cart have when forced" do
|
|
574
|
+
@extra_args = ["--remove", "70GB", "--force"]
|
|
575
|
+
run_output.should match('None')
|
|
576
|
+
end
|
|
577
|
+
it "should set storage for the indicated app and cart" do
|
|
578
|
+
@extra_args = ["--set", "6GB"]
|
|
579
|
+
run_output.should match('6GB')
|
|
580
|
+
end
|
|
581
|
+
it "should work correctly with a bare number value" do
|
|
582
|
+
@extra_args = ["--set", "6"]
|
|
583
|
+
run_output.should match('6GB')
|
|
584
|
+
end
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
context 'when run with invalid arguments' do
|
|
588
|
+
let(:arguments) { cmd_base | cart_type | std_args }
|
|
589
|
+
it "should raise an error when multiple storage operations are provided" do
|
|
590
|
+
@extra_args = ["--show", "--add", "5GB"]
|
|
591
|
+
fail_with_message('Only one storage action can be performed at a time')
|
|
592
|
+
end
|
|
593
|
+
it "should raise an error when the storage amount is not provided" do
|
|
594
|
+
@extra_args = ["--set"]
|
|
595
|
+
fail_with_message('missing argument')
|
|
596
|
+
end
|
|
597
|
+
it "should raise an error when the storage amount is invalid" do
|
|
598
|
+
@extra_args = ["--set", "5ZB"]
|
|
599
|
+
fail_with_message("The amount format must be a number, optionally followed by 'GB'")
|
|
600
|
+
end
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
context 'when run against an outdated broker' do
|
|
604
|
+
before { rest_client.stub(:api_version_negotiated).and_return(1.2) }
|
|
605
|
+
let(:arguments) { cmd_base | cart_type | std_args }
|
|
606
|
+
|
|
607
|
+
it 'adding storage should raise a version error' do
|
|
608
|
+
@extra_args = ["--add", "1GB"]
|
|
609
|
+
fail_with_message('The server does not support this command \(requires 1.3, found 1.2\).')
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
end
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
describe 'cartridge add with env vars' do
|
|
616
|
+
let!(:rest_client){ MockRestClient.new }
|
|
617
|
+
before do
|
|
618
|
+
domain = rest_client.add_domain("mock_domain")
|
|
619
|
+
@app = domain.add_application("app1", "mock_type")
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
[['app', 'cartridge', 'add', 'unique_mock_cart', '-e', 'FOO=BAR', '--app', 'app1'],
|
|
623
|
+
['app', 'cartridge', 'add', 'unique_mock_cart', '--env', 'FOO=BAR', '--app', 'app1']
|
|
624
|
+
].each_with_index do |args, i|
|
|
625
|
+
context "when run with single env var #{i}" do
|
|
626
|
+
let(:arguments) { args }
|
|
627
|
+
it { succeed_with_message(/Environment Variables:\s+FOO=BAR/) }
|
|
628
|
+
end
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
[['app', 'cartridge', 'add', 'unique_mock_cart', '-e', 'FOO1=BAR1', '-e', 'FOO2=BAR2', '--app', 'app1'],
|
|
632
|
+
['app', 'cartridge', 'add', 'unique_mock_cart', '--env', 'FOO1=BAR1', '--env', 'FOO2=BAR2', '--app', 'app1']
|
|
633
|
+
].each_with_index do |args, i|
|
|
634
|
+
context "when run with multiple env vars #{i}" do
|
|
635
|
+
let(:arguments) { args }
|
|
636
|
+
it { succeed_with_message(/Environment Variables:\s+FOO1=BAR1, FOO2=BAR2/) }
|
|
637
|
+
end
|
|
638
|
+
end
|
|
639
|
+
|
|
640
|
+
[['app', 'cartridge', 'add', 'unique_mock_cart', '-e', File.expand_path('../../assets/env_vars.txt', __FILE__), '--app', 'app1'],
|
|
641
|
+
['app', 'cartridge', 'add', 'unique_mock_cart', '--env', File.expand_path('../../assets/env_vars.txt', __FILE__), '--app', 'app1']
|
|
642
|
+
].each_with_index do |args, i|
|
|
643
|
+
context "when run with env vars from files #{i}" do
|
|
644
|
+
let(:arguments) { args }
|
|
645
|
+
it { succeed_with_message(/Environment Variables:\s+BAR=456, FOO=123, MY_EMPTY_ENV_VAR=, MY_OPENSHIFT_ENV_VAR=mongodb:\/\/user:pass@host:port\/\n/) }
|
|
646
|
+
end
|
|
647
|
+
end
|
|
648
|
+
|
|
649
|
+
[['app', 'cartridge', 'add', 'unique_mock_cart', '-e', 'FOO=BAR', '--app', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password'],
|
|
650
|
+
['app', 'cartridge', 'add', 'unique_mock_cart', '--env', 'FOO=BAR', '--app', 'app1', '--noprompt', '--config', 'test.conf', '-l', 'test@test.foo', '-p', 'password']
|
|
651
|
+
].each_with_index do |args, i|
|
|
652
|
+
context "when run against a server without env vars support #{i}" do
|
|
653
|
+
let(:arguments) { args }
|
|
654
|
+
before do
|
|
655
|
+
@app.stub(:has_param?).with('ADD_CARTRIDGE','environment_variables').and_return(false)
|
|
656
|
+
@app.stub(:has_param?).with('ADD_CARTRIDGE','gear_size').and_return(true)
|
|
657
|
+
end
|
|
658
|
+
it { expect { run }.to exit_with_code(0) }
|
|
659
|
+
it { run_output.should match(/Server does not support environment variables/) }
|
|
660
|
+
it { run_output.should_not match(/Environment Variables:\s+FOO=BAR/) }
|
|
661
|
+
end
|
|
662
|
+
end
|
|
663
|
+
|
|
664
|
+
end
|
|
665
|
+
end
|