chef-dk 0.14.25 → 0.15.9

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 (328) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +15 -12
  3. data/Gemfile.lock +56 -82
  4. data/LICENSE +201 -201
  5. data/acceptance/.shared/kitchen_acceptance/.kitchen.digitalocean.yml +27 -27
  6. data/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +288 -288
  7. data/acceptance/.shared/kitchen_acceptance/.kitchen.vagrant.yml +52 -52
  8. data/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb +51 -51
  9. data/acceptance/.shared/kitchen_acceptance/metadata.rb +1 -1
  10. data/acceptance/Gemfile.lock +18 -21
  11. data/acceptance/README.md +132 -132
  12. data/acceptance/trivial/.acceptance/acceptance-cookbook/.gitignore +2 -2
  13. data/acceptance/trivial/.acceptance/acceptance-cookbook/metadata.rb +2 -2
  14. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/destroy.rb +1 -1
  15. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/provision.rb +1 -1
  16. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/verify.rb +1 -1
  17. data/acceptance/trivial/.kitchen.yml +7 -7
  18. data/acceptance/trivial/test/integration/chefdk-current-install/inspec/chef_client_spec.rb +5 -5
  19. data/bin/chef +25 -25
  20. data/chef-dk.gemspec +1 -0
  21. data/lib/chef-dk.rb +19 -19
  22. data/lib/chef-dk/authenticated_http.rb +40 -40
  23. data/lib/chef-dk/chef_runner.rb +1 -1
  24. data/lib/chef-dk/cli.rb +2 -2
  25. data/lib/chef-dk/command/base.rb +79 -79
  26. data/lib/chef-dk/command/clean_policy_cookbooks.rb +116 -116
  27. data/lib/chef-dk/command/clean_policy_revisions.rb +113 -113
  28. data/lib/chef-dk/command/delete_policy.rb +122 -122
  29. data/lib/chef-dk/command/delete_policy_group.rb +122 -122
  30. data/lib/chef-dk/command/diff.rb +316 -316
  31. data/lib/chef-dk/command/env.rb +90 -90
  32. data/lib/chef-dk/command/exec.rb +45 -45
  33. data/lib/chef-dk/command/export.rb +2 -2
  34. data/lib/chef-dk/command/gem.rb +47 -47
  35. data/lib/chef-dk/command/generate.rb +2 -0
  36. data/lib/chef-dk/command/generator_commands/app.rb +107 -107
  37. data/lib/chef-dk/command/generator_commands/attribute.rb +37 -37
  38. data/lib/chef-dk/command/generator_commands/base.rb +148 -148
  39. data/lib/chef-dk/command/generator_commands/build_cookbook.rb +110 -0
  40. data/lib/chef-dk/command/generator_commands/cookbook.rb +21 -0
  41. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
  42. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
  43. data/lib/chef-dk/command/generator_commands/generator_generator.rb +177 -177
  44. data/lib/chef-dk/command/generator_commands/lwrp.rb +36 -36
  45. data/lib/chef-dk/command/generator_commands/policyfile.rb +127 -127
  46. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
  47. data/lib/chef-dk/command/generator_commands/repo.rb +125 -125
  48. data/lib/chef-dk/command/generator_commands/template.rb +46 -46
  49. data/lib/chef-dk/command/install.rb +121 -121
  50. data/lib/chef-dk/command/provision.rb +438 -438
  51. data/lib/chef-dk/command/push.rb +118 -118
  52. data/lib/chef-dk/command/push_archive.rb +126 -126
  53. data/lib/chef-dk/command/shell_init.rb +180 -180
  54. data/lib/chef-dk/command/show_policy.rb +165 -165
  55. data/lib/chef-dk/command/undelete.rb +155 -155
  56. data/lib/chef-dk/command/update.rb +148 -148
  57. data/lib/chef-dk/command/verify.rb +9 -11
  58. data/lib/chef-dk/completions/bash.sh.erb +5 -5
  59. data/lib/chef-dk/completions/chef.fish.erb +10 -10
  60. data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
  61. data/lib/chef-dk/configurable.rb +69 -69
  62. data/lib/chef-dk/cookbook_metadata.rb +45 -45
  63. data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
  64. data/lib/chef-dk/cookbook_profiler/git.rb +151 -151
  65. data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
  66. data/lib/chef-dk/cookbook_profiler/null_scm.rb +32 -32
  67. data/lib/chef-dk/exceptions.rb +129 -129
  68. data/lib/chef-dk/helpers.rb +24 -17
  69. data/lib/chef-dk/pager.rb +106 -106
  70. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +138 -138
  71. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +54 -54
  72. data/lib/chef-dk/policyfile/community_cookbook_source.rb +97 -97
  73. data/lib/chef-dk/policyfile/comparison_base.rb +124 -124
  74. data/lib/chef-dk/policyfile/cookbook_location_specification.rb +154 -154
  75. data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
  76. data/lib/chef-dk/policyfile/cookbook_sources.rb +22 -22
  77. data/lib/chef-dk/policyfile/delivery_supermarket_source.rb +90 -90
  78. data/lib/chef-dk/policyfile/differ.rb +266 -266
  79. data/lib/chef-dk/policyfile/dsl.rb +261 -261
  80. data/lib/chef-dk/policyfile/lister.rb +232 -232
  81. data/lib/chef-dk/policyfile/null_cookbook_source.rb +45 -45
  82. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
  83. data/lib/chef-dk/policyfile/reports/install.rb +70 -70
  84. data/lib/chef-dk/policyfile/reports/table_printer.rb +58 -58
  85. data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
  86. data/lib/chef-dk/policyfile/solution_dependencies.rb +298 -298
  87. data/lib/chef-dk/policyfile/storage_config.rb +100 -100
  88. data/lib/chef-dk/policyfile/undo_record.rb +142 -142
  89. data/lib/chef-dk/policyfile/undo_stack.rb +130 -130
  90. data/lib/chef-dk/policyfile/uploader.rb +213 -213
  91. data/lib/chef-dk/policyfile_compiler.rb +419 -419
  92. data/lib/chef-dk/policyfile_lock.rb +552 -552
  93. data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
  94. data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +125 -125
  95. data/lib/chef-dk/policyfile_services/export_repo.rb +421 -421
  96. data/lib/chef-dk/policyfile_services/install.rb +126 -126
  97. data/lib/chef-dk/policyfile_services/push_archive.rb +204 -204
  98. data/lib/chef-dk/policyfile_services/rm_policy.rb +142 -142
  99. data/lib/chef-dk/policyfile_services/rm_policy_group.rb +86 -86
  100. data/lib/chef-dk/policyfile_services/show_policy.rb +237 -237
  101. data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
  102. data/lib/chef-dk/policyfile_services/update_attributes.rb +104 -104
  103. data/lib/chef-dk/service_exception_inspectors.rb +25 -25
  104. data/lib/chef-dk/service_exception_inspectors/base.rb +40 -40
  105. data/lib/chef-dk/service_exception_inspectors/http.rb +121 -121
  106. data/lib/chef-dk/service_exceptions.rb +143 -143
  107. data/lib/chef-dk/shell_out.rb +36 -36
  108. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +3 -3
  109. data/lib/chef-dk/skeletons/code_generator/files/default/build-cookbook/.kitchen.yml +21 -0
  110. data/lib/chef-dk/skeletons/code_generator/files/default/build-cookbook/README.md +146 -0
  111. data/lib/chef-dk/skeletons/code_generator/files/default/build-cookbook/test-fixture-recipe.rb +7 -0
  112. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +102 -102
  113. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
  114. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +54 -54
  115. data/lib/chef-dk/skeletons/code_generator/files/default/delivery-config.json +10 -0
  116. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +16 -16
  117. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +28 -28
  118. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -27
  119. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +7 -7
  120. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +3 -3
  121. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +8 -8
  122. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +58 -58
  123. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
  124. data/lib/chef-dk/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -6
  125. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
  126. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
  127. data/lib/chef-dk/skeletons/code_generator/files/default/repo/policies/README.md +24 -24
  128. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +9 -9
  129. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
  130. data/lib/chef-dk/skeletons/code_generator/files/default/serverspec_spec_helper.rb +8 -8
  131. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +2 -2
  132. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper_policyfile.rb +2 -2
  133. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
  134. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +97 -97
  135. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +12 -12
  136. data/lib/chef-dk/skeletons/code_generator/recipes/build_cookbook.rb +88 -0
  137. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +6 -0
  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.gplv2.erb +339 -339
  146. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
  147. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
  148. data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -25
  149. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
  150. data/lib/chef-dk/skeletons/code_generator/templates/default/build-cookbook/Berksfile.erb +20 -0
  151. data/lib/chef-dk/skeletons/code_generator/templates/default/build-cookbook/metadata.rb.erb +9 -0
  152. data/lib/chef-dk/skeletons/code_generator/templates/default/build-cookbook/recipe.rb.erb +8 -0
  153. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +3 -2
  154. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +3 -2
  155. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +7 -7
  156. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -5
  157. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +20 -20
  158. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +11 -11
  159. data/lib/chef-dk/skeletons/code_generator/templates/default/serverspec_default_spec.rb.erb +9 -9
  160. data/lib/chef-dk/ui.rb +58 -58
  161. data/lib/chef-dk/version.rb +1 -1
  162. data/lib/kitchen/provisioner/policyfile_zero.rb +195 -195
  163. data/omnibus_overrides.rb +2 -1
  164. data/spec/shared/a_file_generator.rb +125 -125
  165. data/spec/shared/a_generated_file.rb +12 -12
  166. data/spec/shared/command_with_ui_object.rb +11 -11
  167. data/spec/shared/fixture_cookbook_checksums.rb +47 -47
  168. data/spec/shared/setup_git_cookbooks.rb +53 -53
  169. data/spec/spec_helper.rb +51 -51
  170. data/spec/test_helpers.rb +84 -84
  171. data/spec/unit/chef_runner_spec.rb +1 -1
  172. data/spec/unit/cli_spec.rb +23 -6
  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/build_cookbook_spec.rb +309 -0
  186. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +32 -32
  187. data/spec/unit/command/generator_commands/cookbook_spec.rb +98 -4
  188. data/spec/unit/command/generator_commands/generator_generator_spec.rb +229 -229
  189. data/spec/unit/command/generator_commands/lwrp_spec.rb +32 -32
  190. data/spec/unit/command/generator_commands/policyfile_spec.rb +225 -225
  191. data/spec/unit/command/generator_commands/recipe_spec.rb +34 -34
  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 +1 -3
  202. data/spec/unit/commands_map_spec.rb +57 -57
  203. data/spec/unit/configurable_spec.rb +41 -41
  204. data/spec/unit/cookbook_metadata_spec.rb +98 -98
  205. data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
  206. data/spec/unit/cookbook_profiler/identifiers_spec.rb +83 -83
  207. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
  208. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
  209. data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
  210. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
  211. data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -5
  212. data/spec/unit/fixtures/configurable/test_configurable.rb +10 -10
  213. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  214. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
  215. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  216. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
  217. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  218. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  219. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
  220. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
  221. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
  222. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
  223. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
  224. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
  225. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
  226. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
  227. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
  228. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
  229. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
  230. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
  231. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
  232. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
  233. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
  234. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +36 -36
  235. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
  236. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
  237. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
  238. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
  239. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
  240. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
  241. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
  242. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
  243. data/spec/unit/fixtures/example_cookbook/README.md +4 -4
  244. data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
  245. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
  246. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
  247. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
  248. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
  249. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
  250. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
  251. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
  252. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
  253. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
  254. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
  255. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
  256. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
  257. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
  258. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
  259. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
  260. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
  261. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
  262. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
  263. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
  264. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
  265. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
  266. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
  267. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
  268. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
  269. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
  270. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
  271. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
  272. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
  273. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
  274. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
  275. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
  276. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  277. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  278. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  279. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  280. data/spec/unit/gemfile_util_spec.rb +41 -0
  281. data/spec/unit/helpers_spec.rb +19 -0
  282. data/spec/unit/pager_spec.rb +119 -119
  283. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -93
  284. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +34 -34
  285. data/spec/unit/policyfile/community_cookbook_source_spec.rb +84 -84
  286. data/spec/unit/policyfile/comparison_base_spec.rb +343 -343
  287. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +277 -277
  288. data/spec/unit/policyfile/cookbook_locks_spec.rb +529 -529
  289. data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +130 -130
  290. data/spec/unit/policyfile/differ_spec.rb +687 -687
  291. data/spec/unit/policyfile/lister_spec.rb +272 -272
  292. data/spec/unit/policyfile/null_cookbook_source_spec.rb +35 -35
  293. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
  294. data/spec/unit/policyfile/reports/install_spec.rb +115 -115
  295. data/spec/unit/policyfile/reports/upload_spec.rb +96 -96
  296. data/spec/unit/policyfile/solution_dependencies_spec.rb +145 -145
  297. data/spec/unit/policyfile/storage_config_spec.rb +172 -172
  298. data/spec/unit/policyfile/undo_record_spec.rb +260 -260
  299. data/spec/unit/policyfile/undo_stack_spec.rb +266 -266
  300. data/spec/unit/policyfile/uploader_spec.rb +410 -410
  301. data/spec/unit/policyfile_demands_spec.rb +1203 -1203
  302. data/spec/unit/policyfile_evaluation_spec.rb +642 -642
  303. data/spec/unit/policyfile_lock_build_spec.rb +1056 -1056
  304. data/spec/unit/policyfile_lock_install_spec.rb +138 -138
  305. data/spec/unit/policyfile_lock_serialization_spec.rb +425 -425
  306. data/spec/unit/policyfile_lock_validation_spec.rb +611 -611
  307. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
  308. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +275 -275
  309. data/spec/unit/policyfile_services/export_repo_spec.rb +481 -481
  310. data/spec/unit/policyfile_services/install_spec.rb +211 -211
  311. data/spec/unit/policyfile_services/push_archive_spec.rb +378 -378
  312. data/spec/unit/policyfile_services/push_spec.rb +233 -233
  313. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +241 -241
  314. data/spec/unit/policyfile_services/rm_policy_spec.rb +266 -266
  315. data/spec/unit/policyfile_services/show_policy_spec.rb +889 -889
  316. data/spec/unit/policyfile_services/undelete_spec.rb +304 -304
  317. data/spec/unit/policyfile_services/update_attributes_spec.rb +217 -217
  318. data/spec/unit/service_exception_inspectors/base_spec.rb +43 -43
  319. data/spec/unit/service_exception_inspectors/http_spec.rb +140 -140
  320. data/spec/unit/shell_out_spec.rb +34 -34
  321. data/tasks/bin/bundle-platform +6 -2
  322. data/tasks/bin/bundle-platform.bat +0 -0
  323. data/tasks/bin/create-override-gemfile +0 -0
  324. data/tasks/bundle_util.rb +18 -2
  325. data/tasks/gemfile_util.rb +53 -8
  326. data/version_policy.rb +9 -1
  327. data/warning.txt +9 -9
  328. metadata +30 -3
@@ -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