chef-dk 0.2.0 → 0.2.1

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