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,98 @@
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/storage_config'
20
+
21
+ describe ChefDK::Policyfile::StorageConfig do
22
+
23
+ let(:config_options) { {} }
24
+
25
+ let(:storage_config) do
26
+ described_class.new(config_options)
27
+ end
28
+
29
+ context "with explicit path options" do
30
+
31
+ let(:cache_path) do
32
+ File.expand_path("spec/unit/fixtures/cookbook_cache", project_root)
33
+ end
34
+
35
+ let(:relative_paths_root) do
36
+ File.expand_path("spec/unit/fixtures/", project_root)
37
+ end
38
+
39
+ let(:config_options) do
40
+ { cache_path: cache_path, relative_paths_root: relative_paths_root }
41
+ end
42
+
43
+ it "uses the provided option for relative_paths_root" do
44
+ expect(storage_config.relative_paths_root).to eq(relative_paths_root)
45
+ end
46
+
47
+ it "uses the provided cache_path" do
48
+ expect(storage_config.cache_path).to eq(cache_path)
49
+ end
50
+ end
51
+
52
+ context "with default options" do
53
+
54
+ it "defaults to the CookbookOmnifetch configured cache path" do
55
+ expect(storage_config.cache_path).to eq(CookbookOmnifetch.storage_path)
56
+ end
57
+
58
+ it "defaults to the current working directory for relative_paths_root" do
59
+ expect(storage_config.relative_paths_root).to eq(Dir.pwd)
60
+ end
61
+ end
62
+
63
+ describe "updating storage config for policyfile location" do
64
+
65
+ before do
66
+ storage_config.use_policyfile("/path/to/Policyfile.rb")
67
+ end
68
+
69
+ it "updates the relative_paths_root to be relative to a policyfile" do
70
+ expect(storage_config.relative_paths_root).to eq("/path/to")
71
+ end
72
+
73
+ it "stores the location of the policyfile" do
74
+ expect(storage_config.policyfile_filename).to eq("/path/to/Policyfile.rb")
75
+ end
76
+
77
+ end
78
+
79
+
80
+ describe "updating storage config for policyfile lock location" do
81
+
82
+ before do
83
+ storage_config.use_policyfile_lock("/path/to/Policyfile.lock.json")
84
+ end
85
+
86
+ it "updates the relative_paths_root to be relative to a policyfile" do
87
+ expect(storage_config.relative_paths_root).to eq("/path/to")
88
+ end
89
+
90
+ it "stores the location of the policyfile" do
91
+ expect(storage_config.policyfile_lock_filename).to eq("/path/to/Policyfile.lock.json")
92
+ end
93
+
94
+ end
95
+
96
+
97
+ end
98
+
@@ -0,0 +1,292 @@
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/uploader'
20
+
21
+ # We load this here to ensure we get the "verifying doubles" behavior from
22
+ # RSpec. It's not used by Policyfile::Uploader, but it's a collaborator.
23
+ require 'chef-dk/authenticated_http'
24
+
25
+ describe ChefDK::Policyfile::Uploader do
26
+
27
+ let(:policyfile_lock_data) do
28
+ {
29
+ "name"=> "example",
30
+ "run_list"=> [ "recipe[omnibus::default]" ],
31
+ "cookbook_locks"=> {
32
+ "omnibus"=> {
33
+ "version"=> "2.2.0",
34
+ "identifier"=> "64b3e64306cff223206348e46af545b19032b170",
35
+ "dotted_decimal_identifier"=> "28345299219435506.9887234981653237.76628930769264",
36
+ "cache_key"=> "omnibus-2cf98f9797cacce9c8688fc4e74858b858e2bc14",
37
+ "origin"=> "git@github.com:opscode-cookbooks/omnibus.git",
38
+ "source_options"=> {
39
+ "git"=> "git@github.com:opscode-cookbooks/omnibus.git",
40
+ "revision"=> "2cf98f9797cacce9c8688fc4e74858b858e2bc14",
41
+ "branch"=> "master"
42
+ }
43
+ }
44
+ }
45
+ }
46
+ end
47
+
48
+ let(:policyfile_lock) { instance_double("ChefDK::PolicyfileLock", name: "example",
49
+ to_lock: policyfile_lock_data) }
50
+
51
+ let(:policy_group) { "unit-test" }
52
+
53
+ let(:http_client) { instance_double("ChefDK::AuthenticatedHTTP") }
54
+
55
+ let(:uploader) { described_class.new(policyfile_lock, policy_group, http_client: http_client) }
56
+
57
+ let(:policyfile_as_data_bag_item) do
58
+
59
+ policyfile_as_data_bag_item = {
60
+ "id" => "example-unit-test",
61
+ "name" => "data_bag_item_policyfiles_example-unit-test",
62
+ "data_bag" => "policyfiles"
63
+ }
64
+ policyfile_as_data_bag_item["raw_data"] = policyfile_lock_data.dup
65
+ policyfile_as_data_bag_item["raw_data"]["id"] = "example-unit-test"
66
+ policyfile_as_data_bag_item["json_class"] = "Chef::DataBagItem"
67
+ policyfile_as_data_bag_item
68
+ end
69
+
70
+ it "has a lockfile" do
71
+ expect(uploader.policyfile_lock).to eq(policyfile_lock)
72
+ end
73
+
74
+ it "has a policy group" do
75
+ expect(uploader.policy_group).to eq(policy_group)
76
+ end
77
+
78
+ it "has an HTTP client" do
79
+ expect(uploader.http_client).to eq(http_client)
80
+ end
81
+
82
+ context "when created without an HTTP client" do
83
+
84
+ let(:http_client) { nil }
85
+
86
+ it "creates an HTTP client with default config" do
87
+ skip "TODO: determine correct behavior"
88
+ end
89
+
90
+ end
91
+
92
+
93
+ describe "creating uploading documents in compat mode" do
94
+
95
+ let(:cookbook_locks) { {} }
96
+ let(:cookbook_versions) { {} }
97
+
98
+ let(:existing_cookbook_on_remote) do
99
+ {"apt"=>
100
+ {"url"=>"http://localhost:8889/cookbooks/apt",
101
+ "versions"=>
102
+ [{"url"=>
103
+ "http://localhost:8889/cookbooks/apt/46097674477573307.43471642740453733.243606720748315",
104
+ "version"=>"46097674477573307.43471642740453733.243606720748315"}]},
105
+ "build-essential"=>
106
+ {"url"=>"http://localhost:8889/cookbooks/build-essential",
107
+ "versions"=>
108
+ [{"url"=>
109
+ "http://localhost:8889/cookbooks/build-essential/67369247788170534.26353953100055918.55660493423796",
110
+ "version"=>"67369247788170534.26353953100055918.55660493423796"}]},
111
+ "java"=>
112
+ {"url"=>"http://localhost:8889/cookbooks/java",
113
+ "versions"=>
114
+ [{"url"=>
115
+ "http://localhost:8889/cookbooks/java/5664982062912610.52588194571203830.6215746262253",
116
+ "version"=>"5664982062912610.52588194571203830.6215746262253"}]},
117
+ "jenkins"=>
118
+ {"url"=>"http://localhost:8889/cookbooks/jenkins",
119
+ "versions"=>
120
+ [{"url"=>
121
+ "http://localhost:8889/cookbooks/jenkins/69194928762630300.30177357398946006.269829039948647",
122
+ "version"=>"69194928762630300.30177357398946006.269829039948647"}]}
123
+ }
124
+ end
125
+
126
+ before do
127
+ allow(policyfile_lock).to receive(:cookbook_locks).and_return(cookbook_locks)
128
+ end
129
+
130
+ def lock_double(name, dotted_decimal_id)
131
+ cache_path = "/home/user/cache_path/#{name}"
132
+
133
+ lock = instance_double("ChefDK::Policyfile::CookbookLock",
134
+ name: name,
135
+ dotted_decimal_identifier: dotted_decimal_id,
136
+ cookbook_path: cache_path)
137
+
138
+ cookbook_version = instance_double("Chef::CookbookVersion",
139
+ name: name,
140
+ version: dotted_decimal_id)
141
+
142
+ allow(ChefDK::Policyfile::ReadCookbookForCompatModeUpload).
143
+ to receive(:load).
144
+ with(name, dotted_decimal_id, cache_path).
145
+ and_return(cookbook_version)
146
+
147
+ cookbook_versions[name] = cookbook_version
148
+ cookbook_locks[name] = lock
149
+
150
+ lock
151
+ end
152
+
153
+ it "ensures a data bag named 'policyfiles' exists" do
154
+ expect(http_client).to receive(:post).with('data', {"name" => "policyfiles"})
155
+ uploader.data_bag_create
156
+ end
157
+
158
+ it "does not error when the 'policyfiles' data bag exists" do
159
+ response = double("Net::HTTP response", code: "409")
160
+ error = Net::HTTPServerException.new("conflict", response)
161
+ expect(http_client).to receive(:post).with('data', {"name" => "policyfiles"}).and_raise(error)
162
+ expect { uploader.data_bag_create }.to_not raise_error
163
+ end
164
+
165
+ it "uploads the policyfile as a data bag item" do
166
+ response = double("Net::HTTP response", code: "404")
167
+ error = Net::HTTPServerException.new("Not Found", response)
168
+ expect(http_client).to receive(:put).
169
+ with('data/policyfiles/example-unit-test', policyfile_as_data_bag_item).
170
+ and_raise(error)
171
+ expect(http_client).to receive(:post).
172
+ with('data/policyfiles', policyfile_as_data_bag_item)
173
+
174
+ uploader.data_bag_item_create
175
+ end
176
+
177
+ it "replaces an existing policyfile on the server if it exists" do
178
+ expect(http_client).to receive(:put).
179
+ with('data/policyfiles/example-unit-test', policyfile_as_data_bag_item)
180
+
181
+ uploader.data_bag_item_create
182
+ end
183
+
184
+ it "enumerates the cookbooks already on the server" do
185
+ expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote)
186
+ expect(uploader.existing_cookbook_on_remote).to eq(existing_cookbook_on_remote)
187
+ end
188
+
189
+ context "with an empty policyfile lock" do
190
+
191
+ it "has an empty list of cookbooks for possible upload" do
192
+ expect(policyfile_lock).to receive(:validate_cookbooks!)
193
+
194
+ expect(uploader.cookbook_versions_for_policy).to eq([])
195
+ end
196
+
197
+ it "has an empty list of cookbooks that need to be uploaded" do
198
+ expect(policyfile_lock).to receive(:validate_cookbooks!)
199
+
200
+ expect(uploader.cookbook_versions_to_upload).to eq([])
201
+ end
202
+
203
+ end
204
+
205
+ context "with a set of cookbooks that don't exist on the server" do
206
+
207
+ before do
208
+ lock_double("my_apache2", "123.456.789")
209
+ lock_double("my_jenkins", "321.654.987")
210
+ end
211
+
212
+ it "lists the cookbooks in the lock as possibly needing to be uploaded" do
213
+ expect(policyfile_lock).to receive(:validate_cookbooks!)
214
+
215
+ expect(uploader.cookbook_versions_for_policy).to eq(cookbook_versions.values)
216
+ end
217
+
218
+ it "lists all cookbooks in the lock as needing to be uploaded" do
219
+ expect(policyfile_lock).to receive(:validate_cookbooks!)
220
+ expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote)
221
+
222
+ expect(uploader.cookbook_versions_to_upload).to eq(cookbook_versions.values)
223
+ end
224
+
225
+ it "uploads the cookbooks and then the policy" do
226
+ expect(policyfile_lock).to receive(:validate_cookbooks!)
227
+ expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote)
228
+
229
+ cookbook_uploader = instance_double("Chef::CookbookUploader")
230
+ expect(Chef::CookbookUploader).to receive(:new).
231
+ with(cookbook_versions.values, :rest => http_client).
232
+ and_return(cookbook_uploader)
233
+ expect(cookbook_uploader).to receive(:upload_cookbooks)
234
+
235
+ # behavior for these tested above
236
+ expect(uploader).to receive(:data_bag_create)
237
+ expect(uploader).to receive(:data_bag_item_create)
238
+
239
+ uploader.upload
240
+ end
241
+
242
+ end
243
+
244
+ context "with a set of cookbooks where some already exist on the server" do
245
+
246
+ before do
247
+ # These are new:
248
+ lock_double("my_apache2", "123.456.789")
249
+ lock_double("my_jenkins", "321.654.987")
250
+
251
+ # Have this one:
252
+ lock_double("build-essential", "67369247788170534.26353953100055918.55660493423796")
253
+ end
254
+
255
+ let(:expected_cookbooks_for_upload) do
256
+ [
257
+ cookbook_versions["my_apache2"],
258
+ cookbook_versions["my_jenkins"]
259
+ ]
260
+ end
261
+
262
+ it "lists only cookbooks not on the server as needing to be uploaded" do
263
+ expect(policyfile_lock).to receive(:validate_cookbooks!)
264
+ expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote)
265
+
266
+
267
+ expect(uploader.cookbook_versions_to_upload).to eq(expected_cookbooks_for_upload)
268
+ end
269
+
270
+ it "uploads the cookbooks and then the policy" do
271
+ expect(policyfile_lock).to receive(:validate_cookbooks!)
272
+ expect(http_client).to receive(:get).with('cookbooks?num_versions=all').and_return(existing_cookbook_on_remote)
273
+
274
+ cookbook_uploader = instance_double("Chef::CookbookUploader")
275
+ expect(Chef::CookbookUploader).to receive(:new).
276
+ with(expected_cookbooks_for_upload, :rest => http_client).
277
+ and_return(cookbook_uploader)
278
+ expect(cookbook_uploader).to receive(:upload_cookbooks)
279
+
280
+ # behavior for these tested above
281
+ expect(uploader).to receive(:data_bag_create)
282
+ expect(uploader).to receive(:data_bag_item_create)
283
+
284
+ uploader.upload
285
+ end
286
+
287
+ end
288
+
289
+ end
290
+
291
+ end
292
+
@@ -29,8 +29,6 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
29
29
  let(:policyfile) do
30
30
  policyfile = ChefDK::PolicyfileCompiler.new.build do |p|
31
31
 
32
- p.policyfile_filename = "/no-such-place/Policyfile.rb"
33
-
34
32
  p.default_source(*default_source) if default_source
35
33
  p.run_list(*run_list)
36
34
 
@@ -128,6 +126,29 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
128
126
  end
129
127
  end
130
128
 
129
+ describe "when normalizing run_list items" do
130
+
131
+ it "normalizes a bare cookbook name" do
132
+ policyfile.run_list("local-cookbook")
133
+ expect(policyfile.normalized_run_list).to eq(["recipe[local-cookbook::default]"])
134
+ end
135
+
136
+ it "normalizes a bare cookbook::recipe item" do
137
+ policyfile.run_list("local-cookbook::server")
138
+ expect(policyfile.normalized_run_list).to eq(["recipe[local-cookbook::server]"])
139
+ end
140
+
141
+ it "normalizes a recipe[] item with implicit default" do
142
+ policyfile.run_list("recipe[local-cookbook]")
143
+ expect(policyfile.normalized_run_list).to eq(["recipe[local-cookbook::default]"])
144
+ end
145
+
146
+ it "does not modify a fully qualified recipe" do
147
+ policyfile.run_list("recipe[local-cookbook::jazz_hands]")
148
+ expect(policyfile.normalized_run_list).to eq(["recipe[local-cookbook::jazz_hands]"])
149
+ end
150
+
151
+ end
131
152
 
132
153
  before do
133
154
  expect(policyfile.errors).to eq([])
@@ -149,6 +170,14 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
149
170
  expect(policyfile).to receive(:ensure_cache_dir_exists)
150
171
  expect(policyfile.graph_solution).to eq({})
151
172
  end
173
+
174
+ it "has an empty set of solution_dependencies" do
175
+ expected_solution_deps = {
176
+ "Policyfile" => [],
177
+ "dependencies" => {}
178
+ }
179
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
180
+ end
152
181
  end
153
182
 
154
183
  context "Given a run list and no local or git cookbooks" do
@@ -172,6 +201,14 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
172
201
  expect(policyfile.graph_solution).to eq({"remote-cb" => "1.1.1"})
173
202
  end
174
203
 
204
+ it "includes the cookbook in the solution dependencies" do
205
+ expected_solution_deps = {
206
+ "Policyfile" => [],
207
+ "dependencies" => { "remote-cb (1.1.1)" => [] }
208
+ }
209
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
210
+ end
211
+
175
212
  end
176
213
 
177
214
  context "And the default source is the chef-server" do
@@ -199,8 +236,9 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
199
236
 
200
237
  before do
201
238
  policyfile.dsl.cookbook('local-cookbook', path: "/foo")
202
- policyfile.cookbook_spec_for("local-cookbook").stub(:version).and_return("2.3.4")
203
- policyfile.cookbook_spec_for("local-cookbook").stub(:dependencies).and_return([])
239
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:version).and_return("2.3.4")
240
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:dependencies).and_return([])
241
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:ensure_cached).and_return(true)
204
242
  end
205
243
 
206
244
  it "demands a solution using the local cookbook" do
@@ -214,6 +252,14 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
214
252
  expect(policyfile.artifacts_graph).to eq(expected_artifacts_graph)
215
253
  end
216
254
 
255
+ it "includes the cookbook in the solution dependencies" do
256
+ expected_solution_deps = {
257
+ "Policyfile" => [ [ "local-cookbook", ">= 0.0.0" ] ],
258
+ "dependencies" => { "local-cookbook (2.3.4)" => [] }
259
+ }
260
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
261
+ end
262
+
217
263
  end
218
264
 
219
265
  context "Given a local cookbook with a dependency and only the local cookbook in the run list" do
@@ -226,9 +272,9 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
226
272
 
227
273
  before do
228
274
  policyfile.dsl.cookbook("local-cookbook", path: "foo/")
229
- policyfile.cookbook_spec_for("local-cookbook").stub(:ensure_cached)
230
- policyfile.cookbook_spec_for("local-cookbook").stub(:version).and_return("2.3.4")
231
- policyfile.cookbook_spec_for("local-cookbook").stub(:dependencies).and_return([ [ "local-cookbook-dep-one", "~> 1.0"] ])
275
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:ensure_cached)
276
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:version).and_return("2.3.4")
277
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:dependencies).and_return([ [ "local-cookbook-dep-one", "~> 1.0"] ])
232
278
  end
233
279
 
234
280
  it "demands a solution using the local cookbook" do
@@ -248,6 +294,18 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
248
294
  expect(policyfile.graph_solution).to eq({"local-cookbook" => "2.3.4", "local-cookbook-dep-one" => "1.5.0"})
249
295
  end
250
296
 
297
+ it "includes the cookbook and dependencies in the solution dependencies" do
298
+ expected_solution_deps = {
299
+ "Policyfile" => [ [ "local-cookbook", ">= 0.0.0" ] ],
300
+ "dependencies" => {
301
+ "local-cookbook (2.3.4)" => [[ "local-cookbook-dep-one", "~> 1.0"]],
302
+ "local-cookbook-dep-one (1.5.0)" => []
303
+ }
304
+
305
+ }
306
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
307
+ end
308
+
251
309
  end
252
310
  context "And the default source is the chef server" do
253
311
 
@@ -255,9 +313,9 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
255
313
 
256
314
  before do
257
315
  policyfile.dsl.cookbook("local-cookbook", path: "foo/")
258
- policyfile.cookbook_spec_for("local-cookbook").stub(:ensure_cached)
259
- policyfile.cookbook_spec_for("local-cookbook").stub(:version).and_return("2.3.4")
260
- policyfile.cookbook_spec_for("local-cookbook").stub(:dependencies).and_return([ [ "local-cookbook-dep-one", "~> 1.0"] ])
316
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:ensure_cached)
317
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:version).and_return("2.3.4")
318
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:dependencies).and_return([ [ "local-cookbook-dep-one", "~> 1.0"] ])
261
319
  end
262
320
 
263
321
  it "demands a solution using the local cookbook" do
@@ -280,6 +338,18 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
280
338
  expect(policyfile.graph_solution).to eq({"local-cookbook" => "2.3.4", "local-cookbook-dep-one" => "1.6.0"})
281
339
  end
282
340
 
341
+ it "includes the cookbook and dependencies in the solution dependencies" do
342
+ expected_solution_deps = {
343
+ "Policyfile" => [ [ "local-cookbook", ">= 0.0.0" ] ],
344
+ "dependencies" => {
345
+ "local-cookbook (2.3.4)" => [[ "local-cookbook-dep-one", "~> 1.0"]],
346
+ "local-cookbook-dep-one (1.6.0)" => []
347
+ }
348
+
349
+ }
350
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
351
+ end
352
+
283
353
  end
284
354
  end
285
355
 
@@ -289,9 +359,9 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
289
359
 
290
360
  before do
291
361
  policyfile.dsl.cookbook("git-sourced-cookbook", git: "git://git.example.org:user/a-cookbook.git")
292
- policyfile.cookbook_spec_for("git-sourced-cookbook").stub(:ensure_cached)
293
- policyfile.cookbook_spec_for("git-sourced-cookbook").stub(:version).and_return("8.6.7")
294
- policyfile.cookbook_spec_for("git-sourced-cookbook").stub(:dependencies).and_return([ ])
362
+ allow(policyfile.cookbook_location_spec_for("git-sourced-cookbook")).to receive(:ensure_cached)
363
+ allow(policyfile.cookbook_location_spec_for("git-sourced-cookbook")).to receive(:version).and_return("8.6.7")
364
+ allow(policyfile.cookbook_location_spec_for("git-sourced-cookbook")).to receive(:dependencies).and_return([ ])
295
365
  end
296
366
 
297
367
  it "demands a solution using the git sourced cookbook" do
@@ -309,6 +379,18 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
309
379
  expect(policyfile).to receive(:ensure_cache_dir_exists)
310
380
  expect(policyfile.graph_solution).to eq({"git-sourced-cookbook" => "8.6.7"})
311
381
  end
382
+
383
+ it "includes the cookbook and dependencies in the solution dependencies" do
384
+ expected_solution_deps = {
385
+ "Policyfile" => [ [ "git-sourced-cookbook", ">= 0.0.0" ] ],
386
+ "dependencies" => {
387
+ "git-sourced-cookbook (8.6.7)" => []
388
+ }
389
+
390
+ }
391
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
392
+ end
393
+
312
394
  end
313
395
 
314
396
  context "Given a git-sourced cookbook with a dependency and only the git cookbook in the run list" do
@@ -317,9 +399,9 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
317
399
 
318
400
  before do
319
401
  policyfile.dsl.cookbook("git-sourced-cookbook", git: "git://git.example.org:user/a-cookbook.git")
320
- policyfile.cookbook_spec_for("git-sourced-cookbook").stub(:ensure_cached)
321
- policyfile.cookbook_spec_for("git-sourced-cookbook").stub(:version).and_return("8.6.7")
322
- policyfile.cookbook_spec_for("git-sourced-cookbook").stub(:dependencies).and_return([ ["git-sourced-cookbook-dep", "~> 2.2" ] ])
402
+ allow(policyfile.cookbook_location_spec_for("git-sourced-cookbook")).to receive(:ensure_cached)
403
+ allow(policyfile.cookbook_location_spec_for("git-sourced-cookbook")).to receive(:version).and_return("8.6.7")
404
+ allow(policyfile.cookbook_location_spec_for("git-sourced-cookbook")).to receive(:dependencies).and_return([ ["git-sourced-cookbook-dep", "~> 2.2" ] ])
323
405
  end
324
406
 
325
407
  context "And the default source is the community site" do
@@ -342,6 +424,19 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
342
424
  expect(policyfile).to receive(:ensure_cache_dir_exists)
343
425
  expect(policyfile.graph_solution).to eq({"git-sourced-cookbook" => "8.6.7", "git-sourced-cookbook-dep" => "2.8.0"})
344
426
  end
427
+
428
+ it "includes the cookbook and dependencies in the solution dependencies" do
429
+ expected_solution_deps = {
430
+ "Policyfile" => [ [ "git-sourced-cookbook", ">= 0.0.0" ] ],
431
+ "dependencies" => {
432
+ "git-sourced-cookbook (8.6.7)" => [ [ "git-sourced-cookbook-dep", "~> 2.2" ] ],
433
+ "git-sourced-cookbook-dep (2.8.0)" => []
434
+ }
435
+
436
+ }
437
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
438
+ end
439
+
345
440
  end
346
441
 
347
442
  context "And the default source is the chef server" do
@@ -364,6 +459,19 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
364
459
  expect(policyfile).to receive(:ensure_cache_dir_exists)
365
460
  expect(policyfile.graph_solution).to eq({"git-sourced-cookbook" => "8.6.7", "git-sourced-cookbook-dep" => "2.9.0"})
366
461
  end
462
+
463
+ it "includes the cookbook and dependencies in the solution dependencies" do
464
+ expected_solution_deps = {
465
+ "Policyfile" => [ [ "git-sourced-cookbook", ">= 0.0.0" ] ],
466
+ "dependencies" => {
467
+ "git-sourced-cookbook (8.6.7)" => [ [ "git-sourced-cookbook-dep", "~> 2.2" ] ],
468
+ "git-sourced-cookbook-dep (2.9.0)" => []
469
+ }
470
+
471
+ }
472
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
473
+ end
474
+
367
475
  end
368
476
  end
369
477
 
@@ -373,9 +481,9 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
373
481
 
374
482
  before do
375
483
  policyfile.dsl.cookbook("local-cookbook", path: "foo/")
376
- policyfile.cookbook_spec_for("local-cookbook").stub(:ensure_cached)
377
- policyfile.cookbook_spec_for("local-cookbook").stub(:version).and_return("2.3.4")
378
- policyfile.cookbook_spec_for("local-cookbook").stub(:dependencies).and_return([])
484
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:ensure_cached)
485
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:version).and_return("2.3.4")
486
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:dependencies).and_return([])
379
487
  end
380
488
 
381
489
  context "And the default source is the community site" do
@@ -397,6 +505,18 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
397
505
  expect(policyfile.graph_solution).to eq({"local-cookbook" => "2.3.4", "remote-cb" => "1.1.1"})
398
506
  end
399
507
 
508
+ it "includes the cookbook and dependencies in the solution dependencies" do
509
+ expected_solution_deps = {
510
+ "Policyfile" => [ [ "local-cookbook", ">= 0.0.0" ] ],
511
+ "dependencies" => {
512
+ "local-cookbook (2.3.4)" => [],
513
+ "remote-cb (1.1.1)" => []
514
+ }
515
+
516
+ }
517
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
518
+ end
519
+
400
520
  end
401
521
 
402
522
  context "And the default source is the chef server" do
@@ -418,6 +538,18 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
418
538
  expect(policyfile.graph_solution).to eq({"local-cookbook" => "2.3.4", "remote-cb" => "1.1.1"})
419
539
  end
420
540
 
541
+ it "includes the cookbook and dependencies in the solution dependencies" do
542
+ expected_solution_deps = {
543
+ "Policyfile" => [ [ "local-cookbook", ">= 0.0.0" ] ],
544
+ "dependencies" => {
545
+ "local-cookbook (2.3.4)" => [],
546
+ "remote-cb (1.1.1)" => []
547
+ }
548
+
549
+ }
550
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
551
+ end
552
+
421
553
  end
422
554
  end
423
555
 
@@ -440,6 +572,16 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
440
572
  expect(policyfile.graph_solution).to eq({"remote-cb" => "0.1.0"})
441
573
  end
442
574
 
575
+ it "includes the policyfile constraint in the solution dependencies" do
576
+ expected_solution_deps = {
577
+ "Policyfile" => [ [ "remote-cb", "~> 0.1" ] ],
578
+ "dependencies" => {
579
+ "remote-cb (0.1.0)" => []
580
+ }
581
+
582
+ }
583
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
584
+ end
443
585
  end
444
586
 
445
587
  context "given a cookbook that isn't in the run list is specified with a version constraint in the policyfile" do
@@ -453,9 +595,9 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
453
595
 
454
596
  policyfile.dsl.cookbook("local-cookbook", path: "foo/")
455
597
 
456
- policyfile.cookbook_spec_for("local-cookbook").stub(:ensure_cached)
457
- policyfile.cookbook_spec_for("local-cookbook").stub(:version).and_return("2.3.4")
458
- policyfile.cookbook_spec_for("local-cookbook").stub(:dependencies).and_return([])
598
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:ensure_cached)
599
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:version).and_return("2.3.4")
600
+ allow(policyfile.cookbook_location_spec_for("local-cookbook")).to receive(:dependencies).and_return([])
459
601
  end
460
602
 
461
603
  it "demands a solution that matches the version constraint in the policyfile" do
@@ -468,16 +610,27 @@ describe ChefDK::PolicyfileCompiler, "when expressing the Policyfile graph deman
468
610
  end
469
611
 
470
612
  it "builds a policyfile lock from the constraints" do
471
- pending
613
+ skip
472
614
  expect(policyfile).to receive(:cache_path).and_return(Pathname.new("~/.nopenope/cache"))
473
615
  expect(policyfile.lock).to eq(:wat)
474
616
  end
475
617
 
618
+ it "includes the policyfile constraint in the solution dependencies" do
619
+ expected_solution_deps = {
620
+ "Policyfile" => [ [ "remote-cb", "~> 0.1" ], [ "local-cookbook", ">= 0.0.0"] ],
621
+ "dependencies" => {
622
+ "local-cookbook (2.3.4)" => [],
623
+ "remote-cb (0.1.0)" => []
624
+ }
625
+
626
+ }
627
+ expect(policyfile.solution_dependencies.to_lock).to eq(expected_solution_deps)
628
+ end
476
629
  end
477
630
 
478
631
  context "Given a run_list with roles" do
479
632
  it "expands the roles from the given role source" do
480
- pending
633
+ skip
481
634
  end
482
635
  end
483
636