cf 0.1.5 → 0.6.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/LICENSE +1277 -30
- data/Rakefile +12 -1
- data/bin/cf +0 -3
- data/lib/cf.rb +6 -0
- data/lib/cf/cli.rb +389 -190
- data/lib/cf/cli/app/app.rb +45 -0
- data/lib/cf/cli/app/apps.rb +99 -0
- data/lib/cf/cli/app/base.rb +90 -0
- data/lib/cf/cli/app/crashes.rb +42 -0
- data/lib/cf/cli/app/delete.rb +95 -0
- data/lib/cf/cli/app/deprecated.rb +11 -0
- data/lib/cf/cli/app/env.rb +78 -0
- data/lib/cf/cli/app/files.rb +137 -0
- data/lib/cf/cli/app/health.rb +26 -0
- data/lib/cf/cli/app/instances.rb +53 -0
- data/lib/cf/cli/app/logs.rb +76 -0
- data/lib/cf/cli/app/push.rb +105 -0
- data/lib/cf/cli/app/push/create.rb +149 -0
- data/lib/cf/cli/app/push/interactions.rb +94 -0
- data/lib/cf/cli/app/push/sync.rb +64 -0
- data/lib/cf/cli/app/rename.rb +35 -0
- data/lib/cf/cli/app/restart.rb +20 -0
- data/lib/cf/cli/app/scale.rb +69 -0
- data/lib/cf/cli/app/start.rb +143 -0
- data/lib/cf/cli/app/stats.rb +67 -0
- data/lib/cf/cli/app/stop.rb +27 -0
- data/lib/cf/cli/domain/base.rb +8 -0
- data/lib/cf/cli/domain/domains.rb +40 -0
- data/lib/cf/cli/domain/map.rb +55 -0
- data/lib/cf/cli/domain/unmap.rb +56 -0
- data/lib/cf/cli/help.rb +15 -0
- data/lib/cf/cli/interactive.rb +105 -0
- data/lib/cf/cli/organization/base.rb +12 -0
- data/lib/cf/cli/organization/create.rb +32 -0
- data/lib/cf/cli/organization/delete.rb +73 -0
- data/lib/cf/cli/organization/org.rb +45 -0
- data/lib/cf/cli/organization/orgs.rb +35 -0
- data/lib/cf/cli/organization/rename.rb +36 -0
- data/lib/cf/cli/route/base.rb +8 -0
- data/lib/cf/cli/route/map.rb +70 -0
- data/lib/cf/cli/route/routes.rb +26 -0
- data/lib/cf/cli/route/unmap.rb +62 -0
- data/lib/cf/cli/service/base.rb +8 -0
- data/lib/cf/cli/service/bind.rb +44 -0
- data/lib/cf/cli/service/create.rb +107 -0
- data/lib/cf/cli/service/delete.rb +82 -0
- data/lib/cf/cli/service/rename.rb +35 -0
- data/lib/cf/cli/service/service.rb +40 -0
- data/lib/cf/cli/service/services.rb +99 -0
- data/lib/cf/cli/service/unbind.rb +38 -0
- data/lib/cf/cli/space/base.rb +19 -0
- data/lib/cf/cli/space/create.rb +63 -0
- data/lib/cf/cli/space/delete.rb +95 -0
- data/lib/cf/cli/space/rename.rb +39 -0
- data/lib/cf/cli/space/space.rb +64 -0
- data/lib/cf/cli/space/spaces.rb +55 -0
- data/lib/cf/cli/space/switch.rb +16 -0
- data/lib/cf/cli/start/base.rb +93 -0
- data/lib/cf/cli/start/colors.rb +13 -0
- data/lib/cf/cli/start/info.rb +124 -0
- data/lib/cf/cli/start/login.rb +94 -0
- data/lib/cf/cli/start/logout.rb +17 -0
- data/lib/cf/cli/start/target.rb +69 -0
- data/lib/cf/cli/start/target_interactions.rb +37 -0
- data/lib/cf/cli/start/targets.rb +16 -0
- data/lib/cf/cli/user/base.rb +29 -0
- data/lib/cf/cli/user/create.rb +39 -0
- data/lib/cf/cli/user/passwd.rb +43 -0
- data/lib/cf/cli/user/register.rb +42 -0
- data/lib/cf/cli/user/users.rb +32 -0
- data/lib/cf/constants.rb +10 -7
- data/lib/cf/detect.rb +113 -48
- data/lib/cf/errors.rb +17 -0
- data/lib/cf/plugin.rb +28 -12
- data/lib/cf/spacing.rb +89 -0
- data/lib/cf/spec_helper.rb +1 -0
- data/lib/cf/test_support.rb +6 -0
- data/lib/cf/version.rb +1 -1
- data/spec/assets/hello-sinatra/Gemfile +3 -0
- data/spec/assets/hello-sinatra/Gemfile.lock +17 -0
- data/spec/assets/hello-sinatra/config.ru +3 -0
- data/spec/assets/hello-sinatra/fat-cat-makes-app-larger.png +0 -0
- data/spec/assets/hello-sinatra/main.rb +6 -0
- data/spec/assets/specker_runner/specker_runner_input.rb +6 -0
- data/spec/assets/specker_runner/specker_runner_pause.rb +5 -0
- data/spec/cf/cli/app/base_spec.rb +17 -0
- data/spec/cf/cli/app/delete_spec.rb +188 -0
- data/spec/cf/cli/app/instances_spec.rb +65 -0
- data/spec/cf/cli/app/push/create_spec.rb +661 -0
- data/spec/cf/cli/app/push_spec.rb +369 -0
- data/spec/cf/cli/app/rename_spec.rb +104 -0
- data/spec/cf/cli/app/scale_spec.rb +75 -0
- data/spec/cf/cli/app/start_spec.rb +208 -0
- data/spec/cf/cli/app/stats_spec.rb +68 -0
- data/spec/cf/cli/domain/map_spec.rb +130 -0
- data/spec/cf/cli/domain/unmap_spec.rb +69 -0
- data/spec/cf/cli/organization/orgs_spec.rb +108 -0
- data/spec/cf/cli/organization/rename_spec.rb +113 -0
- data/spec/cf/cli/route/map_spec.rb +121 -0
- data/spec/cf/cli/route/unmap_spec.rb +155 -0
- data/spec/cf/cli/service/bind_spec.rb +25 -0
- data/spec/cf/cli/service/delete_spec.rb +22 -0
- data/spec/cf/cli/service/rename_spec.rb +105 -0
- data/spec/cf/cli/service/service_spec.rb +23 -0
- data/spec/cf/cli/service/unbind_spec.rb +25 -0
- data/spec/cf/cli/space/create_spec.rb +93 -0
- data/spec/cf/cli/space/rename_spec.rb +102 -0
- data/spec/cf/cli/space/spaces_spec.rb +104 -0
- data/spec/cf/cli/space/switch_space_spec.rb +55 -0
- data/spec/cf/cli/start/info_spec.rb +160 -0
- data/spec/cf/cli/start/login_spec.rb +142 -0
- data/spec/cf/cli/start/logout_spec.rb +50 -0
- data/spec/cf/cli/start/target_spec.rb +123 -0
- data/spec/cf/cli/user/create_spec.rb +54 -0
- data/spec/cf/cli/user/passwd_spec.rb +102 -0
- data/spec/cf/cli/user/register_spec.rb +140 -0
- data/spec/cf/cli_spec.rb +442 -0
- data/spec/cf/detect_spec.rb +54 -0
- data/spec/console_app_specker/console_app_specker_matchers_spec.rb +173 -0
- data/spec/console_app_specker/specker_runner_spec.rb +167 -0
- data/spec/features/account_lifecycle_spec.rb +85 -0
- data/spec/features/login_spec.rb +66 -0
- data/spec/features/push_flow_spec.rb +125 -0
- data/spec/features/switching_targets_spec.rb +32 -0
- data/spec/spec_helper.rb +72 -0
- data/spec/support/command_helper.rb +81 -0
- data/spec/support/config_helper.rb +15 -0
- data/spec/support/console_app_specker_matchers.rb +86 -0
- data/spec/support/fake_home_dir.rb +55 -0
- data/spec/support/interact_helper.rb +29 -0
- data/spec/support/shared_examples/errors.rb +40 -0
- data/spec/support/shared_examples/input.rb +14 -0
- data/spec/support/specker_runner.rb +80 -0
- data/spec/support/tracking_expector.rb +71 -0
- metadata +427 -66
- data/lib/cf/cli/app.rb +0 -595
- data/lib/cf/cli/command.rb +0 -444
- data/lib/cf/cli/dots.rb +0 -133
- data/lib/cf/cli/service.rb +0 -112
- data/lib/cf/cli/user.rb +0 -71
data/lib/cf/plugin.rb
CHANGED
|
@@ -9,12 +9,25 @@ module CF
|
|
|
9
9
|
@@plugins = []
|
|
10
10
|
|
|
11
11
|
def self.load_all
|
|
12
|
-
# auto-load gems with '
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
Gem::Specification.find_all
|
|
16
|
-
s.name =~ /
|
|
17
|
-
|
|
12
|
+
# auto-load gems with 'cf-plugin' in their name
|
|
13
|
+
matching =
|
|
14
|
+
if Gem::Specification.respond_to? :find_all
|
|
15
|
+
Gem::Specification.find_all do |s|
|
|
16
|
+
s.name =~ /cf-plugin/
|
|
17
|
+
end
|
|
18
|
+
else
|
|
19
|
+
Gem.source_index.find_name(/cf-plugin/)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
enabled = Set.new(matching.collect(&:name))
|
|
23
|
+
|
|
24
|
+
cf_gems = Gem.loaded_specs["cf"]
|
|
25
|
+
((cf_gems && cf_gems.dependencies) || Gem.loaded_specs.values).each do |dep|
|
|
26
|
+
if dep.name =~ /cf-plugin/
|
|
27
|
+
require "#{dep.name}/plugin"
|
|
28
|
+
enabled.delete dep.name
|
|
29
|
+
end
|
|
30
|
+
end
|
|
18
31
|
|
|
19
32
|
# allow explicit enabling/disabling of gems via config
|
|
20
33
|
plugins = File.expand_path(CF::PLUGINS_FILE)
|
|
@@ -28,13 +41,16 @@ module CF
|
|
|
28
41
|
# we require this file specifically so people can require the gem
|
|
29
42
|
# without it plugging into CF
|
|
30
43
|
enabled.each do |gemname|
|
|
31
|
-
|
|
44
|
+
begin
|
|
45
|
+
require "#{gemname}/plugin"
|
|
46
|
+
rescue Gem::LoadError => e
|
|
47
|
+
puts "Failed to load #{gemname}:"
|
|
48
|
+
puts " #{e}"
|
|
49
|
+
puts
|
|
50
|
+
puts "You may need to update or remove this plugin."
|
|
51
|
+
puts
|
|
52
|
+
end
|
|
32
53
|
end
|
|
33
54
|
end
|
|
34
55
|
end
|
|
35
|
-
|
|
36
|
-
def self.Plugin(target = CLI, &blk)
|
|
37
|
-
# SUPER FANCY PLUGIN SYSTEM
|
|
38
|
-
target.class_eval &blk
|
|
39
|
-
end
|
|
40
56
|
end
|
data/lib/cf/spacing.rb
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
module CF
|
|
2
|
+
module Spacing
|
|
3
|
+
@@indentation = 0
|
|
4
|
+
|
|
5
|
+
def indented
|
|
6
|
+
@@indentation += 1
|
|
7
|
+
yield
|
|
8
|
+
ensure
|
|
9
|
+
@@indentation -= 1
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def line(msg = "")
|
|
13
|
+
return puts "" if msg.empty?
|
|
14
|
+
|
|
15
|
+
start_line(msg)
|
|
16
|
+
puts ""
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def start_line(msg)
|
|
20
|
+
print " " * @@indentation unless quiet?
|
|
21
|
+
print msg
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def lines(blob)
|
|
25
|
+
blob.each_line do |line|
|
|
26
|
+
start_line(line)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
line
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def quiet?
|
|
33
|
+
false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def spaced(vals)
|
|
37
|
+
num = 0
|
|
38
|
+
vals.each do |val|
|
|
39
|
+
line unless quiet? || num == 0
|
|
40
|
+
yield val
|
|
41
|
+
num += 1
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def tabular(*rows)
|
|
46
|
+
spacings = []
|
|
47
|
+
rows.each do |row|
|
|
48
|
+
next unless row
|
|
49
|
+
|
|
50
|
+
row.each.with_index do |col, i|
|
|
51
|
+
next unless col
|
|
52
|
+
|
|
53
|
+
width = text_width(col)
|
|
54
|
+
|
|
55
|
+
if !spacings[i] || width > spacings[i]
|
|
56
|
+
spacings[i] = width
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
columns = spacings.size
|
|
62
|
+
rows.each do |row|
|
|
63
|
+
next unless row
|
|
64
|
+
|
|
65
|
+
row.each.with_index do |col, i|
|
|
66
|
+
next unless col
|
|
67
|
+
|
|
68
|
+
start_line justify(col, spacings[i])
|
|
69
|
+
print " " unless i + 1 == columns
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
line
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def trim_escapes(str)
|
|
77
|
+
str.gsub(/\e\[\d+m/, "")
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def text_width(str)
|
|
81
|
+
trim_escapes(str).size
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def justify(str, width)
|
|
85
|
+
trimmed = trim_escapes(str)
|
|
86
|
+
str.ljust(width + (str.size - trimmed.size))
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require File.expand_path("../../../spec/spec_helper", __FILE__)
|
data/lib/cf/version.rb
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
GEM
|
|
2
|
+
remote: https://rubygems.org/
|
|
3
|
+
specs:
|
|
4
|
+
rack (1.5.2)
|
|
5
|
+
rack-protection (1.3.2)
|
|
6
|
+
rack
|
|
7
|
+
sinatra (1.3.4)
|
|
8
|
+
rack (~> 1.4)
|
|
9
|
+
rack-protection (~> 1.3)
|
|
10
|
+
tilt (~> 1.3, >= 1.3.3)
|
|
11
|
+
tilt (1.3.3)
|
|
12
|
+
|
|
13
|
+
PLATFORMS
|
|
14
|
+
ruby
|
|
15
|
+
|
|
16
|
+
DEPENDENCIES
|
|
17
|
+
sinatra
|
|
Binary file
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require "cf/cli/app/base"
|
|
3
|
+
|
|
4
|
+
describe CF::App::Base do
|
|
5
|
+
describe '#human_size' do
|
|
6
|
+
let(:base) { CF::App::Base.new }
|
|
7
|
+
|
|
8
|
+
it { base.human_size(1_023).should == "1023.0B" }
|
|
9
|
+
it { base.human_size(1_024).should == "1.0K" }
|
|
10
|
+
it { base.human_size(1_024 * 1_024).should == "1.0M" }
|
|
11
|
+
it { base.human_size(1_024 * 1_024 * 1.5).should == "1.5M" }
|
|
12
|
+
it { base.human_size(1_024 * 1_024 * 1_024).should == "1.0G" }
|
|
13
|
+
it { base.human_size(1_024 * 1_024 * 1_024 * 1.5).should == "1.5G" }
|
|
14
|
+
it { base.human_size(1_024 * 1_024 * 1_024 * 1.234, 3).should == "1.234G" }
|
|
15
|
+
it { base.human_size(31395840).should == "29.9M" } # tests against floating point errors
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require "cf/cli/app/delete"
|
|
3
|
+
|
|
4
|
+
describe CF::App::Delete do
|
|
5
|
+
let(:global) { { :color => false, :quiet => true } }
|
|
6
|
+
let(:inputs) { {} }
|
|
7
|
+
let(:given) { {} }
|
|
8
|
+
let(:client) { fake_client }
|
|
9
|
+
let(:app) {}
|
|
10
|
+
let(:new_name) { "some-new-name" }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
any_instance_of(CF::CLI) do |cli|
|
|
14
|
+
stub(cli).client { client }
|
|
15
|
+
stub(cli).precondition { nil }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
subject { Mothership.new.invoke(:delete, inputs, given, global) }
|
|
20
|
+
|
|
21
|
+
describe 'metadata' do
|
|
22
|
+
let(:command) { Mothership.commands[:delete] }
|
|
23
|
+
|
|
24
|
+
describe 'command' do
|
|
25
|
+
subject { command }
|
|
26
|
+
its(:description) { should eq "Delete an application" }
|
|
27
|
+
it { expect(Mothership::Help.group(:apps, :manage)).to include(subject) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
include_examples 'inputs must have descriptions'
|
|
31
|
+
|
|
32
|
+
describe 'arguments' do
|
|
33
|
+
subject { command.arguments }
|
|
34
|
+
it 'has the correct argument order' do
|
|
35
|
+
should eq([{ :type => :splat, :value => nil, :name => :apps }])
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context 'when there are no apps' do
|
|
41
|
+
context 'and an app is given' do
|
|
42
|
+
let(:given) { { :app => "some-app" } }
|
|
43
|
+
it { expect { subject }.to raise_error(CF::UserError, "Unknown app 'some-app'.") }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
context 'and an app is not given' do
|
|
47
|
+
it { expect { subject }.to raise_error(CF::UserError, "No applications.") }
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
context 'when there are apps' do
|
|
52
|
+
let(:client) { fake_client(:apps => apps) }
|
|
53
|
+
let(:apps) { [basic_app, app_with_orphans, app_without_orphans] }
|
|
54
|
+
let(:service_1) { fake :service_instance }
|
|
55
|
+
let(:service_2) { fake :service_instance }
|
|
56
|
+
let(:basic_app) { fake(:app, :name => "basic_app") }
|
|
57
|
+
let(:app_with_orphans) {
|
|
58
|
+
fake :app,
|
|
59
|
+
:name => "app_with_orphans",
|
|
60
|
+
:service_bindings => [
|
|
61
|
+
fake(:service_binding, :service_instance => service_1),
|
|
62
|
+
fake(:service_binding, :service_instance => service_2)
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
let(:app_without_orphans) {
|
|
66
|
+
fake :app,
|
|
67
|
+
:name => "app_without_orphans",
|
|
68
|
+
:service_bindings => [
|
|
69
|
+
fake(:service_binding, :service_instance => service_1)
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
context 'and no app is given' do
|
|
74
|
+
it 'asks for the app' do
|
|
75
|
+
mock_ask("Delete which application?", anything) { basic_app }
|
|
76
|
+
stub_ask { true }
|
|
77
|
+
stub(basic_app).delete!
|
|
78
|
+
subject
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
context 'and a basic app is given' do
|
|
83
|
+
let(:deleted_app) { basic_app }
|
|
84
|
+
let(:given) { { :app => deleted_app.name } }
|
|
85
|
+
|
|
86
|
+
context 'and it asks for confirmation' do
|
|
87
|
+
context 'and the user answers no' do
|
|
88
|
+
it 'does not delete the application' do
|
|
89
|
+
mock_ask("Really delete #{deleted_app.name}?", anything) { false }
|
|
90
|
+
dont_allow(deleted_app).delete!
|
|
91
|
+
subject
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context 'and the user answers yes' do
|
|
96
|
+
it 'deletes the application' do
|
|
97
|
+
mock_ask("Really delete #{deleted_app.name}?", anything) { true }
|
|
98
|
+
mock(deleted_app).delete!
|
|
99
|
+
subject
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
context 'and --force is given' do
|
|
105
|
+
let(:global) { { :force => true, :color => false, :quiet => true } }
|
|
106
|
+
|
|
107
|
+
it 'deletes the application without asking to confirm' do
|
|
108
|
+
dont_allow_ask
|
|
109
|
+
mock(deleted_app).delete!
|
|
110
|
+
subject
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
context 'and an app with orphaned services is given' do
|
|
116
|
+
let(:deleted_app) { app_with_orphans }
|
|
117
|
+
let(:inputs) { { :app => deleted_app } }
|
|
118
|
+
|
|
119
|
+
context 'and it asks for confirmation' do
|
|
120
|
+
context 'and the user answers yes' do
|
|
121
|
+
it 'asks to delete orphaned services' do
|
|
122
|
+
stub_ask("Really delete #{deleted_app.name}?", anything) { true }
|
|
123
|
+
stub(deleted_app).delete!
|
|
124
|
+
|
|
125
|
+
stub(service_2).invalidate!
|
|
126
|
+
|
|
127
|
+
mock_ask("Delete orphaned service #{service_2.name}?", anything) { true }
|
|
128
|
+
|
|
129
|
+
any_instance_of(CF::App::Delete) do |del|
|
|
130
|
+
mock(del).invoke :delete_service, :service => service_2,
|
|
131
|
+
:really => true
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
subject
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
context 'and the user answers no' do
|
|
139
|
+
it 'does not ask to delete orphaned serivces, or delete them' do
|
|
140
|
+
stub_ask("Really delete #{deleted_app.name}?", anything) { false }
|
|
141
|
+
dont_allow(deleted_app).delete!
|
|
142
|
+
|
|
143
|
+
stub(service_2).invalidate!
|
|
144
|
+
|
|
145
|
+
dont_allow_ask("Delete orphaned service #{service_2.name}?")
|
|
146
|
+
|
|
147
|
+
any_instance_of(CF::App::Delete) do |del|
|
|
148
|
+
dont_allow(del).invoke(:delete_service, anything)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
subject
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
context 'and --force is given' do
|
|
157
|
+
let(:global) { { :force => true, :color => false, :quiet => true } }
|
|
158
|
+
|
|
159
|
+
it 'does not delete orphaned services' do
|
|
160
|
+
dont_allow_ask
|
|
161
|
+
stub(deleted_app).delete!
|
|
162
|
+
|
|
163
|
+
any_instance_of(CF::App::Delete) do |del|
|
|
164
|
+
dont_allow(del).invoke(:delete_service, anything)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
subject
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
context 'and --delete-orphaned is given' do
|
|
172
|
+
let(:inputs) { { :app => deleted_app, :delete_orphaned => true } }
|
|
173
|
+
|
|
174
|
+
it 'deletes the orphaned services' do
|
|
175
|
+
stub_ask("Really delete #{deleted_app.name}?", anything) { true }
|
|
176
|
+
stub(deleted_app).delete!
|
|
177
|
+
|
|
178
|
+
any_instance_of(CF::App::Delete) do |del|
|
|
179
|
+
mock(del).invoke :delete_service, :service => service_2,
|
|
180
|
+
:really => true
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
subject
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'stringio'
|
|
3
|
+
|
|
4
|
+
describe CF::App::Stats do
|
|
5
|
+
let(:global) { { :color => false } }
|
|
6
|
+
let(:inputs) { { :app => apps[0] } }
|
|
7
|
+
let(:given) { {} }
|
|
8
|
+
let(:client) { fake_client(:apps => apps) }
|
|
9
|
+
let(:apps) { [fake(:app, :name => "basic_app")] }
|
|
10
|
+
let(:time) { Time.local(2012, 11, 1, 2, 30) }
|
|
11
|
+
|
|
12
|
+
before do
|
|
13
|
+
any_instance_of(CF::CLI) do |cli|
|
|
14
|
+
stub(cli).client { client }
|
|
15
|
+
stub(cli).precondition { nil }
|
|
16
|
+
end
|
|
17
|
+
stub(client.base).instances(anything) do
|
|
18
|
+
{
|
|
19
|
+
"12" => {:state => "STOPPED", :since => time.to_i, :debug_ip => "foo", :debug_port => "bar", :console_ip => "baz", :console_port => "qux"},
|
|
20
|
+
"1" => {:state => "STOPPED", :since => time.to_i, :debug_ip => "foo", :debug_port => "bar", :console_ip => "baz", :console_port => "qux"},
|
|
21
|
+
"2" => {:state => "STARTED", :since => time.to_i, :debug_ip => "foo", :debug_port => "bar", :console_ip => "baz", :console_port => "qux"}
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
subject do
|
|
27
|
+
capture_output do
|
|
28
|
+
Mothership.new.invoke(:instances, inputs, given, global)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
describe 'metadata' do
|
|
33
|
+
let(:command) { Mothership.commands[:instances] }
|
|
34
|
+
|
|
35
|
+
describe 'command' do
|
|
36
|
+
subject { command }
|
|
37
|
+
its(:description) { should eq "List an app's instances" }
|
|
38
|
+
it { expect(Mothership::Help.group(:apps, :info)).to include(subject) }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
include_examples 'inputs must have descriptions'
|
|
42
|
+
|
|
43
|
+
describe 'arguments' do
|
|
44
|
+
subject { command.arguments }
|
|
45
|
+
it 'has no arguments' do
|
|
46
|
+
should eq([{:type=>:splat, :value=>nil, :name=>:apps}])
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'prints out the instances in the correct order' do
|
|
52
|
+
subject
|
|
53
|
+
expect(output).to say("instance #1")
|
|
54
|
+
expect(output).to say("instance #2")
|
|
55
|
+
expect(output).to say("instance #12")
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it 'prints out one of the instances correctly' do
|
|
59
|
+
subject
|
|
60
|
+
expect(output).to say("instance #2: started")
|
|
61
|
+
expect(output).to say(" started: #{time.strftime("%F %r")}")
|
|
62
|
+
expect(output).to say(" debugger: port bar at foo")
|
|
63
|
+
expect(output).to say(" console: port qux at baz")
|
|
64
|
+
end
|
|
65
|
+
end
|