chef-dk 0.2.0 → 0.2.1

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.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -1
  3. data/lib/chef-dk/authenticated_http.rb +40 -0
  4. data/lib/chef-dk/chef_runner.rb +5 -0
  5. data/lib/chef-dk/command/exec.rb +4 -1
  6. data/lib/chef-dk/command/generate.rb +11 -0
  7. data/lib/chef-dk/command/generator_commands.rb +20 -365
  8. data/lib/chef-dk/command/generator_commands/app.rb +99 -0
  9. data/lib/chef-dk/command/generator_commands/attribute.rb +37 -0
  10. data/lib/chef-dk/command/generator_commands/base.rb +76 -0
  11. data/lib/chef-dk/command/generator_commands/cookbook.rb +100 -0
  12. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +99 -0
  13. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -0
  14. data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -0
  15. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -0
  16. data/lib/chef-dk/command/generator_commands/repo.rb +96 -0
  17. data/lib/chef-dk/command/generator_commands/template.rb +45 -0
  18. data/lib/chef-dk/command/verify.rb +28 -0
  19. data/lib/chef-dk/component_test.rb +16 -3
  20. data/lib/chef-dk/cookbook_omnifetch.rb +2 -0
  21. data/lib/chef-dk/cookbook_profiler/identifiers.rb +3 -15
  22. data/lib/chef-dk/exceptions.rb +15 -0
  23. data/lib/chef-dk/generator.rb +102 -25
  24. data/lib/chef-dk/policyfile/community_cookbook_source.rb +0 -7
  25. data/lib/chef-dk/policyfile/{cookbook_spec.rb → cookbook_location_specification.rb} +35 -6
  26. data/lib/chef-dk/policyfile/cookbook_locks.rb +305 -0
  27. data/lib/chef-dk/policyfile/dsl.rb +26 -12
  28. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +70 -0
  29. data/lib/chef-dk/policyfile/solution_dependencies.rb +204 -0
  30. data/lib/chef-dk/policyfile/storage_config.rb +77 -0
  31. data/lib/chef-dk/policyfile/uploader.rb +110 -0
  32. data/lib/chef-dk/policyfile_compiler.rb +59 -29
  33. data/lib/chef-dk/policyfile_lock.rb +104 -160
  34. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +1 -1
  35. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +0 -1
  36. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +66 -0
  37. data/lib/chef-dk/skeletons/code_generator/files/default/repo/Rakefile +65 -0
  38. data/lib/chef-dk/skeletons/code_generator/files/default/repo/certificates/README.md +19 -0
  39. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/README-policy.md +9 -0
  40. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/README.md +54 -0
  41. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +63 -0
  42. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +5 -0
  43. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +16 -0
  44. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +7 -1
  45. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +62 -0
  46. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -0
  47. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apache2.erb +201 -0
  48. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -0
  49. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -0
  50. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -0
  51. data/lib/chef-dk/skeletons/code_generator/templates/default/default_recipe.rb.erb +1 -4
  52. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +3 -3
  53. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/config/rake.rb.erb +38 -0
  54. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +11 -0
  55. data/lib/chef-dk/version.rb +1 -1
  56. data/spec/shared/a_file_generator.rb +121 -0
  57. data/spec/shared/a_generated_file.rb +12 -0
  58. data/spec/shared/fixture_cookbook_checksums.rb +47 -0
  59. data/spec/spec_helper.rb +4 -2
  60. data/spec/unit/chef_runner_spec.rb +12 -5
  61. data/spec/unit/cli_spec.rb +4 -4
  62. data/spec/unit/command/base_spec.rb +1 -1
  63. data/spec/unit/command/exec_spec.rb +37 -27
  64. data/spec/unit/command/generate_spec.rb +3 -3
  65. data/spec/unit/command/generator_commands/app_spec.rb +131 -0
  66. data/spec/unit/command/generator_commands/attribute_spec.rb +32 -0
  67. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -0
  68. data/spec/unit/command/generator_commands/cookbook_spec.rb +205 -0
  69. data/spec/unit/command/generator_commands/lwrp_spec.rb +32 -0
  70. data/spec/unit/command/generator_commands/recipe_spec.rb +32 -0
  71. data/spec/unit/command/generator_commands/repo_spec.rb +287 -0
  72. data/spec/unit/command/generator_commands/template_spec.rb +32 -0
  73. data/spec/unit/command/shell_init_spec.rb +4 -4
  74. data/spec/unit/command/verify_spec.rb +9 -9
  75. data/spec/unit/commands_map_spec.rb +1 -1
  76. data/spec/unit/component_test_spec.rb +3 -3
  77. data/spec/unit/cookbook_profiler/git_spec.rb +7 -7
  78. data/spec/unit/cookbook_profiler/identifiers_spec.rb +12 -8
  79. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +1 -1
  80. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +1 -1
  81. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +1 -1
  82. data/spec/unit/fixtures/example_cookbook/Berksfile +1 -1
  83. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -0
  84. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -0
  85. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -0
  86. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -0
  87. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +1 -1
  88. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -0
  89. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -0
  90. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -0
  91. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -0
  92. data/spec/unit/generator_spec.rb +120 -0
  93. data/spec/unit/policyfile/{cookbook_spec_spec.rb → cookbook_location_specification_spec.rb} +83 -38
  94. data/spec/unit/policyfile/cookbook_locks_spec.rb +354 -0
  95. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +85 -0
  96. data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -0
  97. data/spec/unit/policyfile/storage_config_spec.rb +98 -0
  98. data/spec/unit/policyfile/uploader_spec.rb +292 -0
  99. data/spec/unit/policyfile_demands_spec.rb +177 -24
  100. data/spec/unit/policyfile_evaluation_spec.rb +40 -12
  101. data/spec/unit/{policyfile_builder_spec.rb → policyfile_lock_build_spec.rb} +179 -64
  102. data/spec/unit/policyfile_lock_install_spec.rb +138 -0
  103. data/spec/unit/policyfile_lock_validation_spec.rb +610 -0
  104. metadata +103 -59
  105. data/spec/unit/command/generator_commands_spec.rb +0 -504
@@ -0,0 +1,354 @@
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/policyfile/cookbook_locks'
20
+
21
+ shared_examples_for "Cookbook Lock" do
22
+
23
+ let(:cookbook_lock_data) { cookbook_lock.to_lock }
24
+
25
+ it "has a cookbook name" do
26
+ expect(cookbook_lock.name).to eq(cookbook_name)
27
+ end
28
+
29
+ it "has a source_options attribute" do
30
+ cookbook_lock.source_options = { artifactserver: "https://artifacts.example.com/nginx/1.0.0/download" }
31
+ expect(cookbook_lock.source_options).to eq({ artifactserver: "https://artifacts.example.com/nginx/1.0.0/download" })
32
+ end
33
+
34
+ it "has an identifier attribute" do
35
+ cookbook_lock.identifier = "my-opaque-id"
36
+ expect(cookbook_lock.identifier).to eq("my-opaque-id")
37
+ end
38
+
39
+ it "has a dotted_decimal_identifier attribute" do
40
+ cookbook_lock.dotted_decimal_identifier = "123.456.789"
41
+ expect(cookbook_lock.dotted_decimal_identifier).to eq("123.456.789")
42
+ end
43
+
44
+ it "has a version attribute" do
45
+ cookbook_lock.version = "1.2.3"
46
+ expect(cookbook_lock.version).to eq("1.2.3")
47
+ end
48
+
49
+ it "has a storage config" do
50
+ expect(cookbook_lock.storage_config).to eq(storage_config)
51
+ end
52
+
53
+ context "when the underlying cookbook has not been mutated, or #refresh! has not been called" do
54
+
55
+ it "is not updated" do
56
+ expect(cookbook_lock).to_not be_updated
57
+ end
58
+
59
+ it "does not have an updated identifier" do
60
+ expect(cookbook_lock.identifier_updated?).to be false
61
+ end
62
+
63
+ it "does not have an updated version" do
64
+ expect(cookbook_lock.version_updated?).to be false
65
+ end
66
+
67
+ end
68
+
69
+ context "when version and identifier attributes are populated" do
70
+
71
+ before do
72
+ allow(cookbook_lock).to receive(:validate!)
73
+
74
+ cookbook_lock.identifier = "my-opaque-id"
75
+ cookbook_lock.dotted_decimal_identifier = "123.456.789"
76
+ cookbook_lock.version = "1.2.3"
77
+ cookbook_lock.source_options = { :sourcekey => "location info" }
78
+ end
79
+
80
+ it "includes the identifier in the lock data" do
81
+ expect(cookbook_lock_data["identifier"]).to eq("my-opaque-id")
82
+ end
83
+
84
+ it "includes the dotted decimal identifier in the lock data" do
85
+ expect(cookbook_lock_data["dotted_decimal_identifier"]).to eq("123.456.789")
86
+ end
87
+
88
+ it "includes the version in lock data" do
89
+ expect(cookbook_lock_data["version"]).to eq("1.2.3")
90
+ end
91
+
92
+ it "includes the source_options in lock data" do
93
+ expect(cookbook_lock_data["source_options"]).to eq({ :sourcekey => "location info" })
94
+ end
95
+
96
+ it "creates a CookbookLocationSpecification with the source and version data" do
97
+ location_spec = cookbook_lock.cookbook_location_spec
98
+ expect(location_spec.name).to eq(cookbook_name)
99
+ expect(location_spec.version_constraint).to eq(Semverse::Constraint.new("= 1.2.3"))
100
+ expect(location_spec.source_options).to eq({ sourcekey: "location info" })
101
+ end
102
+
103
+ it "delegates #dependencies to cookbook_location_spec" do
104
+ deps = [ [ "foo", ">= 0.0.0"], [ "bar", "~> 2.1" ] ]
105
+ expect(cookbook_lock.cookbook_location_spec).to receive(:dependencies).and_return(deps)
106
+ expect(cookbook_lock.dependencies).to eq(deps)
107
+ end
108
+
109
+ end
110
+
111
+ context "when created from lock data" do
112
+
113
+ let(:lock_data) do
114
+ {
115
+ "identifier" => "my-opaque-id",
116
+ "dotted_decimal_identifier" => "123.456.789",
117
+ "version" => "1.2.3",
118
+ "source_options" => { "sourcekey" => "location info" }
119
+ }
120
+ end
121
+
122
+ before do
123
+ cookbook_lock.build_from_lock_data(lock_data)
124
+ end
125
+
126
+ it "sets the identifier attribute" do
127
+ expect(cookbook_lock.identifier).to eq("my-opaque-id")
128
+ end
129
+
130
+ it "sets the dotted_decimal_identifier attribute" do
131
+ expect(cookbook_lock.dotted_decimal_identifier).to eq("123.456.789")
132
+ end
133
+
134
+ it "sets the version attribute" do
135
+ expect(cookbook_lock.version).to eq("1.2.3")
136
+ end
137
+
138
+ it "sets the source options" do
139
+ expect(cookbook_lock.source_options).to eq({ sourcekey: "location info" })
140
+ end
141
+ end
142
+
143
+ end
144
+
145
+
146
+ describe ChefDK::Policyfile::CachedCookbook do
147
+
148
+ let(:cookbook_name) { "nginx" }
149
+
150
+ let(:storage_config) { ChefDK::Policyfile::StorageConfig.new }
151
+
152
+ let(:cookbook_lock) do
153
+ described_class.new(cookbook_name, storage_config)
154
+ end
155
+
156
+ include_examples "Cookbook Lock"
157
+
158
+ it "has a cache_key attribute" do
159
+ cookbook_lock.cache_key = "nginx-1.0.0-example.com"
160
+ expect(cookbook_lock.cache_key).to eq("nginx-1.0.0-example.com")
161
+ end
162
+
163
+ it "has an origin attribute" do
164
+ cookbook_lock.origin = "https://artifacts.example.com/nginx/1.0.0/download"
165
+ expect(cookbook_lock.origin).to eq("https://artifacts.example.com/nginx/1.0.0/download")
166
+ end
167
+
168
+ it "errors locating the cookbook when the cache key is not set" do
169
+ expect { cookbook_lock.cookbook_path }.to raise_error(ChefDK::MissingCookbookLockData)
170
+ end
171
+
172
+ it "ignores calls to #refresh!" do
173
+ expect { cookbook_lock.refresh! }.to_not raise_error
174
+ end
175
+
176
+ context "when populated with valid data" do
177
+
178
+ let(:cookbook_name) { "foo" }
179
+
180
+ let(:cache_path) { File.join(fixtures_path, "cached_cookbooks") }
181
+
182
+ before do
183
+ cookbook_lock.cache_key = "foo-1.0.0"
184
+
185
+ storage_config.cache_path = cache_path
186
+ end
187
+
188
+ it "gives the path to the cookbook in the cache" do
189
+ expect(cookbook_lock.cookbook_path).to eq(File.join(cache_path, "foo-1.0.0"))
190
+ end
191
+
192
+ end
193
+
194
+ end
195
+
196
+ describe ChefDK::Policyfile::LocalCookbook do
197
+
198
+ let(:cookbook_name) { "nginx" }
199
+
200
+ let(:storage_config) { ChefDK::Policyfile::StorageConfig.new }
201
+
202
+ let(:cookbook_lock) do
203
+ lock = described_class.new(cookbook_name, storage_config)
204
+ allow(lock).to receive(:scm_info).and_return({})
205
+ lock
206
+ end
207
+
208
+ include_examples "Cookbook Lock"
209
+
210
+ describe "gathering identifier info" do
211
+ let(:identifiers) do
212
+ instance_double("ChefDK::CookbookProfiler::Identifiers",
213
+ content_identifier: "abc123",
214
+ dotted_decimal_identifier: "111.222.333",
215
+ semver_version: "1.2.3")
216
+ end
217
+
218
+ before do
219
+ allow(cookbook_lock).to receive(:identifiers).and_return(identifiers)
220
+ cookbook_lock.gather_profile_data
221
+ end
222
+
223
+ it "sets the content identifier" do
224
+ expect(cookbook_lock.identifier).to eq("abc123")
225
+ end
226
+
227
+ it "sets the backwards compatible dotted decimal identifer equivalent" do
228
+ expect(cookbook_lock.dotted_decimal_identifier).to eq("111.222.333")
229
+ end
230
+
231
+ it "collects the 'real' SemVer version of the cookbook" do
232
+ expect(cookbook_lock.version).to eq("1.2.3")
233
+ end
234
+
235
+ end
236
+
237
+ context "when loading data from a serialized form" do
238
+
239
+ let(:previous_lock_data) do
240
+ {
241
+ "identifier" => "abc123",
242
+ "dotted_decimal_identifier" => "111.222.333",
243
+ "version" => "1.2.3",
244
+ "source" => "../my_repo/nginx",
245
+ "source_options" => {
246
+ "path" => "../my_repo/nginx"
247
+ }
248
+ }
249
+ end
250
+
251
+ before do
252
+ cookbook_lock.build_from_lock_data(previous_lock_data)
253
+ end
254
+
255
+ it "sets the identifier" do
256
+ expect(cookbook_lock.identifier).to eq("abc123")
257
+ end
258
+
259
+ it "sets the dotted_decimal_identifier" do
260
+ expect(cookbook_lock.dotted_decimal_identifier).to eq("111.222.333")
261
+ end
262
+
263
+ it "sets the version" do
264
+ expect(cookbook_lock.version).to eq("1.2.3")
265
+ end
266
+
267
+ it "sets the source attribute" do
268
+ expect(cookbook_lock.source).to eq("../my_repo/nginx")
269
+ end
270
+
271
+ it "sets the source options, symbolizing keys so the data is compatible with CookbookLocationSpecification" do
272
+ expected = { path: "../my_repo/nginx" }
273
+ expect(cookbook_lock.source_options).to eq(expected)
274
+ end
275
+
276
+ context "after the data has been refreshed" do
277
+
278
+ before do
279
+ allow(cookbook_lock).to receive(:identifiers).and_return(identifiers)
280
+ cookbook_lock.refresh!
281
+ end
282
+
283
+ context "and the underlying hasn't been mutated" do
284
+
285
+ let(:identifiers) do
286
+ instance_double("ChefDK::CookbookProfiler::Identifiers",
287
+ content_identifier: "abc123",
288
+ dotted_decimal_identifier: "111.222.333",
289
+ semver_version: "1.2.3")
290
+ end
291
+
292
+ it "has the correct identifier" do
293
+ expect(cookbook_lock.identifier).to eq("abc123")
294
+ end
295
+
296
+ it "has the correct dotted_decimal_identifier" do
297
+ expect(cookbook_lock.dotted_decimal_identifier).to eq("111.222.333")
298
+ end
299
+
300
+ it "has the correct version" do
301
+ expect(cookbook_lock.version).to eq("1.2.3")
302
+ end
303
+
304
+ it "sets the updated flag to false" do
305
+ expect(cookbook_lock).to_not be_updated
306
+ end
307
+
308
+ it "sets the version_updated flag to false" do
309
+ expect(cookbook_lock.version_updated?).to be(false)
310
+ end
311
+
312
+ it "sets the identifier_updated flag to false" do
313
+ expect(cookbook_lock.identifier_updated?).to be(false)
314
+ end
315
+
316
+ end
317
+
318
+ context "and the underlying data has been mutated" do
319
+ # represents the updated state of the cookbook
320
+ let(:identifiers) do
321
+ instance_double("ChefDK::CookbookProfiler::Identifiers",
322
+ content_identifier: "def456",
323
+ dotted_decimal_identifier: "777.888.999",
324
+ semver_version: "7.8.9")
325
+ end
326
+
327
+ it "sets the content identifier to the new identifier" do
328
+ expect(cookbook_lock.identifier).to eq("def456")
329
+ end
330
+
331
+ it "sets the dotted_decimal_identifier to the new identifier" do
332
+ expect(cookbook_lock.dotted_decimal_identifier).to eq("777.888.999")
333
+ end
334
+
335
+ it "sets the SemVer version to the new version" do
336
+ expect(cookbook_lock.version).to eq("7.8.9")
337
+ end
338
+
339
+ it "sets the updated flag to true" do
340
+ expect(cookbook_lock).to be_updated
341
+ end
342
+
343
+ it "sets the version_updated flag to true" do
344
+ expect(cookbook_lock.version_updated?).to be(true)
345
+ end
346
+
347
+ it "sets the identifier_updated flag to true" do
348
+ expect(cookbook_lock.identifier_updated?).to be(true)
349
+ end
350
+ end
351
+ end
352
+ end
353
+
354
+ end
@@ -0,0 +1,85 @@
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/policyfile/read_cookbook_for_compat_mode_upload'
20
+
21
+ describe ChefDK::Policyfile::ReadCookbookForCompatModeUpload do
22
+
23
+ let(:cookbook_name) { "noignore" }
24
+
25
+ let(:version_override) { "123.456.789" }
26
+
27
+ let(:directory_path) { File.join(fixtures_path, "local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb") }
28
+
29
+ let(:reader) { described_class.new(cookbook_name, version_override, directory_path) }
30
+
31
+ it "has a cookbook_name" do
32
+ expect(reader.cookbook_name).to eq(cookbook_name)
33
+ end
34
+
35
+ it "has a version number override" do
36
+ expect(reader.version_override).to eq(version_override)
37
+ end
38
+
39
+ it "has a directory path" do
40
+ expect(reader.directory_path).to eq(directory_path)
41
+ end
42
+
43
+ it "has an empty chefignore when the cookbook doesn't include one" do
44
+ expect(reader.chefignore.ignores).to eq([])
45
+ end
46
+
47
+ it "loads the cookbook with the correct name" do
48
+ expect(reader.cookbook_version.name).to eq(:noignore)
49
+ end
50
+
51
+ it "loads the cookbook with the correct version" do
52
+ expect(reader.cookbook_version.version).to eq(version_override)
53
+ end
54
+
55
+ it "freezes the cookbook version" do
56
+ expect(reader.cookbook_version.frozen_version?).to be true
57
+ end
58
+
59
+ context "when a cookbook has a chefignore file" do
60
+
61
+ let(:directory_path) { File.join(fixtures_path, "cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb") }
62
+
63
+ let(:copied_cookbook_path) { File.join(tempdir, "baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb") }
64
+
65
+ let(:chefignored_file) { File.join(copied_cookbook_path, "Guardfile") }
66
+
67
+ let(:reader_with_ignored_files) do
68
+ described_class.new(cookbook_name, version_override, copied_cookbook_path)
69
+ end
70
+
71
+ before do
72
+ FileUtils.cp_r(directory_path, copied_cookbook_path)
73
+ File.open(chefignored_file, "w+") { |f| f.puts "This file should not affect the cookbooks checksum" }
74
+ end
75
+
76
+ after do
77
+ clear_tempdir
78
+ end
79
+
80
+ it "excludes ignored files from the list of cookbook files" do
81
+ expect(reader_with_ignored_files.cookbook_version.root_filenames).to_not include(chefignored_file)
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,145 @@
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/policyfile/solution_dependencies'
20
+
21
+ describe ChefDK::Policyfile::SolutionDependencies do
22
+
23
+ let(:dependency_data) { {} }
24
+
25
+ let(:solution_dependencies) do
26
+ s = described_class.new
27
+ s.consume_lock_data(dependency_data)
28
+ s
29
+ end
30
+
31
+ it "has a list of dependencies declared in the Policyfile" do
32
+ expect(solution_dependencies.policyfile_dependencies).to eq([])
33
+ end
34
+
35
+ it "has a map of dependencies declared by cookbooks" do
36
+ expect(solution_dependencies.cookbook_dependencies).to eq({})
37
+ end
38
+
39
+ context "when populated with dependency data from a lockfile" do
40
+
41
+ let(:dependency_data) do
42
+ {
43
+ "Policyfile" => [
44
+ [ "nginx", "~> 1.0"], ["postgresql", ">= 0.0.0" ]
45
+ ],
46
+ "dependencies" => {
47
+ "nginx (1.2.3)" => [ ["apt", "~> 2.3"], ["yum", "~>3.4"] ],
48
+ "apt (2.5.6)" => [],
49
+ "yum (3.4.1)" => [],
50
+ "postgresql (5.0.0)" => []
51
+ }
52
+ }
53
+ end
54
+
55
+ it "has a list of dependencies from the policyfile" do
56
+ expected = [ "nginx", "~> 1.0"], ["postgresql", ">= 0.0.0" ]
57
+ expect(solution_dependencies.policyfile_dependencies_for_lock).to eq(expected)
58
+ end
59
+
60
+ it "has a list of dependencies from cookbooks" do
61
+ expected = {
62
+ "nginx (1.2.3)" => [ ["apt", "~> 2.3"], ["yum", "~> 3.4"] ],
63
+ "apt (2.5.6)" => [],
64
+ "yum (3.4.1)" => [],
65
+ "postgresql (5.0.0)" => []
66
+ }
67
+ expect(solution_dependencies.cookbook_deps_for_lock).to eq(expected)
68
+ end
69
+
70
+ end
71
+
72
+ context "when populated with dependency data" do
73
+
74
+ let(:expected_deps_for_lock) do
75
+ {
76
+ "nginx (1.2.3)" => [ ["apt", "~> 2.3"], ["yum", "~> 3.4"] ],
77
+ "apt (2.5.6)" => [],
78
+ "yum (3.4.1)" => [],
79
+ "postgresql (5.0.0)" => []
80
+ }
81
+ end
82
+
83
+ let(:expected_policyfile_deps_for_lock) do
84
+ [ [ "nginx", "~> 1.0"], ["postgresql", ">= 0.0.0" ] ]
85
+ end
86
+
87
+ before do
88
+ solution_dependencies.add_policyfile_dep("nginx", "~> 1.0")
89
+ solution_dependencies.add_policyfile_dep("postgresql", ">= 0.0.0")
90
+ solution_dependencies.add_cookbook_dep("nginx", "1.2.3", [ ["apt", "~> 2.3"], ["yum", "~>3.4"] ])
91
+ solution_dependencies.add_cookbook_dep("apt", "2.5.6", [])
92
+ solution_dependencies.add_cookbook_dep("yum", "3.4.1", [])
93
+ solution_dependencies.add_cookbook_dep("postgresql", "5.0.0", [])
94
+ end
95
+
96
+ it "has a list of dependencies from the Policyfile" do
97
+ expect(solution_dependencies.policyfile_dependencies_for_lock).to eq(expected_policyfile_deps_for_lock)
98
+ end
99
+
100
+ it "has a list of dependencies from cookbooks" do
101
+ expect(solution_dependencies.cookbook_deps_for_lock).to eq(expected_deps_for_lock)
102
+ end
103
+
104
+ it "generates lock info containing both policyfile and cookbook dependencies" do
105
+ expected = {"Policyfile" => expected_policyfile_deps_for_lock, "dependencies" => expected_deps_for_lock}
106
+ expect(solution_dependencies.to_lock).to eq(expected)
107
+ end
108
+
109
+ describe "checking for dependency conflicts" do
110
+
111
+ it "does not raise if a cookbook that's in the dependency set with a different version doesn't conflict" do
112
+ solution_dependencies.update_cookbook_dep("yum", "3.5.0", [ ])
113
+ expect(solution_dependencies.test_conflict!('yum', '3.5.0')).to be(false)
114
+ end
115
+
116
+ it "raises if a cookbook is not in the current solution set" do
117
+ expected_message = "Cookbook foo (1.0.0) not in the working set, cannot test for conflicts"
118
+ expect { solution_dependencies.test_conflict!('foo', '1.0.0') }.to raise_error(ChefDK::CookbookNotInWorkingSet, expected_message)
119
+ end
120
+
121
+ it "raises when a cookbook conflicts with a Policyfile constraint" do
122
+ solution_dependencies.update_cookbook_dep("nginx", "2.0.0", [])
123
+
124
+ expected_message = "Cookbook nginx (2.0.0) conflicts with other dependencies:\nPolicyfile depends on nginx ~> 1.0"
125
+ expect { solution_dependencies.test_conflict!('nginx', '2.0.0') }.to raise_error(ChefDK::DependencyConflict, expected_message)
126
+ end
127
+
128
+ it "raises when a cookbook conflicts with another cookbook's dependency constraint" do
129
+ solution_dependencies.update_cookbook_dep("apt", "3.0.0", [])
130
+
131
+ expected_message = "Cookbook apt (3.0.0) conflicts with other dependencies:\nnginx (1.2.3) depends on apt ~> 2.3"
132
+ expect { solution_dependencies.test_conflict!('apt', '3.0.0') }.to raise_error(ChefDK::DependencyConflict, expected_message)
133
+ end
134
+
135
+ it "raises when a cookbook's dependencies are no longer satisfiable" do
136
+ solution_dependencies.update_cookbook_dep("nginx", "1.2.3", [ [ "apt", "~> 3.0" ] ])
137
+ expected_message = "Cookbook nginx (1.2.3) has dependency constraints that cannot be met by the existing cookbook set:\n" +
138
+ "Dependency on apt ~> 3.0 conflicts with existing version apt (2.5.6)"
139
+ expect { solution_dependencies.test_conflict!('nginx', '1.2.3') }.to raise_error(ChefDK::DependencyConflict, expected_message)
140
+ end
141
+
142
+ end
143
+ end
144
+
145
+ end