chef-dk 0.10.0 → 0.11.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.
- checksums.yaml +4 -4
- data/Gemfile +5 -0
- data/README.md +19 -4
- data/Rakefile +9 -0
- data/chef-dk.gemspec +3 -1
- data/lib/chef-dk/chef_runner.rb +9 -0
- data/lib/chef-dk/command/export.rb +6 -0
- data/lib/chef-dk/command/generator_commands.rb +3 -3
- data/lib/chef-dk/command/generator_commands/base.rb +27 -0
- data/lib/chef-dk/command/update.rb +19 -0
- data/lib/chef-dk/configurable.rb +13 -1
- data/lib/chef-dk/exceptions.rb +3 -0
- data/lib/chef-dk/policyfile/cookbook_location_specification.rb +13 -0
- data/lib/chef-dk/policyfile/cookbook_locks.rb +1 -1
- data/lib/chef-dk/policyfile/dsl.rb +40 -2
- data/lib/chef-dk/policyfile_compiler.rb +43 -4
- data/lib/chef-dk/policyfile_services/export_repo.rb +156 -51
- data/lib/chef-dk/policyfile_services/install.rb +1 -0
- data/lib/chef-dk/policyfile_services/push_archive.rb +33 -2
- data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +7 -5
- data/lib/chef-dk/skeletons/code_generator/files/default/repo/policies/README.md +1 -1
- data/lib/chef-dk/version.rb +1 -1
- data/lib/kitchen/provisioner/policyfile_zero.rb +8 -3
- data/spec/shared/custom_generator_cookbook.rb +15 -2
- data/spec/unit/chef_runner_spec.rb +28 -0
- data/spec/unit/command/export_spec.rb +11 -0
- data/spec/unit/command/generator_commands/base_spec.rb +136 -0
- data/spec/unit/command/update_spec.rb +24 -0
- data/spec/unit/configurable_spec.rb +41 -0
- data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -0
- data/spec/unit/fixtures/configurable/test_configurable.rb +10 -0
- data/spec/unit/policyfile/cookbook_location_specification_spec.rb +21 -1
- data/spec/unit/policyfile/cookbook_locks_spec.rb +1 -1
- data/spec/unit/policyfile_demands_spec.rb +206 -0
- data/spec/unit/policyfile_evaluation_spec.rb +85 -0
- data/spec/unit/policyfile_lock_serialization_spec.rb +1 -1
- data/spec/unit/policyfile_services/export_repo_spec.rb +78 -36
- data/spec/unit/policyfile_services/install_spec.rb +20 -0
- data/spec/unit/policyfile_services/push_archive_spec.rb +41 -8
- metadata +27 -11
@@ -81,6 +81,34 @@ describe ChefDK::ChefRunner do
|
|
81
81
|
expect(test_state[:converged_recipes]).to eq([ "recipe_one", "recipe_two" ])
|
82
82
|
end
|
83
83
|
|
84
|
+
context "when policyfile options are set in the workstation config" do
|
85
|
+
|
86
|
+
before do
|
87
|
+
Chef::Config.use_policyfile true
|
88
|
+
Chef::Config.policy_name "workstation"
|
89
|
+
Chef::Config.policy_group "test"
|
90
|
+
|
91
|
+
# chef-client ignores `deployment_group` unless
|
92
|
+
# `policy_document_native_api` is set to false
|
93
|
+
Chef::Config.deployment_group "workstation-test"
|
94
|
+
Chef::Config.policy_document_native_api false
|
95
|
+
end
|
96
|
+
|
97
|
+
it "unsets the options" do
|
98
|
+
chef_runner.configure
|
99
|
+
|
100
|
+
expect(Chef::Config.use_policyfile).to be(false)
|
101
|
+
expect(Chef::Config.policy_name).to be_nil
|
102
|
+
expect(Chef::Config.policy_group).to be_nil
|
103
|
+
expect(Chef::Config.deployment_group).to be_nil
|
104
|
+
end
|
105
|
+
|
106
|
+
it "converges successfully" do
|
107
|
+
expect { chef_runner.converge }.to_not raise_error
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
84
112
|
context "when the embedded chef run fails" do
|
85
113
|
|
86
114
|
let(:embedded_runner) { instance_double("Chef::Runner") }
|
@@ -128,6 +128,17 @@ describe ChefDK::Command::Export do
|
|
128
128
|
it "returns 0" do
|
129
129
|
expect(command.run(params)).to eq(0)
|
130
130
|
end
|
131
|
+
|
132
|
+
it "prints instructions for running chef-client in the repo" do
|
133
|
+
command.run(params)
|
134
|
+
|
135
|
+
expected_message = <<-MESSAGE
|
136
|
+
To converge this system with the exported policy, run:
|
137
|
+
cd /path/to/export
|
138
|
+
chef-client -z
|
139
|
+
MESSAGE
|
140
|
+
expect(ui.output).to include(expected_message)
|
141
|
+
end
|
131
142
|
end
|
132
143
|
|
133
144
|
context "when the command is unsuccessful" do
|
@@ -0,0 +1,136 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014 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 'pry'
|
19
|
+
require 'spec_helper'
|
20
|
+
require 'chef-dk/command/generator_commands/base'
|
21
|
+
|
22
|
+
describe ChefDK::Command::GeneratorCommands::Base do
|
23
|
+
describe 'parsing Chef configuration' do
|
24
|
+
let(:cli_args) do
|
25
|
+
[
|
26
|
+
"-C", "Business Man",
|
27
|
+
"-I", "Serious Business",
|
28
|
+
"-m", "business.man@corporation.com"
|
29
|
+
]
|
30
|
+
end
|
31
|
+
|
32
|
+
before do
|
33
|
+
Chef::Config.reset
|
34
|
+
end
|
35
|
+
|
36
|
+
context 'when generator configuration is defined' do
|
37
|
+
before do
|
38
|
+
Chef::Config.reset
|
39
|
+
Chef::Config.chefdk.generator.copyright_holder = "This Guy"
|
40
|
+
Chef::Config.chefdk.generator.email = "this.guy@twothumbs.net"
|
41
|
+
Chef::Config.chefdk.generator.license = "Two Thumbs License"
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'uses the defined values' do
|
45
|
+
cmd = ChefDK::Command::GeneratorCommands::Base.new([])
|
46
|
+
cmd.parse_options
|
47
|
+
cmd.setup_context
|
48
|
+
cfg = cmd.config
|
49
|
+
expect(cfg[:copyright_holder]).to eq('This Guy')
|
50
|
+
expect(cfg[:email]).to eq('this.guy@twothumbs.net')
|
51
|
+
expect(cfg[:license]).to eq('Two Thumbs License')
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'when cli overrides are provided' do
|
55
|
+
before do
|
56
|
+
Chef::Config.reset
|
57
|
+
Chef::Config.chefdk.generator.copyright_holder = "This Guy"
|
58
|
+
Chef::Config.chefdk.generator.email = "this.guy@twothumbs.net"
|
59
|
+
Chef::Config.chefdk.generator.license = "Two Thumbs License"
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'uses the cli args' do
|
63
|
+
cmd = ChefDK::Command::GeneratorCommands::Base.new(cli_args)
|
64
|
+
cmd.parse_options(cli_args)
|
65
|
+
cmd.setup_context
|
66
|
+
cfg = cmd.config
|
67
|
+
expect(cfg[:copyright_holder]).to eq('Business Man')
|
68
|
+
expect(cfg[:email]).to eq('business.man@corporation.com')
|
69
|
+
expect(cfg[:license]).to eq('Serious Business')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when knife configuration is also defined' do
|
74
|
+
|
75
|
+
before do
|
76
|
+
Chef::Config.reset
|
77
|
+
Chef::Config.chefdk.generator.copyright_holder = "This Guy"
|
78
|
+
Chef::Config.chefdk.generator.email = "this.guy@twothumbs.net"
|
79
|
+
Chef::Config.chefdk.generator.license = "Two Thumbs License"
|
80
|
+
Chef::Config.knife.cookbook_copyright = "Knife User"
|
81
|
+
Chef::Config.knife.cookbook_email = "knife.user@example.com"
|
82
|
+
Chef::Config.knife.cookbook_license = "GPLv9000"
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'uses the generator configuration' do
|
86
|
+
cmd = ChefDK::Command::GeneratorCommands::Base.new([])
|
87
|
+
cmd.parse_options
|
88
|
+
cmd.setup_context
|
89
|
+
cfg = cmd.config
|
90
|
+
expect(cfg[:copyright_holder]).to eq('This Guy')
|
91
|
+
expect(cfg[:email]).to eq('this.guy@twothumbs.net')
|
92
|
+
expect(cfg[:license]).to eq('Two Thumbs License')
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'when knife configuration is defined' do
|
98
|
+
before do
|
99
|
+
Chef::Config.reset
|
100
|
+
Chef::Config.knife.cookbook_copyright = "Knife User"
|
101
|
+
Chef::Config.knife.cookbook_email = "knife.user@example.com"
|
102
|
+
Chef::Config.knife.cookbook_license = "GPLv9000"
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'uses the defined values' do
|
106
|
+
cmd = ChefDK::Command::GeneratorCommands::Base.new([])
|
107
|
+
cmd.parse_options
|
108
|
+
cmd.setup_context
|
109
|
+
cfg = cmd.config
|
110
|
+
expect(cfg[:copyright_holder]).to eq('Knife User')
|
111
|
+
expect(cfg[:email]).to eq('knife.user@example.com')
|
112
|
+
expect(cfg[:license]).to eq('GPLv9000')
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'when cli overrides are provided' do
|
116
|
+
|
117
|
+
before do
|
118
|
+
Chef::Config.reset
|
119
|
+
Chef::Config.knife.cookbook_copyright = "Knife User"
|
120
|
+
Chef::Config.knife.cookbook_email = "knife.user@example.com"
|
121
|
+
Chef::Config.knife.cookbook_license = "GPLv9000"
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'uses the cli args' do
|
125
|
+
cmd = ChefDK::Command::GeneratorCommands::Base.new(cli_args)
|
126
|
+
cmd.parse_options(cli_args)
|
127
|
+
cmd.setup_context
|
128
|
+
cfg = cmd.config
|
129
|
+
expect(cfg[:copyright_holder]).to eq('Business Man')
|
130
|
+
expect(cfg[:email]).to eq('business.man@corporation.com')
|
131
|
+
expect(cfg[:license]).to eq('Serious Business')
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -39,6 +39,10 @@ describe ChefDK::Command::Update do
|
|
39
39
|
expect(command.debug?).to be(false)
|
40
40
|
end
|
41
41
|
|
42
|
+
it "doesn't set a config path by default" do
|
43
|
+
expect(command.config_path).to be_nil
|
44
|
+
end
|
45
|
+
|
42
46
|
context "when debug mode is set" do
|
43
47
|
|
44
48
|
let(:params) { [ "-D" ] }
|
@@ -48,6 +52,26 @@ describe ChefDK::Command::Update do
|
|
48
52
|
end
|
49
53
|
end
|
50
54
|
|
55
|
+
context "when an explicit config file path is given" do
|
56
|
+
|
57
|
+
let(:params) { %w[ -c ~/.chef/alternate_config.rb ] }
|
58
|
+
|
59
|
+
let(:chef_config_loader) { instance_double("Chef::WorkstationConfigLoader") }
|
60
|
+
|
61
|
+
it "sets the config file path to the given value" do
|
62
|
+
expect(command.config_path).to eq("~/.chef/alternate_config.rb")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "loads the config from the given path" do
|
66
|
+
expect(Chef::WorkstationConfigLoader).to receive(:new).
|
67
|
+
with("~/.chef/alternate_config.rb").
|
68
|
+
and_return(chef_config_loader)
|
69
|
+
expect(chef_config_loader).to receive(:load)
|
70
|
+
expect(command.chef_config).to eq(Chef::Config)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
51
75
|
context "when attributes update mode is set" do
|
52
76
|
|
53
77
|
let(:params) { ["-a"] }
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#
|
2
|
+
# Copyright:: Copyright (c) 2014 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/configurable'
|
20
|
+
require 'unit/fixtures/configurable/test_configurable'
|
21
|
+
|
22
|
+
describe ChefDK::Configurable do
|
23
|
+
|
24
|
+
let(:includer) { TestConfigurable.new }
|
25
|
+
|
26
|
+
it 'provides chef_config' do
|
27
|
+
expect(includer.chef_config).to eq Chef::Config
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'provides chefdk_config' do
|
31
|
+
expect(includer.chefdk_config).to eq Chef::Config.chefdk
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'provides knife_config' do
|
35
|
+
expect(includer.knife_config).to eq Chef::Config.knife
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'provides generator_config' do
|
39
|
+
expect(includer.generator_config).to eq Chef::Config.chefdk.generator
|
40
|
+
end
|
41
|
+
end
|
@@ -30,7 +30,9 @@ describe ChefDK::Policyfile::CookbookLocationSpecification do
|
|
30
30
|
|
31
31
|
let(:cached_cookbook) { double("ChefDK::CookbookMetadata") }
|
32
32
|
|
33
|
-
let(:
|
33
|
+
let(:install_path) { Pathname.new("~/.chefdk/cache/cookbooks/my_cookbook-1.0.0") }
|
34
|
+
|
35
|
+
let(:installer) { double("CookbookOmnifetch location", cached_cookbook: cached_cookbook, install_path: install_path) }
|
34
36
|
|
35
37
|
let(:storage_config) do
|
36
38
|
ChefDK::Policyfile::StorageConfig.new.use_policyfile(policyfile_filename)
|
@@ -135,6 +137,24 @@ describe ChefDK::Policyfile::CookbookLocationSpecification do
|
|
135
137
|
expect(cookbook_location_spec.dependencies).to eq("apt" => "~> 1.2.3")
|
136
138
|
end
|
137
139
|
|
140
|
+
it "determines whether a cookbook has a given recipe" do
|
141
|
+
cookbook_path = cookbook_location_spec.cookbook_path
|
142
|
+
# "cache" cookbook_path so we stub the correct object
|
143
|
+
allow(cookbook_location_spec).to receive(:cookbook_path).and_return(cookbook_path)
|
144
|
+
|
145
|
+
default_recipe_path = install_path.join("recipes/default.rb")
|
146
|
+
nope_recipe_path = install_path.join("recipes/nope.rb")
|
147
|
+
|
148
|
+
expect(cookbook_path).to receive(:join).with("recipes/default.rb").and_return(default_recipe_path)
|
149
|
+
expect(cookbook_path).to receive(:join).with("recipes/nope.rb").and_return(nope_recipe_path)
|
150
|
+
|
151
|
+
expect(default_recipe_path).to receive(:exist?).and_return(true)
|
152
|
+
expect(nope_recipe_path).to receive(:exist?).and_return(false)
|
153
|
+
|
154
|
+
expect(cookbook_location_spec.cookbook_has_recipe?("default")).to be(true)
|
155
|
+
expect(cookbook_location_spec.cookbook_has_recipe?("nope")).to be(false)
|
156
|
+
end
|
157
|
+
|
138
158
|
end
|
139
159
|
|
140
160
|
describe "when created with no source" do
|
@@ -468,7 +468,7 @@ describe ChefDK::Policyfile::ArchivedCookbook do
|
|
468
468
|
described_class.new(wrapped_cookbook_lock, storage_config)
|
469
469
|
end
|
470
470
|
|
471
|
-
let(:archived_cookbook_path) { File.join(storage_config.relative_paths_root, "
|
471
|
+
let(:archived_cookbook_path) { File.join(storage_config.relative_paths_root, "cookbook_artifacts", "nginx-abc123") }
|
472
472
|
|
473
473
|
it "sets cookbook_path to the path within the archive" do
|
474
474
|
expect(cookbook_lock.cookbook_path).to eq(archived_cookbook_path)
|
@@ -182,6 +182,212 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
|
|
182
182
|
expect(policyfile.errors).to eq([])
|
183
183
|
end
|
184
184
|
|
185
|
+
context "Given resolvable cookbook demands" do
|
186
|
+
|
187
|
+
let(:default_source) { [:supermarket] }
|
188
|
+
|
189
|
+
let(:trimmed_cookbook_universe) do
|
190
|
+
{
|
191
|
+
"remote-cb" => {
|
192
|
+
"1.1.1" => [ ]
|
193
|
+
}
|
194
|
+
|
195
|
+
}
|
196
|
+
end
|
197
|
+
|
198
|
+
let(:remote_cb_source_opts) do
|
199
|
+
{ artifactserver: "https://supermarket.example/c/remote-cb/1.1.1/download", version: "1.1.1" }
|
200
|
+
end
|
201
|
+
|
202
|
+
let(:default_source_obj) do
|
203
|
+
instance_double("ChefDK::Policyfile::CommunityCookbookSource")
|
204
|
+
end
|
205
|
+
|
206
|
+
let(:cb_location_spec) do
|
207
|
+
s = "Cookbook 'remote-cb'"
|
208
|
+
s << " = 1.1.1"
|
209
|
+
s << " #{remote_cb_source_opts}"
|
210
|
+
|
211
|
+
instance_double("ChefDK::Policyfile::CookbookLocationSpecification",
|
212
|
+
name: "remote-cb",
|
213
|
+
version_constraint: Semverse::Constraint.new("= 1.1.1"),
|
214
|
+
ensure_cached: nil,
|
215
|
+
to_s: s)
|
216
|
+
end
|
217
|
+
|
218
|
+
before do
|
219
|
+
policyfile.default_source.replace([ default_source_obj ])
|
220
|
+
|
221
|
+
allow(default_source_obj).to receive(:universe_graph).
|
222
|
+
and_return(trimmed_cookbook_universe)
|
223
|
+
|
224
|
+
allow(default_source_obj).to receive(:preferred_source_for?).
|
225
|
+
with("remote-cb").
|
226
|
+
and_return(true)
|
227
|
+
|
228
|
+
allow(default_source_obj).to receive(:source_options_for).
|
229
|
+
with("remote-cb", "1.1.1").
|
230
|
+
and_return(remote_cb_source_opts)
|
231
|
+
|
232
|
+
|
233
|
+
allow(ChefDK::Policyfile::CookbookLocationSpecification).to receive(:new).
|
234
|
+
with("remote-cb", "= 1.1.1", remote_cb_source_opts, policyfile.storage_config).
|
235
|
+
and_return(cb_location_spec)
|
236
|
+
|
237
|
+
allow(cb_location_spec).to receive(:installed?).and_return(true)
|
238
|
+
end
|
239
|
+
|
240
|
+
context "when the resolved cookbooks have the recipes requested by the run list" do
|
241
|
+
|
242
|
+
context "with an implied default recipe" do
|
243
|
+
|
244
|
+
before do
|
245
|
+
expect(cb_location_spec).to receive(:cookbook_has_recipe?).
|
246
|
+
with("default").
|
247
|
+
and_return(true)
|
248
|
+
end
|
249
|
+
|
250
|
+
let(:run_list) { ["remote-cb"] }
|
251
|
+
|
252
|
+
it "installs without error" do
|
253
|
+
expect { policyfile.install }.to_not raise_error
|
254
|
+
end
|
255
|
+
|
256
|
+
end
|
257
|
+
|
258
|
+
context "with an explicit recipe name" do
|
259
|
+
|
260
|
+
before do
|
261
|
+
expect(cb_location_spec).to receive(:cookbook_has_recipe?).
|
262
|
+
with("this_exists").
|
263
|
+
and_return(true)
|
264
|
+
end
|
265
|
+
|
266
|
+
let(:run_list) { ["remote-cb::this_exists"] }
|
267
|
+
|
268
|
+
it "installs without error" do
|
269
|
+
expect { policyfile.install }.to_not raise_error
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
|
274
|
+
context "with a fully qualified recipe name" do
|
275
|
+
|
276
|
+
before do
|
277
|
+
expect(cb_location_spec).to receive(:cookbook_has_recipe?).
|
278
|
+
with("this_exists").
|
279
|
+
and_return(true)
|
280
|
+
end
|
281
|
+
|
282
|
+
let(:run_list) { ["recipe[remote-cb::this_exists]"] }
|
283
|
+
|
284
|
+
it "installs without error" do
|
285
|
+
expect { policyfile.install }.to_not raise_error
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
end
|
291
|
+
|
292
|
+
context "when the resolved cookbooks do not have the recipes requested by the run list" do
|
293
|
+
|
294
|
+
context "when the cookbook with a missing recipe appears once in the run list" do
|
295
|
+
before do
|
296
|
+
expect(cb_location_spec).to receive(:cookbook_has_recipe?).
|
297
|
+
with("this_recipe_doesnt_exist").
|
298
|
+
and_return(false)
|
299
|
+
end
|
300
|
+
|
301
|
+
let(:run_list) { ["remote-cb::this_recipe_doesnt_exist"] }
|
302
|
+
|
303
|
+
it "emits an error" do
|
304
|
+
message =<<-MESSAGE
|
305
|
+
The installed cookbooks do not contain all the recipes required by your run list(s):
|
306
|
+
Cookbook 'remote-cb' = 1.1.1 {:artifactserver=>"https://supermarket.example/c/remote-cb/1.1.1/download", :version=>"1.1.1"}
|
307
|
+
is missing the following required recipes:
|
308
|
+
* this_recipe_doesnt_exist
|
309
|
+
|
310
|
+
You may have specified an incorrect recipe in your run list,
|
311
|
+
or this recipe may not be available in that version of the cookbook
|
312
|
+
MESSAGE
|
313
|
+
|
314
|
+
expect { policyfile.install }.to raise_error do |e|
|
315
|
+
expect(e).to be_a(ChefDK::CookbookDoesNotContainRequiredRecipe)
|
316
|
+
expect(e.message).to eq(message)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
context "when there is one valid item and one invalid item in the run list" do
|
322
|
+
|
323
|
+
before do
|
324
|
+
expect(cb_location_spec).to receive(:cookbook_has_recipe?).
|
325
|
+
with("default").
|
326
|
+
and_return(true)
|
327
|
+
expect(cb_location_spec).to receive(:cookbook_has_recipe?).
|
328
|
+
with("this_recipe_doesnt_exist").
|
329
|
+
and_return(false)
|
330
|
+
end
|
331
|
+
|
332
|
+
|
333
|
+
let(:run_list) { ["remote-cb::default", "remote-cb::this_recipe_doesnt_exist"] }
|
334
|
+
|
335
|
+
it "emits an error" do
|
336
|
+
message =<<-MESSAGE
|
337
|
+
The installed cookbooks do not contain all the recipes required by your run list(s):
|
338
|
+
Cookbook 'remote-cb' = 1.1.1 {:artifactserver=>"https://supermarket.example/c/remote-cb/1.1.1/download", :version=>"1.1.1"}
|
339
|
+
is missing the following required recipes:
|
340
|
+
* this_recipe_doesnt_exist
|
341
|
+
|
342
|
+
You may have specified an incorrect recipe in your run list,
|
343
|
+
or this recipe may not be available in that version of the cookbook
|
344
|
+
MESSAGE
|
345
|
+
|
346
|
+
expect { policyfile.install }.to raise_error do |e|
|
347
|
+
expect(e).to be_a(ChefDK::CookbookDoesNotContainRequiredRecipe)
|
348
|
+
expect(e.message).to eq(message)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
end
|
353
|
+
|
354
|
+
context "when there are multiple invalid items in the run list" do
|
355
|
+
|
356
|
+
before do
|
357
|
+
expect(cb_location_spec).to receive(:cookbook_has_recipe?).
|
358
|
+
with("this_recipe_doesnt_exist").
|
359
|
+
and_return(false)
|
360
|
+
expect(cb_location_spec).to receive(:cookbook_has_recipe?).
|
361
|
+
with("this_also_doesnt_exist").
|
362
|
+
and_return(false)
|
363
|
+
end
|
364
|
+
|
365
|
+
let(:run_list) { ["remote-cb::this_recipe_doesnt_exist", "remote-cb::this_also_doesnt_exist"] }
|
366
|
+
|
367
|
+
it "emits an error" do
|
368
|
+
message =<<-MESSAGE
|
369
|
+
The installed cookbooks do not contain all the recipes required by your run list(s):
|
370
|
+
Cookbook 'remote-cb' = 1.1.1 {:artifactserver=>"https://supermarket.example/c/remote-cb/1.1.1/download", :version=>"1.1.1"}
|
371
|
+
is missing the following required recipes:
|
372
|
+
* this_recipe_doesnt_exist
|
373
|
+
* this_also_doesnt_exist
|
374
|
+
|
375
|
+
You may have specified an incorrect recipe in your run list,
|
376
|
+
or this recipe may not be available in that version of the cookbook
|
377
|
+
MESSAGE
|
378
|
+
|
379
|
+
expect { policyfile.install }.to raise_error do |e|
|
380
|
+
expect(e).to be_a(ChefDK::CookbookDoesNotContainRequiredRecipe)
|
381
|
+
expect(e.message).to eq(message)
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
end
|
386
|
+
|
387
|
+
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
185
391
|
context "Given no local or git cookbooks, no default source, and an empty run list" do
|
186
392
|
|
187
393
|
let(:run_list) { [] }
|