cfoundry 1.5.3 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|