manifests-cf-plugin 0.7.0.rc1
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.
- data/Rakefile +5 -0
- data/lib/manifests-cf-plugin.rb +317 -0
- data/lib/manifests-cf-plugin/errors.rb +33 -0
- data/lib/manifests-cf-plugin/loader.rb +31 -0
- data/lib/manifests-cf-plugin/loader/builder.rb +37 -0
- data/lib/manifests-cf-plugin/loader/normalizer.rb +149 -0
- data/lib/manifests-cf-plugin/loader/resolver.rb +79 -0
- data/lib/manifests-cf-plugin/plugin.rb +145 -0
- data/lib/manifests-cf-plugin/version.rb +3 -0
- data/spec/manifests-cf-plugin/errors_spec.rb +29 -0
- data/spec/manifests-cf-plugin/loader/builder_spec.rb +84 -0
- data/spec/manifests-cf-plugin/loader/normalizer_spec.rb +176 -0
- data/spec/manifests-cf-plugin/plugin_spec.rb +365 -0
- data/spec/manifests-cf-plugin_spec.rb +321 -0
- data/spec/spec_helper.rb +17 -0
- metadata +173 -0
@@ -0,0 +1,365 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
require "manifests-cf-plugin/plugin"
|
4
|
+
|
5
|
+
|
6
|
+
describe ManifestsPlugin do
|
7
|
+
let(:manifest) { {} }
|
8
|
+
let(:manifest_file) { nil }
|
9
|
+
let(:inputs_hash) { {} }
|
10
|
+
let(:given_hash) { {} }
|
11
|
+
let(:global_hash) { { :quiet => true } }
|
12
|
+
let(:command) { nil }
|
13
|
+
let(:inputs) { Mothership::Inputs.new(Mothership.commands[:push], nil, inputs_hash, given_hash, global_hash) }
|
14
|
+
let(:plugin) { ManifestsPlugin.new(command, inputs) }
|
15
|
+
|
16
|
+
let(:client) { fake_client }
|
17
|
+
|
18
|
+
before do
|
19
|
+
stub(plugin).manifest { manifest }
|
20
|
+
stub(plugin).manifest_file { manifest_file } if manifest_file
|
21
|
+
stub(plugin).client { client }
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#wrap_with_optional_name" do
|
25
|
+
let(:name_made_optional) { true }
|
26
|
+
let(:wrapped) { mock! }
|
27
|
+
|
28
|
+
subject { plugin.send(:wrap_with_optional_name, name_made_optional, wrapped, inputs) }
|
29
|
+
|
30
|
+
context "when --all is given" do
|
31
|
+
let(:inputs_hash) { { :all => true } }
|
32
|
+
|
33
|
+
it "skips all manifest-related logic, and invokes the command" do
|
34
|
+
mock(wrapped).call
|
35
|
+
dont_allow(plugin).show_manifest_usage
|
36
|
+
subject
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when there is no manifest" do
|
41
|
+
let(:manifest) { nil }
|
42
|
+
|
43
|
+
context "and an app is given" do
|
44
|
+
let(:given_hash) { { :app => "foo" } }
|
45
|
+
|
46
|
+
it "passes through to the command" do
|
47
|
+
mock(wrapped).call
|
48
|
+
dont_allow(plugin).show_manifest_usage
|
49
|
+
subject
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "and an app is NOT given" do
|
54
|
+
let(:inputs_hash) { {} }
|
55
|
+
|
56
|
+
context "and we made it optional" do
|
57
|
+
it "fails manually" do
|
58
|
+
mock(plugin).no_apps
|
59
|
+
subject
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "and we did NOT make it optional" do
|
64
|
+
let(:name_made_optional) { false }
|
65
|
+
|
66
|
+
it "passes through to the command" do
|
67
|
+
mock(wrapped).call
|
68
|
+
dont_allow(plugin).show_manifest_usage
|
69
|
+
subject
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "when there is a manifest" do
|
76
|
+
let(:manifest_file) { "/abc/manifest.yml" }
|
77
|
+
|
78
|
+
before do
|
79
|
+
stub(plugin).show_manifest_usage
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when no apps are given" do
|
83
|
+
context "and the user's working directory matches a particular app in the manifest" do
|
84
|
+
let(:manifest) { { :applications => [{ :name => "foo", :path => "/abc/foo" }] } }
|
85
|
+
|
86
|
+
it "calls the command for only that app" do
|
87
|
+
mock(wrapped).call(anything) do |inputs|
|
88
|
+
expect(inputs.given[:app]).to eq "foo"
|
89
|
+
end
|
90
|
+
|
91
|
+
stub(Dir).pwd { "/abc/foo" }
|
92
|
+
|
93
|
+
subject
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context "and the user's working directory isn't in the manifest" do
|
98
|
+
let(:manifest) { { :applications => [{ :name => "foo" }, { :name => "bar" }] } }
|
99
|
+
|
100
|
+
it "calls the command for all apps in the manifest" do
|
101
|
+
uncalled_apps = ["foo", "bar"]
|
102
|
+
mock(wrapped).call(anything).twice do |inputs|
|
103
|
+
uncalled_apps.delete inputs.given[:app]
|
104
|
+
end
|
105
|
+
|
106
|
+
subject
|
107
|
+
|
108
|
+
expect(uncalled_apps).to be_empty
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
context "when any of the given apps are not in the manifest" do
|
114
|
+
let(:manifest) { { :applications => [{ :name => "a" }, { :name => "b" }] } }
|
115
|
+
|
116
|
+
context "and --apps is given" do
|
117
|
+
let(:given_hash) { { :apps => ["x", "a"] } }
|
118
|
+
|
119
|
+
it "passes through to the original command" do
|
120
|
+
mock(plugin).show_manifest_usage
|
121
|
+
|
122
|
+
uncalled_apps = ["a", "x"]
|
123
|
+
mock(wrapped).call(anything).twice do |inputs|
|
124
|
+
uncalled_apps.delete inputs.given[:app]
|
125
|
+
end
|
126
|
+
|
127
|
+
subject
|
128
|
+
|
129
|
+
expect(uncalled_apps).to be_empty
|
130
|
+
subject
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when none of the given apps are in the manifest" do
|
136
|
+
let(:manifest) { { :applications => [{ :name => "a" }, { :name => "b" }] } }
|
137
|
+
|
138
|
+
context "and --apps is given" do
|
139
|
+
let(:given_hash) { { :apps => ["x", "y"] } }
|
140
|
+
|
141
|
+
it "passes through to the original command" do
|
142
|
+
dont_allow(plugin).show_manifest_usage
|
143
|
+
mock(wrapped).call
|
144
|
+
subject
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "when an app name that's in the manifest is given" do
|
150
|
+
let(:manifest) { { :applications => [{ :name => "foo" }] } }
|
151
|
+
let(:given_hash) { { :app => "foo" } }
|
152
|
+
|
153
|
+
it "calls the command with that app" do
|
154
|
+
mock(wrapped).call(anything) do |inputs|
|
155
|
+
expect(inputs.given[:app]).to eq "foo"
|
156
|
+
end
|
157
|
+
|
158
|
+
subject
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context "when a path to an app that's in the manifest is given" do
|
163
|
+
let(:manifest) { { :applications => [{ :name => "foo", :path => "/abc/foo" }] } }
|
164
|
+
let(:given_hash) { { :app => "/abc/foo" } }
|
165
|
+
|
166
|
+
it "calls the command with that app" do
|
167
|
+
mock(wrapped).call(anything) do |inputs|
|
168
|
+
expect(inputs.given[:app]).to eq "foo"
|
169
|
+
end
|
170
|
+
|
171
|
+
subject
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "#wrap_push" do
|
178
|
+
let(:wrapped) { mock! }
|
179
|
+
let(:command) { Mothership.commands[:push] }
|
180
|
+
|
181
|
+
subject { plugin.send(:wrap_push, wrapped, inputs) }
|
182
|
+
|
183
|
+
before do
|
184
|
+
stub(plugin).show_manifest_usage
|
185
|
+
end
|
186
|
+
|
187
|
+
context "with a manifest" do
|
188
|
+
let(:manifest_file) { "/abc/manifest.yml" }
|
189
|
+
|
190
|
+
let(:manifest) do
|
191
|
+
{ :applications => [
|
192
|
+
{ :name => "a",
|
193
|
+
:path => "/abc/a",
|
194
|
+
:instances => "200",
|
195
|
+
:memory => "128M"
|
196
|
+
}
|
197
|
+
]
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
# cf push foo
|
202
|
+
context "and a name is given" do
|
203
|
+
context "and the name is present in the manifest" do
|
204
|
+
let(:given_hash) { { :name => "a" } }
|
205
|
+
|
206
|
+
context "and the app exists" do
|
207
|
+
let(:app) { fake :app, :name => "a" }
|
208
|
+
let(:client) { fake_client :apps => [app] }
|
209
|
+
|
210
|
+
context "and --reset was given" do
|
211
|
+
let(:inputs_hash) { { :reset => true } }
|
212
|
+
let(:given_hash) { { :name => "a", :instances => "100" } }
|
213
|
+
|
214
|
+
it "rebases their inputs on the manifest's values" do
|
215
|
+
mock(wrapped).call(anything) do |inputs|
|
216
|
+
expect(inputs.given).to eq(
|
217
|
+
:name => "a", :path => "/abc/a", :instances => "100", :memory => "128M")
|
218
|
+
end
|
219
|
+
|
220
|
+
subject
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context "and the app does NOT exist" do
|
226
|
+
it "pushes a new app with the inputs from the manifest" do
|
227
|
+
mock(wrapped).call(anything) do |inputs|
|
228
|
+
expect(inputs.given).to eq(
|
229
|
+
:name => "a", :path => "/abc/a", :instances => "200", :memory => "128M")
|
230
|
+
end
|
231
|
+
|
232
|
+
subject
|
233
|
+
end
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context "and the name is NOT present in the manifest" do
|
238
|
+
let(:given_hash) { { :name => "x" } }
|
239
|
+
|
240
|
+
it "fails, saying that name was not found in the manifest" do
|
241
|
+
expect { subject }.to raise_error(CF::UserError, /Could not find .+ in the manifest./)
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# cf push ./abc
|
247
|
+
context "and a path is given" do
|
248
|
+
context "and there are apps matching that path in the manifest" do
|
249
|
+
let(:manifest) do
|
250
|
+
{ :applications => [
|
251
|
+
{ :name => "a",
|
252
|
+
:path => "/abc/a",
|
253
|
+
:instances => "200",
|
254
|
+
:memory => "128M"
|
255
|
+
},
|
256
|
+
{ :name => "b",
|
257
|
+
:path => "/abc/a",
|
258
|
+
:instances => "200",
|
259
|
+
:memory => "128M"
|
260
|
+
}
|
261
|
+
]
|
262
|
+
}
|
263
|
+
end
|
264
|
+
|
265
|
+
let(:given_hash) { { :name => "/abc/a" } }
|
266
|
+
|
267
|
+
it "pushes the found apps" do
|
268
|
+
pushed_apps = []
|
269
|
+
mock(wrapped).call(anything).twice do |inputs|
|
270
|
+
pushed_apps << inputs[:name]
|
271
|
+
end
|
272
|
+
|
273
|
+
subject
|
274
|
+
|
275
|
+
expect(pushed_apps).to eq(["a", "b"])
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
context "and there are NOT apps matching that path in the manifest" do
|
280
|
+
let(:given_hash) { { :name => "/abc/x" } }
|
281
|
+
|
282
|
+
it "fails, saying that the path was not found in the manifest" do
|
283
|
+
expect { subject }.to raise_error(CF::UserError, /Path .+ is not present in manifest/)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
context "without a manifest" do
|
290
|
+
let(:app) { mock! }
|
291
|
+
let(:manifest) { nil }
|
292
|
+
|
293
|
+
it "asks to save the manifest when uploading the application" do
|
294
|
+
mock_ask("Save configuration?", :default => false)
|
295
|
+
stub(wrapped).call { plugin.filter(:push_app, app) }
|
296
|
+
subject
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
describe "#push_input_for" do
|
302
|
+
context "with an existing app" do
|
303
|
+
before do
|
304
|
+
stub(plugin).from_manifest { "PATH" }
|
305
|
+
app.changes.clear
|
306
|
+
end
|
307
|
+
|
308
|
+
let(:client) { fake_client(:apps => [app]) }
|
309
|
+
let(:manifest_memory) { "256M" }
|
310
|
+
let(:app) { fake :app, :name => "a", :memory => 256 }
|
311
|
+
let(:manifest) { { :name => "a", :memory => manifest_memory } }
|
312
|
+
|
313
|
+
subject { plugin.send(:push_input_for, manifest, inputs) }
|
314
|
+
|
315
|
+
context "with --reset" do
|
316
|
+
let(:inputs_hash) { { :reset => true } }
|
317
|
+
|
318
|
+
context "with changes" do
|
319
|
+
let(:manifest_memory) { "128M" }
|
320
|
+
|
321
|
+
it "applies the changes" do
|
322
|
+
subject[:memory].should == "128M"
|
323
|
+
end
|
324
|
+
|
325
|
+
it "does not ask to set --reset" do
|
326
|
+
dont_allow(plugin).warn_reset_changes
|
327
|
+
subject
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
context "without changes" do
|
332
|
+
it "does not ask to set --reset" do
|
333
|
+
dont_allow(plugin).warn_reset_changes
|
334
|
+
subject
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context "without --reset" do
|
340
|
+
let(:inputs_hash) { {} }
|
341
|
+
|
342
|
+
context "with changes" do
|
343
|
+
let(:manifest_memory) { "128M" }
|
344
|
+
|
345
|
+
it "asks user to provide --reset" do
|
346
|
+
mock(plugin).warn_reset_changes
|
347
|
+
subject
|
348
|
+
end
|
349
|
+
|
350
|
+
it "does not apply changes" do
|
351
|
+
stub(plugin).warn_reset_changes
|
352
|
+
subject[:memory].should == nil
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
context "without changes" do
|
357
|
+
it "does not ask to set --reset" do
|
358
|
+
dont_allow(plugin).warn_reset_changes
|
359
|
+
subject
|
360
|
+
end
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
@@ -0,0 +1,321 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'manifests-cf-plugin'
|
3
|
+
|
4
|
+
describe CFManifests do
|
5
|
+
let(:inputs_hash) { {} }
|
6
|
+
let(:given_hash) { {} }
|
7
|
+
let(:global_hash) { {} }
|
8
|
+
let(:inputs) { Mothership::Inputs.new(nil, nil, inputs_hash, given_hash, global_hash) }
|
9
|
+
|
10
|
+
let(:cmd) do
|
11
|
+
manifest = CF::App::Push.new(nil, inputs)
|
12
|
+
manifest.extend CFManifests
|
13
|
+
stub(manifest).client { client }
|
14
|
+
manifest
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:target_base) { "some-cloud.com" }
|
18
|
+
|
19
|
+
let(:foo) { fake(:app, :name => "foo") }
|
20
|
+
let(:bar) { fake(:app, :name => "bar") }
|
21
|
+
let(:baz) { fake(:app, :name => "baz") }
|
22
|
+
let(:xxx) { fake(:app, :name => "xxx") }
|
23
|
+
let(:yyy) { fake(:app, :name => "yyy") }
|
24
|
+
|
25
|
+
let(:client) do
|
26
|
+
fake_client :apps => [foo, bar, baz, xxx, yyy]
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:manifest_file) { "/abc/manifest.yml" }
|
30
|
+
|
31
|
+
before do
|
32
|
+
stub(cmd).target_base { target_base }
|
33
|
+
stub(cmd).v2? { true }
|
34
|
+
|
35
|
+
stub(cmd).manifest { manifest }
|
36
|
+
stub(cmd).manifest_file { manifest_file }
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#find_apps' do
|
40
|
+
subject { cmd.find_apps(nil) }
|
41
|
+
|
42
|
+
context 'when there is no manifest file' do
|
43
|
+
before { stub(cmd).manifest { nil } }
|
44
|
+
it { should eq [] }
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#create_manifest_for' do
|
49
|
+
let(:app) {
|
50
|
+
fake :app,
|
51
|
+
:framework => fake(:framework),
|
52
|
+
:runtime => fake(:runtime),
|
53
|
+
:memory => 2048,
|
54
|
+
:total_instances => 2,
|
55
|
+
:command => "ruby main.rb",
|
56
|
+
:buildpack => "git://example.com/foo.git",
|
57
|
+
:routes => [
|
58
|
+
fake(:route,
|
59
|
+
:host => "some-app-name",
|
60
|
+
:domain => fake(:domain, :name => target_base))
|
61
|
+
],
|
62
|
+
:service_bindings => [
|
63
|
+
fake(
|
64
|
+
:service_binding,
|
65
|
+
:service_instance =>
|
66
|
+
fake(
|
67
|
+
:service_instance,
|
68
|
+
:name => "service-1",
|
69
|
+
:service_plan =>
|
70
|
+
fake(
|
71
|
+
:service_plan,
|
72
|
+
:name => "P200",
|
73
|
+
:service => fake(:service))))
|
74
|
+
]
|
75
|
+
}
|
76
|
+
|
77
|
+
subject { cmd.create_manifest_for(app, "some-path") }
|
78
|
+
|
79
|
+
its(["name"]) { should eq app.name }
|
80
|
+
its(["framework"]) { should eq app.framework.name }
|
81
|
+
its(["runtime"]) { should eq app.runtime.name }
|
82
|
+
its(["memory"]) { should eq "2G" }
|
83
|
+
its(["instances"]) { should eq 2 }
|
84
|
+
its(["path"]) { should eq "some-path" }
|
85
|
+
its(["url"]) { should eq "some-app-name.${target-base}" }
|
86
|
+
its(["command"]) { should eq "ruby main.rb" }
|
87
|
+
its(["buildpack"]) { should eq "git://example.com/foo.git" }
|
88
|
+
|
89
|
+
it "contains the service information" do
|
90
|
+
expect(subject["services"]).to be_a Hash
|
91
|
+
|
92
|
+
services = subject["services"]
|
93
|
+
app.service_bindings.each do |b|
|
94
|
+
service = b.service_instance
|
95
|
+
|
96
|
+
expect(services).to include service.name
|
97
|
+
|
98
|
+
info = services[service.name]
|
99
|
+
|
100
|
+
plan = service.service_plan
|
101
|
+
offering = plan.service
|
102
|
+
|
103
|
+
{ "plan" => plan.name,
|
104
|
+
"label" => offering.label,
|
105
|
+
"provider" => offering.provider,
|
106
|
+
"version" => offering.version
|
107
|
+
}.each do |attr, val|
|
108
|
+
expect(info).to include attr
|
109
|
+
expect(info[attr]).to eq val
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'when there is no url' do
|
115
|
+
let(:app) {
|
116
|
+
fake :app,
|
117
|
+
:framework => fake(:framework),
|
118
|
+
:runtime => fake(:runtime),
|
119
|
+
:memory => 2048,
|
120
|
+
:total_instances => 2
|
121
|
+
}
|
122
|
+
|
123
|
+
its(["url"]) { should eq "none" }
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'when there is no command' do
|
127
|
+
let(:app) {
|
128
|
+
fake :app,
|
129
|
+
:framework => fake(:framework),
|
130
|
+
:runtime => fake(:runtime),
|
131
|
+
:memory => 2048,
|
132
|
+
:total_instances => 2
|
133
|
+
}
|
134
|
+
|
135
|
+
it { should_not include "command" }
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when there are no service bindings' do
|
139
|
+
let(:app) {
|
140
|
+
fake :app,
|
141
|
+
:framework => fake(:framework),
|
142
|
+
:runtime => fake(:runtime),
|
143
|
+
:memory => 2048,
|
144
|
+
:total_instances => 2
|
145
|
+
}
|
146
|
+
|
147
|
+
it { should_not include "services" }
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "#setup_services" do
|
152
|
+
let(:service_bindings) { [] }
|
153
|
+
let(:app) { fake :app, :service_bindings => service_bindings }
|
154
|
+
|
155
|
+
before do
|
156
|
+
dont_allow_ask(anything, anything)
|
157
|
+
end
|
158
|
+
|
159
|
+
context "when services are defined in the manifest" do
|
160
|
+
let(:info) {
|
161
|
+
{ :services => { "service-1" => { :label => "mysql", :plan => "100" } } }
|
162
|
+
}
|
163
|
+
|
164
|
+
let(:service_1) { fake(:service_instance, :name => "service-1") }
|
165
|
+
|
166
|
+
let(:plan_100) { fake :service_plan, :name => "100" }
|
167
|
+
|
168
|
+
let(:mysql) {
|
169
|
+
fake(
|
170
|
+
:service,
|
171
|
+
:label => "mysql",
|
172
|
+
:provider => "core",
|
173
|
+
:service_plans => [plan_100])
|
174
|
+
}
|
175
|
+
|
176
|
+
let(:service_instances) { [] }
|
177
|
+
|
178
|
+
let(:client) {
|
179
|
+
fake_client :services => [mysql], :service_instances => service_instances
|
180
|
+
}
|
181
|
+
|
182
|
+
context "and the services exist" do
|
183
|
+
let(:service_instances) { [service_1] }
|
184
|
+
|
185
|
+
context "and are already bound" do
|
186
|
+
let(:service_bindings) { [fake(:service_binding, :service_instance => service_1)] }
|
187
|
+
|
188
|
+
it "does neither create nor bind the service again" do
|
189
|
+
dont_allow(cmd).invoke :create_service, anything
|
190
|
+
dont_allow(cmd).invoke :bind_service, anything
|
191
|
+
cmd.send(:setup_services, app, info)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "but are not bound" do
|
196
|
+
it "does not create the services" do
|
197
|
+
dont_allow(cmd).invoke :create_service, anything
|
198
|
+
stub(cmd).invoke :bind_service, anything
|
199
|
+
cmd.send(:setup_services, app, info)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "binds the service" do
|
203
|
+
mock(cmd).invoke :bind_service, :app => app, :service => service_1
|
204
|
+
cmd.send(:setup_services, app, info)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
context "and the services do not exist" do
|
210
|
+
it "creates the services" do
|
211
|
+
mock(cmd).invoke :create_service, :app => app,
|
212
|
+
:name => service_1.name, :offering => mysql, :plan => plan_100
|
213
|
+
dont_allow(cmd).invoke :bind_service, anything
|
214
|
+
cmd.send(:setup_services, app, info)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
context "when there are no services defined" do
|
220
|
+
let(:info) { {} }
|
221
|
+
|
222
|
+
it "does not ask anything" do
|
223
|
+
cmd.send(:setup_services, app, info)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe "#apps_in_manifest" do
|
229
|
+
let(:foo_hash) { { :name => "foo", :path => "/abc/foo" } }
|
230
|
+
let(:bar_hash) { { :name => "bar", :path => "/abc/bar" } }
|
231
|
+
let(:baz_hash) { { :name => "baz", :path => "/abc/baz" } }
|
232
|
+
|
233
|
+
let(:manifest) { { :applications => [foo_hash, bar_hash, baz_hash] } }
|
234
|
+
|
235
|
+
subject { cmd.apps_in_manifest(inputs) }
|
236
|
+
|
237
|
+
context "when no apps are passed" do
|
238
|
+
let(:given_hash) { {} }
|
239
|
+
|
240
|
+
its(:first) { should eq [] }
|
241
|
+
its(:last) { should eq [] }
|
242
|
+
end
|
243
|
+
|
244
|
+
context "when app names are passed" do
|
245
|
+
context "and all of them are in the manifest" do
|
246
|
+
let(:given_hash) { { :apps => ["foo", "bar"] } }
|
247
|
+
|
248
|
+
its(:first) { should eq [foo_hash, bar_hash] }
|
249
|
+
its(:last) { should eq [] }
|
250
|
+
end
|
251
|
+
|
252
|
+
context "and one of them is in the manifest" do
|
253
|
+
let(:given_hash) { { :apps => ["foo", "xxx"] } }
|
254
|
+
|
255
|
+
its(:first) { should eq [foo_hash] }
|
256
|
+
its(:last) { should eq ["xxx"] }
|
257
|
+
end
|
258
|
+
|
259
|
+
context "and none of them are in the manifest" do
|
260
|
+
let(:given_hash) { { :apps => ["xxx", "yyy"] } }
|
261
|
+
|
262
|
+
its(:first) { should eq [] }
|
263
|
+
its(:last) { should eq ["xxx", "yyy"] }
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
context "when apps are passed as paths" do
|
268
|
+
context "and the paths are in the manifest" do
|
269
|
+
let(:given_hash) { { :apps => ["/abc/foo"] } }
|
270
|
+
|
271
|
+
its(:first) { should eq [foo_hash] }
|
272
|
+
its(:last) { should eq [] }
|
273
|
+
end
|
274
|
+
|
275
|
+
context "and any path is not in the manifest" do
|
276
|
+
let(:given_hash) { { :apps => ["/abc/xxx"] } }
|
277
|
+
|
278
|
+
it "fails with a manifest-specific method (i.e. path not in manifest)" do
|
279
|
+
expect { subject }.to raise_error(CF::UserError, /Path .+ is not present in manifest/)
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
describe "#all_apps" do
|
286
|
+
let(:applications) do
|
287
|
+
[
|
288
|
+
{:name => "foo", :path => "/abc"},
|
289
|
+
{:name => "bar", :path => "/abc"},
|
290
|
+
{:name => "baz", :path => "/abc/baz"}
|
291
|
+
]
|
292
|
+
end
|
293
|
+
|
294
|
+
let(:manifest) do
|
295
|
+
{ :applications => applications }
|
296
|
+
end
|
297
|
+
|
298
|
+
subject { cmd.all_apps }
|
299
|
+
|
300
|
+
it "returns all of the apps described in the manifest, as hashes" do
|
301
|
+
expect(subject).to eq applications
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
describe "#current_apps" do
|
306
|
+
let(:manifest) do
|
307
|
+
{:applications => [
|
308
|
+
{:name => "foo", :path => "/abc"},
|
309
|
+
{:name => "bar", :path => "/abc"},
|
310
|
+
{:name => "baz", :path => "/abc/baz"}
|
311
|
+
]}
|
312
|
+
end
|
313
|
+
|
314
|
+
subject { cmd.current_apps }
|
315
|
+
|
316
|
+
it "returns the applications with the cwd as their path" do
|
317
|
+
stub(Dir).pwd { "/abc" }
|
318
|
+
expect(subject).to eq [{ :name => "foo", :path => "/abc"}, { :name => "bar", :path => "/abc" }]
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|