vmc 0.4.2 → 0.4.3
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/lib/vmc.rb +2 -5
- data/lib/vmc/cli/app/apps.rb +4 -1
- data/lib/vmc/cli/app/push.rb +38 -221
- data/lib/vmc/cli/app/push/create.rb +125 -0
- data/lib/vmc/cli/app/push/interaction.rb +64 -0
- data/lib/vmc/cli/app/push/sync.rb +59 -0
- data/lib/vmc/cli/app/rename.rb +1 -1
- data/lib/vmc/cli/organization/base.rb +14 -0
- data/lib/vmc/cli/organization/create_org.rb +28 -0
- data/lib/vmc/cli/organization/delete_org.rb +65 -0
- data/lib/vmc/cli/organization/org.rb +46 -0
- data/lib/vmc/cli/organization/orgs.rb +35 -0
- data/lib/vmc/cli/organization/rename.rb +32 -0
- data/lib/vmc/cli/service/base.rb +8 -0
- data/lib/vmc/cli/service/binding.rb +66 -0
- data/lib/vmc/cli/service/create.rb +104 -0
- data/lib/vmc/cli/service/delete.rb +84 -0
- data/lib/vmc/cli/service/rename.rb +32 -0
- data/lib/vmc/cli/service/service.rb +45 -0
- data/lib/vmc/cli/service/services.rb +118 -0
- data/lib/vmc/cli/space/base.rb +21 -0
- data/lib/vmc/cli/space/create.rb +57 -0
- data/lib/vmc/cli/space/delete.rb +92 -0
- data/lib/vmc/cli/space/rename.rb +36 -0
- data/lib/vmc/cli/space/space.rb +67 -0
- data/lib/vmc/cli/space/spaces.rb +57 -0
- data/lib/vmc/cli/space/take.rb +18 -0
- data/lib/vmc/cli/start/base.rb +100 -0
- data/lib/vmc/cli/start/colors.rb +14 -0
- data/lib/vmc/cli/start/info.rb +124 -0
- data/lib/vmc/cli/start/login.rb +94 -0
- data/lib/vmc/cli/start/logout.rb +14 -0
- data/lib/vmc/cli/start/register.rb +38 -0
- data/lib/vmc/cli/start/target.rb +68 -0
- data/lib/vmc/cli/start/targets.rb +17 -0
- data/lib/vmc/version.rb +1 -1
- data/spec/factories/app_factory.rb +5 -0
- data/spec/factories/client_factory.rb +10 -1
- data/spec/factories/domain_factory.rb +2 -1
- data/spec/factories/factory.rb +1 -0
- data/spec/factories/framework_factory.rb +1 -0
- data/spec/factories/organization_factory.rb +18 -0
- data/spec/factories/route_factory.rb +1 -0
- data/spec/factories/runtime_factory.rb +10 -0
- data/spec/factories/service_binding_factory.rb +9 -0
- data/spec/factories/service_factory.rb +17 -0
- data/spec/factories/service_instance_factory.rb +10 -0
- data/spec/factories/service_plan_factory.rb +11 -0
- data/spec/factories/space_factory.rb +10 -0
- data/spec/support/interact_helpers.rb +7 -3
- data/spec/vmc/cli/app/push/create_spec.rb +450 -0
- data/spec/vmc/cli/app/push_spec.rb +303 -9
- data/spec/vmc/cli/app/rename_spec.rb +9 -4
- data/spec/vmc/cli/organization/rename_spec.rb +113 -0
- data/spec/vmc/cli/route/delete_route_spec.rb +2 -2
- data/spec/vmc/cli/service/rename_spec.rb +114 -0
- data/spec/vmc/cli/space/rename_spec.rb +114 -0
- metadata +109 -64
- data/lib/vmc/cli/organization.rb +0 -176
- data/lib/vmc/cli/service.rb +0 -387
- data/lib/vmc/cli/space.rb +0 -284
- data/lib/vmc/cli/start.rb +0 -432
- data/spec/assets/hello-sinatra/Gemfile.lock +0 -17
@@ -0,0 +1,38 @@
|
|
1
|
+
require "vmc/detect"
|
2
|
+
require "vmc/cli/start/base"
|
3
|
+
|
4
|
+
module VMC::Start
|
5
|
+
class Register < Base
|
6
|
+
desc "Create a user and log in"
|
7
|
+
group :start, :hidden => true
|
8
|
+
input(:email, :argument => true, :desc => "Desired email") {
|
9
|
+
ask("Email")
|
10
|
+
}
|
11
|
+
input(:password, :desc => "Desired password") {
|
12
|
+
ask("Password", :echo => "*", :forget => true)
|
13
|
+
}
|
14
|
+
input(:verify, :desc => "Repeat password") {
|
15
|
+
ask("Confirm Password", :echo => "*", :forget => true)
|
16
|
+
}
|
17
|
+
input :login, :type => :boolean, :default => true,
|
18
|
+
:desc => "Automatically log in?"
|
19
|
+
def register
|
20
|
+
show_context
|
21
|
+
|
22
|
+
email = input[:email]
|
23
|
+
password = input[:password]
|
24
|
+
|
25
|
+
if !force? && password != input[:verify]
|
26
|
+
fail "Passwords do not match."
|
27
|
+
end
|
28
|
+
|
29
|
+
with_progress("Creating user") do
|
30
|
+
client.register(email, password)
|
31
|
+
end
|
32
|
+
|
33
|
+
if input[:login]
|
34
|
+
invoke :login, :username => email, :password => password
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "vmc/detect"
|
2
|
+
require "vmc/cli/start/base"
|
3
|
+
|
4
|
+
module VMC::Start
|
5
|
+
class Target < Base
|
6
|
+
desc "Set or display the target cloud, organization, and space"
|
7
|
+
group :start
|
8
|
+
input :url, :argument => :optional, :desc => "Target URL to switch to"
|
9
|
+
input(:organization, :aliases => ["--org", "-o"],
|
10
|
+
:from_given => find_by_name("organization"),
|
11
|
+
:desc => "Organization") { |orgs|
|
12
|
+
ask("Organization", :choices => orgs, :display => proc(&:name))
|
13
|
+
}
|
14
|
+
input(:space, :alias => "-s",
|
15
|
+
:from_given => find_by_name("space"),
|
16
|
+
:desc => "Space") { |spaces|
|
17
|
+
ask("Space", :choices => spaces, :display => proc(&:name))
|
18
|
+
}
|
19
|
+
def target
|
20
|
+
if !input.given?(:url) && !input.given?(:organization) && !input.given?(:space)
|
21
|
+
display_target
|
22
|
+
display_org_and_space unless quiet?
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
if input.given?(:url)
|
27
|
+
target = sane_target_url(input[:url])
|
28
|
+
with_progress("Setting target to #{c(target, :name)}") do
|
29
|
+
client(target).info # check that it's valid before setting
|
30
|
+
set_target(target)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
return unless v2? && client.logged_in?
|
35
|
+
|
36
|
+
if input.given?(:organization) || input.given?(:space)
|
37
|
+
info = target_info
|
38
|
+
|
39
|
+
select_org_and_space(input, info)
|
40
|
+
|
41
|
+
save_target_info(info)
|
42
|
+
end
|
43
|
+
|
44
|
+
return if quiet?
|
45
|
+
|
46
|
+
invalidate_client
|
47
|
+
|
48
|
+
line
|
49
|
+
display_target
|
50
|
+
display_org_and_space
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def display_org_and_space
|
56
|
+
return unless v2?
|
57
|
+
|
58
|
+
if org = client.current_organization
|
59
|
+
line "organization: #{c(org.name, :name)}"
|
60
|
+
end
|
61
|
+
|
62
|
+
if space = client.current_space
|
63
|
+
line "space: #{c(space.name, :name)}"
|
64
|
+
end
|
65
|
+
rescue CFoundry::APIError
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "vmc/detect"
|
2
|
+
require "vmc/cli/start/base"
|
3
|
+
|
4
|
+
module VMC::Start
|
5
|
+
class Targets < Base
|
6
|
+
desc "List known targets."
|
7
|
+
group :start, :hidden => true
|
8
|
+
def targets
|
9
|
+
targets_info.each do |target, _|
|
10
|
+
line target
|
11
|
+
# TODO: print org/space
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
data/lib/vmc/version.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
FactoryGirl.define do
|
2
2
|
factory :app, :class => CFoundry::V2::App do
|
3
|
+
guid { FactoryGirl.generate(:guid) }
|
3
4
|
name { FactoryGirl.generate(:random_string) }
|
5
|
+
memory 128
|
6
|
+
total_instances 0
|
7
|
+
production false
|
8
|
+
state "STOPPED"
|
4
9
|
|
5
10
|
initialize_with do
|
6
11
|
CFoundry::V2::App.new(nil, nil)
|
@@ -4,13 +4,22 @@ FactoryGirl.define do
|
|
4
4
|
routes []
|
5
5
|
apps []
|
6
6
|
frameworks []
|
7
|
+
runtimes []
|
8
|
+
service_instances []
|
9
|
+
spaces []
|
10
|
+
organizations []
|
11
|
+
logged_in true
|
7
12
|
end
|
8
13
|
|
9
14
|
after_build do |client, evaluator|
|
10
|
-
RR.stub(client).logged_in? {
|
15
|
+
RR.stub(client).logged_in? { evaluator.logged_in }
|
11
16
|
RR.stub(client).routes { evaluator.routes }
|
12
17
|
RR.stub(client).apps { evaluator.apps }
|
13
18
|
RR.stub(client).frameworks { evaluator.frameworks }
|
19
|
+
RR.stub(client).runtimes { evaluator.runtimes }
|
20
|
+
RR.stub(client).service_instances { evaluator.service_instances }
|
21
|
+
RR.stub(client).spaces { evaluator.spaces }
|
22
|
+
RR.stub(client).organizations { evaluator.organizations }
|
14
23
|
end
|
15
24
|
end
|
16
25
|
end
|
data/spec/factories/factory.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :organization, :class => CFoundry::V2::Organization do
|
3
|
+
guid { FactoryGirl.generate(:guid) }
|
4
|
+
name { FactoryGirl.generate(:random_string) }
|
5
|
+
|
6
|
+
ignore do
|
7
|
+
spaces []
|
8
|
+
end
|
9
|
+
|
10
|
+
initialize_with do
|
11
|
+
CFoundry::V2::Organization.new(nil, nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
after_build do |org, evaluator|
|
15
|
+
RR.stub(org).spaces { evaluator.spaces }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :service, :class => CFoundry::V2::Service do
|
3
|
+
guid { FactoryGirl.generate(:guid) }
|
4
|
+
label "redis"
|
5
|
+
provider "core"
|
6
|
+
url "http://example.com"
|
7
|
+
description "small key-value store"
|
8
|
+
version "2.8"
|
9
|
+
info_url "http://cloudfoundry.com/redis"
|
10
|
+
active true
|
11
|
+
|
12
|
+
initialize_with do
|
13
|
+
CFoundry::V2::Service.new(nil, nil)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,10 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :service_instance, :class => CFoundry::V2::ServiceInstance do
|
3
|
+
guid { FactoryGirl.generate(:guid) }
|
4
|
+
name { FactoryGirl.generate(:random_string) }
|
5
|
+
|
6
|
+
initialize_with do
|
7
|
+
CFoundry::V2::ServiceInstance.new(nil, nil)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -1,13 +1,17 @@
|
|
1
1
|
def stub_ask(*args, &block)
|
2
|
+
a_stub = nil
|
2
3
|
any_instance_of VMC::CLI do |interactive|
|
3
|
-
stub(interactive).ask(*args, &block)
|
4
|
+
a_stub = stub(interactive).ask(*args, &block)
|
4
5
|
end
|
6
|
+
a_stub
|
5
7
|
end
|
6
8
|
|
7
9
|
def mock_ask(*args, &block)
|
10
|
+
a_mock = nil
|
8
11
|
any_instance_of VMC::CLI do |interactive|
|
9
|
-
mock(interactive).ask(*args, &block)
|
12
|
+
a_mock = mock(interactive).ask(*args, &block)
|
10
13
|
end
|
14
|
+
a_mock
|
11
15
|
end
|
12
16
|
|
13
17
|
def dont_allow_ask(*args)
|
@@ -20,4 +24,4 @@ def mock_with_progress(message)
|
|
20
24
|
any_instance_of VMC::CLI do |interactive|
|
21
25
|
mock(interactive).with_progress(message) { |_, block| block.call }
|
22
26
|
end
|
23
|
-
end
|
27
|
+
end
|
@@ -0,0 +1,450 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe VMC::App::Create do
|
4
|
+
let(:inputs) { {} }
|
5
|
+
let(:given) { {} }
|
6
|
+
let(:global) { { :color => false, :quiet => true } }
|
7
|
+
|
8
|
+
let(:frameworks) { FactoryGirl.build_list(:framework, 3) }
|
9
|
+
let(:framework) { frameworks.first }
|
10
|
+
let(:standalone) { FactoryGirl.build(:framework, :name => "standalone") }
|
11
|
+
|
12
|
+
let(:runtimes) { FactoryGirl.build_list(:runtime, 3) }
|
13
|
+
let(:runtime) { runtimes.first }
|
14
|
+
|
15
|
+
let(:service_instances) { FactoryGirl.build_list(:service_instance, 5) }
|
16
|
+
|
17
|
+
let(:client) do
|
18
|
+
FactoryGirl.build(
|
19
|
+
:client,
|
20
|
+
:frameworks => frameworks, :runtimes => runtimes,
|
21
|
+
:service_instances => service_instances)
|
22
|
+
end
|
23
|
+
|
24
|
+
before do
|
25
|
+
any_instance_of(VMC::CLI) do |cli|
|
26
|
+
stub(cli).client { client }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:create) do
|
31
|
+
create = VMC::App::Push.new
|
32
|
+
create.path = "somePath"
|
33
|
+
create.input = Mothership::Inputs.new(Mothership.commands[:push], create, inputs, given, global)
|
34
|
+
create
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#get_inputs' do
|
38
|
+
subject { create.get_inputs }
|
39
|
+
|
40
|
+
let(:inputs) do
|
41
|
+
{ :name => "some-name",
|
42
|
+
:instances => 1,
|
43
|
+
:plan => "p100",
|
44
|
+
:framework => framework,
|
45
|
+
:runtime => runtime,
|
46
|
+
:memory => "1G"
|
47
|
+
}
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when all the inputs are given' do
|
51
|
+
its([:name]) { should eq "some-name" }
|
52
|
+
its([:total_instances]) { should eq 1 }
|
53
|
+
its([:space]) { should eq client.current_space }
|
54
|
+
its([:production]) { should eq true }
|
55
|
+
its([:framework]) { should eq framework }
|
56
|
+
its([:command]) { should eq nil }
|
57
|
+
its([:runtime]) { should eq runtime }
|
58
|
+
its([:memory]) { should eq 1024 }
|
59
|
+
end
|
60
|
+
|
61
|
+
context 'when certain inputs are not given' do
|
62
|
+
it 'should ask for the name' do
|
63
|
+
inputs.delete(:name)
|
64
|
+
mock_ask("Name") { "some-name" }
|
65
|
+
subject
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should ask for the total instances' do
|
69
|
+
inputs.delete(:instances)
|
70
|
+
mock_ask("Instances", anything) { 1 }
|
71
|
+
subject
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should ask for the framework' do
|
75
|
+
inputs.delete(:framework)
|
76
|
+
mock_ask('Framework', anything) do |_, options|
|
77
|
+
expect(options[:choices]).to eq frameworks.sort_by(&:name)
|
78
|
+
framework
|
79
|
+
end
|
80
|
+
subject
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should ask for the command if the framework is standalone' do
|
84
|
+
inputs[:framework] = standalone
|
85
|
+
mock_ask("Startup command") { "ruby main.rb" }
|
86
|
+
subject
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should ask for the runtime' do
|
90
|
+
inputs.delete(:runtime)
|
91
|
+
mock_ask('Runtime', anything) do |_, options|
|
92
|
+
expect(options[:choices]).to eq runtimes.sort_by(&:name)
|
93
|
+
runtime
|
94
|
+
end
|
95
|
+
subject
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should ask for the memory' do
|
99
|
+
inputs.delete(:memory)
|
100
|
+
|
101
|
+
memory_choices = %w(64M 128M 256M 512M 1G)
|
102
|
+
stub(create).memory_choices { memory_choices }
|
103
|
+
|
104
|
+
mock_ask('Memory Limit', anything) do |_, options|
|
105
|
+
expect(options[:choices]).to eq memory_choices
|
106
|
+
"1G"
|
107
|
+
end
|
108
|
+
|
109
|
+
subject
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe '#determine_framework' do
|
115
|
+
subject { create.determine_framework }
|
116
|
+
|
117
|
+
context 'when framework is given' do
|
118
|
+
let(:inputs) { { :framework => framework } }
|
119
|
+
|
120
|
+
it 'does not try to get the frameworks' do
|
121
|
+
any_instance_of(VMC::Detector) do |detector|
|
122
|
+
dont_allow(detector).detect_framework
|
123
|
+
dont_allow(detector).all_frameworks
|
124
|
+
end
|
125
|
+
|
126
|
+
dont_allow_ask
|
127
|
+
dont_allow(client).frameworks
|
128
|
+
|
129
|
+
subject
|
130
|
+
end
|
131
|
+
|
132
|
+
it { should eq framework }
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'when framework is not given' do
|
136
|
+
context 'and a framework is detected' do
|
137
|
+
it "lists the detected framework and an 'other' option" do
|
138
|
+
any_instance_of(VMC::Detector) do |detector|
|
139
|
+
mock(detector).detect_framework { framework }
|
140
|
+
end
|
141
|
+
|
142
|
+
mock_ask('Framework', anything) do |_, options|
|
143
|
+
expect(options[:choices]).to eq [framework, :other] #frameworks.sort_by(&:name)
|
144
|
+
framework
|
145
|
+
end
|
146
|
+
|
147
|
+
subject
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'and a framework is not detected' do
|
152
|
+
it "lists all available frameworks" do
|
153
|
+
any_instance_of(VMC::Detector) do |detector|
|
154
|
+
stub(detector).detect_framework
|
155
|
+
end
|
156
|
+
|
157
|
+
mock_ask('Framework', anything) do |_, options|
|
158
|
+
expect(options[:choices]).to eq frameworks.sort_by(&:name)
|
159
|
+
framework
|
160
|
+
end
|
161
|
+
|
162
|
+
subject
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe '#detect_runtimes' do
|
169
|
+
subject { create.determine_runtime(framework) }
|
170
|
+
|
171
|
+
context 'when runtime is given' do
|
172
|
+
let(:inputs) { { :runtime => runtime } }
|
173
|
+
|
174
|
+
it 'does not try to get the runtime' do
|
175
|
+
any_instance_of(VMC::Detector) do |detector|
|
176
|
+
dont_allow(detector).detect_runtime
|
177
|
+
dont_allow(detector).all_runtimes
|
178
|
+
end
|
179
|
+
|
180
|
+
dont_allow_ask
|
181
|
+
dont_allow(client).runtimes
|
182
|
+
|
183
|
+
subject
|
184
|
+
end
|
185
|
+
|
186
|
+
it { should eq runtime }
|
187
|
+
end
|
188
|
+
|
189
|
+
context 'when runtime is not given' do
|
190
|
+
context 'and the framework is standalone' do
|
191
|
+
let(:framework) { standalone }
|
192
|
+
|
193
|
+
it "detects the runtime" do
|
194
|
+
any_instance_of(VMC::Detector) do |detector|
|
195
|
+
mock(detector).detect_runtimes { runtimes }
|
196
|
+
end
|
197
|
+
|
198
|
+
mock_ask('Runtime', anything) do |_, options|
|
199
|
+
expect(options[:choices]).to eq(runtimes.sort_by(&:name) + [:other])
|
200
|
+
runtime
|
201
|
+
end
|
202
|
+
|
203
|
+
subject
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context 'and the framework is not standalone' do
|
208
|
+
it "gets the runtimes based on the framework" do
|
209
|
+
any_instance_of(VMC::Detector) do |detector|
|
210
|
+
mock(detector).runtimes(framework) { runtimes }
|
211
|
+
end
|
212
|
+
|
213
|
+
mock_ask('Runtime', anything) do |_, options|
|
214
|
+
expect(options[:choices]).to eq(runtimes.sort_by(&:name) + [:other])
|
215
|
+
runtime
|
216
|
+
end
|
217
|
+
|
218
|
+
subject
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
describe '#create_app' do
|
225
|
+
before { dont_allow_ask }
|
226
|
+
|
227
|
+
let(:app) { FactoryGirl.build(:app, :guid => nil) }
|
228
|
+
|
229
|
+
let(:attributes) do
|
230
|
+
{ :name => "some-app",
|
231
|
+
:total_instances => 2,
|
232
|
+
:framework => framework,
|
233
|
+
:runtime => runtime,
|
234
|
+
:production => false,
|
235
|
+
:memory => 1024
|
236
|
+
}
|
237
|
+
end
|
238
|
+
|
239
|
+
before { stub(client).app { app } }
|
240
|
+
|
241
|
+
subject { create.create_app(attributes) }
|
242
|
+
|
243
|
+
it 'creates an app based on the resulting inputs' do
|
244
|
+
attributes.each do |key, val|
|
245
|
+
mock(app).__send__(:"#{key}=", val)
|
246
|
+
end
|
247
|
+
|
248
|
+
mock(create).filter(:create_app, app) { app }
|
249
|
+
|
250
|
+
mock(app).create!
|
251
|
+
|
252
|
+
subject
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
describe '#map_url' do
|
257
|
+
let(:app) { FactoryGirl.build(:app) }
|
258
|
+
let(:url_choices) { %W(#{app.name}.foo-cloud.com) }
|
259
|
+
|
260
|
+
before do
|
261
|
+
stub(create).url_choices { url_choices }
|
262
|
+
end
|
263
|
+
|
264
|
+
subject { create.map_url(app) }
|
265
|
+
|
266
|
+
it "maps a url" do
|
267
|
+
mock_ask('URL', anything) do |_, options|
|
268
|
+
expect(options[:choices]).to eq(url_choices + %w(none))
|
269
|
+
expect(options[:default]).to eq url_choices.first
|
270
|
+
url_choices.first
|
271
|
+
end
|
272
|
+
|
273
|
+
mock(create).invoke(:map, :app => app, :url => url_choices.first)
|
274
|
+
|
275
|
+
subject
|
276
|
+
end
|
277
|
+
|
278
|
+
context "when mapping fails" do
|
279
|
+
before do
|
280
|
+
mock_ask('URL', anything) { url_choices.first }
|
281
|
+
|
282
|
+
mock(create).invoke(:map, :app => app, :url => url_choices.first) do
|
283
|
+
raise CFoundry::RouteHostTaken.new(1234, "foo")
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
it "asks again" do
|
288
|
+
stub(create).line
|
289
|
+
|
290
|
+
mock_ask('URL', anything) { url_choices.first }
|
291
|
+
|
292
|
+
stub(create).invoke(:map, :app => app, :url => url_choices.first)
|
293
|
+
|
294
|
+
subject
|
295
|
+
end
|
296
|
+
|
297
|
+
it "reports the failure message" do
|
298
|
+
mock(create).line "foo"
|
299
|
+
mock(create).line
|
300
|
+
|
301
|
+
stub_ask('URL', anything) { url_choices.first }
|
302
|
+
|
303
|
+
stub(create).invoke(:map, :app => app, :url => url_choices.first)
|
304
|
+
|
305
|
+
subject
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
describe '#create_services' do
|
311
|
+
let(:app) { FactoryGirl.build(:app) }
|
312
|
+
subject { create.create_services(app) }
|
313
|
+
|
314
|
+
context 'when forcing' do
|
315
|
+
let(:inputs) { {:force => true} }
|
316
|
+
|
317
|
+
it "does not ask to create any services" do
|
318
|
+
dont_allow_ask("Create services for application?", anything)
|
319
|
+
subject
|
320
|
+
end
|
321
|
+
|
322
|
+
it "does not create any services" do
|
323
|
+
dont_allow(create).invoke(:create_service, anything)
|
324
|
+
subject
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
context 'when not forcing' do
|
329
|
+
let(:inputs) { { :force => false } }
|
330
|
+
|
331
|
+
it 'does not create the service if asked not to' do
|
332
|
+
mock_ask("Create services for application?", anything) { false }
|
333
|
+
dont_allow(create).invoke(:create_service, anything)
|
334
|
+
|
335
|
+
subject
|
336
|
+
end
|
337
|
+
|
338
|
+
it 'asks again to create a service' do
|
339
|
+
mock_ask("Create services for application?", anything) { true }
|
340
|
+
mock(create).invoke(:create_service, { :app => app }, :plan => :interact).ordered
|
341
|
+
|
342
|
+
mock_ask("Create another service?", :default => false) { true }
|
343
|
+
mock(create).invoke(:create_service, { :app => app }, :plan => :interact).ordered
|
344
|
+
|
345
|
+
mock_ask("Create another service?", :default => false) { true }
|
346
|
+
mock(create).invoke(:create_service, { :app => app }, :plan => :interact).ordered
|
347
|
+
|
348
|
+
mock_ask("Create another service?", :default => false) { false }
|
349
|
+
dont_allow(create).invoke(:create_service, anything).ordered
|
350
|
+
|
351
|
+
subject
|
352
|
+
end
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
describe '#bind_services' do
|
357
|
+
let(:app) { FactoryGirl.build(:app) }
|
358
|
+
|
359
|
+
subject { create.bind_services(app) }
|
360
|
+
|
361
|
+
context 'when forcing' do
|
362
|
+
let(:global) { { :force => true, :color => false, :quiet => true } }
|
363
|
+
|
364
|
+
it "does not ask to bind any services" do
|
365
|
+
dont_allow_ask("Bind other services to application?", anything)
|
366
|
+
subject
|
367
|
+
end
|
368
|
+
|
369
|
+
it "does not bind any services" do
|
370
|
+
dont_allow(create).invoke(:bind_service, anything)
|
371
|
+
subject
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
context 'when not forcing' do
|
376
|
+
it 'does not bind the service if asked not to' do
|
377
|
+
mock_ask("Bind other services to application?", anything) { false }
|
378
|
+
dont_allow(create).invoke(:bind_service, anything)
|
379
|
+
|
380
|
+
subject
|
381
|
+
end
|
382
|
+
|
383
|
+
it 'asks again to bind a service' do
|
384
|
+
bind_times = 3
|
385
|
+
call_count = 0
|
386
|
+
|
387
|
+
mock_ask("Bind other services to application?", anything) { true }
|
388
|
+
|
389
|
+
mock(create).invoke(:bind_service, :app => app).times(bind_times) do
|
390
|
+
call_count += 1
|
391
|
+
stub(app).services { service_instances.first(call_count) }
|
392
|
+
end
|
393
|
+
|
394
|
+
mock_ask("Bind another service?", anything).times(bind_times) do
|
395
|
+
call_count < bind_times
|
396
|
+
end
|
397
|
+
|
398
|
+
subject
|
399
|
+
end
|
400
|
+
|
401
|
+
it 'stops asking if there are no more services to bind' do
|
402
|
+
bind_times = service_instances.size
|
403
|
+
call_count = 0
|
404
|
+
|
405
|
+
mock_ask("Bind other services to application?", anything) { true }
|
406
|
+
|
407
|
+
mock(create).invoke(:bind_service, :app => app).times(bind_times) do
|
408
|
+
call_count += 1
|
409
|
+
stub(app).services { service_instances.first(call_count) }
|
410
|
+
end
|
411
|
+
|
412
|
+
mock_ask("Bind another service?", anything).times(bind_times - 1) { true }
|
413
|
+
|
414
|
+
subject
|
415
|
+
end
|
416
|
+
|
417
|
+
context 'when there are no services' do
|
418
|
+
let(:service_instances) { [] }
|
419
|
+
|
420
|
+
it 'does not ask to bind anything' do
|
421
|
+
dont_allow_ask
|
422
|
+
subject
|
423
|
+
end
|
424
|
+
end
|
425
|
+
end
|
426
|
+
end
|
427
|
+
|
428
|
+
describe '#start_app' do
|
429
|
+
let(:app) { FactoryGirl.build(:app) }
|
430
|
+
subject { create.start_app(app) }
|
431
|
+
|
432
|
+
context 'when the start flag is provided' do
|
433
|
+
let(:inputs) { {:start => true} }
|
434
|
+
|
435
|
+
it 'invokes the start command' do
|
436
|
+
mock(create).invoke(:start, :app => app)
|
437
|
+
subject
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
context 'when the start flag is not provided' do
|
442
|
+
let(:inputs) { {:start => false} }
|
443
|
+
|
444
|
+
it 'invokes the start command' do
|
445
|
+
dont_allow(create).invoke(:start, anything)
|
446
|
+
subject
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|