chef-dk 2.3.4 → 2.4.17
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.
- checksums.yaml +4 -4
- data/Gemfile +22 -18
- data/Gemfile.lock +184 -254
- data/README.md +1 -1
- data/Rakefile +1 -1
- data/acceptance/Gemfile.lock +27 -32
- data/lib/chef-dk/chef_server_api_multi.rb +73 -0
- data/lib/chef-dk/command/update.rb +5 -12
- data/lib/chef-dk/configurable.rb +19 -0
- data/lib/chef-dk/cookbook_omnifetch.rb +1 -0
- data/lib/chef-dk/exceptions.rb +11 -0
- data/lib/chef-dk/generator.rb +1 -1
- data/lib/chef-dk/policyfile/attribute_merge_checker.rb +110 -0
- data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +5 -4
- data/lib/chef-dk/policyfile/chef_server_lock_fetcher.rb +164 -0
- data/lib/chef-dk/policyfile/cookbook_location_specification.rb +3 -3
- data/lib/chef-dk/policyfile/dsl.rb +16 -0
- data/lib/chef-dk/policyfile/included_policies_cookbook_source.rb +156 -0
- data/lib/chef-dk/policyfile/local_lock_fetcher.rb +122 -0
- data/lib/chef-dk/policyfile/lock_applier.rb +80 -0
- data/lib/chef-dk/policyfile/null_cookbook_source.rb +4 -0
- data/lib/chef-dk/policyfile/policyfile_location_specification.rb +122 -0
- data/lib/chef-dk/policyfile_compiler.rb +129 -16
- data/lib/chef-dk/policyfile_lock.rb +30 -0
- data/lib/chef-dk/policyfile_services/install.rb +7 -1
- data/lib/chef-dk/policyfile_services/update_attributes.rb +10 -2
- data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +14 -1
- data/lib/chef-dk/version.rb +1 -1
- data/omnibus_overrides.rb +6 -6
- data/spec/unit/chef_server_api_multi_spec.rb +120 -0
- data/spec/unit/command/update_spec.rb +3 -3
- data/spec/unit/configurable_spec.rb +27 -0
- data/spec/unit/policyfile/attribute_merge_checker_spec.rb +80 -0
- data/spec/unit/policyfile/chef_server_lock_fetcher_spec.rb +161 -0
- data/spec/unit/policyfile/cookbook_location_specification_spec.rb +48 -0
- data/spec/unit/policyfile/included_policies_cookbook_source_spec.rb +242 -0
- data/spec/unit/policyfile/local_lock_fetcher_spec.rb +161 -0
- data/spec/unit/policyfile/lock_applier_spec.rb +100 -0
- data/spec/unit/policyfile_demands_spec.rb +1 -1
- data/spec/unit/policyfile_includes_dsl_spec.rb +159 -0
- data/spec/unit/policyfile_includes_spec.rb +720 -0
- data/spec/unit/policyfile_install_with_includes_spec.rb +232 -0
- data/spec/unit/policyfile_lock_build_spec.rb +11 -2
- data/spec/unit/policyfile_services/update_attributes_spec.rb +13 -0
- metadata +28 -3
|
@@ -278,6 +278,16 @@ describe ChefDK::Policyfile::CookbookLocationSpecification do
|
|
|
278
278
|
|
|
279
279
|
let(:source_options) { { chef_server: "https://api.opscode.com/organizations/chef-oss-dev/cookbooks/my_cookbook/versions/2.0.0/download" } }
|
|
280
280
|
|
|
281
|
+
let(:http_client) { instance_double("ChefDK::ChefServerAPIMulti") }
|
|
282
|
+
|
|
283
|
+
before do
|
|
284
|
+
CookbookOmnifetch.integration.default_chef_server_http_client = http_client
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
after do
|
|
288
|
+
CookbookOmnifetch.integration.default_chef_server_http_client = nil
|
|
289
|
+
end
|
|
290
|
+
|
|
281
291
|
it "has a chef_server installer" do
|
|
282
292
|
expect(cookbook_location_spec.installer).to be_a_kind_of(CookbookOmnifetch::ChefServerLocation)
|
|
283
293
|
end
|
|
@@ -296,4 +306,42 @@ describe ChefDK::Policyfile::CookbookLocationSpecification do
|
|
|
296
306
|
end
|
|
297
307
|
|
|
298
308
|
end
|
|
309
|
+
|
|
310
|
+
describe "when created with a chef_server_artifact source" do
|
|
311
|
+
|
|
312
|
+
let(:source_options) do
|
|
313
|
+
{
|
|
314
|
+
chef_server_artifact: "https://api.opscode.com/organizations/chef-oss-dev/",
|
|
315
|
+
identifier: "09d43fad354b3efcc5b5836fef5137131f60f974",
|
|
316
|
+
}
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
let(:http_client) { instance_double("ChefDK::ChefServerAPIMulti") }
|
|
320
|
+
|
|
321
|
+
before do
|
|
322
|
+
CookbookOmnifetch.integration.default_chef_server_http_client = http_client
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
after do
|
|
326
|
+
CookbookOmnifetch.integration.default_chef_server_http_client = nil
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
it "has a chef_server_artifact installer" do
|
|
330
|
+
expect(cookbook_location_spec.installer).to be_a_kind_of(CookbookOmnifetch::ChefServerArtifactLocation)
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
it "does has a fixed version" do
|
|
334
|
+
expect(cookbook_location_spec.version_fixed?).to be(true)
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
it "is a mirror of a canonical upstream" do
|
|
338
|
+
expect(cookbook_location_spec.mirrors_canonical_upstream?).to be(true)
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
it "is valid" do
|
|
342
|
+
expect(cookbook_location_spec.errors.size).to eq(0)
|
|
343
|
+
expect(cookbook_location_spec).to be_valid
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
end
|
|
299
347
|
end
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright:: Copyright (c) 2017 Chef Software Inc.
|
|
3
|
+
# License:: Apache License, Version 2.0
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
require "spec_helper"
|
|
19
|
+
require "chef-dk/policyfile/included_policies_cookbook_source"
|
|
20
|
+
require "chef-dk/policyfile/policyfile_location_specification"
|
|
21
|
+
|
|
22
|
+
describe ChefDK::Policyfile::IncludedPoliciesCookbookSource do
|
|
23
|
+
|
|
24
|
+
let(:external_cookbook_universe) do
|
|
25
|
+
{
|
|
26
|
+
"cookbookA" => {
|
|
27
|
+
"1.0.0" => [ ],
|
|
28
|
+
"2.0.0" => [ ["cookbookB", "= 1.0.0" ] ],
|
|
29
|
+
},
|
|
30
|
+
"cookbookB" => {
|
|
31
|
+
"1.0.0" => [ ],
|
|
32
|
+
},
|
|
33
|
+
"cookbookC" => {
|
|
34
|
+
"1.0.0" => [ ],
|
|
35
|
+
"2.0.0" => [ ],
|
|
36
|
+
},
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
let(:policy1_cookbooks) do
|
|
41
|
+
[
|
|
42
|
+
{
|
|
43
|
+
name: "cookbookA",
|
|
44
|
+
version: "2.0.0",
|
|
45
|
+
},
|
|
46
|
+
# cookbookB because cookbookA depends on it
|
|
47
|
+
{
|
|
48
|
+
name: "cookbookB",
|
|
49
|
+
version: "1.0.0",
|
|
50
|
+
},
|
|
51
|
+
]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
let(:randomize_sources) { false }
|
|
55
|
+
let(:add_random_cookbook) { false }
|
|
56
|
+
|
|
57
|
+
def build_lockdata(cookbooks)
|
|
58
|
+
nonce = if randomize_sources
|
|
59
|
+
Random.rand
|
|
60
|
+
else
|
|
61
|
+
nil
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
cookbook_locks = cookbooks.inject({}) do |acc, cookbook_info|
|
|
65
|
+
acc[cookbook_info[:name]] = {
|
|
66
|
+
"version" => cookbook_info[:version],
|
|
67
|
+
"identifier" => "identifier",
|
|
68
|
+
"dotted_decimal_identifier" => "dotted_decimal_identifier",
|
|
69
|
+
"cache_key" => "#{cookbook_info[:name]}-#{cookbook_info[:version]}",
|
|
70
|
+
"origin" => "uri",
|
|
71
|
+
"source_options" => { "version" => cookbook_info[:version] }.tap do |so|
|
|
72
|
+
so["nonce"] = nonce if !nonce.nil?
|
|
73
|
+
end,
|
|
74
|
+
}
|
|
75
|
+
acc
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
solution_dependencies_lock = cookbooks.map do |cookbook_info|
|
|
79
|
+
[cookbook_info[:name], cookbook_info[:version]]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
solution_dependencies_cookbooks = cookbooks.inject({}) do |acc, cookbook_info|
|
|
83
|
+
acc["#{cookbook_info[:name]} (#{cookbook_info[:version]})"] = external_cookbook_universe[cookbook_info[:name]][cookbook_info[:version]]
|
|
84
|
+
acc
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
{
|
|
88
|
+
"name" => "included_policyfile",
|
|
89
|
+
"revision_id" => "myrevisionid",
|
|
90
|
+
"run_list" => ["recipe[myrunlist::default]"],
|
|
91
|
+
"cookbook_locks" => cookbook_locks,
|
|
92
|
+
"default_attributes" => {},
|
|
93
|
+
"override_attributes" => {},
|
|
94
|
+
"solution_dependencies" => {
|
|
95
|
+
"Policyfile" => solution_dependencies_lock,
|
|
96
|
+
## We dont use dependencies, no need to fill it out
|
|
97
|
+
"dependencies" => solution_dependencies_cookbooks,
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
let(:policy1_lockdata) do
|
|
103
|
+
build_lockdata(policy1_cookbooks)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
let(:policy2_lockdata) do
|
|
107
|
+
build_lockdata(policy2_cookbooks)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
let(:policy1_fetcher) do
|
|
111
|
+
instance_double("ChefDK::Policyfile::LocalLockFetcher").tap do |double|
|
|
112
|
+
allow(double).to receive(:lock_data).and_return(policy1_lockdata)
|
|
113
|
+
allow(double).to receive(:valid?).and_return(true)
|
|
114
|
+
allow(double).to receive(:errors).and_return([])
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
let(:policy2_fetcher) do
|
|
119
|
+
instance_double("ChefDK::Policyfile::LocalLockFetcher").tap do |double|
|
|
120
|
+
allow(double).to receive(:lock_data).and_return(policy2_lockdata)
|
|
121
|
+
allow(double).to receive(:valid?).and_return(true)
|
|
122
|
+
allow(double).to receive(:errors).and_return([])
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
let(:policy1_location_spec) do
|
|
127
|
+
ChefDK::Policyfile::PolicyfileLocationSpecification.new("policy1", { :path => "somelocation" }, nil).tap do |spec|
|
|
128
|
+
allow(spec).to receive(:valid?).and_return(true)
|
|
129
|
+
allow(spec).to receive(:fetcher).and_return(policy1_fetcher)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
let(:policy2_location_spec) do
|
|
134
|
+
ChefDK::Policyfile::PolicyfileLocationSpecification.new("policy2", { :path => "somelocation" }, nil).tap do |spec|
|
|
135
|
+
allow(spec).to receive(:valid?).and_return(true)
|
|
136
|
+
allow(spec).to receive(:fetcher).and_return(policy2_fetcher)
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
let(:policies) { [] }
|
|
141
|
+
|
|
142
|
+
let(:cookbook_source) { ChefDK::Policyfile::IncludedPoliciesCookbookSource.new(policies) }
|
|
143
|
+
|
|
144
|
+
context "when no policies are included" do
|
|
145
|
+
it "returns false for preferred_source_for" do
|
|
146
|
+
expect(cookbook_source.preferred_source_for?("foo")).to eq(false)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "has an empty universe" do
|
|
150
|
+
expect(cookbook_source.universe_graph).to eq({})
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
context "when a single policy is to be included" do
|
|
155
|
+
let(:policies) { [policy1_location_spec] }
|
|
156
|
+
|
|
157
|
+
it "does not have a preferred source for unlocked cookbooks" do
|
|
158
|
+
expect(cookbook_source.preferred_source_for?("cookbookC")).to eq(false)
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it "has a preferred source for the included cookbooks" do
|
|
162
|
+
expect(cookbook_source.preferred_source_for?("cookbookA")).to eq(true)
|
|
163
|
+
expect(cookbook_source.preferred_source_for?("cookbookB")).to eq(true)
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "returns nil for the source options versions not included" do
|
|
167
|
+
expect(cookbook_source.source_options_for("cookbookA", "1.0.0")).to eq(nil)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
it "returns the correct source options when the cookbook is included" do
|
|
171
|
+
expect(cookbook_source.source_options_for("cookbookA", "2.0.0")).to eq({ :version => "2.0.0" })
|
|
172
|
+
expect(cookbook_source.source_options_for("cookbookB", "1.0.0")).to eq({ :version => "1.0.0" })
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
it "has a universe with the used cookbooks" do
|
|
176
|
+
expect(cookbook_source.universe_graph).to eq({
|
|
177
|
+
"cookbookA" => {
|
|
178
|
+
"2.0.0" => external_cookbook_universe["cookbookA"]["2.0.0"],
|
|
179
|
+
},
|
|
180
|
+
"cookbookB" => {
|
|
181
|
+
"1.0.0" => external_cookbook_universe["cookbookB"]["1.0.0"],
|
|
182
|
+
},
|
|
183
|
+
})
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
context "when multiple policies are to be included" do
|
|
188
|
+
let(:policies) { [policy1_location_spec, policy2_location_spec] }
|
|
189
|
+
|
|
190
|
+
context "when the policies use the same cookbooks with the same versions and sources" do
|
|
191
|
+
let(:policy2_cookbooks) { policy1_cookbooks + [{ name: "cookbookC", version: "2.0.0" }] }
|
|
192
|
+
|
|
193
|
+
it "has a preferred source for the included cookbooks" do
|
|
194
|
+
expect(cookbook_source.preferred_source_for?("cookbookA")).to eq(true)
|
|
195
|
+
expect(cookbook_source.preferred_source_for?("cookbookB")).to eq(true)
|
|
196
|
+
expect(cookbook_source.preferred_source_for?("cookbookC")).to eq(true)
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
it "returns the correct source options when the cookbook is included" do
|
|
200
|
+
expect(cookbook_source.source_options_for("cookbookA", "2.0.0")).to eq({ :version => "2.0.0" })
|
|
201
|
+
expect(cookbook_source.source_options_for("cookbookB", "1.0.0")).to eq({ :version => "1.0.0" })
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
it "has a universe with the used cookbooks" do
|
|
205
|
+
expect(cookbook_source.universe_graph).to eq({
|
|
206
|
+
"cookbookA" => {
|
|
207
|
+
"2.0.0" => external_cookbook_universe["cookbookA"]["2.0.0"],
|
|
208
|
+
},
|
|
209
|
+
"cookbookB" => {
|
|
210
|
+
"1.0.0" => external_cookbook_universe["cookbookB"]["1.0.0"],
|
|
211
|
+
},
|
|
212
|
+
"cookbookC" => {
|
|
213
|
+
"2.0.0" => external_cookbook_universe["cookbookC"]["2.0.0"],
|
|
214
|
+
},
|
|
215
|
+
})
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
context "when the policies have the same versions with conflicting sources" do
|
|
220
|
+
let(:randomize_sources) { true }
|
|
221
|
+
let(:policy2_cookbooks) { policy1_cookbooks }
|
|
222
|
+
|
|
223
|
+
it "raises an error when check_for_conflicts! is called" do
|
|
224
|
+
expect { cookbook_source.check_for_conflicts! }.to raise_error(
|
|
225
|
+
ChefDK::Policyfile::IncludedPoliciesCookbookSource::ConflictingCookbookSources)
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
context "when the policies have conflicting versions" do
|
|
230
|
+
let(:policy2_cookbooks) { [{ name: "cookbookA", version: "1.0.0" }] }
|
|
231
|
+
|
|
232
|
+
it "raises an error when check_for_conflicts! is called" do
|
|
233
|
+
expect { cookbook_source.check_for_conflicts! }.to raise_error(
|
|
234
|
+
ChefDK::Policyfile::IncludedPoliciesCookbookSource::ConflictingCookbookVersions)
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
context "when the policies have conflicting dependencies" do
|
|
239
|
+
it "raises an error when check_for_conflicts! is called"
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright:: Copyright (c) 2017 Chef Software Inc.
|
|
3
|
+
# License:: Apache License, Version 2.0
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
#
|
|
17
|
+
|
|
18
|
+
require "spec_helper"
|
|
19
|
+
require "chef-dk/policyfile/local_lock_fetcher"
|
|
20
|
+
|
|
21
|
+
describe ChefDK::Policyfile::LocalLockFetcher do
|
|
22
|
+
|
|
23
|
+
let(:minimal_lockfile_json) do
|
|
24
|
+
<<-E
|
|
25
|
+
{
|
|
26
|
+
"revision_id": "6fe753184c8946052d3231bb4212116df28d89a3a5f7ae52832ad408419dd5eb",
|
|
27
|
+
"name": "install-example",
|
|
28
|
+
"run_list": [
|
|
29
|
+
"recipe[local-cookbook::default]"
|
|
30
|
+
],
|
|
31
|
+
"cookbook_locks": {
|
|
32
|
+
"local-cookbook": {
|
|
33
|
+
"version": "2.3.4",
|
|
34
|
+
"identifier": "fab501cfaf747901bd82c1bc706beae7dc3a350c",
|
|
35
|
+
"dotted_decimal_identifier": "70567763561641081.489844270461035.258281553147148",
|
|
36
|
+
"source": "cookbooks/local-cookbook",
|
|
37
|
+
"cache_key": null,
|
|
38
|
+
"scm_info": null,
|
|
39
|
+
"source_options": {
|
|
40
|
+
"path": "../cookbooks/local-cookbook"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"default_attributes": {},
|
|
45
|
+
"override_attributes": {},
|
|
46
|
+
"solution_dependencies": {
|
|
47
|
+
"Policyfile": [
|
|
48
|
+
[
|
|
49
|
+
"local-cookbook",
|
|
50
|
+
">= 0.0.0"
|
|
51
|
+
]
|
|
52
|
+
],
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"local-cookbook (2.3.4)": [
|
|
55
|
+
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
E
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
let(:lock_file_path) { "#{tempdir}/foo/bar/baz/foo.lock.json" }
|
|
64
|
+
let(:storage_config) { ChefDK::Policyfile::StorageConfig.new.use_policyfile("#{tempdir}/Policyfile.rb") }
|
|
65
|
+
|
|
66
|
+
before do
|
|
67
|
+
reset_tempdir
|
|
68
|
+
FileUtils.mkdir_p(Pathname.new(lock_file_path).dirname)
|
|
69
|
+
File.open(lock_file_path, "w") { |file| file.write(minimal_lockfile_json) }
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
after do
|
|
73
|
+
reset_tempdir
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def minimal_lockfile
|
|
77
|
+
FFI_Yajl::Parser.parse(minimal_lockfile_json)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
let(:minimal_lockfile_modified) do
|
|
81
|
+
minimal_lockfile.tap do |lockfile|
|
|
82
|
+
lockfile["cookbook_locks"]["local-cookbook"]["source_options"] = { "path" => "foo/bar/cookbooks/local-cookbook" }
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
subject(:fetcher) { described_class.new("foo", source_options, storage_config) }
|
|
87
|
+
|
|
88
|
+
context "when the path is a file" do
|
|
89
|
+
context "and the file exists" do
|
|
90
|
+
let(:source_options) do
|
|
91
|
+
{
|
|
92
|
+
path: lock_file_path,
|
|
93
|
+
}
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
let(:source_options_for_lock) { source_options }
|
|
97
|
+
|
|
98
|
+
it "loads the policy from disk" do
|
|
99
|
+
expect(fetcher.lock_data).to eq(minimal_lockfile_modified)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it "returns source_options_for_lock" do
|
|
103
|
+
expect(fetcher.source_options).to eq(source_options)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
it "applies can apply source options from the lock" do
|
|
107
|
+
fetcher.apply_locked_source_options(source_options_for_lock)
|
|
108
|
+
expect(fetcher.lock_data).to eq(minimal_lockfile_modified)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context "and the file does not exist" do
|
|
113
|
+
let(:source_options) do
|
|
114
|
+
{
|
|
115
|
+
path: Pathname.new(lock_file_path).dirname.join("dne.json.lock").to_s,
|
|
116
|
+
}
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it "raises an error" do
|
|
120
|
+
expect { fetcher.lock_data }.to raise_error(ChefDK::LocalPolicyfileLockNotFound)
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
context "when the path is a directory" do
|
|
126
|
+
context "and the file exists" do
|
|
127
|
+
let(:source_options) do
|
|
128
|
+
{
|
|
129
|
+
path: Pathname.new(lock_file_path).dirname.to_s,
|
|
130
|
+
}
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
let(:source_options_for_lock) { source_options }
|
|
134
|
+
|
|
135
|
+
it "loads the policy from disk" do
|
|
136
|
+
expect(fetcher.lock_data).to eq(minimal_lockfile_modified)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "returns source_options_for_lock" do
|
|
140
|
+
expect(fetcher.source_options).to eq(source_options)
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "applies can apply source options from the lock" do
|
|
144
|
+
fetcher.apply_locked_source_options(source_options_for_lock)
|
|
145
|
+
expect(fetcher.lock_data).to eq(minimal_lockfile_modified)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
context "and the file does not exist" do
|
|
150
|
+
let(:source_options) do
|
|
151
|
+
{
|
|
152
|
+
path: Pathname.new(lock_file_path).dirname.parent.to_s,
|
|
153
|
+
}
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
it "raises an error" do
|
|
157
|
+
expect { fetcher.lock_data }.to raise_error(ChefDK::LocalPolicyfileLockNotFound, /provide the file name as part of the path/)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|