chef-dk 0.9.0 → 0.10.0

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