chef-dk 0.13.21 → 0.14.25

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 (336) hide show
  1. checksums.yaml +4 -4
  2. data/CONTRIBUTING.md +186 -186
  3. data/Gemfile +37 -14
  4. data/Gemfile.lock +178 -72
  5. data/LICENSE +201 -201
  6. data/README.md +11 -148
  7. data/acceptance/.shared/kitchen_acceptance/.kitchen.digitalocean.yml +27 -27
  8. data/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +288 -288
  9. data/acceptance/.shared/kitchen_acceptance/.kitchen.vagrant.yml +52 -52
  10. data/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb +51 -51
  11. data/acceptance/.shared/kitchen_acceptance/metadata.rb +1 -1
  12. data/acceptance/Gemfile +2 -1
  13. data/acceptance/Gemfile.lock +39 -42
  14. data/acceptance/README.md +132 -132
  15. data/acceptance/trivial/.acceptance/acceptance-cookbook/.gitignore +2 -2
  16. data/acceptance/trivial/.acceptance/acceptance-cookbook/metadata.rb +2 -2
  17. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/destroy.rb +1 -1
  18. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/provision.rb +1 -1
  19. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/verify.rb +1 -1
  20. data/acceptance/trivial/.kitchen.yml +7 -7
  21. data/acceptance/trivial/test/integration/chefdk-current-install/inspec/chef_client_spec.rb +5 -5
  22. data/bin/chef +25 -25
  23. data/lib/chef-dk.rb +19 -19
  24. data/lib/chef-dk/authenticated_http.rb +40 -40
  25. data/lib/chef-dk/chef_runner.rb +107 -107
  26. data/lib/chef-dk/cli.rb +200 -200
  27. data/lib/chef-dk/command/base.rb +79 -79
  28. data/lib/chef-dk/command/clean_policy_cookbooks.rb +116 -116
  29. data/lib/chef-dk/command/clean_policy_revisions.rb +113 -113
  30. data/lib/chef-dk/command/delete_policy.rb +122 -122
  31. data/lib/chef-dk/command/delete_policy_group.rb +122 -122
  32. data/lib/chef-dk/command/diff.rb +316 -316
  33. data/lib/chef-dk/command/env.rb +90 -90
  34. data/lib/chef-dk/command/exec.rb +45 -45
  35. data/lib/chef-dk/command/export.rb +157 -157
  36. data/lib/chef-dk/command/gem.rb +47 -47
  37. data/lib/chef-dk/command/generate.rb +120 -120
  38. data/lib/chef-dk/command/generator_commands.rb +83 -80
  39. data/lib/chef-dk/command/generator_commands/app.rb +107 -107
  40. data/lib/chef-dk/command/generator_commands/attribute.rb +37 -37
  41. data/lib/chef-dk/command/generator_commands/base.rb +148 -148
  42. data/lib/chef-dk/command/generator_commands/cookbook.rb +153 -153
  43. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
  44. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
  45. data/lib/chef-dk/command/generator_commands/generator_generator.rb +177 -177
  46. data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -36
  47. data/lib/chef-dk/command/generator_commands/policyfile.rb +127 -127
  48. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
  49. data/lib/chef-dk/command/generator_commands/repo.rb +125 -125
  50. data/lib/chef-dk/command/generator_commands/template.rb +46 -46
  51. data/lib/chef-dk/command/install.rb +121 -121
  52. data/lib/chef-dk/command/provision.rb +438 -438
  53. data/lib/chef-dk/command/push.rb +118 -118
  54. data/lib/chef-dk/command/push_archive.rb +126 -126
  55. data/lib/chef-dk/command/shell_init.rb +180 -180
  56. data/lib/chef-dk/command/show_policy.rb +165 -165
  57. data/lib/chef-dk/command/undelete.rb +155 -155
  58. data/lib/chef-dk/command/update.rb +148 -148
  59. data/lib/chef-dk/command/verify.rb +106 -29
  60. data/lib/chef-dk/completions/bash.sh.erb +5 -5
  61. data/lib/chef-dk/completions/chef.fish.erb +10 -10
  62. data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
  63. data/lib/chef-dk/component_test.rb +30 -1
  64. data/lib/chef-dk/configurable.rb +69 -69
  65. data/lib/chef-dk/cookbook_metadata.rb +45 -45
  66. data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
  67. data/lib/chef-dk/cookbook_profiler/git.rb +151 -151
  68. data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
  69. data/lib/chef-dk/cookbook_profiler/null_scm.rb +32 -32
  70. data/lib/chef-dk/exceptions.rb +129 -129
  71. data/lib/chef-dk/generator.rb +163 -163
  72. data/lib/chef-dk/helpers.rb +159 -159
  73. data/lib/chef-dk/pager.rb +106 -106
  74. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +138 -138
  75. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +54 -54
  76. data/lib/chef-dk/policyfile/community_cookbook_source.rb +97 -97
  77. data/lib/chef-dk/policyfile/comparison_base.rb +124 -124
  78. data/lib/chef-dk/policyfile/cookbook_location_specification.rb +154 -154
  79. data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
  80. data/lib/chef-dk/policyfile/cookbook_sources.rb +22 -22
  81. data/lib/chef-dk/policyfile/delivery_supermarket_source.rb +90 -90
  82. data/lib/chef-dk/policyfile/differ.rb +266 -266
  83. data/lib/chef-dk/policyfile/dsl.rb +261 -261
  84. data/lib/chef-dk/policyfile/lister.rb +232 -232
  85. data/lib/chef-dk/policyfile/null_cookbook_source.rb +45 -45
  86. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
  87. data/lib/chef-dk/policyfile/reports/install.rb +70 -70
  88. data/lib/chef-dk/policyfile/reports/table_printer.rb +58 -58
  89. data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
  90. data/lib/chef-dk/policyfile/solution_dependencies.rb +298 -298
  91. data/lib/chef-dk/policyfile/storage_config.rb +100 -100
  92. data/lib/chef-dk/policyfile/undo_record.rb +142 -142
  93. data/lib/chef-dk/policyfile/undo_stack.rb +130 -130
  94. data/lib/chef-dk/policyfile/uploader.rb +213 -213
  95. data/lib/chef-dk/policyfile_compiler.rb +419 -419
  96. data/lib/chef-dk/policyfile_lock.rb +552 -552
  97. data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
  98. data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +125 -125
  99. data/lib/chef-dk/policyfile_services/export_repo.rb +421 -421
  100. data/lib/chef-dk/policyfile_services/install.rb +126 -126
  101. data/lib/chef-dk/policyfile_services/push.rb +114 -114
  102. data/lib/chef-dk/policyfile_services/push_archive.rb +204 -204
  103. data/lib/chef-dk/policyfile_services/rm_policy.rb +142 -142
  104. data/lib/chef-dk/policyfile_services/rm_policy_group.rb +86 -86
  105. data/lib/chef-dk/policyfile_services/show_policy.rb +237 -237
  106. data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
  107. data/lib/chef-dk/policyfile_services/update_attributes.rb +104 -104
  108. data/lib/chef-dk/service_exception_inspectors.rb +25 -25
  109. data/lib/chef-dk/service_exception_inspectors/base.rb +40 -40
  110. data/lib/chef-dk/service_exception_inspectors/http.rb +121 -121
  111. data/lib/chef-dk/service_exceptions.rb +143 -143
  112. data/lib/chef-dk/shell_out.rb +36 -36
  113. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +3 -3
  114. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +102 -102
  115. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
  116. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +54 -54
  117. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +16 -16
  118. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +28 -28
  119. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -27
  120. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +7 -7
  121. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +3 -3
  122. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +8 -8
  123. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +58 -58
  124. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
  125. data/lib/chef-dk/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -6
  126. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
  127. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
  128. data/lib/chef-dk/skeletons/code_generator/files/default/repo/policies/README.md +24 -24
  129. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +9 -9
  130. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
  131. data/lib/chef-dk/skeletons/code_generator/files/default/serverspec_spec_helper.rb +8 -8
  132. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +2 -2
  133. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper_policyfile.rb +2 -2
  134. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
  135. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +97 -97
  136. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +12 -12
  137. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +117 -117
  138. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +24 -24
  139. data/lib/chef-dk/skeletons/code_generator/recipes/lwrp.rb +23 -23
  140. data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +8 -8
  141. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +27 -27
  142. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +67 -67
  143. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -32
  144. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -3
  145. data/lib/chef-dk/skeletons/code_generator/templates/default/{LICENSE.apache2.erb → LICENSE.apachev2.erb} +201 -201
  146. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -339
  147. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
  148. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
  149. data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -25
  150. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
  151. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +21 -21
  152. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +32 -32
  153. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +7 -7
  154. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -5
  155. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +20 -20
  156. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +11 -11
  157. data/lib/chef-dk/skeletons/code_generator/templates/default/serverspec_default_spec.rb.erb +9 -9
  158. data/lib/chef-dk/ui.rb +58 -58
  159. data/lib/chef-dk/version.rb +1 -1
  160. data/lib/kitchen/provisioner/policyfile_zero.rb +195 -195
  161. data/omnibus_overrides.rb +19 -11
  162. data/spec/shared/a_file_generator.rb +125 -125
  163. data/spec/shared/a_generated_file.rb +12 -12
  164. data/spec/shared/command_with_ui_object.rb +11 -11
  165. data/spec/shared/custom_generator_cookbook.rb +130 -130
  166. data/spec/shared/fixture_cookbook_checksums.rb +47 -47
  167. data/spec/shared/setup_git_cookbooks.rb +53 -53
  168. data/spec/spec_helper.rb +51 -51
  169. data/spec/test_helpers.rb +84 -84
  170. data/spec/unit/chef_runner_spec.rb +139 -139
  171. data/spec/unit/cli_spec.rb +357 -357
  172. data/spec/unit/command/base_spec.rb +173 -169
  173. data/spec/unit/command/clean_policy_cookbooks_spec.rb +181 -181
  174. data/spec/unit/command/clean_policy_revisions_spec.rb +181 -181
  175. data/spec/unit/command/delete_policy_group_spec.rb +207 -207
  176. data/spec/unit/command/delete_policy_spec.rb +207 -207
  177. data/spec/unit/command/diff_spec.rb +312 -312
  178. data/spec/unit/command/env_spec.rb +52 -52
  179. data/spec/unit/command/exec_spec.rb +179 -179
  180. data/spec/unit/command/export_spec.rb +200 -200
  181. data/spec/unit/command/generate_spec.rb +142 -142
  182. data/spec/unit/command/generator_commands/app_spec.rb +169 -169
  183. data/spec/unit/command/generator_commands/attribute_spec.rb +32 -32
  184. data/spec/unit/command/generator_commands/base_spec.rb +136 -136
  185. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -32
  186. data/spec/unit/command/generator_commands/cookbook_spec.rb +450 -450
  187. data/spec/unit/command/generator_commands/generator_generator_spec.rb +229 -229
  188. data/spec/unit/command/generator_commands/lwrp_spec.rb +32 -32
  189. data/spec/unit/command/generator_commands/policyfile_spec.rb +225 -225
  190. data/spec/unit/command/generator_commands/recipe_spec.rb +34 -34
  191. data/spec/unit/command/generator_commands/repo_spec.rb +374 -367
  192. data/spec/unit/command/generator_commands/template_spec.rb +32 -32
  193. data/spec/unit/command/install_spec.rb +179 -179
  194. data/spec/unit/command/provision_spec.rb +592 -592
  195. data/spec/unit/command/push_archive_spec.rb +153 -153
  196. data/spec/unit/command/push_spec.rb +199 -199
  197. data/spec/unit/command/shell_init_spec.rb +329 -329
  198. data/spec/unit/command/show_policy_spec.rb +235 -235
  199. data/spec/unit/command/undelete_spec.rb +246 -246
  200. data/spec/unit/command/update_spec.rb +275 -275
  201. data/spec/unit/command/verify_spec.rb +15 -6
  202. data/spec/unit/commands_map_spec.rb +57 -57
  203. data/spec/unit/component_test_spec.rb +128 -126
  204. data/spec/unit/configurable_spec.rb +41 -41
  205. data/spec/unit/cookbook_metadata_spec.rb +98 -98
  206. data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
  207. data/spec/unit/cookbook_profiler/identifiers_spec.rb +83 -83
  208. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
  209. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
  210. data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
  211. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
  212. data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -5
  213. data/spec/unit/fixtures/configurable/test_configurable.rb +10 -10
  214. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  215. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
  216. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  217. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
  218. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  219. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  220. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
  221. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
  222. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
  223. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
  224. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
  225. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
  226. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
  227. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
  228. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
  229. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
  230. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
  231. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
  232. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
  233. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
  234. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
  235. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +36 -36
  236. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
  237. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
  238. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
  239. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
  240. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
  241. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
  242. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
  243. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
  244. data/spec/unit/fixtures/example_cookbook/README.md +4 -4
  245. data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
  246. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
  247. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
  248. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
  249. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
  250. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
  251. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
  252. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
  253. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
  254. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
  255. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
  256. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
  257. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
  258. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
  259. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
  260. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
  261. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
  262. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
  263. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
  264. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
  265. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
  266. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
  267. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
  268. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
  269. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
  270. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
  271. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
  272. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
  273. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
  274. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
  275. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
  276. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
  277. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  278. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  279. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  280. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  281. data/spec/unit/generator_spec.rb +119 -120
  282. data/spec/unit/helpers_spec.rb +92 -92
  283. data/spec/unit/pager_spec.rb +119 -119
  284. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -93
  285. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +34 -34
  286. data/spec/unit/policyfile/community_cookbook_source_spec.rb +84 -84
  287. data/spec/unit/policyfile/comparison_base_spec.rb +343 -343
  288. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +277 -277
  289. data/spec/unit/policyfile/cookbook_locks_spec.rb +529 -529
  290. data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +130 -130
  291. data/spec/unit/policyfile/differ_spec.rb +687 -687
  292. data/spec/unit/policyfile/lister_spec.rb +272 -272
  293. data/spec/unit/policyfile/null_cookbook_source_spec.rb +35 -35
  294. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
  295. data/spec/unit/policyfile/reports/install_spec.rb +115 -115
  296. data/spec/unit/policyfile/reports/upload_spec.rb +96 -96
  297. data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -145
  298. data/spec/unit/policyfile/storage_config_spec.rb +172 -172
  299. data/spec/unit/policyfile/undo_record_spec.rb +260 -260
  300. data/spec/unit/policyfile/undo_stack_spec.rb +266 -266
  301. data/spec/unit/policyfile/uploader_spec.rb +410 -410
  302. data/spec/unit/policyfile_demands_spec.rb +1203 -1203
  303. data/spec/unit/policyfile_evaluation_spec.rb +642 -642
  304. data/spec/unit/policyfile_lock_build_spec.rb +1056 -1056
  305. data/spec/unit/policyfile_lock_install_spec.rb +138 -138
  306. data/spec/unit/policyfile_lock_serialization_spec.rb +425 -425
  307. data/spec/unit/policyfile_lock_validation_spec.rb +611 -611
  308. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
  309. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +275 -275
  310. data/spec/unit/policyfile_services/export_repo_spec.rb +481 -481
  311. data/spec/unit/policyfile_services/install_spec.rb +211 -211
  312. data/spec/unit/policyfile_services/push_archive_spec.rb +378 -378
  313. data/spec/unit/policyfile_services/push_spec.rb +233 -233
  314. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +241 -241
  315. data/spec/unit/policyfile_services/rm_policy_spec.rb +266 -266
  316. data/spec/unit/policyfile_services/show_policy_spec.rb +889 -889
  317. data/spec/unit/policyfile_services/undelete_spec.rb +304 -304
  318. data/spec/unit/policyfile_services/update_attributes_spec.rb +217 -217
  319. data/spec/unit/service_exception_inspectors/base_spec.rb +43 -43
  320. data/spec/unit/service_exception_inspectors/http_spec.rb +140 -140
  321. data/spec/unit/shell_out_spec.rb +34 -34
  322. data/spec/unit/tasks/helpers_spec.rb +75 -0
  323. data/tasks/bin/bundle-platform +0 -0
  324. data/tasks/bin/bundle-platform.bat +0 -0
  325. data/tasks/bin/create-override-gemfile +110 -0
  326. data/tasks/bundle.rb +27 -11
  327. data/tasks/bundle_util.rb +6 -5
  328. data/tasks/dependencies.rb +97 -122
  329. data/tasks/gemfile_util.rb +357 -66
  330. data/tasks/helpers.rb +47 -0
  331. data/tasks/version.rb +1 -5
  332. data/version_policy.rb +66 -41
  333. data/warning.txt +9 -9
  334. metadata +7 -5
  335. data/Gemfile.windows +0 -34
  336. data/Gemfile.windows.lock +0 -936
@@ -1,1056 +1,1056 @@
1
- # -*- coding: UTF-8 -*-
2
- #
3
- # Copyright:: Copyright (c) 2014 Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require 'spec_helper'
20
- require 'shared/setup_git_cookbooks'
21
- require 'shared/fixture_cookbook_checksums'
22
- require 'chef-dk/policyfile/storage_config'
23
- require 'chef-dk/policyfile_lock.rb'
24
-
25
- describe ChefDK::PolicyfileLock, "building a lockfile" do
26
-
27
- include_context "fixture cookbooks checksums"
28
-
29
- # For debugging giant nested hashes...
30
- def expect_hash_equal(actual, expected)
31
- expected.each do |key, expected_value|
32
- expect(actual).to have_key(key)
33
- if expected_value.kind_of?(Hash)
34
- expect_hash_equal(actual[key], expected_value)
35
- else
36
- expect(actual[key]).to eq(expected_value)
37
- end
38
- end
39
- expect(actual).to eq(expected)
40
- end
41
-
42
- let(:cache_path) do
43
- File.expand_path("spec/unit/fixtures/cookbook_cache", project_root)
44
- end
45
-
46
- let(:relative_paths_root) do
47
- File.expand_path("spec/unit/fixtures/", project_root)
48
- end
49
-
50
- let(:storage_config) do
51
- ChefDK::Policyfile::StorageConfig.new( cache_path: cache_path, relative_paths_root: relative_paths_root )
52
- end
53
-
54
- context "when a cached cookbook omits the cache key" do
55
-
56
- let(:policyfile_lock) do
57
- ChefDK::PolicyfileLock.build(storage_config) do |p|
58
-
59
- p.name = "invalid_cache_key_policyfile"
60
-
61
- p.run_list = [ "recipe[foo]" ]
62
-
63
- p.cached_cookbook("nosuchthing") do |cb|
64
- end
65
- end
66
- end
67
-
68
- it "raises a descriptive error" do
69
- expect { policyfile_lock.to_lock }.to raise_error(ChefDK::CachedCookbookNotFound)
70
- end
71
-
72
- end
73
-
74
- context "when a local cookbook omits the path" do
75
-
76
- let(:policyfile_lock) do
77
- ChefDK::PolicyfileLock.build(storage_config) do |p|
78
-
79
- p.name = "invalid_local_cookbook"
80
-
81
- p.run_list = [ "recipe[foo]" ]
82
-
83
- p.local_cookbook("nosuchthing") do |cb|
84
- end
85
- end
86
- end
87
-
88
- it "raises a descriptive error" do
89
- expect { policyfile_lock.to_lock }.to raise_error(ChefDK::LocalCookbookNotFound)
90
- end
91
- end
92
-
93
- context "when a local cookbook has an incorrect path" do
94
-
95
- let(:policyfile_lock) do
96
- ChefDK::PolicyfileLock.build(storage_config) do |p|
97
-
98
- p.name = "invalid_local_cookbook"
99
-
100
- p.run_list = [ "recipe[foo]" ]
101
-
102
- p.local_cookbook("nosuchthing") do |cb|
103
- cb.source = "nopenopenope"
104
- end
105
- end
106
- end
107
-
108
- it "raises a descriptive error" do
109
- expect { policyfile_lock.to_lock }.to raise_error(ChefDK::LocalCookbookNotFound)
110
- end
111
- end
112
-
113
- context "when a cookbook is not in the cache" do
114
-
115
- let(:policyfile_lock) do
116
- ChefDK::PolicyfileLock.build(storage_config) do |p|
117
-
118
- p.name = "invalid_cache_key_policyfile"
119
-
120
- p.run_list = [ "recipe[foo]" ]
121
-
122
- p.cached_cookbook("nosuchthing") do |cb|
123
- cb.cache_key = "nosuchthing-1.0.0"
124
- end
125
- end
126
- end
127
-
128
- it "raises a descriptive error" do
129
- expect { policyfile_lock.to_lock }.to raise_error(ChefDK::CachedCookbookNotFound)
130
- end
131
-
132
- end
133
-
134
- describe "policyfiles with invalid attributes" do
135
-
136
- let(:policyfile_lock) do
137
- ChefDK::PolicyfileLock.build(storage_config) do |p|
138
-
139
- p.name = "invalid_cache_key_policyfile"
140
-
141
- p.run_list = [ "recipe[foo]" ]
142
-
143
- p.cached_cookbook("foo") do |cb|
144
- cb.cache_key = "foo-1.0.0"
145
- end
146
-
147
- p.default_attributes = default_attributes
148
- end
149
- end
150
-
151
- context "invalid floats - infinity" do
152
-
153
- let(:default_attributes) { {"infinity" => Float::INFINITY} }
154
-
155
- it "raises a descriptive error" do
156
- expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
157
- end
158
- end
159
-
160
- context "invalid floats - nan" do
161
-
162
- let(:default_attributes) { {"infinity" => Float::NAN} }
163
-
164
- it "raises a descriptive error" do
165
- expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
166
- end
167
- end
168
-
169
- context "non-string hash/object keys" do
170
-
171
- let(:default_attributes) { {1906 => "lol nope"} }
172
-
173
- it "raises a descriptive error" do
174
- expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
175
- end
176
- end
177
-
178
- context "values that are not Hash/Array/String/Float/Integer/true/false/nil" do
179
-
180
- let(:default_attributes) { { "raw object" => Object.new } }
181
-
182
- it "raises a descriptive error" do
183
- expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
184
- end
185
- end
186
-
187
- end
188
-
189
- context "with a minimal policyfile" do
190
-
191
- let(:policyfile_lock) do
192
- ChefDK::PolicyfileLock.build(storage_config) do |p|
193
-
194
- p.name = "minimal_policyfile"
195
-
196
- p.run_list = [ "recipe[foo]" ]
197
- p.cached_cookbook("foo") do |cb|
198
- cb.cache_key = "foo-1.0.0"
199
- end
200
-
201
- end
202
- end
203
-
204
- let(:expected_canonical_revision_string) do
205
- <<-REVISION_STRING
206
- name:minimal_policyfile
207
- run-list-item:recipe[foo]
208
- cookbook:foo;id:467dc855408ce8b74f991c5dc2fd72a6aa369b60
209
- default_attributes:{}
210
- override_attributes:{}
211
- REVISION_STRING
212
- end
213
-
214
- let(:expected_revision_id) do
215
- Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
216
- end
217
-
218
- let(:compiled_policyfile) do
219
- {
220
- "revision_id" => expected_revision_id,
221
-
222
- "name" => "minimal_policyfile",
223
-
224
- "run_list" => ["recipe[foo]"],
225
-
226
- "cookbook_locks" => {
227
-
228
- "foo" => {
229
- "version" => "1.0.0",
230
- "identifier" => cookbook_foo_cksum,
231
- "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
232
- "cache_key" => "foo-1.0.0",
233
- "origin" => nil,
234
- "source_options" => nil
235
- },
236
- },
237
- "default_attributes" => {},
238
- "override_attributes" => {},
239
-
240
- "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
241
- }
242
- end
243
-
244
- it "has a cache path" do
245
- expect(policyfile_lock.cache_path).to eq(cache_path)
246
- end
247
-
248
- it "computes a minimal policyfile" do
249
- expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
250
- end
251
-
252
- it "generates a canonical revision string" do
253
- expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
254
- end
255
-
256
- it "generates a revision id" do
257
- expect(policyfile_lock.revision_id).to eq(expected_revision_id)
258
- end
259
-
260
- end
261
-
262
- context "with a policyfile containing attributes" do
263
-
264
- let(:policyfile_lock) do
265
- ChefDK::PolicyfileLock.build(storage_config) do |p|
266
-
267
- p.name = "minimal_policyfile"
268
-
269
- p.run_list = [ "recipe[foo]" ]
270
- p.cached_cookbook("foo") do |cb|
271
- cb.cache_key = "foo-1.0.0"
272
- end
273
-
274
- p.default_attributes = {
275
- "foo" => "bar",
276
- "aaa".encode('utf-16') => "aaa".encode('utf-16'),
277
- "ddd" => true,
278
- "ccc" => false,
279
- "bbb" => nil,
280
- "e" => 1.2,
281
- "f" => 5,
282
- "g" => 1_000_000_000_000_000.0,
283
- "nested" => { "a" => "b" }
284
- }
285
- p.override_attributes = { "foo2" => "baz" }
286
-
287
- end
288
- end
289
-
290
- let(:expected_canonical_revision_string) do
291
- <<-REVISION_STRING
292
- name:minimal_policyfile
293
- run-list-item:recipe[foo]
294
- cookbook:foo;id:467dc855408ce8b74f991c5dc2fd72a6aa369b60
295
- default_attributes:{"aaa":"aaa","bbb":null,"ccc":false,"ddd":true,"e":1.2,"f":5,"foo":"bar","g":1e+15,"nested":{"a":"b"}}
296
- override_attributes:{"foo2":"baz"}
297
- REVISION_STRING
298
- end
299
-
300
- let(:expected_revision_id) do
301
- Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
302
- end
303
-
304
- let(:compiled_policyfile) do
305
- {
306
- "revision_id" => expected_revision_id,
307
-
308
- "name" => "minimal_policyfile",
309
-
310
- "run_list" => ["recipe[foo]"],
311
-
312
- "cookbook_locks" => {
313
-
314
- "foo" => {
315
- "version" => "1.0.0",
316
- "identifier" => cookbook_foo_cksum,
317
- "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
318
- "cache_key" => "foo-1.0.0",
319
- "origin" => nil,
320
- "source_options" => nil
321
- },
322
- },
323
- "default_attributes" => {
324
- "foo" => "bar",
325
- "aaa".encode('utf-16') => "aaa".encode('utf-16'),
326
- "ddd" => true,
327
- "ccc" => false,
328
- "bbb" => nil,
329
- "e" => 1.2,
330
- "f" => 5,
331
- "g" => 1_000_000_000_000_000.0,
332
- "nested" => { "a" => "b" }
333
- },
334
- "override_attributes" => { "foo2" => "baz" },
335
-
336
- "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
337
- }
338
- end
339
-
340
- it "has a cache path" do
341
- expect(policyfile_lock.cache_path).to eq(cache_path)
342
- end
343
-
344
- it "computes a minimal policyfile" do
345
- expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
346
- end
347
-
348
- it "generates a canonical revision string" do
349
- expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
350
- end
351
-
352
- it "generates a revision id" do
353
- expect(policyfile_lock.revision_id).to eq(expected_revision_id)
354
- end
355
-
356
- end
357
-
358
- context "with a policyfile containing a local cookbook" do
359
-
360
- include_context "setup git cookbooks"
361
- include_context "setup git cookbook remote"
362
-
363
- let(:relative_paths_root) do
364
- tempdir
365
- end
366
-
367
- let(:policyfile_lock) do
368
- ChefDK::PolicyfileLock.build(storage_config) do |p|
369
-
370
- p.name = "dev_cookbook"
371
-
372
- p.run_list = [ "recipe[bar]" ]
373
- p.local_cookbook("bar") do |cb|
374
- cb.source = "bar"
375
- end
376
-
377
- end
378
- end
379
-
380
- let(:expected_canonical_revision_string) do
381
- <<-REVISION_STRING
382
- name:dev_cookbook
383
- run-list-item:recipe[bar]
384
- cookbook:bar;id:#{cookbook_bar_cksum}
385
- default_attributes:{}
386
- override_attributes:{}
387
- REVISION_STRING
388
- end
389
-
390
- let(:expected_revision_id) do
391
- Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
392
- end
393
-
394
- let(:compiled_policyfile) do
395
- {
396
-
397
- "revision_id" => expected_revision_id,
398
-
399
- "name" => "dev_cookbook",
400
-
401
- "run_list" => ["recipe[bar]"],
402
-
403
- "cookbook_locks" => {
404
-
405
- "bar" => {
406
- "version" => "0.1.0",
407
- "identifier" => cookbook_bar_cksum,
408
- "dotted_decimal_identifier" => cookbook_bar_cksum_dotted,
409
-
410
- "source" => "bar",
411
- "cache_key" => nil,
412
- "scm_info" => {
413
- "scm" => "git",
414
- "remote" => remote_url,
415
- "revision" => current_rev,
416
- "working_tree_clean" => true,
417
- "published" => true,
418
- "synchronized_remote_branches"=>["origin/master"]
419
- },
420
- "source_options" => nil
421
- },
422
- },
423
-
424
- "default_attributes" => {},
425
- "override_attributes" => {},
426
-
427
- "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
428
- }
429
- end
430
-
431
- it "computes a lockfile including git data" do
432
- actual_lock = policyfile_lock.to_lock
433
- expect(actual_lock).to eq(compiled_policyfile)
434
- end
435
-
436
- it "generates a canonical revision string" do
437
- expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
438
- end
439
-
440
- it "generates a revision id" do
441
- expect(policyfile_lock.revision_id).to eq(expected_revision_id)
442
- end
443
-
444
- end
445
-
446
- context "with a policyfile using custom identifiers" do
447
-
448
- include_context "setup git cookbooks"
449
-
450
- let(:relative_paths_root) do
451
- tempdir
452
- end
453
-
454
- let(:policyfile_lock) do
455
- ChefDK::PolicyfileLock.build(storage_config) do |p|
456
-
457
- p.name = "custom_identifier"
458
-
459
- p.run_list = [ "recipe[foo]" ]
460
-
461
- p.cached_cookbook("foo") do |cb|
462
- cb.cache_key = "foo-1.0.0"
463
-
464
- # Explicitly set the identifier and dotted decimal identifiers to the
465
- # version number (but it could be anything).
466
- cb.identifier = "1.0.0"
467
- cb.dotted_decimal_identifier ="1.0.0"
468
- end
469
-
470
- p.local_cookbook("bar") do |cb|
471
- cb.source = "bar"
472
- cb.identifier = "0.1.0"
473
- cb.dotted_decimal_identifier = "0.1.0"
474
- end
475
- end
476
-
477
- end
478
-
479
- let(:expected_canonical_revision_string) do
480
- <<-REVISION_STRING
481
- name:custom_identifier
482
- run-list-item:recipe[foo]
483
- cookbook:foo;id:1.0.0
484
- cookbook:bar;id:0.1.0
485
- default_attributes:{}
486
- override_attributes:{}
487
- REVISION_STRING
488
- end
489
-
490
- let(:expected_revision_id) do
491
- Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
492
- end
493
-
494
- let(:compiled_policyfile) do
495
- {
496
-
497
- "revision_id" => expected_revision_id,
498
-
499
- "name" => "custom_identifier",
500
-
501
- "run_list" => ["recipe[foo]"],
502
-
503
- "cookbook_locks" => {
504
-
505
- "foo" => {
506
- "version" => "1.0.0",
507
- "identifier" => "1.0.0",
508
- "dotted_decimal_identifier" => "1.0.0",
509
- "cache_key" => "foo-1.0.0",
510
- "origin" => nil,
511
- "source_options" => nil
512
- },
513
-
514
- "bar" => {
515
- "version" => "0.1.0",
516
- "identifier" => "0.1.0",
517
- "dotted_decimal_identifier" => "0.1.0",
518
-
519
- "source" => "bar",
520
- "cache_key" => nil,
521
- "scm_info" => {
522
- "scm" => "git",
523
- "remote" => nil,
524
- "revision" => current_rev,
525
- "working_tree_clean" => true,
526
- "published" => false,
527
- "synchronized_remote_branches"=>[]
528
- },
529
- "source_options" => nil
530
- },
531
- },
532
-
533
- "default_attributes" => {},
534
- "override_attributes" => {},
535
-
536
- "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
537
- }
538
- end
539
-
540
- it "generates a lockfile with custom identifiers" do
541
- expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
542
- end
543
-
544
- it "generates a canonical revision string" do
545
- expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
546
- end
547
-
548
- it "generates a revision id" do
549
- expect(policyfile_lock.revision_id).to eq(expected_revision_id)
550
- end
551
-
552
- end
553
-
554
- context "with a policyfile lock with a mix of cached and local cookbooks" do
555
-
556
- include_context "setup git cookbooks"
557
-
558
- let(:relative_paths_root) do
559
- tempdir
560
- end
561
-
562
- let(:policyfile_lock) do
563
-
564
- ChefDK::PolicyfileLock.build(storage_config) do |p|
565
-
566
- # Required
567
- p.name = "basic_example"
568
-
569
- # Required. Should be fully expanded without roles
570
- p.run_list = ["recipe[foo]", "recipe[bar]", "recipe[baz::non_default]"]
571
-
572
- # A cached_cookbook is stored in the cache directory in a subdirectory
573
- # given by 'cache_key'. It is assumed to be static (not modified by the
574
- # user).
575
- p.cached_cookbook("foo") do |cb|
576
- cb.cache_key = "foo-1.0.0"
577
-
578
- # Optional attribute that humans can use to understand where a cookbook
579
- # came from.
580
- cb.origin = "https://community.chef.io/api/cookbooks/foo/1.0.0"
581
- end
582
-
583
- p.local_cookbook("bar") do |cb|
584
- cb.source = "bar"
585
- end
586
-
587
- p.cached_cookbook("baz") do |cb|
588
- cb.cache_key = "baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb"
589
- cb.origin = "git://github.com/chef-cookbooks/bar.git"
590
- end
591
-
592
- p.cached_cookbook("dep_of_bar") do |cb|
593
- cb.cache_key = "dep_of_bar-1.2.3"
594
- cb.origin = "https://chef-server.example.com/cookbooks/dep_of_bar/1.2.3"
595
- end
596
- end
597
-
598
- end
599
-
600
- let(:expected_canonical_revision_string) do
601
- <<-REVISION_STRING
602
- name:basic_example
603
- run-list-item:recipe[foo]
604
- run-list-item:recipe[bar]
605
- run-list-item:recipe[baz::non_default]
606
- cookbook:foo;id:#{cookbook_foo_cksum}
607
- cookbook:bar;id:#{cookbook_bar_cksum}
608
- cookbook:baz;id:#{cookbook_baz_cksum}
609
- cookbook:dep_of_bar;id:#{cookbook_dep_of_bar_cksum}
610
- default_attributes:{}
611
- override_attributes:{}
612
- REVISION_STRING
613
- end
614
-
615
- let(:expected_revision_id) do
616
- Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
617
- end
618
-
619
- let(:compiled_policyfile) do
620
- {
621
-
622
- "revision_id" => expected_revision_id,
623
-
624
- "name" => "basic_example",
625
-
626
- "run_list" => ["recipe[foo]", "recipe[bar]", "recipe[baz::non_default]"],
627
-
628
- "cookbook_locks" => {
629
-
630
- "foo" => {
631
- "version" => "1.0.0",
632
- "identifier" => cookbook_foo_cksum,
633
- "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
634
- "origin" => "https://community.chef.io/api/cookbooks/foo/1.0.0",
635
- "cache_key" => "foo-1.0.0",
636
- "source_options" => nil
637
- },
638
-
639
- "bar" => {
640
- "version" => "0.1.0",
641
- "identifier" => cookbook_bar_cksum,
642
- "dotted_decimal_identifier" => cookbook_bar_cksum_dotted,
643
- "source" => "bar",
644
- "cache_key" => nil,
645
-
646
- "scm_info" => {
647
- "scm" => "git",
648
- "remote" => nil,
649
- "revision" => current_rev,
650
- "working_tree_clean" => true,
651
- "published" => false,
652
- "synchronized_remote_branches"=>[]
653
- },
654
- "source_options" => nil
655
- },
656
-
657
- "baz" => {
658
- "version" => "1.2.3",
659
- "identifier"=> cookbook_baz_cksum,
660
- "dotted_decimal_identifier" => cookbook_baz_cksum_dotted,
661
- "cache_key" => "baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb",
662
- "origin" => "git://github.com/chef-cookbooks/bar.git",
663
- "source_options" => nil
664
- },
665
-
666
- "dep_of_bar" => {
667
- "version" => "1.2.3",
668
- "identifier" => cookbook_dep_of_bar_cksum,
669
- "dotted_decimal_identifier" => cookbook_dep_of_bar_cksum_dotted,
670
- "origin" => "https://chef-server.example.com/cookbooks/dep_of_bar/1.2.3",
671
- "cache_key" => "dep_of_bar-1.2.3",
672
- "source_options" => nil
673
-
674
- },
675
-
676
- },
677
-
678
- "default_attributes" => {},
679
- "override_attributes" => {},
680
-
681
- "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
682
-
683
- }
684
- end
685
-
686
- it "generates a lockfile with the relevant profile data for each cookbook" do
687
- generated = policyfile_lock.to_lock
688
- expect(generated['name']).to eq(compiled_policyfile['name'])
689
- expect(generated['run_list']).to eq(compiled_policyfile['run_list'])
690
-
691
- generated_locks = generated['cookbook_locks']
692
- expected_locks = compiled_policyfile['cookbook_locks']
693
-
694
- # test individually so failures are easier to read
695
- expect(generated_locks['foo']).to eq(expected_locks['foo'])
696
- expect(generated_locks['bar']).to eq(expected_locks['bar'])
697
- expect(generated_locks['baz']).to eq(expected_locks['baz'])
698
- expect(generated_locks['dep_of_bar']).to eq(expected_locks['dep_of_bar'])
699
-
700
- expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
701
- end
702
-
703
- it "generates a canonical revision string" do
704
- expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
705
- end
706
-
707
- it "generates a revision id" do
708
- expect(policyfile_lock.revision_id).to eq(expected_revision_id)
709
- end
710
-
711
- end
712
-
713
- context "with solution dependencies specified" do
714
-
715
- let(:policyfile_lock) do
716
- ChefDK::PolicyfileLock.build(storage_config) do |p|
717
-
718
- p.name = "minimal_policyfile"
719
-
720
- p.run_list = [ "recipe[foo]" ]
721
- p.cached_cookbook("foo") do |cb|
722
- cb.cache_key = "foo-1.0.0"
723
- end
724
-
725
- p.dependencies do |deps|
726
- deps.add_cookbook_dep("foo", "1.0.0", [])
727
- end
728
-
729
- end
730
- end
731
-
732
- let(:expected_canonical_revision_string) do
733
- <<-REVISION_STRING
734
- name:minimal_policyfile
735
- run-list-item:recipe[foo]
736
- cookbook:foo;id:#{cookbook_foo_cksum}
737
- default_attributes:{}
738
- override_attributes:{}
739
- REVISION_STRING
740
- end
741
-
742
- let(:expected_revision_id) do
743
- Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
744
- end
745
-
746
- let(:compiled_policyfile) do
747
- {
748
-
749
- "revision_id" => expected_revision_id,
750
-
751
- "name" => "minimal_policyfile",
752
-
753
- "run_list" => ["recipe[foo]"],
754
-
755
- "cookbook_locks" => {
756
-
757
- "foo" => {
758
- "version" => "1.0.0",
759
- "identifier" => cookbook_foo_cksum,
760
- "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
761
- "cache_key" => "foo-1.0.0",
762
- "origin" => nil,
763
- "source_options" => nil
764
- },
765
- },
766
-
767
- "default_attributes" => {},
768
- "override_attributes" => {},
769
-
770
- "solution_dependencies" => {
771
- "Policyfile" => [],
772
- "dependencies" => {"foo (1.0.0)" => []}
773
- }
774
- }
775
- end
776
-
777
- it "computes a minimal policyfile" do
778
- expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
779
- end
780
-
781
- end
782
-
783
- context "with named run_lists specified" do
784
-
785
- let(:policyfile_lock) do
786
- ChefDK::PolicyfileLock.build(storage_config) do |p|
787
-
788
- p.name = "minimal_policyfile"
789
-
790
- p.run_list = [ "recipe[foo]" ]
791
-
792
- p.named_run_lists = { "rl2" => [ "recipe[foo::bar]" ] }
793
-
794
- p.cached_cookbook("foo") do |cb|
795
- cb.cache_key = "foo-1.0.0"
796
- end
797
-
798
- end
799
- end
800
-
801
- let(:expected_canonical_revision_string) do
802
- <<-REVISION_STRING
803
- name:minimal_policyfile
804
- run-list-item:recipe[foo]
805
- named-run-list:rl2;run-list-item:recipe[foo::bar]
806
- cookbook:foo;id:#{cookbook_foo_cksum}
807
- default_attributes:{}
808
- override_attributes:{}
809
- REVISION_STRING
810
- end
811
-
812
- let(:expected_revision_id) do
813
- Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
814
- end
815
-
816
- let(:compiled_policyfile) do
817
- {
818
-
819
- "revision_id" => expected_revision_id,
820
-
821
- "name" => "minimal_policyfile",
822
-
823
- "run_list" => ["recipe[foo]"],
824
-
825
- "named_run_lists" => { "rl2" => [ "recipe[foo::bar]" ] },
826
-
827
- "cookbook_locks" => {
828
-
829
- "foo" => {
830
- "version" => "1.0.0",
831
- "identifier" => cookbook_foo_cksum,
832
- "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
833
- "cache_key" => "foo-1.0.0",
834
- "origin" => nil,
835
- "source_options" => nil
836
- },
837
- },
838
-
839
- "default_attributes" => {},
840
- "override_attributes" => {},
841
-
842
- "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
843
- }
844
- end
845
-
846
- it "includes the named run lists in the compiled policyfile" do
847
- expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
848
- end
849
-
850
- it "generates a canonical revision string" do
851
- expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
852
- end
853
-
854
- it "generates a revision id" do
855
- expect(policyfile_lock.revision_id).to eq(expected_revision_id)
856
- end
857
-
858
- end
859
-
860
- describe "building a policyfile lock from a policyfile compiler" do
861
-
862
- include_context "setup git cookbooks"
863
-
864
- let(:relative_paths_root) do
865
- tempdir
866
- end
867
-
868
- let(:cached_cookbook_uri) { "https://supermarket.chef.io/api/v1/cookbooks/foo/versions/1.0.0/download" }
869
-
870
- let(:cached_location_spec) do
871
- double( "ChefDK::Policyfile::CookbookLocationSpecification",
872
- mirrors_canonical_upstream?: true,
873
- cache_key: "foo-1.0.0",
874
- uri: cached_cookbook_uri,
875
- source_options_for_lock: { "artifactserver" => cached_cookbook_uri, "version" => "1.0.0" })
876
- end
877
-
878
- let(:local_location_spec) do
879
- double( "ChefDK::Policyfile::CookbookLocationSpecification",
880
- mirrors_canonical_upstream?: false,
881
- relative_paths_root: relative_paths_root,
882
- relative_path: "bar",
883
- source_options_for_lock: { "path" => "bar" })
884
- end
885
-
886
- let(:policyfile_solution_dependencies) do
887
- ChefDK::Policyfile::SolutionDependencies.new.tap do |s|
888
- s.add_policyfile_dep("foo", "~> 1.0")
889
- s.add_cookbook_dep("foo", "1.0.0", [])
890
- s.add_cookbook_dep("bar", "0.1.0", [])
891
- end
892
- end
893
-
894
- let(:policyfile_default_attrs) do
895
- {
896
- "foo" => "bar",
897
- "abc" => { "def" => { "ghi" => "xyz" } },
898
- "baz" => {
899
- "more_nested_stuff" => "yup",
900
- "an_array" => ["a", "b", "c"]
901
- }
902
- }
903
- end
904
-
905
- let(:canonicalized_default_attrs) do
906
- elements = [
907
- %q{"abc":{"def":{"ghi":"xyz"}}},
908
- %q{"baz":{"an_array":["a","b","c"],"more_nested_stuff":"yup"}},
909
- %q{"foo":"bar"}
910
- ]
911
- "{" + elements.join(',') + "}"
912
- end
913
-
914
- let(:policyfile_override_attrs) do
915
- {
916
- "foo" => "bar",
917
- "abc" => { "def" => { "ghi" => "xyz" } },
918
- "baz" => {
919
- "more_nested_stuff" => "yup",
920
- "an_array" => ["a", "b", "c"]
921
- }
922
- }
923
- end
924
-
925
- let(:canonicalized_override_attrs) { canonicalized_default_attrs }
926
-
927
- let(:policyfile_compiler) do
928
- double( "ChefDK::PolicyfileCompiler",
929
- name: "my-policyfile",
930
- normalized_run_list: %w[recipe[foo::default] recipe[bar::default]],
931
- normalized_named_run_lists: { "rl2" => %w[recipe[bar::default]] },
932
- all_cookbook_location_specs: {"foo" => cached_location_spec, "bar" => local_location_spec},
933
- solution_dependencies: policyfile_solution_dependencies,
934
- default_attributes: policyfile_default_attrs,
935
- override_attributes: policyfile_override_attrs )
936
- end
937
-
938
- let(:policyfile_lock) do
939
- ChefDK::PolicyfileLock.build_from_compiler(policyfile_compiler, storage_config)
940
- end
941
-
942
-
943
- let(:expected_canonical_revision_string) do
944
- <<-REVISION_STRING
945
- name:my-policyfile
946
- run-list-item:recipe[foo::default]
947
- run-list-item:recipe[bar::default]
948
- named-run-list:rl2;run-list-item:recipe[bar::default]
949
- cookbook:foo;id:#{cookbook_foo_cksum}
950
- cookbook:bar;id:#{cookbook_bar_cksum}
951
- default_attributes:#{canonicalized_default_attrs}
952
- override_attributes:#{canonicalized_override_attrs}
953
- REVISION_STRING
954
- end
955
-
956
- let(:expected_revision_id) do
957
- Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
958
- end
959
-
960
- let(:compiled_policyfile) do
961
- {
962
-
963
- "revision_id" => expected_revision_id,
964
-
965
- "name" => "my-policyfile",
966
-
967
- "run_list" => ["recipe[foo::default]", "recipe[bar::default]"],
968
-
969
- "named_run_lists" => { "rl2" => ["recipe[bar::default]"] },
970
-
971
- "cookbook_locks" => {
972
-
973
- "foo" => {
974
- "version" => "1.0.0",
975
- "identifier" => cookbook_foo_cksum,
976
- "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
977
- "cache_key" => "foo-1.0.0",
978
- "origin" => cached_cookbook_uri,
979
- "source_options" => { "artifactserver" => cached_cookbook_uri, "version" => "1.0.0" }
980
- },
981
-
982
- "bar" => {
983
- "version" => "0.1.0",
984
- "identifier" => cookbook_bar_cksum,
985
- "dotted_decimal_identifier" => cookbook_bar_cksum_dotted,
986
- "source" => "bar",
987
- "cache_key" => nil,
988
-
989
- "scm_info" => {
990
- "scm" => "git",
991
- "remote" => nil,
992
- "revision" => current_rev,
993
- "working_tree_clean" => true,
994
- "published" => false,
995
- "synchronized_remote_branches"=>[]
996
- },
997
- "source_options" => { "path" => "bar" }
998
- }
999
- },
1000
-
1001
- "default_attributes" => {
1002
- "foo" => "bar",
1003
- "abc" => { "def" => { "ghi" => "xyz" } },
1004
- "baz" => {
1005
- "more_nested_stuff" => "yup",
1006
- "an_array" => ["a", "b", "c"]
1007
- }
1008
- },
1009
-
1010
- "override_attributes" => {
1011
- "foo" => "bar",
1012
- "abc" => { "def" => { "ghi" => "xyz" } },
1013
- "baz" => {
1014
- "more_nested_stuff" => "yup",
1015
- "an_array" => ["a", "b", "c"]
1016
- }
1017
- },
1018
- "solution_dependencies" => {
1019
- "Policyfile" => [ [ "foo", "~> 1.0" ] ],
1020
- "dependencies" => { "foo (1.0.0)" => [], "bar (0.1.0)" => [] }
1021
- }
1022
- }
1023
- end
1024
-
1025
- it "adds a cached cookbook lock generator for the compiler's cached cookbook" do
1026
- expect(policyfile_lock.cookbook_locks).to have_key("foo")
1027
- cb_lock = policyfile_lock.cookbook_locks["foo"]
1028
- expect(cb_lock.origin).to eq(cached_location_spec.uri)
1029
- expect(cb_lock.cache_key).to eq(cached_location_spec.cache_key)
1030
- end
1031
-
1032
- it "adds a local cookbook lock generator for the compiler's local cookbook" do
1033
- expect(policyfile_lock.cookbook_locks).to have_key("bar")
1034
- cb_lock = policyfile_lock.cookbook_locks["bar"]
1035
- expect(cb_lock.source).to eq(local_location_spec.relative_path)
1036
- end
1037
-
1038
- it "sets named run lists on the policyfile lock" do
1039
- expect(policyfile_lock.named_run_lists).to eq("rl2" => %w[recipe[bar::default]])
1040
- end
1041
-
1042
- it "generates a lockfile data structure" do
1043
- expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
1044
- end
1045
-
1046
- it "generates a canonical revision string" do
1047
- expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
1048
- end
1049
-
1050
- it "generates a revision id" do
1051
- expect(policyfile_lock.revision_id).to eq(expected_revision_id)
1052
- end
1053
-
1054
- end
1055
-
1056
- end
1
+ # -*- coding: UTF-8 -*-
2
+ #
3
+ # Copyright:: Copyright (c) 2014 Chef Software Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'spec_helper'
20
+ require 'shared/setup_git_cookbooks'
21
+ require 'shared/fixture_cookbook_checksums'
22
+ require 'chef-dk/policyfile/storage_config'
23
+ require 'chef-dk/policyfile_lock.rb'
24
+
25
+ describe ChefDK::PolicyfileLock, "building a lockfile" do
26
+
27
+ include_context "fixture cookbooks checksums"
28
+
29
+ # For debugging giant nested hashes...
30
+ def expect_hash_equal(actual, expected)
31
+ expected.each do |key, expected_value|
32
+ expect(actual).to have_key(key)
33
+ if expected_value.kind_of?(Hash)
34
+ expect_hash_equal(actual[key], expected_value)
35
+ else
36
+ expect(actual[key]).to eq(expected_value)
37
+ end
38
+ end
39
+ expect(actual).to eq(expected)
40
+ end
41
+
42
+ let(:cache_path) do
43
+ File.expand_path("spec/unit/fixtures/cookbook_cache", project_root)
44
+ end
45
+
46
+ let(:relative_paths_root) do
47
+ File.expand_path("spec/unit/fixtures/", project_root)
48
+ end
49
+
50
+ let(:storage_config) do
51
+ ChefDK::Policyfile::StorageConfig.new( cache_path: cache_path, relative_paths_root: relative_paths_root )
52
+ end
53
+
54
+ context "when a cached cookbook omits the cache key" do
55
+
56
+ let(:policyfile_lock) do
57
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
58
+
59
+ p.name = "invalid_cache_key_policyfile"
60
+
61
+ p.run_list = [ "recipe[foo]" ]
62
+
63
+ p.cached_cookbook("nosuchthing") do |cb|
64
+ end
65
+ end
66
+ end
67
+
68
+ it "raises a descriptive error" do
69
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::CachedCookbookNotFound)
70
+ end
71
+
72
+ end
73
+
74
+ context "when a local cookbook omits the path" do
75
+
76
+ let(:policyfile_lock) do
77
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
78
+
79
+ p.name = "invalid_local_cookbook"
80
+
81
+ p.run_list = [ "recipe[foo]" ]
82
+
83
+ p.local_cookbook("nosuchthing") do |cb|
84
+ end
85
+ end
86
+ end
87
+
88
+ it "raises a descriptive error" do
89
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::LocalCookbookNotFound)
90
+ end
91
+ end
92
+
93
+ context "when a local cookbook has an incorrect path" do
94
+
95
+ let(:policyfile_lock) do
96
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
97
+
98
+ p.name = "invalid_local_cookbook"
99
+
100
+ p.run_list = [ "recipe[foo]" ]
101
+
102
+ p.local_cookbook("nosuchthing") do |cb|
103
+ cb.source = "nopenopenope"
104
+ end
105
+ end
106
+ end
107
+
108
+ it "raises a descriptive error" do
109
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::LocalCookbookNotFound)
110
+ end
111
+ end
112
+
113
+ context "when a cookbook is not in the cache" do
114
+
115
+ let(:policyfile_lock) do
116
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
117
+
118
+ p.name = "invalid_cache_key_policyfile"
119
+
120
+ p.run_list = [ "recipe[foo]" ]
121
+
122
+ p.cached_cookbook("nosuchthing") do |cb|
123
+ cb.cache_key = "nosuchthing-1.0.0"
124
+ end
125
+ end
126
+ end
127
+
128
+ it "raises a descriptive error" do
129
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::CachedCookbookNotFound)
130
+ end
131
+
132
+ end
133
+
134
+ describe "policyfiles with invalid attributes" do
135
+
136
+ let(:policyfile_lock) do
137
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
138
+
139
+ p.name = "invalid_cache_key_policyfile"
140
+
141
+ p.run_list = [ "recipe[foo]" ]
142
+
143
+ p.cached_cookbook("foo") do |cb|
144
+ cb.cache_key = "foo-1.0.0"
145
+ end
146
+
147
+ p.default_attributes = default_attributes
148
+ end
149
+ end
150
+
151
+ context "invalid floats - infinity" do
152
+
153
+ let(:default_attributes) { {"infinity" => Float::INFINITY} }
154
+
155
+ it "raises a descriptive error" do
156
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
157
+ end
158
+ end
159
+
160
+ context "invalid floats - nan" do
161
+
162
+ let(:default_attributes) { {"infinity" => Float::NAN} }
163
+
164
+ it "raises a descriptive error" do
165
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
166
+ end
167
+ end
168
+
169
+ context "non-string hash/object keys" do
170
+
171
+ let(:default_attributes) { {1906 => "lol nope"} }
172
+
173
+ it "raises a descriptive error" do
174
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
175
+ end
176
+ end
177
+
178
+ context "values that are not Hash/Array/String/Float/Integer/true/false/nil" do
179
+
180
+ let(:default_attributes) { { "raw object" => Object.new } }
181
+
182
+ it "raises a descriptive error" do
183
+ expect { policyfile_lock.to_lock }.to raise_error(ChefDK::InvalidPolicyfileAttribute)
184
+ end
185
+ end
186
+
187
+ end
188
+
189
+ context "with a minimal policyfile" do
190
+
191
+ let(:policyfile_lock) do
192
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
193
+
194
+ p.name = "minimal_policyfile"
195
+
196
+ p.run_list = [ "recipe[foo]" ]
197
+ p.cached_cookbook("foo") do |cb|
198
+ cb.cache_key = "foo-1.0.0"
199
+ end
200
+
201
+ end
202
+ end
203
+
204
+ let(:expected_canonical_revision_string) do
205
+ <<-REVISION_STRING
206
+ name:minimal_policyfile
207
+ run-list-item:recipe[foo]
208
+ cookbook:foo;id:467dc855408ce8b74f991c5dc2fd72a6aa369b60
209
+ default_attributes:{}
210
+ override_attributes:{}
211
+ REVISION_STRING
212
+ end
213
+
214
+ let(:expected_revision_id) do
215
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
216
+ end
217
+
218
+ let(:compiled_policyfile) do
219
+ {
220
+ "revision_id" => expected_revision_id,
221
+
222
+ "name" => "minimal_policyfile",
223
+
224
+ "run_list" => ["recipe[foo]"],
225
+
226
+ "cookbook_locks" => {
227
+
228
+ "foo" => {
229
+ "version" => "1.0.0",
230
+ "identifier" => cookbook_foo_cksum,
231
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
232
+ "cache_key" => "foo-1.0.0",
233
+ "origin" => nil,
234
+ "source_options" => nil
235
+ },
236
+ },
237
+ "default_attributes" => {},
238
+ "override_attributes" => {},
239
+
240
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
241
+ }
242
+ end
243
+
244
+ it "has a cache path" do
245
+ expect(policyfile_lock.cache_path).to eq(cache_path)
246
+ end
247
+
248
+ it "computes a minimal policyfile" do
249
+ expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
250
+ end
251
+
252
+ it "generates a canonical revision string" do
253
+ expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
254
+ end
255
+
256
+ it "generates a revision id" do
257
+ expect(policyfile_lock.revision_id).to eq(expected_revision_id)
258
+ end
259
+
260
+ end
261
+
262
+ context "with a policyfile containing attributes" do
263
+
264
+ let(:policyfile_lock) do
265
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
266
+
267
+ p.name = "minimal_policyfile"
268
+
269
+ p.run_list = [ "recipe[foo]" ]
270
+ p.cached_cookbook("foo") do |cb|
271
+ cb.cache_key = "foo-1.0.0"
272
+ end
273
+
274
+ p.default_attributes = {
275
+ "foo" => "bar",
276
+ "aaa".encode('utf-16') => "aaa".encode('utf-16'),
277
+ "ddd" => true,
278
+ "ccc" => false,
279
+ "bbb" => nil,
280
+ "e" => 1.2,
281
+ "f" => 5,
282
+ "g" => 1_000_000_000_000_000.0,
283
+ "nested" => { "a" => "b" }
284
+ }
285
+ p.override_attributes = { "foo2" => "baz" }
286
+
287
+ end
288
+ end
289
+
290
+ let(:expected_canonical_revision_string) do
291
+ <<-REVISION_STRING
292
+ name:minimal_policyfile
293
+ run-list-item:recipe[foo]
294
+ cookbook:foo;id:467dc855408ce8b74f991c5dc2fd72a6aa369b60
295
+ default_attributes:{"aaa":"aaa","bbb":null,"ccc":false,"ddd":true,"e":1.2,"f":5,"foo":"bar","g":1e+15,"nested":{"a":"b"}}
296
+ override_attributes:{"foo2":"baz"}
297
+ REVISION_STRING
298
+ end
299
+
300
+ let(:expected_revision_id) do
301
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
302
+ end
303
+
304
+ let(:compiled_policyfile) do
305
+ {
306
+ "revision_id" => expected_revision_id,
307
+
308
+ "name" => "minimal_policyfile",
309
+
310
+ "run_list" => ["recipe[foo]"],
311
+
312
+ "cookbook_locks" => {
313
+
314
+ "foo" => {
315
+ "version" => "1.0.0",
316
+ "identifier" => cookbook_foo_cksum,
317
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
318
+ "cache_key" => "foo-1.0.0",
319
+ "origin" => nil,
320
+ "source_options" => nil
321
+ },
322
+ },
323
+ "default_attributes" => {
324
+ "foo" => "bar",
325
+ "aaa".encode('utf-16') => "aaa".encode('utf-16'),
326
+ "ddd" => true,
327
+ "ccc" => false,
328
+ "bbb" => nil,
329
+ "e" => 1.2,
330
+ "f" => 5,
331
+ "g" => 1_000_000_000_000_000.0,
332
+ "nested" => { "a" => "b" }
333
+ },
334
+ "override_attributes" => { "foo2" => "baz" },
335
+
336
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
337
+ }
338
+ end
339
+
340
+ it "has a cache path" do
341
+ expect(policyfile_lock.cache_path).to eq(cache_path)
342
+ end
343
+
344
+ it "computes a minimal policyfile" do
345
+ expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
346
+ end
347
+
348
+ it "generates a canonical revision string" do
349
+ expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
350
+ end
351
+
352
+ it "generates a revision id" do
353
+ expect(policyfile_lock.revision_id).to eq(expected_revision_id)
354
+ end
355
+
356
+ end
357
+
358
+ context "with a policyfile containing a local cookbook" do
359
+
360
+ include_context "setup git cookbooks"
361
+ include_context "setup git cookbook remote"
362
+
363
+ let(:relative_paths_root) do
364
+ tempdir
365
+ end
366
+
367
+ let(:policyfile_lock) do
368
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
369
+
370
+ p.name = "dev_cookbook"
371
+
372
+ p.run_list = [ "recipe[bar]" ]
373
+ p.local_cookbook("bar") do |cb|
374
+ cb.source = "bar"
375
+ end
376
+
377
+ end
378
+ end
379
+
380
+ let(:expected_canonical_revision_string) do
381
+ <<-REVISION_STRING
382
+ name:dev_cookbook
383
+ run-list-item:recipe[bar]
384
+ cookbook:bar;id:#{cookbook_bar_cksum}
385
+ default_attributes:{}
386
+ override_attributes:{}
387
+ REVISION_STRING
388
+ end
389
+
390
+ let(:expected_revision_id) do
391
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
392
+ end
393
+
394
+ let(:compiled_policyfile) do
395
+ {
396
+
397
+ "revision_id" => expected_revision_id,
398
+
399
+ "name" => "dev_cookbook",
400
+
401
+ "run_list" => ["recipe[bar]"],
402
+
403
+ "cookbook_locks" => {
404
+
405
+ "bar" => {
406
+ "version" => "0.1.0",
407
+ "identifier" => cookbook_bar_cksum,
408
+ "dotted_decimal_identifier" => cookbook_bar_cksum_dotted,
409
+
410
+ "source" => "bar",
411
+ "cache_key" => nil,
412
+ "scm_info" => {
413
+ "scm" => "git",
414
+ "remote" => remote_url,
415
+ "revision" => current_rev,
416
+ "working_tree_clean" => true,
417
+ "published" => true,
418
+ "synchronized_remote_branches"=>["origin/master"]
419
+ },
420
+ "source_options" => nil
421
+ },
422
+ },
423
+
424
+ "default_attributes" => {},
425
+ "override_attributes" => {},
426
+
427
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
428
+ }
429
+ end
430
+
431
+ it "computes a lockfile including git data" do
432
+ actual_lock = policyfile_lock.to_lock
433
+ expect(actual_lock).to eq(compiled_policyfile)
434
+ end
435
+
436
+ it "generates a canonical revision string" do
437
+ expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
438
+ end
439
+
440
+ it "generates a revision id" do
441
+ expect(policyfile_lock.revision_id).to eq(expected_revision_id)
442
+ end
443
+
444
+ end
445
+
446
+ context "with a policyfile using custom identifiers" do
447
+
448
+ include_context "setup git cookbooks"
449
+
450
+ let(:relative_paths_root) do
451
+ tempdir
452
+ end
453
+
454
+ let(:policyfile_lock) do
455
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
456
+
457
+ p.name = "custom_identifier"
458
+
459
+ p.run_list = [ "recipe[foo]" ]
460
+
461
+ p.cached_cookbook("foo") do |cb|
462
+ cb.cache_key = "foo-1.0.0"
463
+
464
+ # Explicitly set the identifier and dotted decimal identifiers to the
465
+ # version number (but it could be anything).
466
+ cb.identifier = "1.0.0"
467
+ cb.dotted_decimal_identifier ="1.0.0"
468
+ end
469
+
470
+ p.local_cookbook("bar") do |cb|
471
+ cb.source = "bar"
472
+ cb.identifier = "0.1.0"
473
+ cb.dotted_decimal_identifier = "0.1.0"
474
+ end
475
+ end
476
+
477
+ end
478
+
479
+ let(:expected_canonical_revision_string) do
480
+ <<-REVISION_STRING
481
+ name:custom_identifier
482
+ run-list-item:recipe[foo]
483
+ cookbook:foo;id:1.0.0
484
+ cookbook:bar;id:0.1.0
485
+ default_attributes:{}
486
+ override_attributes:{}
487
+ REVISION_STRING
488
+ end
489
+
490
+ let(:expected_revision_id) do
491
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
492
+ end
493
+
494
+ let(:compiled_policyfile) do
495
+ {
496
+
497
+ "revision_id" => expected_revision_id,
498
+
499
+ "name" => "custom_identifier",
500
+
501
+ "run_list" => ["recipe[foo]"],
502
+
503
+ "cookbook_locks" => {
504
+
505
+ "foo" => {
506
+ "version" => "1.0.0",
507
+ "identifier" => "1.0.0",
508
+ "dotted_decimal_identifier" => "1.0.0",
509
+ "cache_key" => "foo-1.0.0",
510
+ "origin" => nil,
511
+ "source_options" => nil
512
+ },
513
+
514
+ "bar" => {
515
+ "version" => "0.1.0",
516
+ "identifier" => "0.1.0",
517
+ "dotted_decimal_identifier" => "0.1.0",
518
+
519
+ "source" => "bar",
520
+ "cache_key" => nil,
521
+ "scm_info" => {
522
+ "scm" => "git",
523
+ "remote" => nil,
524
+ "revision" => current_rev,
525
+ "working_tree_clean" => true,
526
+ "published" => false,
527
+ "synchronized_remote_branches"=>[]
528
+ },
529
+ "source_options" => nil
530
+ },
531
+ },
532
+
533
+ "default_attributes" => {},
534
+ "override_attributes" => {},
535
+
536
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
537
+ }
538
+ end
539
+
540
+ it "generates a lockfile with custom identifiers" do
541
+ expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
542
+ end
543
+
544
+ it "generates a canonical revision string" do
545
+ expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
546
+ end
547
+
548
+ it "generates a revision id" do
549
+ expect(policyfile_lock.revision_id).to eq(expected_revision_id)
550
+ end
551
+
552
+ end
553
+
554
+ context "with a policyfile lock with a mix of cached and local cookbooks" do
555
+
556
+ include_context "setup git cookbooks"
557
+
558
+ let(:relative_paths_root) do
559
+ tempdir
560
+ end
561
+
562
+ let(:policyfile_lock) do
563
+
564
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
565
+
566
+ # Required
567
+ p.name = "basic_example"
568
+
569
+ # Required. Should be fully expanded without roles
570
+ p.run_list = ["recipe[foo]", "recipe[bar]", "recipe[baz::non_default]"]
571
+
572
+ # A cached_cookbook is stored in the cache directory in a subdirectory
573
+ # given by 'cache_key'. It is assumed to be static (not modified by the
574
+ # user).
575
+ p.cached_cookbook("foo") do |cb|
576
+ cb.cache_key = "foo-1.0.0"
577
+
578
+ # Optional attribute that humans can use to understand where a cookbook
579
+ # came from.
580
+ cb.origin = "https://community.chef.io/api/cookbooks/foo/1.0.0"
581
+ end
582
+
583
+ p.local_cookbook("bar") do |cb|
584
+ cb.source = "bar"
585
+ end
586
+
587
+ p.cached_cookbook("baz") do |cb|
588
+ cb.cache_key = "baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb"
589
+ cb.origin = "git://github.com/chef-cookbooks/bar.git"
590
+ end
591
+
592
+ p.cached_cookbook("dep_of_bar") do |cb|
593
+ cb.cache_key = "dep_of_bar-1.2.3"
594
+ cb.origin = "https://chef-server.example.com/cookbooks/dep_of_bar/1.2.3"
595
+ end
596
+ end
597
+
598
+ end
599
+
600
+ let(:expected_canonical_revision_string) do
601
+ <<-REVISION_STRING
602
+ name:basic_example
603
+ run-list-item:recipe[foo]
604
+ run-list-item:recipe[bar]
605
+ run-list-item:recipe[baz::non_default]
606
+ cookbook:foo;id:#{cookbook_foo_cksum}
607
+ cookbook:bar;id:#{cookbook_bar_cksum}
608
+ cookbook:baz;id:#{cookbook_baz_cksum}
609
+ cookbook:dep_of_bar;id:#{cookbook_dep_of_bar_cksum}
610
+ default_attributes:{}
611
+ override_attributes:{}
612
+ REVISION_STRING
613
+ end
614
+
615
+ let(:expected_revision_id) do
616
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
617
+ end
618
+
619
+ let(:compiled_policyfile) do
620
+ {
621
+
622
+ "revision_id" => expected_revision_id,
623
+
624
+ "name" => "basic_example",
625
+
626
+ "run_list" => ["recipe[foo]", "recipe[bar]", "recipe[baz::non_default]"],
627
+
628
+ "cookbook_locks" => {
629
+
630
+ "foo" => {
631
+ "version" => "1.0.0",
632
+ "identifier" => cookbook_foo_cksum,
633
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
634
+ "origin" => "https://community.chef.io/api/cookbooks/foo/1.0.0",
635
+ "cache_key" => "foo-1.0.0",
636
+ "source_options" => nil
637
+ },
638
+
639
+ "bar" => {
640
+ "version" => "0.1.0",
641
+ "identifier" => cookbook_bar_cksum,
642
+ "dotted_decimal_identifier" => cookbook_bar_cksum_dotted,
643
+ "source" => "bar",
644
+ "cache_key" => nil,
645
+
646
+ "scm_info" => {
647
+ "scm" => "git",
648
+ "remote" => nil,
649
+ "revision" => current_rev,
650
+ "working_tree_clean" => true,
651
+ "published" => false,
652
+ "synchronized_remote_branches"=>[]
653
+ },
654
+ "source_options" => nil
655
+ },
656
+
657
+ "baz" => {
658
+ "version" => "1.2.3",
659
+ "identifier"=> cookbook_baz_cksum,
660
+ "dotted_decimal_identifier" => cookbook_baz_cksum_dotted,
661
+ "cache_key" => "baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb",
662
+ "origin" => "git://github.com/chef-cookbooks/bar.git",
663
+ "source_options" => nil
664
+ },
665
+
666
+ "dep_of_bar" => {
667
+ "version" => "1.2.3",
668
+ "identifier" => cookbook_dep_of_bar_cksum,
669
+ "dotted_decimal_identifier" => cookbook_dep_of_bar_cksum_dotted,
670
+ "origin" => "https://chef-server.example.com/cookbooks/dep_of_bar/1.2.3",
671
+ "cache_key" => "dep_of_bar-1.2.3",
672
+ "source_options" => nil
673
+
674
+ },
675
+
676
+ },
677
+
678
+ "default_attributes" => {},
679
+ "override_attributes" => {},
680
+
681
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
682
+
683
+ }
684
+ end
685
+
686
+ it "generates a lockfile with the relevant profile data for each cookbook" do
687
+ generated = policyfile_lock.to_lock
688
+ expect(generated['name']).to eq(compiled_policyfile['name'])
689
+ expect(generated['run_list']).to eq(compiled_policyfile['run_list'])
690
+
691
+ generated_locks = generated['cookbook_locks']
692
+ expected_locks = compiled_policyfile['cookbook_locks']
693
+
694
+ # test individually so failures are easier to read
695
+ expect(generated_locks['foo']).to eq(expected_locks['foo'])
696
+ expect(generated_locks['bar']).to eq(expected_locks['bar'])
697
+ expect(generated_locks['baz']).to eq(expected_locks['baz'])
698
+ expect(generated_locks['dep_of_bar']).to eq(expected_locks['dep_of_bar'])
699
+
700
+ expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
701
+ end
702
+
703
+ it "generates a canonical revision string" do
704
+ expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
705
+ end
706
+
707
+ it "generates a revision id" do
708
+ expect(policyfile_lock.revision_id).to eq(expected_revision_id)
709
+ end
710
+
711
+ end
712
+
713
+ context "with solution dependencies specified" do
714
+
715
+ let(:policyfile_lock) do
716
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
717
+
718
+ p.name = "minimal_policyfile"
719
+
720
+ p.run_list = [ "recipe[foo]" ]
721
+ p.cached_cookbook("foo") do |cb|
722
+ cb.cache_key = "foo-1.0.0"
723
+ end
724
+
725
+ p.dependencies do |deps|
726
+ deps.add_cookbook_dep("foo", "1.0.0", [])
727
+ end
728
+
729
+ end
730
+ end
731
+
732
+ let(:expected_canonical_revision_string) do
733
+ <<-REVISION_STRING
734
+ name:minimal_policyfile
735
+ run-list-item:recipe[foo]
736
+ cookbook:foo;id:#{cookbook_foo_cksum}
737
+ default_attributes:{}
738
+ override_attributes:{}
739
+ REVISION_STRING
740
+ end
741
+
742
+ let(:expected_revision_id) do
743
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
744
+ end
745
+
746
+ let(:compiled_policyfile) do
747
+ {
748
+
749
+ "revision_id" => expected_revision_id,
750
+
751
+ "name" => "minimal_policyfile",
752
+
753
+ "run_list" => ["recipe[foo]"],
754
+
755
+ "cookbook_locks" => {
756
+
757
+ "foo" => {
758
+ "version" => "1.0.0",
759
+ "identifier" => cookbook_foo_cksum,
760
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
761
+ "cache_key" => "foo-1.0.0",
762
+ "origin" => nil,
763
+ "source_options" => nil
764
+ },
765
+ },
766
+
767
+ "default_attributes" => {},
768
+ "override_attributes" => {},
769
+
770
+ "solution_dependencies" => {
771
+ "Policyfile" => [],
772
+ "dependencies" => {"foo (1.0.0)" => []}
773
+ }
774
+ }
775
+ end
776
+
777
+ it "computes a minimal policyfile" do
778
+ expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
779
+ end
780
+
781
+ end
782
+
783
+ context "with named run_lists specified" do
784
+
785
+ let(:policyfile_lock) do
786
+ ChefDK::PolicyfileLock.build(storage_config) do |p|
787
+
788
+ p.name = "minimal_policyfile"
789
+
790
+ p.run_list = [ "recipe[foo]" ]
791
+
792
+ p.named_run_lists = { "rl2" => [ "recipe[foo::bar]" ] }
793
+
794
+ p.cached_cookbook("foo") do |cb|
795
+ cb.cache_key = "foo-1.0.0"
796
+ end
797
+
798
+ end
799
+ end
800
+
801
+ let(:expected_canonical_revision_string) do
802
+ <<-REVISION_STRING
803
+ name:minimal_policyfile
804
+ run-list-item:recipe[foo]
805
+ named-run-list:rl2;run-list-item:recipe[foo::bar]
806
+ cookbook:foo;id:#{cookbook_foo_cksum}
807
+ default_attributes:{}
808
+ override_attributes:{}
809
+ REVISION_STRING
810
+ end
811
+
812
+ let(:expected_revision_id) do
813
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
814
+ end
815
+
816
+ let(:compiled_policyfile) do
817
+ {
818
+
819
+ "revision_id" => expected_revision_id,
820
+
821
+ "name" => "minimal_policyfile",
822
+
823
+ "run_list" => ["recipe[foo]"],
824
+
825
+ "named_run_lists" => { "rl2" => [ "recipe[foo::bar]" ] },
826
+
827
+ "cookbook_locks" => {
828
+
829
+ "foo" => {
830
+ "version" => "1.0.0",
831
+ "identifier" => cookbook_foo_cksum,
832
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
833
+ "cache_key" => "foo-1.0.0",
834
+ "origin" => nil,
835
+ "source_options" => nil
836
+ },
837
+ },
838
+
839
+ "default_attributes" => {},
840
+ "override_attributes" => {},
841
+
842
+ "solution_dependencies" => { "Policyfile" => [], "dependencies" => {} }
843
+ }
844
+ end
845
+
846
+ it "includes the named run lists in the compiled policyfile" do
847
+ expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
848
+ end
849
+
850
+ it "generates a canonical revision string" do
851
+ expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
852
+ end
853
+
854
+ it "generates a revision id" do
855
+ expect(policyfile_lock.revision_id).to eq(expected_revision_id)
856
+ end
857
+
858
+ end
859
+
860
+ describe "building a policyfile lock from a policyfile compiler" do
861
+
862
+ include_context "setup git cookbooks"
863
+
864
+ let(:relative_paths_root) do
865
+ tempdir
866
+ end
867
+
868
+ let(:cached_cookbook_uri) { "https://supermarket.chef.io/api/v1/cookbooks/foo/versions/1.0.0/download" }
869
+
870
+ let(:cached_location_spec) do
871
+ double( "ChefDK::Policyfile::CookbookLocationSpecification",
872
+ mirrors_canonical_upstream?: true,
873
+ cache_key: "foo-1.0.0",
874
+ uri: cached_cookbook_uri,
875
+ source_options_for_lock: { "artifactserver" => cached_cookbook_uri, "version" => "1.0.0" })
876
+ end
877
+
878
+ let(:local_location_spec) do
879
+ double( "ChefDK::Policyfile::CookbookLocationSpecification",
880
+ mirrors_canonical_upstream?: false,
881
+ relative_paths_root: relative_paths_root,
882
+ relative_path: "bar",
883
+ source_options_for_lock: { "path" => "bar" })
884
+ end
885
+
886
+ let(:policyfile_solution_dependencies) do
887
+ ChefDK::Policyfile::SolutionDependencies.new.tap do |s|
888
+ s.add_policyfile_dep("foo", "~> 1.0")
889
+ s.add_cookbook_dep("foo", "1.0.0", [])
890
+ s.add_cookbook_dep("bar", "0.1.0", [])
891
+ end
892
+ end
893
+
894
+ let(:policyfile_default_attrs) do
895
+ {
896
+ "foo" => "bar",
897
+ "abc" => { "def" => { "ghi" => "xyz" } },
898
+ "baz" => {
899
+ "more_nested_stuff" => "yup",
900
+ "an_array" => ["a", "b", "c"]
901
+ }
902
+ }
903
+ end
904
+
905
+ let(:canonicalized_default_attrs) do
906
+ elements = [
907
+ %q{"abc":{"def":{"ghi":"xyz"}}},
908
+ %q{"baz":{"an_array":["a","b","c"],"more_nested_stuff":"yup"}},
909
+ %q{"foo":"bar"}
910
+ ]
911
+ "{" + elements.join(',') + "}"
912
+ end
913
+
914
+ let(:policyfile_override_attrs) do
915
+ {
916
+ "foo" => "bar",
917
+ "abc" => { "def" => { "ghi" => "xyz" } },
918
+ "baz" => {
919
+ "more_nested_stuff" => "yup",
920
+ "an_array" => ["a", "b", "c"]
921
+ }
922
+ }
923
+ end
924
+
925
+ let(:canonicalized_override_attrs) { canonicalized_default_attrs }
926
+
927
+ let(:policyfile_compiler) do
928
+ double( "ChefDK::PolicyfileCompiler",
929
+ name: "my-policyfile",
930
+ normalized_run_list: %w[recipe[foo::default] recipe[bar::default]],
931
+ normalized_named_run_lists: { "rl2" => %w[recipe[bar::default]] },
932
+ all_cookbook_location_specs: {"foo" => cached_location_spec, "bar" => local_location_spec},
933
+ solution_dependencies: policyfile_solution_dependencies,
934
+ default_attributes: policyfile_default_attrs,
935
+ override_attributes: policyfile_override_attrs )
936
+ end
937
+
938
+ let(:policyfile_lock) do
939
+ ChefDK::PolicyfileLock.build_from_compiler(policyfile_compiler, storage_config)
940
+ end
941
+
942
+
943
+ let(:expected_canonical_revision_string) do
944
+ <<-REVISION_STRING
945
+ name:my-policyfile
946
+ run-list-item:recipe[foo::default]
947
+ run-list-item:recipe[bar::default]
948
+ named-run-list:rl2;run-list-item:recipe[bar::default]
949
+ cookbook:foo;id:#{cookbook_foo_cksum}
950
+ cookbook:bar;id:#{cookbook_bar_cksum}
951
+ default_attributes:#{canonicalized_default_attrs}
952
+ override_attributes:#{canonicalized_override_attrs}
953
+ REVISION_STRING
954
+ end
955
+
956
+ let(:expected_revision_id) do
957
+ Digest::SHA256.new.hexdigest(expected_canonical_revision_string)
958
+ end
959
+
960
+ let(:compiled_policyfile) do
961
+ {
962
+
963
+ "revision_id" => expected_revision_id,
964
+
965
+ "name" => "my-policyfile",
966
+
967
+ "run_list" => ["recipe[foo::default]", "recipe[bar::default]"],
968
+
969
+ "named_run_lists" => { "rl2" => ["recipe[bar::default]"] },
970
+
971
+ "cookbook_locks" => {
972
+
973
+ "foo" => {
974
+ "version" => "1.0.0",
975
+ "identifier" => cookbook_foo_cksum,
976
+ "dotted_decimal_identifier" => cookbook_foo_cksum_dotted,
977
+ "cache_key" => "foo-1.0.0",
978
+ "origin" => cached_cookbook_uri,
979
+ "source_options" => { "artifactserver" => cached_cookbook_uri, "version" => "1.0.0" }
980
+ },
981
+
982
+ "bar" => {
983
+ "version" => "0.1.0",
984
+ "identifier" => cookbook_bar_cksum,
985
+ "dotted_decimal_identifier" => cookbook_bar_cksum_dotted,
986
+ "source" => "bar",
987
+ "cache_key" => nil,
988
+
989
+ "scm_info" => {
990
+ "scm" => "git",
991
+ "remote" => nil,
992
+ "revision" => current_rev,
993
+ "working_tree_clean" => true,
994
+ "published" => false,
995
+ "synchronized_remote_branches"=>[]
996
+ },
997
+ "source_options" => { "path" => "bar" }
998
+ }
999
+ },
1000
+
1001
+ "default_attributes" => {
1002
+ "foo" => "bar",
1003
+ "abc" => { "def" => { "ghi" => "xyz" } },
1004
+ "baz" => {
1005
+ "more_nested_stuff" => "yup",
1006
+ "an_array" => ["a", "b", "c"]
1007
+ }
1008
+ },
1009
+
1010
+ "override_attributes" => {
1011
+ "foo" => "bar",
1012
+ "abc" => { "def" => { "ghi" => "xyz" } },
1013
+ "baz" => {
1014
+ "more_nested_stuff" => "yup",
1015
+ "an_array" => ["a", "b", "c"]
1016
+ }
1017
+ },
1018
+ "solution_dependencies" => {
1019
+ "Policyfile" => [ [ "foo", "~> 1.0" ] ],
1020
+ "dependencies" => { "foo (1.0.0)" => [], "bar (0.1.0)" => [] }
1021
+ }
1022
+ }
1023
+ end
1024
+
1025
+ it "adds a cached cookbook lock generator for the compiler's cached cookbook" do
1026
+ expect(policyfile_lock.cookbook_locks).to have_key("foo")
1027
+ cb_lock = policyfile_lock.cookbook_locks["foo"]
1028
+ expect(cb_lock.origin).to eq(cached_location_spec.uri)
1029
+ expect(cb_lock.cache_key).to eq(cached_location_spec.cache_key)
1030
+ end
1031
+
1032
+ it "adds a local cookbook lock generator for the compiler's local cookbook" do
1033
+ expect(policyfile_lock.cookbook_locks).to have_key("bar")
1034
+ cb_lock = policyfile_lock.cookbook_locks["bar"]
1035
+ expect(cb_lock.source).to eq(local_location_spec.relative_path)
1036
+ end
1037
+
1038
+ it "sets named run lists on the policyfile lock" do
1039
+ expect(policyfile_lock.named_run_lists).to eq("rl2" => %w[recipe[bar::default]])
1040
+ end
1041
+
1042
+ it "generates a lockfile data structure" do
1043
+ expect(policyfile_lock.to_lock).to eq(compiled_policyfile)
1044
+ end
1045
+
1046
+ it "generates a canonical revision string" do
1047
+ expect(policyfile_lock.canonical_revision_string).to eq(expected_canonical_revision_string)
1048
+ end
1049
+
1050
+ it "generates a revision id" do
1051
+ expect(policyfile_lock.revision_id).to eq(expected_revision_id)
1052
+ end
1053
+
1054
+ end
1055
+
1056
+ end