cfoundry 1.5.3 → 2.0.0
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/cfoundry/test_support.rb +2 -2
- data/lib/cfoundry/v2/app.rb +3 -6
- data/lib/cfoundry/v2/model.rb +1 -0
- data/lib/cfoundry/version.rb +1 -1
- data/spec/cfoundry/client_spec.rb +1 -1
- data/spec/cfoundry/rest_client_spec.rb +1 -1
- data/spec/cfoundry/trace_helpers_spec.rb +6 -6
- data/spec/cfoundry/upload_helpers_spec.rb +125 -137
- data/spec/cfoundry/v2/app_event_spec.rb +63 -59
- data/spec/cfoundry/v2/app_spec.rb +195 -188
- data/spec/cfoundry/v2/client_spec.rb +60 -56
- data/spec/cfoundry/v2/domain_spec.rb +9 -6
- data/spec/cfoundry/v2/model_magic/model_magic/attribute_spec.rb +89 -88
- data/spec/cfoundry/v2/model_magic/model_magic/has_summary_spec.rb +12 -13
- data/spec/cfoundry/v2/model_magic/model_magic/to_many_spec.rb +46 -52
- data/spec/cfoundry/v2/model_magic/model_magic/to_one_spec.rb +96 -87
- data/spec/cfoundry/v2/model_spec.rb +236 -241
- data/spec/cfoundry/v2/organization_spec.rb +20 -22
- data/spec/cfoundry/v2/quota_definition_spec.rb +45 -47
- data/spec/cfoundry/v2/route_spec.rb +28 -25
- data/spec/cfoundry/v2/space_spec.rb +9 -11
- data/spec/cfoundry/validator_spec.rb +69 -67
- data/spec/factories/app_events_factory.rb +7 -0
- data/spec/factories/apps_factory.rb +11 -0
- data/spec/factories/clients_factory.rb +5 -0
- data/spec/factories/domains_factory.rb +7 -0
- data/spec/factories/organizations_factory.rb +11 -0
- data/spec/factories/quota_definitions_factory.rb +8 -0
- data/spec/factories/routes_factory.rb +10 -0
- data/spec/factories/spaces_factory.rb +10 -0
- data/spec/factories/users_factory.rb +10 -0
- data/spec/spec_helper.rb +5 -4
- data/spec/support/factory_girl.rb +6 -0
- data/spec/support/shared_examples/model_summary_examples.rb +7 -7
- data/spec/support/test_model_builder.rb +10 -0
- metadata +83 -71
- data/spec/fakes/app_fake.rb +0 -5
- data/spec/fakes/domain_fake.rb +0 -5
- data/spec/fakes/framework_fake.rb +0 -5
- data/spec/fakes/organization_fake.rb +0 -5
- data/spec/fakes/route_fake.rb +0 -5
- data/spec/fakes/runtime_fake.rb +0 -5
- data/spec/fakes/service_fake.rb +0 -5
- data/spec/fakes/service_instance_fake.rb +0 -5
- data/spec/fakes/service_plan_fake.rb +0 -5
- data/spec/fakes/space_fake.rb +0 -5
- data/spec/fakes/user_fake.rb +0 -5
- data/spec/support/fake_helper.rb +0 -248
- data/spec/support/randoms.rb +0 -3
@@ -1,3 +1,3 @@
|
|
1
|
-
Dir[File.expand_path('../../../spec/{support
|
2
|
-
require file
|
1
|
+
Dir[File.expand_path('../../../spec/{support}/**/*.rb', __FILE__)].each do |file|
|
2
|
+
require file unless file =~ /factory_girl/
|
3
3
|
end
|
data/lib/cfoundry/v2/app.rb
CHANGED
@@ -31,7 +31,7 @@ module CFoundry::V2
|
|
31
31
|
attribute :debug, :string, :default => nil
|
32
32
|
to_many :service_bindings
|
33
33
|
to_many :routes
|
34
|
-
to_many :
|
34
|
+
to_many :events, :as => :app_event
|
35
35
|
|
36
36
|
scoped_to_space
|
37
37
|
|
@@ -47,11 +47,8 @@ module CFoundry::V2
|
|
47
47
|
|
48
48
|
private :environment_json
|
49
49
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
def delete!
|
54
|
-
super({:recursive => true})
|
50
|
+
def delete!(opts = {})
|
51
|
+
super(opts.merge(:recursive => true))
|
55
52
|
end
|
56
53
|
|
57
54
|
def instances
|
data/lib/cfoundry/v2/model.rb
CHANGED
data/lib/cfoundry/version.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require "spec_helper"
|
2
2
|
|
3
3
|
describe CFoundry::TraceHelpers do
|
4
|
-
let(:
|
4
|
+
let(:tracehelper_test_class) { Class.new { include CFoundry::TraceHelpers } }
|
5
5
|
let(:request) do
|
6
6
|
{
|
7
7
|
:method => "GET",
|
@@ -21,7 +21,7 @@ describe CFoundry::TraceHelpers do
|
|
21
21
|
before { response[:body] = response_body }
|
22
22
|
|
23
23
|
it "traces the provided response" do
|
24
|
-
|
24
|
+
tracehelper_test_class.new.response_trace(response).should == response_trace
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
@@ -30,7 +30,7 @@ describe CFoundry::TraceHelpers do
|
|
30
30
|
let(:header_trace) { "REQUEST_HEADERS:\n accept : */*\n bb-foo : bar" }
|
31
31
|
let(:body_trace) { "" }
|
32
32
|
|
33
|
-
subject {
|
33
|
+
subject { tracehelper_test_class.new.request_trace(request) }
|
34
34
|
|
35
35
|
context "without a request body" do
|
36
36
|
include_examples "request_trace tests"
|
@@ -45,7 +45,7 @@ describe CFoundry::TraceHelpers do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
it "returns nil if request is nil" do
|
48
|
-
|
48
|
+
tracehelper_test_class.new.request_trace(nil).should == nil
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
@@ -66,7 +66,7 @@ describe CFoundry::TraceHelpers do
|
|
66
66
|
end
|
67
67
|
|
68
68
|
it "returns nil if response is nil" do
|
69
|
-
|
69
|
+
tracehelper_test_class.new.response_trace(nil).should == nil
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -1,194 +1,182 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
let(:guid) { "123" }
|
7
|
-
let(:path) { "#{SPEC_ROOT}/fixtures/apps/with_cfignore" }
|
8
|
-
let(:check_resources) { false }
|
9
|
-
let(:tmpdir) { "#{SPEC_ROOT}/tmp/fake_tmpdir" }
|
10
|
-
|
11
|
-
let(:client) do
|
12
|
-
client = Object.new
|
13
|
-
stub(client).base { base }
|
14
|
-
client
|
15
|
-
end
|
3
|
+
class TestModelWithUploadHelpers < CFoundry::V2::Model
|
4
|
+
include CFoundry::UploadHelpers
|
5
|
+
end
|
16
6
|
|
17
|
-
|
18
|
-
|
19
|
-
|
7
|
+
module CFoundry
|
8
|
+
describe UploadHelpers do
|
9
|
+
describe "#upload" do
|
10
|
+
def relative_glob(dir)
|
11
|
+
base_pathname = Pathname.new(dir)
|
12
|
+
Dir["#{dir}/**/{*,.[^\.]*}"].map do |file|
|
13
|
+
Pathname.new(file).relative_path_from(base_pathname).to_s
|
14
|
+
end
|
15
|
+
end
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
|
17
|
+
def mock_zip(*args, &block)
|
18
|
+
if args.empty?
|
19
|
+
mock(CFoundry::Zip).pack.with_any_args(&block)
|
20
|
+
else
|
21
|
+
mock(CFoundry::Zip).pack(*args, &block)
|
24
22
|
end
|
25
23
|
end
|
26
24
|
|
27
|
-
|
28
|
-
|
25
|
+
let(:base) { Object.new }
|
26
|
+
let(:guid) { "123" }
|
27
|
+
let(:path) { "#{SPEC_ROOT}/fixtures/apps/with_cfignore" }
|
28
|
+
let(:check_resources) { false }
|
29
|
+
let(:tmpdir) { "#{SPEC_ROOT}/tmp/fake_tmpdir" }
|
29
30
|
|
30
|
-
|
31
|
-
FileUtils.rm_rf tmpdir
|
31
|
+
let(:client) { build(:client) }
|
32
32
|
|
33
|
-
|
34
|
-
FileUtils.mkdir_p tmpdir
|
35
|
-
tmpdir
|
36
|
-
end
|
33
|
+
let(:model) { TestModelWithUploadHelpers.new(guid, client) }
|
37
34
|
|
38
|
-
|
39
|
-
|
35
|
+
before do
|
36
|
+
stub(client).base { base }
|
37
|
+
stub(base).upload_app.with_any_args
|
40
38
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
Pathname.new(file).relative_path_from(base_pathname).to_s
|
39
|
+
FileUtils.rm_rf tmpdir
|
40
|
+
stub(Dir).tmpdir do
|
41
|
+
FileUtils.mkdir_p tmpdir
|
42
|
+
tmpdir
|
43
|
+
end
|
47
44
|
end
|
48
|
-
end
|
49
45
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
46
|
+
it "zips the app and uploads the zip file" do
|
47
|
+
zip_path = "#{tmpdir}/#{guid}.zip"
|
48
|
+
mock_zip(anything, zip_path) { true }
|
49
|
+
mock(base).upload_app(guid, zip_path, [])
|
50
|
+
model.upload(path, check_resources)
|
55
51
|
end
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'zips the app and uploads the zip file' do
|
59
|
-
zip_path = "#{tmpdir}/#{guid}.zip"
|
60
|
-
mock_zip(anything, zip_path) { true }
|
61
|
-
mock(base).upload_app(guid, zip_path, [])
|
62
|
-
subject
|
63
|
-
end
|
64
52
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
53
|
+
it "uploads an app with the right guid" do
|
54
|
+
mock_zip
|
55
|
+
mock(base).upload_app(guid, anything, anything)
|
56
|
+
model.upload(path, check_resources)
|
57
|
+
end
|
70
58
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
59
|
+
it "uses a unique directory name when it copies the app" do
|
60
|
+
mock_zip(/#{tmpdir}.*#{guid}.*/, anything)
|
61
|
+
model.upload(path, check_resources)
|
62
|
+
end
|
75
63
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
64
|
+
it "cleans up after itself correctly" do
|
65
|
+
model.upload(path, check_resources)
|
66
|
+
expect(relative_glob(tmpdir)).to be_empty
|
67
|
+
end
|
80
68
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
69
|
+
it "includes the source files of the app in the zip file" do
|
70
|
+
mock_zip do |src, _|
|
71
|
+
files = relative_glob(src)
|
72
|
+
expect(files).to include "non_ignored_dir"
|
73
|
+
expect(files).to include "non_ignored_file.txt"
|
74
|
+
expect(files).to include "non_ignored_dir/file_in_non_ignored_dir.txt"
|
75
|
+
end
|
76
|
+
model.upload(path, check_resources)
|
87
77
|
end
|
88
|
-
subject
|
89
|
-
end
|
90
78
|
|
91
|
-
|
92
|
-
|
93
|
-
|
79
|
+
it "includes hidden files (though stager ignores them currently)" do
|
80
|
+
mock_zip do |src, _|
|
81
|
+
expect(relative_glob(src)).to include ".hidden_file"
|
82
|
+
end
|
83
|
+
model.upload(path, check_resources)
|
94
84
|
end
|
95
|
-
subject
|
96
|
-
end
|
97
85
|
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
86
|
+
it "does not include files and directories specified in the cfignore" do
|
87
|
+
mock_zip do |src, _|
|
88
|
+
files = relative_glob(src)
|
89
|
+
expect(files).to match_array(%w[
|
102
90
|
.hidden_file .cfignore non_ignored_dir ambiguous_ignored
|
103
91
|
non_ignored_dir/file_in_non_ignored_dir.txt non_ignored_file.txt
|
104
92
|
non_ignored_dir/toplevel_ignored.txt
|
105
93
|
])
|
94
|
+
end
|
95
|
+
model.upload(path, check_resources)
|
106
96
|
end
|
107
|
-
subject
|
108
|
-
end
|
109
97
|
|
110
|
-
|
111
|
-
|
112
|
-
|
98
|
+
%w(.git _darcs .svn).each do |source_control_dir_name|
|
99
|
+
context "when there is a #{source_control_dir_name} directory in the app" do
|
100
|
+
before { FileUtils.mkdir_p("#{path}/#{source_control_dir_name}") }
|
113
101
|
|
114
|
-
|
115
|
-
|
116
|
-
|
102
|
+
it "ignores that directory" do
|
103
|
+
mock_zip do |src, _|
|
104
|
+
expect(relative_glob(src)).not_to include source_control_dir_name
|
105
|
+
end
|
106
|
+
model.upload(path, check_resources)
|
117
107
|
end
|
118
|
-
subject
|
119
108
|
end
|
120
109
|
end
|
121
|
-
end
|
122
110
|
|
123
|
-
|
124
|
-
|
111
|
+
context "when there are no files to zip" do
|
112
|
+
before { mock_zip { false } }
|
125
113
|
|
126
|
-
|
127
|
-
|
128
|
-
|
114
|
+
it "passes `false` to #upload_app" do
|
115
|
+
mock(base).upload_app(guid, false, [])
|
116
|
+
model.upload(path, check_resources)
|
117
|
+
end
|
129
118
|
end
|
130
|
-
end
|
131
119
|
|
132
|
-
|
133
|
-
|
134
|
-
|
120
|
+
context "when all files match existing resources" do
|
121
|
+
context "and there are directories" do
|
122
|
+
let(:path) { "#{SPEC_ROOT}/fixtures/apps/with_nested_directories" }
|
135
123
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
end
|
140
|
-
|
141
|
-
stub(base).resource_match(anything) do
|
142
|
-
%w{ xyz foo/bar/baz/fizz }.map do |path|
|
143
|
-
{ :fn => "#{tmpdir}/.cf_#{guid}_files/#{path}" }
|
124
|
+
it "prunes them before zipping" do
|
125
|
+
stub(model).make_fingerprints(anything) do
|
126
|
+
[[], CFoundry::UploadHelpers::RESOURCE_CHECK_LIMIT + 1]
|
144
127
|
end
|
145
|
-
end
|
146
128
|
|
147
|
-
|
129
|
+
stub(base).resource_match(anything) do
|
130
|
+
%w{ xyz foo/bar/baz/fizz }.map do |path|
|
131
|
+
{:fn => "#{tmpdir}/.cf_#{guid}_files/#{path}"}
|
132
|
+
end
|
133
|
+
end
|
148
134
|
|
149
|
-
|
135
|
+
mock(base).upload_app(anything, false, anything)
|
136
|
+
model.upload(path)
|
137
|
+
end
|
150
138
|
end
|
151
139
|
end
|
152
|
-
end
|
153
140
|
|
154
|
-
|
155
|
-
|
141
|
+
context "when only dotfiles don't match existing resources" do
|
142
|
+
let(:path) { "#{SPEC_ROOT}/fixtures/apps/with_dotfiles" }
|
156
143
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
144
|
+
it "does not prune them" do
|
145
|
+
stub(model).make_fingerprints(anything) do
|
146
|
+
[[], CFoundry::UploadHelpers::RESOURCE_CHECK_LIMIT + 1]
|
147
|
+
end
|
161
148
|
|
162
|
-
|
163
|
-
|
164
|
-
|
149
|
+
stub(base).resource_match(anything) do
|
150
|
+
%w{ xyz }.map do |path|
|
151
|
+
{:fn => "#{tmpdir}/.cf_#{guid}_files/#{path}"}
|
152
|
+
end
|
165
153
|
end
|
166
|
-
end
|
167
154
|
|
168
|
-
|
169
|
-
|
170
|
-
|
155
|
+
mock(base).upload_app(anything, anything, anything) do |_, zip, _|
|
156
|
+
expect(zip).to be_a(String)
|
157
|
+
end
|
171
158
|
|
172
|
-
|
159
|
+
model.upload(path)
|
160
|
+
end
|
173
161
|
end
|
174
|
-
end
|
175
162
|
|
176
|
-
|
177
|
-
|
163
|
+
context "when there is a symlink pointing outside of the root" do
|
164
|
+
let(:path) { "#{SPEC_ROOT}/fixtures/apps/with_external_symlink" }
|
178
165
|
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
166
|
+
it "blows up" do
|
167
|
+
expect {
|
168
|
+
model.upload(path)
|
169
|
+
}.to raise_error(CFoundry::Error, /contains links.*that point outside/)
|
170
|
+
end
|
184
171
|
|
185
|
-
|
186
|
-
|
172
|
+
context "and it is cfignored" do
|
173
|
+
let(:path) { "#{SPEC_ROOT}/fixtures/apps/with_ignored_external_symlink" }
|
187
174
|
|
188
|
-
|
189
|
-
|
175
|
+
it "ignores it" do
|
176
|
+
expect { model.upload(path) }.to_not raise_error
|
177
|
+
end
|
190
178
|
end
|
191
179
|
end
|
192
180
|
end
|
193
181
|
end
|
194
|
-
end
|
182
|
+
end
|
@@ -1,77 +1,81 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
module CFoundry
|
4
|
+
module V2
|
5
|
+
describe AppEvent do
|
6
|
+
let(:app) { build(:app) }
|
7
|
+
let(:app_event) { build(:app_event, :app => app) }
|
5
8
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
it "has an app" do
|
11
|
-
subject.app = app
|
12
|
-
expect(subject.app).to eq(app)
|
13
|
-
end
|
9
|
+
it "has an app" do
|
10
|
+
expect(app_event.app).to eq(app)
|
11
|
+
end
|
14
12
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
describe "#instance_guid" do
|
14
|
+
it "has an instance guid" do
|
15
|
+
app_event.instance_guid = "foo"
|
16
|
+
expect(app_event.instance_guid).to eq("foo")
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
19
|
+
context "when an invalid value is assigned" do
|
20
|
+
it "raises a Mismatch exception" do
|
21
|
+
expect {
|
22
|
+
app_event.instance_guid = 123
|
23
|
+
}.to raise_error(Mismatch)
|
24
|
+
end
|
25
|
+
end
|
26
26
|
end
|
27
|
-
end
|
28
|
-
end
|
29
27
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
describe "#instance_index" do
|
29
|
+
it "has an instance index" do
|
30
|
+
app_event.instance_index = 123
|
31
|
+
expect(app_event.instance_index).to eq(123)
|
32
|
+
end
|
35
33
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
context "when an invalid value is assigned" do
|
35
|
+
it "raises a Mismatch exception" do
|
36
|
+
expect {
|
37
|
+
app_event.instance_index = "wrong"
|
38
|
+
}.to raise_error(Mismatch)
|
39
|
+
end
|
40
|
+
end
|
41
41
|
end
|
42
|
-
end
|
43
|
-
end
|
44
42
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
43
|
+
describe "#exit_status" do
|
44
|
+
it "has an instance index" do
|
45
|
+
app_event.exit_status = 123
|
46
|
+
expect(app_event.exit_status).to eq(123)
|
47
|
+
end
|
50
48
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
49
|
+
context "when an invalid value is assigned" do
|
50
|
+
it "raises a Mismatch exception" do
|
51
|
+
expect {
|
52
|
+
app_event.exit_status = "wrong"
|
53
|
+
}.to raise_error(Mismatch)
|
54
|
+
end
|
55
|
+
end
|
56
56
|
end
|
57
|
-
end
|
58
|
-
end
|
59
57
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
58
|
+
describe "#exit_description" do
|
59
|
+
before do
|
60
|
+
stub_request(:get, /v2\/app_events\/.*/).to_return(:body => {:entity => {}}.to_json)
|
61
|
+
end
|
64
62
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
63
|
+
it "defaults to an empty string" do
|
64
|
+
expect(app_event.exit_description).to eq("")
|
65
|
+
end
|
66
|
+
|
67
|
+
it "has an instance guid" do
|
68
|
+
app_event.exit_description = "foo"
|
69
|
+
expect(app_event.exit_description).to eq("foo")
|
70
|
+
end
|
69
71
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
context "when an invalid value is assigned" do
|
73
|
+
it "raises a Mismatch exception" do
|
74
|
+
expect {
|
75
|
+
app_event.exit_description = 123
|
76
|
+
}.to raise_error(Mismatch)
|
77
|
+
end
|
78
|
+
end
|
75
79
|
end
|
76
80
|
end
|
77
81
|
end
|