chef-dk 2.6.2 → 3.0.36

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 (377) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +126 -121
  3. data/Gemfile.lock +812 -807
  4. data/LICENSE +201 -201
  5. data/README.md +333 -333
  6. data/Rakefile +74 -74
  7. data/acceptance/.shared/kitchen_acceptance/.kitchen.digitalocean.yml +27 -27
  8. data/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +287 -287
  9. data/acceptance/.shared/kitchen_acceptance/.kitchen.vagrant.yml +52 -52
  10. data/acceptance/.shared/kitchen_acceptance/libraries/kitchen.rb +51 -51
  11. data/acceptance/.shared/kitchen_acceptance/metadata.rb +1 -1
  12. data/acceptance/Gemfile +21 -21
  13. data/acceptance/Gemfile.lock +334 -334
  14. data/acceptance/README.md +132 -132
  15. data/acceptance/trivial/.acceptance/acceptance-cookbook/.gitignore +2 -2
  16. data/acceptance/trivial/.acceptance/acceptance-cookbook/metadata.rb +2 -2
  17. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/destroy.rb +1 -1
  18. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/provision.rb +1 -1
  19. data/acceptance/trivial/.acceptance/acceptance-cookbook/recipes/verify.rb +1 -1
  20. data/acceptance/trivial/.kitchen.yml +7 -7
  21. data/acceptance/trivial/test/integration/chefdk-current-install/inspec/chef_client_spec.rb +5 -5
  22. data/bin/chef +25 -25
  23. data/chef-dk.gemspec +60 -60
  24. data/lib/chef-dk.rb +19 -19
  25. data/lib/chef-dk/authenticated_http.rb +22 -22
  26. data/lib/chef-dk/builtin_commands.rb +59 -59
  27. data/lib/chef-dk/chef_runner.rb +114 -114
  28. data/lib/chef-dk/chef_server_api_multi.rb +73 -73
  29. data/lib/chef-dk/cli.rb +201 -201
  30. data/lib/chef-dk/command/base.rb +79 -79
  31. data/lib/chef-dk/command/clean_policy_cookbooks.rb +114 -114
  32. data/lib/chef-dk/command/clean_policy_revisions.rb +111 -111
  33. data/lib/chef-dk/command/delete_policy.rb +120 -120
  34. data/lib/chef-dk/command/delete_policy_group.rb +120 -120
  35. data/lib/chef-dk/command/diff.rb +315 -315
  36. data/lib/chef-dk/command/env.rb +89 -89
  37. data/lib/chef-dk/command/exec.rb +44 -44
  38. data/lib/chef-dk/command/export.rb +155 -155
  39. data/lib/chef-dk/command/gem.rb +47 -47
  40. data/lib/chef-dk/command/generate.rb +125 -125
  41. data/lib/chef-dk/command/generator_commands.rb +83 -83
  42. data/lib/chef-dk/command/generator_commands/app.rb +106 -106
  43. data/lib/chef-dk/command/generator_commands/attribute.rb +36 -36
  44. data/lib/chef-dk/command/generator_commands/base.rb +157 -157
  45. data/lib/chef-dk/command/generator_commands/build_cookbook.rb +125 -125
  46. data/lib/chef-dk/command/generator_commands/chef_exts/generator_desc_resource.rb +85 -85
  47. data/lib/chef-dk/command/generator_commands/chef_exts/quieter_doc_formatter.rb +38 -38
  48. data/lib/chef-dk/command/generator_commands/chef_exts/recipe_dsl_ext.rb +39 -39
  49. data/lib/chef-dk/command/generator_commands/cookbook.rb +241 -241
  50. data/lib/chef-dk/command/generator_commands/cookbook_code_file.rb +100 -100
  51. data/lib/chef-dk/command/generator_commands/cookbook_file.rb +45 -45
  52. data/lib/chef-dk/command/generator_commands/generator_generator.rb +174 -174
  53. data/lib/chef-dk/command/generator_commands/helpers.rb +36 -36
  54. data/lib/chef-dk/command/generator_commands/policyfile.rb +124 -126
  55. data/lib/chef-dk/command/generator_commands/recipe.rb +36 -36
  56. data/lib/chef-dk/command/generator_commands/repo.rb +123 -123
  57. data/lib/chef-dk/command/generator_commands/resource.rb +36 -36
  58. data/lib/chef-dk/command/generator_commands/template.rb +46 -46
  59. data/lib/chef-dk/command/install.rb +120 -120
  60. data/lib/chef-dk/command/provision.rb +436 -436
  61. data/lib/chef-dk/command/push.rb +117 -117
  62. data/lib/chef-dk/command/push_archive.rb +125 -125
  63. data/lib/chef-dk/command/shell_init.rb +179 -179
  64. data/lib/chef-dk/command/show_policy.rb +163 -163
  65. data/lib/chef-dk/command/undelete.rb +154 -154
  66. data/lib/chef-dk/command/update.rb +133 -133
  67. data/lib/chef-dk/command/verify.rb +629 -629
  68. data/lib/chef-dk/commands_map.rb +113 -113
  69. data/lib/chef-dk/completions/bash.sh.erb +5 -5
  70. data/lib/chef-dk/completions/chef.fish.erb +10 -10
  71. data/lib/chef-dk/completions/zsh.zsh.erb +21 -21
  72. data/lib/chef-dk/component_test.rb +227 -227
  73. data/lib/chef-dk/configurable.rb +88 -88
  74. data/lib/chef-dk/cookbook_metadata.rb +45 -45
  75. data/lib/chef-dk/cookbook_omnifetch.rb +32 -32
  76. data/lib/chef-dk/cookbook_profiler/git.rb +152 -151
  77. data/lib/chef-dk/cookbook_profiler/identifiers.rb +72 -72
  78. data/lib/chef-dk/cookbook_profiler/null_scm.rb +31 -31
  79. data/lib/chef-dk/exceptions.rb +151 -150
  80. data/lib/chef-dk/generator.rb +165 -165
  81. data/lib/chef-dk/helpers.rb +176 -176
  82. data/lib/chef-dk/pager.rb +104 -105
  83. data/lib/chef-dk/policyfile/artifactory_cookbook_source.rb +102 -102
  84. data/lib/chef-dk/policyfile/attribute_merge_checker.rb +110 -110
  85. data/lib/chef-dk/policyfile/chef_repo_cookbook_source.rb +138 -138
  86. data/lib/chef-dk/policyfile/chef_server_cookbook_source.rb +99 -99
  87. data/lib/chef-dk/policyfile/chef_server_lock_fetcher.rb +167 -164
  88. data/lib/chef-dk/policyfile/community_cookbook_source.rb +95 -95
  89. data/lib/chef-dk/policyfile/comparison_base.rb +123 -123
  90. data/lib/chef-dk/policyfile/cookbook_location_specification.rb +154 -154
  91. data/lib/chef-dk/policyfile/cookbook_locks.rb +466 -466
  92. data/lib/chef-dk/policyfile/cookbook_sources.rb +23 -23
  93. data/lib/chef-dk/policyfile/delivery_supermarket_source.rb +89 -89
  94. data/lib/chef-dk/policyfile/differ.rb +263 -263
  95. data/lib/chef-dk/policyfile/dsl.rb +288 -288
  96. data/lib/chef-dk/policyfile/git_lock_fetcher.rb +265 -0
  97. data/lib/chef-dk/policyfile/included_policies_cookbook_source.rb +156 -156
  98. data/lib/chef-dk/policyfile/lister.rb +229 -229
  99. data/lib/chef-dk/policyfile/local_lock_fetcher.rb +129 -123
  100. data/lib/chef-dk/policyfile/lock_applier.rb +80 -80
  101. data/lib/chef-dk/policyfile/null_cookbook_source.rb +49 -49
  102. data/lib/chef-dk/policyfile/policyfile_location_specification.rb +125 -122
  103. data/lib/chef-dk/policyfile/read_cookbook_for_compat_mode_upload.rb +124 -124
  104. data/lib/chef-dk/policyfile/reports/install.rb +69 -69
  105. data/lib/chef-dk/policyfile/reports/table_printer.rb +57 -57
  106. data/lib/chef-dk/policyfile/reports/upload.rb +70 -70
  107. data/lib/chef-dk/policyfile/solution_dependencies.rb +311 -312
  108. data/lib/chef-dk/policyfile/source_uri.rb +57 -57
  109. data/lib/chef-dk/policyfile/storage_config.rb +112 -102
  110. data/lib/chef-dk/policyfile/undo_record.rb +139 -139
  111. data/lib/chef-dk/policyfile/undo_stack.rb +128 -128
  112. data/lib/chef-dk/policyfile/uploader.rb +213 -213
  113. data/lib/chef-dk/policyfile_compiler.rb +528 -528
  114. data/lib/chef-dk/policyfile_lock.rb +581 -581
  115. data/lib/chef-dk/policyfile_services/clean_policies.rb +95 -95
  116. data/lib/chef-dk/policyfile_services/clean_policy_cookbooks.rb +123 -123
  117. data/lib/chef-dk/policyfile_services/export_repo.rb +419 -420
  118. data/lib/chef-dk/policyfile_services/install.rb +162 -162
  119. data/lib/chef-dk/policyfile_services/push.rb +112 -112
  120. data/lib/chef-dk/policyfile_services/push_archive.rb +164 -200
  121. data/lib/chef-dk/policyfile_services/rm_policy.rb +141 -141
  122. data/lib/chef-dk/policyfile_services/rm_policy_group.rb +85 -85
  123. data/lib/chef-dk/policyfile_services/show_policy.rb +234 -236
  124. data/lib/chef-dk/policyfile_services/undelete.rb +108 -108
  125. data/lib/chef-dk/policyfile_services/update_attributes.rb +110 -110
  126. data/lib/chef-dk/service_exception_inspectors.rb +24 -24
  127. data/lib/chef-dk/service_exception_inspectors/base.rb +39 -39
  128. data/lib/chef-dk/service_exception_inspectors/http.rb +119 -119
  129. data/lib/chef-dk/service_exceptions.rb +142 -142
  130. data/lib/chef-dk/shell_out.rb +36 -36
  131. data/lib/chef-dk/skeletons/code_generator/files/default/Berksfile +4 -4
  132. data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/.kitchen.yml +21 -21
  133. data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/README.md +146 -146
  134. data/lib/chef-dk/skeletons/code_generator/files/default/build_cookbook/test-fixture-recipe.rb +9 -9
  135. data/lib/chef-dk/skeletons/code_generator/files/default/chefignore +104 -107
  136. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README-policy.md +9 -9
  137. data/lib/chef-dk/skeletons/code_generator/files/default/cookbook_readmes/README.md +66 -54
  138. data/lib/chef-dk/skeletons/code_generator/files/default/delivery-config.json +17 -17
  139. data/lib/chef-dk/skeletons/code_generator/files/default/delivery-project.toml +36 -36
  140. data/lib/chef-dk/skeletons/code_generator/files/default/gitignore +22 -22
  141. data/lib/chef-dk/skeletons/code_generator/files/default/repo/README.md +24 -24
  142. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/README.md +27 -27
  143. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/attributes/default.rb +8 -8
  144. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/metadata.rb +7 -7
  145. data/lib/chef-dk/skeletons/code_generator/files/default/repo/cookbooks/example/recipes/default.rb +9 -9
  146. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/README.md +56 -56
  147. data/lib/chef-dk/skeletons/code_generator/files/default/repo/data_bags/example/example_item.json +3 -3
  148. data/lib/chef-dk/skeletons/code_generator/files/default/repo/dot-chef-repo.txt +6 -6
  149. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/README.md +9 -9
  150. data/lib/chef-dk/skeletons/code_generator/files/default/repo/environments/example.json +12 -12
  151. data/lib/chef-dk/skeletons/code_generator/files/default/repo/policies/README.md +24 -24
  152. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/README.md +9 -9
  153. data/lib/chef-dk/skeletons/code_generator/files/default/repo/roles/example.json +12 -12
  154. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper.rb +3 -3
  155. data/lib/chef-dk/skeletons/code_generator/files/default/spec_helper_policyfile.rb +3 -3
  156. data/lib/chef-dk/skeletons/code_generator/metadata.rb +8 -8
  157. data/lib/chef-dk/skeletons/code_generator/recipes/app.rb +89 -89
  158. data/lib/chef-dk/skeletons/code_generator/recipes/attribute.rb +13 -13
  159. data/lib/chef-dk/skeletons/code_generator/recipes/build_cookbook.rb +177 -177
  160. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook.rb +158 -152
  161. data/lib/chef-dk/skeletons/code_generator/recipes/cookbook_file.rb +25 -25
  162. data/lib/chef-dk/skeletons/code_generator/recipes/helpers.rb +21 -21
  163. data/lib/chef-dk/skeletons/code_generator/recipes/policyfile.rb +9 -9
  164. data/lib/chef-dk/skeletons/code_generator/recipes/recipe.rb +52 -52
  165. data/lib/chef-dk/skeletons/code_generator/recipes/repo.rb +68 -68
  166. data/lib/chef-dk/skeletons/code_generator/recipes/resource.rb +13 -13
  167. data/lib/chef-dk/skeletons/code_generator/recipes/template.rb +32 -32
  168. data/lib/chef-dk/skeletons/code_generator/templates/default/CHANGELOG.md.erb +11 -0
  169. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.all_rights.erb +3 -3
  170. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.apachev2.erb +201 -201
  171. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv2.erb +339 -339
  172. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.gplv3.erb +674 -674
  173. data/lib/chef-dk/skeletons/code_generator/templates/default/LICENSE.mit.erb +21 -21
  174. data/lib/chef-dk/skeletons/code_generator/templates/default/Policyfile.rb.erb +25 -25
  175. data/lib/chef-dk/skeletons/code_generator/templates/default/README.md.erb +4 -4
  176. data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/Berksfile.erb +7 -7
  177. data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/metadata.rb.erb +10 -10
  178. data/lib/chef-dk/skeletons/code_generator/templates/default/build_cookbook/recipe.rb.erb +8 -8
  179. data/lib/chef-dk/skeletons/code_generator/templates/default/helpers.rb.erb +39 -39
  180. data/lib/chef-dk/skeletons/code_generator/templates/default/inspec_default_test.rb.erb +18 -18
  181. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen.yml.erb +26 -26
  182. data/lib/chef-dk/skeletons/code_generator/templates/default/kitchen_policyfile.yml.erb +33 -33
  183. data/lib/chef-dk/skeletons/code_generator/templates/default/metadata.rb.erb +20 -20
  184. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe.rb.erb +5 -5
  185. data/lib/chef-dk/skeletons/code_generator/templates/default/recipe_spec.rb.erb +35 -35
  186. data/lib/chef-dk/skeletons/code_generator/templates/default/repo/gitignore.erb +128 -128
  187. data/lib/chef-dk/skeletons/code_generator/templates/default/resource.rb.erb +1 -1
  188. data/lib/chef-dk/ui.rb +57 -57
  189. data/lib/chef-dk/version.rb +20 -20
  190. data/lib/kitchen/provisioner/policyfile_zero.rb +195 -195
  191. data/omnibus_overrides.rb +25 -25
  192. data/spec/shared/a_file_generator.rb +125 -125
  193. data/spec/shared/a_generated_file.rb +12 -12
  194. data/spec/shared/command_with_ui_object.rb +11 -11
  195. data/spec/shared/custom_generator_cookbook.rb +136 -136
  196. data/spec/shared/fixture_cookbook_checksums.rb +46 -46
  197. data/spec/shared/setup_git_committer_config.rb +54 -54
  198. data/spec/shared/setup_git_cookbooks.rb +53 -53
  199. data/spec/spec_helper.rb +51 -51
  200. data/spec/test_helpers.rb +84 -84
  201. data/spec/unit/chef_runner_spec.rb +139 -139
  202. data/spec/unit/chef_server_api_multi_spec.rb +120 -120
  203. data/spec/unit/cli_spec.rb +377 -377
  204. data/spec/unit/command/base_spec.rb +172 -172
  205. data/spec/unit/command/clean_policy_cookbooks_spec.rb +180 -180
  206. data/spec/unit/command/clean_policy_revisions_spec.rb +180 -180
  207. data/spec/unit/command/delete_policy_group_spec.rb +206 -206
  208. data/spec/unit/command/delete_policy_spec.rb +206 -206
  209. data/spec/unit/command/diff_spec.rb +311 -311
  210. data/spec/unit/command/env_spec.rb +52 -52
  211. data/spec/unit/command/exec_spec.rb +178 -178
  212. data/spec/unit/command/export_spec.rb +199 -199
  213. data/spec/unit/command/generate_spec.rb +142 -142
  214. data/spec/unit/command/generator_commands/app_spec.rb +166 -166
  215. data/spec/unit/command/generator_commands/attribute_spec.rb +31 -31
  216. data/spec/unit/command/generator_commands/base_spec.rb +181 -181
  217. data/spec/unit/command/generator_commands/build_cookbook_spec.rb +377 -377
  218. data/spec/unit/command/generator_commands/chef_exts/generator_desc_resource_spec.rb +97 -97
  219. data/spec/unit/command/generator_commands/chef_exts/recipe_dsl_ext_spec.rb +111 -111
  220. data/spec/unit/command/generator_commands/cookbook_file_spec.rb +31 -31
  221. data/spec/unit/command/generator_commands/cookbook_spec.rb +765 -756
  222. data/spec/unit/command/generator_commands/generator_generator_spec.rb +227 -227
  223. data/spec/unit/command/generator_commands/helpers_spec.rb +31 -31
  224. data/spec/unit/command/generator_commands/policyfile_spec.rb +223 -223
  225. data/spec/unit/command/generator_commands/recipe_spec.rb +37 -37
  226. data/spec/unit/command/generator_commands/repo_spec.rb +374 -374
  227. data/spec/unit/command/generator_commands/resource_spec.rb +31 -31
  228. data/spec/unit/command/generator_commands/template_spec.rb +31 -31
  229. data/spec/unit/command/install_spec.rb +179 -179
  230. data/spec/unit/command/provision_spec.rb +589 -589
  231. data/spec/unit/command/push_archive_spec.rb +153 -153
  232. data/spec/unit/command/push_spec.rb +198 -198
  233. data/spec/unit/command/shell_init_spec.rb +339 -339
  234. data/spec/unit/command/show_policy_spec.rb +234 -234
  235. data/spec/unit/command/undelete_spec.rb +244 -244
  236. data/spec/unit/command/update_spec.rb +283 -283
  237. data/spec/unit/command/verify_spec.rb +341 -341
  238. data/spec/unit/commands_map_spec.rb +57 -57
  239. data/spec/unit/component_test_spec.rb +128 -128
  240. data/spec/unit/configurable_spec.rb +68 -68
  241. data/spec/unit/cookbook_metadata_spec.rb +96 -96
  242. data/spec/unit/cookbook_profiler/git_spec.rb +176 -176
  243. data/spec/unit/cookbook_profiler/identifiers_spec.rb +81 -81
  244. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_one.rb +9 -9
  245. data/spec/unit/fixtures/chef-runner-cookbooks/test_cookbook/recipes/recipe_two.rb +9 -9
  246. data/spec/unit/fixtures/command/cli_test_command.rb +26 -26
  247. data/spec/unit/fixtures/command/explicit_path_example.rb +7 -7
  248. data/spec/unit/fixtures/configurable/test_config_loader.rb +5 -5
  249. data/spec/unit/fixtures/configurable/test_configurable.rb +10 -10
  250. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  251. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/Berksfile +3 -3
  252. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  253. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/chefignore +96 -96
  254. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  255. data/spec/unit/fixtures/cookbook_cache/baz-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  256. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/.kitchen.yml +16 -16
  257. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/Berksfile +3 -3
  258. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/README.md +4 -4
  259. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/chefignore +96 -96
  260. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/metadata.rb +8 -8
  261. data/spec/unit/fixtures/cookbook_cache/dep_of_bar-1.2.3/recipes/default.rb +8 -8
  262. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/.kitchen.yml +16 -16
  263. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/Berksfile +3 -3
  264. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/README.md +4 -4
  265. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/chefignore +96 -96
  266. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/metadata.rb +8 -8
  267. data/spec/unit/fixtures/cookbook_cache/foo-1.0.0/recipes/default.rb +8 -8
  268. data/spec/unit/fixtures/cookbooks_api/chef_server_universe.json +56 -56
  269. data/spec/unit/fixtures/cookbooks_api/pruned_chef_server_universe.json +30 -30
  270. data/spec/unit/fixtures/cookbooks_api/pruned_small_universe.json +1321 -1321
  271. data/spec/unit/fixtures/cookbooks_api/small_universe.json +2987 -2987
  272. data/spec/unit/fixtures/cookbooks_api/universe.json +1 -1
  273. data/spec/unit/fixtures/cookbooks_api/update_fixtures.rb +33 -33
  274. data/spec/unit/fixtures/dev_cookbooks/README.md +16 -16
  275. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/integration_test +2 -2
  276. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/berkshelf/verify_me +5 -5
  277. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/chef/verify_me +3 -3
  278. data/spec/unit/fixtures/eg_omnibus_dir/valid/embedded/apps/test-kitchen/verify_me +2 -2
  279. data/spec/unit/fixtures/example_cookbook/.gitignore +17 -17
  280. data/spec/unit/fixtures/example_cookbook/.kitchen.yml +16 -16
  281. data/spec/unit/fixtures/example_cookbook/Berksfile +3 -3
  282. data/spec/unit/fixtures/example_cookbook/README.md +4 -4
  283. data/spec/unit/fixtures/example_cookbook/chefignore +96 -96
  284. data/spec/unit/fixtures/example_cookbook/metadata.rb +8 -8
  285. data/spec/unit/fixtures/example_cookbook/recipes/default.rb +8 -8
  286. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.gitignore +17 -17
  287. data/spec/unit/fixtures/example_cookbook_metadata_json_only/.kitchen.yml +16 -16
  288. data/spec/unit/fixtures/example_cookbook_metadata_json_only/Berksfile +3 -3
  289. data/spec/unit/fixtures/example_cookbook_metadata_json_only/README.md +4 -4
  290. data/spec/unit/fixtures/example_cookbook_metadata_json_only/chefignore +96 -96
  291. data/spec/unit/fixtures/example_cookbook_metadata_json_only/metadata.json +5 -5
  292. data/spec/unit/fixtures/example_cookbook_metadata_json_only/recipes/default.rb +8 -8
  293. data/spec/unit/fixtures/example_cookbook_no_metadata/.gitignore +17 -17
  294. data/spec/unit/fixtures/example_cookbook_no_metadata/.kitchen.yml +16 -16
  295. data/spec/unit/fixtures/example_cookbook_no_metadata/Berksfile +3 -3
  296. data/spec/unit/fixtures/example_cookbook_no_metadata/README.md +4 -4
  297. data/spec/unit/fixtures/example_cookbook_no_metadata/chefignore +96 -96
  298. data/spec/unit/fixtures/example_cookbook_no_metadata/recipes/default.rb +8 -8
  299. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/README.md +4 -4
  300. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/chefignore +96 -96
  301. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/metadata.rb +8 -8
  302. data/spec/unit/fixtures/local_path_cookbooks/another-local-cookbook/recipes/default.rb +8 -8
  303. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/Berksfile +3 -3
  304. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/README.md +4 -4
  305. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/chefignore +96 -96
  306. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/metadata.rb +9 -9
  307. data/spec/unit/fixtures/local_path_cookbooks/cookbook-with-a-dep/recipes/default.rb +8 -8
  308. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/.kitchen.yml +16 -16
  309. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/Berksfile +3 -3
  310. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/README.md +4 -4
  311. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/chefignore +96 -96
  312. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/metadata.rb +8 -8
  313. data/spec/unit/fixtures/local_path_cookbooks/local-cookbook/recipes/default.rb +8 -8
  314. data/spec/unit/fixtures/local_path_cookbooks/metadata-missing/README.md +2 -2
  315. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/.kitchen.yml +16 -16
  316. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/README.md +4 -4
  317. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/metadata.rb +8 -8
  318. data/spec/unit/fixtures/local_path_cookbooks/noignore-f59ee7a5bca6a4e606b67f7f856b768d847c39bb/recipes/default.rb +8 -8
  319. data/spec/unit/generator_spec.rb +119 -119
  320. data/spec/unit/pager_spec.rb +117 -117
  321. data/spec/unit/policyfile/artifactory_cookbook_source_spec.rb +59 -59
  322. data/spec/unit/policyfile/attribute_merge_checker_spec.rb +80 -80
  323. data/spec/unit/policyfile/chef_repo_cookbook_source_spec.rb +93 -93
  324. data/spec/unit/policyfile/chef_server_cookbook_source_spec.rb +55 -55
  325. data/spec/unit/policyfile/chef_server_lock_fetcher_spec.rb +161 -161
  326. data/spec/unit/policyfile/community_cookbook_source_spec.rb +83 -83
  327. data/spec/unit/policyfile/comparison_base_spec.rb +340 -340
  328. data/spec/unit/policyfile/cookbook_location_specification_spec.rb +347 -347
  329. data/spec/unit/policyfile/cookbook_locks_spec.rb +527 -527
  330. data/spec/unit/policyfile/delivery_supermarket_source_spec.rb +129 -129
  331. data/spec/unit/policyfile/differ_spec.rb +686 -686
  332. data/spec/unit/policyfile/git_lock_fetcher_spec.rb +155 -0
  333. data/spec/unit/policyfile/included_policies_cookbook_source_spec.rb +242 -242
  334. data/spec/unit/policyfile/lister_spec.rb +268 -268
  335. data/spec/unit/policyfile/local_lock_fetcher_spec.rb +173 -173
  336. data/spec/unit/policyfile/lock_applier_spec.rb +100 -100
  337. data/spec/unit/policyfile/null_cookbook_source_spec.rb +34 -34
  338. data/spec/unit/policyfile/read_cookbook_for_compat_mode_upload_spec.rb +92 -92
  339. data/spec/unit/policyfile/reports/install_spec.rb +114 -114
  340. data/spec/unit/policyfile/reports/upload_spec.rb +94 -94
  341. data/spec/unit/policyfile/solution_dependencies_spec.rb +170 -170
  342. data/spec/unit/policyfile/source_uri_spec.rb +36 -36
  343. data/spec/unit/policyfile/storage_config_spec.rb +180 -180
  344. data/spec/unit/policyfile/undo_record_spec.rb +258 -258
  345. data/spec/unit/policyfile/undo_stack_spec.rb +265 -265
  346. data/spec/unit/policyfile/uploader_spec.rb +409 -409
  347. data/spec/unit/policyfile_demands_spec.rb +1197 -1197
  348. data/spec/unit/policyfile_evaluation_spec.rb +628 -638
  349. data/spec/unit/policyfile_includes_dsl_spec.rb +159 -159
  350. data/spec/unit/policyfile_includes_spec.rb +720 -720
  351. data/spec/unit/policyfile_install_with_includes_spec.rb +232 -232
  352. data/spec/unit/policyfile_lock_build_spec.rb +1065 -1065
  353. data/spec/unit/policyfile_lock_install_spec.rb +137 -137
  354. data/spec/unit/policyfile_lock_serialization_spec.rb +424 -424
  355. data/spec/unit/policyfile_lock_validation_spec.rb +608 -608
  356. data/spec/unit/policyfile_services/clean_policies_spec.rb +236 -236
  357. data/spec/unit/policyfile_services/clean_policy_cookbooks_spec.rb +272 -272
  358. data/spec/unit/policyfile_services/export_repo_spec.rb +473 -478
  359. data/spec/unit/policyfile_services/install_spec.rb +209 -209
  360. data/spec/unit/policyfile_services/push_archive_spec.rb +359 -374
  361. data/spec/unit/policyfile_services/push_spec.rb +249 -249
  362. data/spec/unit/policyfile_services/rm_policy_group_spec.rb +237 -237
  363. data/spec/unit/policyfile_services/rm_policy_spec.rb +263 -263
  364. data/spec/unit/policyfile_services/show_policy_spec.rb +887 -887
  365. data/spec/unit/policyfile_services/undelete_spec.rb +302 -302
  366. data/spec/unit/policyfile_services/update_attributes_spec.rb +229 -229
  367. data/spec/unit/policyfile_services/update_spec.rb +140 -140
  368. data/spec/unit/service_exception_inspectors/base_spec.rb +41 -41
  369. data/spec/unit/service_exception_inspectors/http_spec.rb +138 -138
  370. data/spec/unit/shell_out_spec.rb +34 -34
  371. data/tasks/announce.rb +57 -57
  372. data/tasks/bin/bundle-platform.bat +2 -2
  373. data/tasks/dependencies.rb +89 -89
  374. data/tasks/templates/prerelease.md.erb +35 -35
  375. data/tasks/templates/release.md.erb +34 -34
  376. data/warning.txt +9 -9
  377. metadata +9 -5
@@ -1,638 +1,628 @@
1
- #
2
- # Copyright:: Copyright (c) 2014 Chef Software Inc.
3
- # License:: Apache License, Version 2.0
4
- #
5
- # Licensed under the Apache License, Version 2.0 (the "License");
6
- # you may not use this file except in compliance with the License.
7
- # You may obtain a copy of the License at
8
- #
9
- # http://www.apache.org/licenses/LICENSE-2.0
10
- #
11
- # Unless required by applicable law or agreed to in writing, software
12
- # distributed under the License is distributed on an "AS IS" BASIS,
13
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
- # See the License for the specific language governing permissions and
15
- # limitations under the License.
16
- #
17
-
18
- require "spec_helper"
19
- require "chef-dk/policyfile_compiler"
20
-
21
- describe ChefDK::PolicyfileCompiler do
22
-
23
- let(:storage_config) { ChefDK::Policyfile::StorageConfig.new.use_policyfile("TestPolicyfile.rb") }
24
-
25
- let(:policyfile) { ChefDK::PolicyfileCompiler.evaluate(policyfile_rb, "TestPolicyfile.rb") }
26
-
27
- describe "Evaluate a policyfile" do
28
-
29
- describe "when the policyfile is not valid" do
30
-
31
- describe "when error! is called" do
32
-
33
- let(:policyfile_rb) { "raise 'oops'" }
34
-
35
- it "raises a PolicyfileError" do
36
- expect { policyfile.error! }.to raise_error(ChefDK::PolicyfileError)
37
- end
38
- end
39
-
40
- context "Given an empty policyfile" do
41
-
42
- let(:policyfile_rb) { "" }
43
-
44
- it "has an invalid run_list" do
45
- expect(policyfile.errors).to include("Invalid run_list. run_list cannot be empty")
46
- end
47
-
48
- end
49
-
50
- context "Given a policyfile with a syntax error" do
51
-
52
- let(:policyfile_rb) { "{{{{::::{{::" }
53
-
54
- it "has a syntax error message" do
55
- expected_error = <<-E
56
- Invalid ruby syntax in policyfile 'TestPolicyfile.rb':
57
-
58
- TestPolicyfile.rb:1: syntax error, unexpected :: at EXPR_BEG, expecting tCONSTANT
59
- {{{{::::{{::
60
- ^
61
- TestPolicyfile.rb:1: syntax error, unexpected end-of-input, expecting tCONSTANT
62
- {{{{::::{{::
63
- ^
64
- E
65
- expect(policyfile.errors.size).to eq(1)
66
- expect(policyfile.errors.first).to eq(expected_error.chomp)
67
- end
68
-
69
- end
70
-
71
- context "Given a policyfile with a ruby error" do
72
-
73
- let(:policyfile_rb) { "raise 'oops'" }
74
-
75
- it "has an error message with code context" do
76
- expect(policyfile.errors.size).to eq(1)
77
- expected_message = <<-E
78
- Evaluation of policyfile 'TestPolicyfile.rb' raised an exception
79
- Exception: RuntimeError "oops"
80
-
81
- Relevant Code:
82
- 1: raise 'oops'
83
-
84
- Backtrace:
85
- TestPolicyfile.rb:1:in `eval_policyfile'
86
- E
87
- expect(policyfile.errors.first).to eq(expected_message)
88
- end
89
- end
90
-
91
- context "when given an invalid run list item" do
92
-
93
- context "when there is only one colon between cookbook and recipe name" do
94
-
95
- let(:policyfile_rb) do
96
- <<-EOH
97
- name "hello"
98
-
99
- # Should be "foo::bar" (missing a colon)
100
- run_list "foo:bar"
101
- EOH
102
- end
103
-
104
- it "has an error message with the offending run list item" do
105
- expect(policyfile.errors).to_not be_empty
106
- expected_message = "Run List Item 'foo:bar' has invalid cookbook name 'foo:bar'.\n" +
107
- "Cookbook names can only contain alphanumerics, hyphens, and underscores.\n" +
108
- "Did you mean 'foo::bar'?"
109
- expect(policyfile.errors.first).to eq(expected_message)
110
- end
111
- end
112
-
113
- context "when there is only one colon between cookbook and recipe name in fully qualified form" do
114
-
115
- let(:policyfile_rb) do
116
- <<-EOH
117
- name "hello"
118
-
119
- # Should be "foo::bar" (missing a colon)
120
- run_list "recipe[foo:bar]"
121
- EOH
122
- end
123
-
124
- it "has an error message with the offending run list item" do
125
- expect(policyfile.errors).to_not be_empty
126
- expected_message = "Run List Item 'recipe[foo:bar]' has invalid cookbook name 'foo:bar'.\n" +
127
- "Cookbook names can only contain alphanumerics, hyphens, and underscores.\n" +
128
- "Did you mean 'recipe[foo::bar]'?"
129
- expect(policyfile.errors.first).to eq(expected_message)
130
- end
131
- end
132
-
133
- context "when the recipe name is empty" do
134
-
135
- let(:policyfile_rb) do
136
- <<-EOH
137
- name "hello"
138
-
139
- # Should be "foo::default" or just "foo"
140
- run_list "foo::"
141
- EOH
142
- end
143
-
144
- it "has an error message with the offending run list item" do
145
- expect(policyfile.errors).to_not be_empty
146
- expected_message = "Run List Item 'foo::' has invalid recipe name ''.\nRecipe names can only contain alphanumerics, hyphens, and underscores."
147
- expect(policyfile.errors.first).to eq(expected_message)
148
- end
149
-
150
- end
151
-
152
- context "with an invalid run list item in a named run list" do
153
-
154
- let(:policyfile_rb) do
155
- <<-EOH
156
- name "hello"
157
-
158
- # this one is valid:
159
- run_list "foo"
160
-
161
- named_run_list :oops, "foo:bar"
162
- EOH
163
- end
164
-
165
- it "has an error message with the offending run list item" do
166
- expect(policyfile.errors).to_not be_empty
167
- expected_message = "Named Run List 'oops' Item 'foo:bar' has invalid cookbook name 'foo:bar'.\n" +
168
- "Cookbook names can only contain alphanumerics, hyphens, and underscores.\n" +
169
- "Did you mean 'foo::bar'?"
170
- expect(policyfile.errors.first).to eq(expected_message)
171
- end
172
-
173
- end
174
- end
175
-
176
- context "when policyfile evaluation is aborted by user signal" do
177
-
178
- let(:policyfile_rb) { "raise Interrupt" }
179
-
180
- it "allows the exception to bubble up" do
181
- expect { policyfile }.to raise_error(Interrupt)
182
- end
183
- end
184
-
185
- context "when given an invalid default source type" do
186
-
187
- let(:policyfile_rb) do
188
- <<-EOH
189
- run_list "foo"
190
- default_source :herp, "derp"
191
- EOH
192
- end
193
-
194
- it "has an invalid source error" do
195
- expect(policyfile.errors.size).to eq(1)
196
- expect(policyfile.errors.first).to eq("Invalid default_source type ':herp'")
197
- end
198
- end
199
-
200
- context "when the url is omitted for chef server default source" do
201
- let(:policyfile_rb) do
202
- <<-EOH
203
- run_list "foo"
204
- default_source :chef_server
205
- EOH
206
- end
207
-
208
- it "has an invalid source error" do
209
- expect(policyfile.errors.size).to eq(1)
210
- expect(policyfile.errors.first).to eq("You must specify the server's URI when using a default_source :chef_server")
211
- end
212
-
213
- end
214
-
215
- context "when a per-cookbook source is specified with invalid options" do
216
- let(:policyfile_rb) do
217
- <<-EOH
218
- run_list "foo"
219
-
220
- cookbook "foo", herp: "derp"
221
- EOH
222
- end
223
-
224
- it "has an invalid source error" do
225
- expect(policyfile.errors.size).to eq(1)
226
- message = "Cookbook `foo' has invalid source options `{:herp=>\"derp\"}'"
227
- expect(policyfile.errors.first).to eq(message)
228
- end
229
- end
230
- end
231
-
232
- context "Given a minimal valid policyfile" do
233
-
234
- let(:policyfile_rb) do
235
- <<-EOH
236
- name "hello"
237
-
238
- run_list "foo", "bar"
239
- EOH
240
- end
241
-
242
- it "has no errors" do
243
- expect(policyfile.errors).to eq([])
244
- end
245
-
246
- it "has a name" do
247
- expect(policyfile.name).to eq("hello")
248
- end
249
-
250
- it "has a run_list" do
251
- expect(policyfile.run_list).to eq(%w{foo bar})
252
- end
253
-
254
- it "gives the run_list as the expanded run_list" do
255
- expect(policyfile.expanded_run_list).to eq(%w{foo bar})
256
- end
257
-
258
- it "has no default cookbook source" do
259
- expect(policyfile.default_source).to be_an(Array)
260
- expect(policyfile.default_source.size).to eq(1)
261
- expect(policyfile.default_source.first).to be_a(ChefDK::Policyfile::NullCookbookSource)
262
- end
263
-
264
- context "with the default source set to the community site" do
265
-
266
- let(:policyfile_rb) do
267
- <<-EOH
268
- run_list "foo", "bar"
269
- default_source :community
270
- EOH
271
- end
272
-
273
- it "has a default source" do
274
- expect(policyfile.errors).to eq([])
275
- expected = [ ChefDK::Policyfile::CommunityCookbookSource.new("https://supermarket.chef.io") ]
276
- expect(policyfile.default_source).to eq(expected)
277
- end
278
-
279
- context "with a custom URI" do
280
-
281
- let(:policyfile_rb) do
282
- <<-EOH
283
- run_list "foo", "bar"
284
- default_source :community, "https://cookbook-api.example.com"
285
- EOH
286
- end
287
-
288
- it "has a default source" do
289
- expect(policyfile.errors).to eq([])
290
- expected = [ ChefDK::Policyfile::CommunityCookbookSource.new("https://cookbook-api.example.com") ]
291
- expect(policyfile.default_source).to eq(expected)
292
- end
293
-
294
- end
295
-
296
- context "with an added cookbook with no options" do
297
-
298
- let(:policyfile_rb) do
299
- <<-EOH
300
- run_list "foo", "bar"
301
- cookbook "baz"
302
- EOH
303
- end
304
-
305
- it "adds the cookbook to the list of location specs" do
306
- expect(policyfile.errors).to eq([])
307
- expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("baz", ">= 0.0.0", {}, storage_config)
308
- expect(policyfile.cookbook_location_specs).to eq("baz" => expected_cb_spec)
309
- end
310
- end
311
-
312
- end
313
-
314
- context "with the default source set to a delivery_supermarket" do
315
-
316
- context "when no URI is given" do
317
-
318
- let(:policyfile_rb) do
319
- <<-EOH
320
- run_list "foo", "bar"
321
- default_source :delivery_supermarket
322
- EOH
323
- end
324
-
325
- it "errors out with a message that the supermarket URI is required" do
326
- expect(policyfile.errors).to eq([ "You must specify the server's URI when using a default_source :delivery_supermarket" ])
327
- end
328
-
329
- end
330
-
331
- context "when the URI is given" do
332
-
333
- let(:policyfile_rb) do
334
- <<-EOH
335
- run_list "foo", "bar"
336
- default_source :delivery_supermarket, "https://supermarket.example.com"
337
- EOH
338
- end
339
-
340
- it "sets the default source to the delivery_supermarket" do
341
- expect(policyfile.errors).to eq([])
342
- expected = [ ChefDK::Policyfile::DeliverySupermarketSource.new("https://supermarket.example.com") ]
343
- expect(policyfile.default_source).to eq(expected)
344
- end
345
-
346
- end
347
-
348
- end
349
-
350
- context "with the default source set to a chef server" do
351
-
352
- let(:policyfile_rb) do
353
- <<-EOH
354
- run_list "foo", "bar"
355
- default_source :chef_server, "https://mychef.example.com"
356
- EOH
357
- end
358
-
359
- it "has a default source" do
360
- expect(policyfile.errors).to eq([])
361
- expected = [ ChefDK::Policyfile::ChefServerCookbookSource.new("https://mychef.example.com") ]
362
- expect(policyfile.default_source).to eq(expected)
363
- end
364
-
365
- end
366
-
367
- context "with the default source set to a chef-repo path" do
368
-
369
- let(:chef_repo) { File.expand_path("spec/unit/fixtures/local_path_cookbooks", project_root) }
370
-
371
- let(:policyfile_rb) do
372
- <<-EOH
373
- run_list "foo", "bar"
374
- default_source :chef_repo, "#{chef_repo}"
375
- EOH
376
- end
377
-
378
- it "has a default source" do
379
- expect(policyfile.errors).to eq([])
380
- expected = [ ChefDK::Policyfile::ChefRepoCookbookSource.new(chef_repo) ]
381
- expect(policyfile.default_source).to eq(expected)
382
- end
383
-
384
- context "when the path to the chef repo is relative" do
385
-
386
- let(:policyfile_rb) do
387
- <<-EOH
388
- run_list "foo", "bar"
389
- default_source :chef_repo, "../cookbooks"
390
- EOH
391
- end
392
-
393
- # storage_config is created with path to Policyfile.rb in CWD
394
- let(:expected_path) { File.expand_path("../cookbooks") }
395
-
396
- it "sets the repo path relative to the directory the policyfile is in" do
397
- expect(policyfile.errors).to eq([])
398
- expect(policyfile.default_source.size).to eq(1)
399
- expect(policyfile.default_source.first).to be_a(ChefDK::Policyfile::ChefRepoCookbookSource)
400
- expect(policyfile.default_source.first.path).to eq(expected_path)
401
- end
402
-
403
- end
404
-
405
- end
406
-
407
- context "with multiple default sources" do
408
- let(:chef_repo) { File.expand_path("spec/unit/fixtures/local_path_cookbooks", project_root) }
409
-
410
- let(:policyfile_rb) do
411
- <<-EOH
412
- run_list "foo", "bar"
413
-
414
- default_source :community
415
- default_source :chef_repo, "#{chef_repo}"
416
- EOH
417
- end
418
-
419
- it "has an array of sources" do
420
- expect(policyfile.errors).to eq([])
421
-
422
- community_source = ChefDK::Policyfile::CommunityCookbookSource.new("https://supermarket.chef.io")
423
- repo_source = ChefDK::Policyfile::ChefRepoCookbookSource.new(chef_repo)
424
- expected = [ community_source, repo_source ]
425
-
426
- expect(policyfile.default_source).to eq(expected)
427
- end
428
-
429
- end
430
-
431
- context "with multiple supermarkets with source preferences set for specific cookbooks" do
432
-
433
- context "when the preferences don't conflict" do
434
- let(:policyfile_rb) do
435
- <<-EOH
436
- run_list "foo", "bar", "baz"
437
-
438
- default_source :supermarket do |s|
439
- s.preferred_for "foo"
440
- end
441
-
442
- default_source :supermarket, "https://mart.example" do |s|
443
- s.preferred_for "bar", "baz"
444
- end
445
- EOH
446
- end
447
-
448
- it "has an array of sources, with cookbook preferences set" do
449
- expect(policyfile.errors).to eq([])
450
- expect(policyfile.default_source.size).to eq(2)
451
-
452
- public_supermarket = policyfile.default_source.first
453
- expect(public_supermarket.preferred_cookbooks).to eq(%w{ foo })
454
-
455
- private_supermarket = policyfile.default_source.last
456
- expect(private_supermarket.uri).to eq("https://mart.example")
457
- expect(private_supermarket.preferred_cookbooks).to eq(%w{ bar baz })
458
- end
459
-
460
- end
461
-
462
- context "when the preferences conflict" do
463
- let(:policyfile_rb) do
464
- # both supermarkets are the preferred source for "foo"
465
- <<-EOH
466
- run_list "foo", "bar"
467
-
468
- default_source :supermarket do |s|
469
- s.preferred_for "foo"
470
- end
471
-
472
- default_source :supermarket, "https://mart.example" do |s|
473
- s.preferred_for "foo"
474
- end
475
- EOH
476
- end
477
-
478
- it "emits an error" do
479
- err = <<-MESSAGE
480
- Multiple sources are marked as the preferred source for some cookbooks. Only one source can be preferred for a cookbook.
481
- supermarket(https://supermarket.chef.io) and supermarket(https://mart.example) are both set as the preferred source for cookbook(s) 'foo'
482
- MESSAGE
483
- expect(policyfile.errors).to eq([err])
484
- end
485
-
486
- end
487
-
488
- end
489
-
490
- end
491
-
492
- describe "assigning cookbooks to specific sources" do
493
-
494
- before do
495
- expect(policyfile.errors).to eq([])
496
- end
497
-
498
- context "when a cookbook is assigned to a local source" do
499
-
500
- let(:policyfile_rb) do
501
- <<-EOH
502
- run_list "foo"
503
- cookbook "foo", path: "local_cookbooks/foo"
504
- EOH
505
- end
506
-
507
- it "sets the source of the cookbook to the local path" do
508
- expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("foo", ">= 0.0.0", { path: "local_cookbooks/foo" }, storage_config)
509
- expect(policyfile.cookbook_location_specs).to eq("foo" => expected_cb_spec)
510
- end
511
-
512
- end
513
-
514
- context "when a cookbook is assigned to a git source" do
515
- let(:policyfile_rb) do
516
- <<-EOH
517
- run_list "foo"
518
- cookbook "foo", git: "git://example.com:me/foo-cookbook.git"
519
- EOH
520
- end
521
-
522
- it "sets the source of the cookbook to the git URL" do
523
- expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("foo", ">= 0.0.0", { git: "git://example.com:me/foo-cookbook.git" }, storage_config)
524
- expect(policyfile.cookbook_location_specs).to eq("foo" => expected_cb_spec)
525
- end
526
-
527
- end
528
-
529
- context "when a cookbook is assigned to a chef_server source" do
530
- let(:policyfile_rb) do
531
- <<-EOH
532
- run_list "foo"
533
- cookbook "foo", chef_server: "https://mychefserver.example.com"
534
- EOH
535
- end
536
-
537
- it "sets the source of the cookbook to the git URL" do
538
- expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("foo", ">= 0.0.0", { chef_server: "https://mychefserver.example.com" }, storage_config)
539
- expect(policyfile.cookbook_location_specs).to eq("foo" => expected_cb_spec)
540
- end
541
-
542
- end
543
-
544
- end
545
-
546
- describe "assigning a cookbook to conflicting sources" do
547
- let(:policyfile_rb) do
548
- <<-EOH
549
- run_list "foo"
550
- cookbook "foo", path: "local_cookbooks/foo"
551
- cookbook "foo", chef_server: "https://mychefserver.example.com"
552
- EOH
553
- end
554
-
555
- it "has a conflicting sources error" do
556
- expected = <<-EOH
557
- Cookbook 'foo' assigned to conflicting sources
558
-
559
- Previous source: {:path=>"local_cookbooks/foo"}
560
- Conflicts with: {:chef_server=>"https://mychefserver.example.com"}
561
- EOH
562
- expect(policyfile.errors.size).to eq(1)
563
- expect(policyfile.errors.first).to eq(expected)
564
- end
565
-
566
- end
567
-
568
- describe "defining attributes" do
569
-
570
- let(:policyfile_rb) do
571
- <<-EOH
572
- name "policy-with-attrs"
573
- run_list "foo"
574
-
575
- # basic attribute setting:
576
- default["foo"] = "bar"
577
-
578
- # auto-vivify
579
- default["abc"]["def"]["ghi"] = "xyz"
580
-
581
- # literal data structures
582
- default["baz"] = {
583
- "more_nested_stuff" => "yup"
584
- }
585
-
586
- # Array literals work and we merge rather than overwrite:
587
- default["baz"]["an_array"] = ["a", "b", "c"]
588
-
589
- # all the same stuff works with overrides:
590
-
591
- override["foo"] = "bar"
592
-
593
- override["abc"]["def"]["ghi"] = "xyz"
594
-
595
- override["baz_override"] = {
596
- "more_nested_stuff" => "yup"
597
- }
598
-
599
- override["baz_override"]["an_array"] = ["a", "b", "c"]
600
- EOH
601
- end
602
-
603
- let(:expected_combined_default_attrs) do
604
- {
605
- "foo" => "bar",
606
- "abc" => { "def" => { "ghi" => "xyz" } },
607
- "baz" => {
608
- "more_nested_stuff" => "yup",
609
- "an_array" => %w{a b c},
610
- },
611
- }
612
- end
613
-
614
- let(:expected_combined_override_attrs) do
615
- {
616
- "foo" => "bar",
617
- "abc" => { "def" => { "ghi" => "xyz" } },
618
- "baz_override" => {
619
- "more_nested_stuff" => "yup",
620
- "an_array" => %w{a b c},
621
- },
622
- }
623
- end
624
-
625
- it "defines default attributes" do
626
- expect(policyfile.errors).to eq([])
627
- expect(policyfile.default_attributes).to eq(expected_combined_default_attrs)
628
- end
629
-
630
- it "defines override attributes" do
631
- expect(policyfile.errors).to eq([])
632
- expect(policyfile.override_attributes).to eq(expected_combined_override_attrs)
633
- end
634
- end
635
-
636
- end
637
-
638
- end
1
+ #
2
+ # Copyright:: Copyright (c) 2014-2018, Chef Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require "spec_helper"
19
+ require "chef-dk/policyfile_compiler"
20
+
21
+ describe ChefDK::PolicyfileCompiler do
22
+
23
+ let(:storage_config) { ChefDK::Policyfile::StorageConfig.new.use_policyfile("TestPolicyfile.rb") }
24
+
25
+ let(:policyfile) { ChefDK::PolicyfileCompiler.evaluate(policyfile_rb, "TestPolicyfile.rb") }
26
+
27
+ describe "Evaluate a policyfile" do
28
+
29
+ describe "when the policyfile is not valid" do
30
+
31
+ describe "when error! is called" do
32
+
33
+ let(:policyfile_rb) { "raise 'oops'" }
34
+
35
+ it "raises a PolicyfileError" do
36
+ expect { policyfile.error! }.to raise_error(ChefDK::PolicyfileError)
37
+ end
38
+ end
39
+
40
+ context "Given an empty policyfile" do
41
+
42
+ let(:policyfile_rb) { "" }
43
+
44
+ it "has an invalid run_list" do
45
+ expect(policyfile.errors).to include("Invalid run_list. run_list cannot be empty")
46
+ end
47
+
48
+ end
49
+
50
+ context "Given a policyfile with a syntax error" do
51
+
52
+ let(:policyfile_rb) { "{{{{::::{{::" }
53
+
54
+ it "has a syntax error message" do
55
+ expect(policyfile.errors.size).to eq(1)
56
+ expect(policyfile.errors.first).to match(/Invalid ruby syntax in policyfile 'TestPolicyfile.rb'/)
57
+ end
58
+
59
+ end
60
+
61
+ context "Given a policyfile with a ruby error" do
62
+
63
+ let(:policyfile_rb) { "raise 'oops'" }
64
+
65
+ it "has an error message with code context" do
66
+ expect(policyfile.errors.size).to eq(1)
67
+ expected_message = <<-E
68
+ Evaluation of policyfile 'TestPolicyfile.rb' raised an exception
69
+ Exception: RuntimeError "oops"
70
+
71
+ Relevant Code:
72
+ 1: raise 'oops'
73
+
74
+ Backtrace:
75
+ TestPolicyfile.rb:1:in `eval_policyfile'
76
+ E
77
+ expect(policyfile.errors.first).to eq(expected_message)
78
+ end
79
+ end
80
+
81
+ context "when given an invalid run list item" do
82
+
83
+ context "when there is only one colon between cookbook and recipe name" do
84
+
85
+ let(:policyfile_rb) do
86
+ <<-EOH
87
+ name "hello"
88
+
89
+ # Should be "foo::bar" (missing a colon)
90
+ run_list "foo:bar"
91
+ EOH
92
+ end
93
+
94
+ it "has an error message with the offending run list item" do
95
+ expect(policyfile.errors).to_not be_empty
96
+ expected_message = "Run List Item 'foo:bar' has invalid cookbook name 'foo:bar'.\n" +
97
+ "Cookbook names can only contain alphanumerics, hyphens, and underscores.\n" +
98
+ "Did you mean 'foo::bar'?"
99
+ expect(policyfile.errors.first).to eq(expected_message)
100
+ end
101
+ end
102
+
103
+ context "when there is only one colon between cookbook and recipe name in fully qualified form" do
104
+
105
+ let(:policyfile_rb) do
106
+ <<-EOH
107
+ name "hello"
108
+
109
+ # Should be "foo::bar" (missing a colon)
110
+ run_list "recipe[foo:bar]"
111
+ EOH
112
+ end
113
+
114
+ it "has an error message with the offending run list item" do
115
+ expect(policyfile.errors).to_not be_empty
116
+ expected_message = "Run List Item 'recipe[foo:bar]' has invalid cookbook name 'foo:bar'.\n" +
117
+ "Cookbook names can only contain alphanumerics, hyphens, and underscores.\n" +
118
+ "Did you mean 'recipe[foo::bar]'?"
119
+ expect(policyfile.errors.first).to eq(expected_message)
120
+ end
121
+ end
122
+
123
+ context "when the recipe name is empty" do
124
+
125
+ let(:policyfile_rb) do
126
+ <<-EOH
127
+ name "hello"
128
+
129
+ # Should be "foo::default" or just "foo"
130
+ run_list "foo::"
131
+ EOH
132
+ end
133
+
134
+ it "has an error message with the offending run list item" do
135
+ expect(policyfile.errors).to_not be_empty
136
+ expected_message = "Run List Item 'foo::' has invalid recipe name ''.\nRecipe names can only contain alphanumerics, hyphens, and underscores."
137
+ expect(policyfile.errors.first).to eq(expected_message)
138
+ end
139
+
140
+ end
141
+
142
+ context "with an invalid run list item in a named run list" do
143
+
144
+ let(:policyfile_rb) do
145
+ <<-EOH
146
+ name "hello"
147
+
148
+ # this one is valid:
149
+ run_list "foo"
150
+
151
+ named_run_list :oops, "foo:bar"
152
+ EOH
153
+ end
154
+
155
+ it "has an error message with the offending run list item" do
156
+ expect(policyfile.errors).to_not be_empty
157
+ expected_message = "Named Run List 'oops' Item 'foo:bar' has invalid cookbook name 'foo:bar'.\n" +
158
+ "Cookbook names can only contain alphanumerics, hyphens, and underscores.\n" +
159
+ "Did you mean 'foo::bar'?"
160
+ expect(policyfile.errors.first).to eq(expected_message)
161
+ end
162
+
163
+ end
164
+ end
165
+
166
+ context "when policyfile evaluation is aborted by user signal" do
167
+
168
+ let(:policyfile_rb) { "raise Interrupt" }
169
+
170
+ it "allows the exception to bubble up" do
171
+ expect { policyfile }.to raise_error(Interrupt)
172
+ end
173
+ end
174
+
175
+ context "when given an invalid default source type" do
176
+
177
+ let(:policyfile_rb) do
178
+ <<-EOH
179
+ run_list "foo"
180
+ default_source :herp, "derp"
181
+ EOH
182
+ end
183
+
184
+ it "has an invalid source error" do
185
+ expect(policyfile.errors.size).to eq(1)
186
+ expect(policyfile.errors.first).to eq("Invalid default_source type ':herp'")
187
+ end
188
+ end
189
+
190
+ context "when the url is omitted for chef server default source" do
191
+ let(:policyfile_rb) do
192
+ <<-EOH
193
+ run_list "foo"
194
+ default_source :chef_server
195
+ EOH
196
+ end
197
+
198
+ it "has an invalid source error" do
199
+ expect(policyfile.errors.size).to eq(1)
200
+ expect(policyfile.errors.first).to eq("You must specify the server's URI when using a default_source :chef_server")
201
+ end
202
+
203
+ end
204
+
205
+ context "when a per-cookbook source is specified with invalid options" do
206
+ let(:policyfile_rb) do
207
+ <<-EOH
208
+ run_list "foo"
209
+
210
+ cookbook "foo", herp: "derp"
211
+ EOH
212
+ end
213
+
214
+ it "has an invalid source error" do
215
+ expect(policyfile.errors.size).to eq(1)
216
+ message = "Cookbook `foo' has invalid source options `{:herp=>\"derp\"}'"
217
+ expect(policyfile.errors.first).to eq(message)
218
+ end
219
+ end
220
+ end
221
+
222
+ context "Given a minimal valid policyfile" do
223
+
224
+ let(:policyfile_rb) do
225
+ <<-EOH
226
+ name "hello"
227
+
228
+ run_list "foo", "bar"
229
+ EOH
230
+ end
231
+
232
+ it "has no errors" do
233
+ expect(policyfile.errors).to eq([])
234
+ end
235
+
236
+ it "has a name" do
237
+ expect(policyfile.name).to eq("hello")
238
+ end
239
+
240
+ it "has a run_list" do
241
+ expect(policyfile.run_list).to eq(%w{foo bar})
242
+ end
243
+
244
+ it "gives the run_list as the expanded run_list" do
245
+ expect(policyfile.expanded_run_list).to eq(%w{foo bar})
246
+ end
247
+
248
+ it "has no default cookbook source" do
249
+ expect(policyfile.default_source).to be_an(Array)
250
+ expect(policyfile.default_source.size).to eq(1)
251
+ expect(policyfile.default_source.first).to be_a(ChefDK::Policyfile::NullCookbookSource)
252
+ end
253
+
254
+ context "with the default source set to the community site" do
255
+
256
+ let(:policyfile_rb) do
257
+ <<-EOH
258
+ run_list "foo", "bar"
259
+ default_source :community
260
+ EOH
261
+ end
262
+
263
+ it "has a default source" do
264
+ expect(policyfile.errors).to eq([])
265
+ expected = [ ChefDK::Policyfile::CommunityCookbookSource.new("https://supermarket.chef.io") ]
266
+ expect(policyfile.default_source).to eq(expected)
267
+ end
268
+
269
+ context "with a custom URI" do
270
+
271
+ let(:policyfile_rb) do
272
+ <<-EOH
273
+ run_list "foo", "bar"
274
+ default_source :community, "https://cookbook-api.example.com"
275
+ EOH
276
+ end
277
+
278
+ it "has a default source" do
279
+ expect(policyfile.errors).to eq([])
280
+ expected = [ ChefDK::Policyfile::CommunityCookbookSource.new("https://cookbook-api.example.com") ]
281
+ expect(policyfile.default_source).to eq(expected)
282
+ end
283
+
284
+ end
285
+
286
+ context "with an added cookbook with no options" do
287
+
288
+ let(:policyfile_rb) do
289
+ <<-EOH
290
+ run_list "foo", "bar"
291
+ cookbook "baz"
292
+ EOH
293
+ end
294
+
295
+ it "adds the cookbook to the list of location specs" do
296
+ expect(policyfile.errors).to eq([])
297
+ expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("baz", ">= 0.0.0", {}, storage_config)
298
+ expect(policyfile.cookbook_location_specs).to eq("baz" => expected_cb_spec)
299
+ end
300
+ end
301
+
302
+ end
303
+
304
+ context "with the default source set to a delivery_supermarket" do
305
+
306
+ context "when no URI is given" do
307
+
308
+ let(:policyfile_rb) do
309
+ <<-EOH
310
+ run_list "foo", "bar"
311
+ default_source :delivery_supermarket
312
+ EOH
313
+ end
314
+
315
+ it "errors out with a message that the supermarket URI is required" do
316
+ expect(policyfile.errors).to eq([ "You must specify the server's URI when using a default_source :delivery_supermarket" ])
317
+ end
318
+
319
+ end
320
+
321
+ context "when the URI is given" do
322
+
323
+ let(:policyfile_rb) do
324
+ <<-EOH
325
+ run_list "foo", "bar"
326
+ default_source :delivery_supermarket, "https://supermarket.example.com"
327
+ EOH
328
+ end
329
+
330
+ it "sets the default source to the delivery_supermarket" do
331
+ expect(policyfile.errors).to eq([])
332
+ expected = [ ChefDK::Policyfile::DeliverySupermarketSource.new("https://supermarket.example.com") ]
333
+ expect(policyfile.default_source).to eq(expected)
334
+ end
335
+
336
+ end
337
+
338
+ end
339
+
340
+ context "with the default source set to a chef server" do
341
+
342
+ let(:policyfile_rb) do
343
+ <<-EOH
344
+ run_list "foo", "bar"
345
+ default_source :chef_server, "https://mychef.example.com"
346
+ EOH
347
+ end
348
+
349
+ it "has a default source" do
350
+ expect(policyfile.errors).to eq([])
351
+ expected = [ ChefDK::Policyfile::ChefServerCookbookSource.new("https://mychef.example.com") ]
352
+ expect(policyfile.default_source).to eq(expected)
353
+ end
354
+
355
+ end
356
+
357
+ context "with the default source set to a chef-repo path" do
358
+
359
+ let(:chef_repo) { File.expand_path("spec/unit/fixtures/local_path_cookbooks", project_root) }
360
+
361
+ let(:policyfile_rb) do
362
+ <<-EOH
363
+ run_list "foo", "bar"
364
+ default_source :chef_repo, "#{chef_repo}"
365
+ EOH
366
+ end
367
+
368
+ it "has a default source" do
369
+ expect(policyfile.errors).to eq([])
370
+ expected = [ ChefDK::Policyfile::ChefRepoCookbookSource.new(chef_repo) ]
371
+ expect(policyfile.default_source).to eq(expected)
372
+ end
373
+
374
+ context "when the path to the chef repo is relative" do
375
+
376
+ let(:policyfile_rb) do
377
+ <<-EOH
378
+ run_list "foo", "bar"
379
+ default_source :chef_repo, "../cookbooks"
380
+ EOH
381
+ end
382
+
383
+ # storage_config is created with path to Policyfile.rb in CWD
384
+ let(:expected_path) { File.expand_path("../cookbooks") }
385
+
386
+ it "sets the repo path relative to the directory the policyfile is in" do
387
+ expect(policyfile.errors).to eq([])
388
+ expect(policyfile.default_source.size).to eq(1)
389
+ expect(policyfile.default_source.first).to be_a(ChefDK::Policyfile::ChefRepoCookbookSource)
390
+ expect(policyfile.default_source.first.path).to eq(expected_path)
391
+ end
392
+
393
+ end
394
+
395
+ end
396
+
397
+ context "with multiple default sources" do
398
+ let(:chef_repo) { File.expand_path("spec/unit/fixtures/local_path_cookbooks", project_root) }
399
+
400
+ let(:policyfile_rb) do
401
+ <<-EOH
402
+ run_list "foo", "bar"
403
+
404
+ default_source :community
405
+ default_source :chef_repo, "#{chef_repo}"
406
+ EOH
407
+ end
408
+
409
+ it "has an array of sources" do
410
+ expect(policyfile.errors).to eq([])
411
+
412
+ community_source = ChefDK::Policyfile::CommunityCookbookSource.new("https://supermarket.chef.io")
413
+ repo_source = ChefDK::Policyfile::ChefRepoCookbookSource.new(chef_repo)
414
+ expected = [ community_source, repo_source ]
415
+
416
+ expect(policyfile.default_source).to eq(expected)
417
+ end
418
+
419
+ end
420
+
421
+ context "with multiple supermarkets with source preferences set for specific cookbooks" do
422
+
423
+ context "when the preferences don't conflict" do
424
+ let(:policyfile_rb) do
425
+ <<-EOH
426
+ run_list "foo", "bar", "baz"
427
+
428
+ default_source :supermarket do |s|
429
+ s.preferred_for "foo"
430
+ end
431
+
432
+ default_source :supermarket, "https://mart.example" do |s|
433
+ s.preferred_for "bar", "baz"
434
+ end
435
+ EOH
436
+ end
437
+
438
+ it "has an array of sources, with cookbook preferences set" do
439
+ expect(policyfile.errors).to eq([])
440
+ expect(policyfile.default_source.size).to eq(2)
441
+
442
+ public_supermarket = policyfile.default_source.first
443
+ expect(public_supermarket.preferred_cookbooks).to eq(%w{ foo })
444
+
445
+ private_supermarket = policyfile.default_source.last
446
+ expect(private_supermarket.uri).to eq("https://mart.example")
447
+ expect(private_supermarket.preferred_cookbooks).to eq(%w{ bar baz })
448
+ end
449
+
450
+ end
451
+
452
+ context "when the preferences conflict" do
453
+ let(:policyfile_rb) do
454
+ # both supermarkets are the preferred source for "foo"
455
+ <<-EOH
456
+ run_list "foo", "bar"
457
+
458
+ default_source :supermarket do |s|
459
+ s.preferred_for "foo"
460
+ end
461
+
462
+ default_source :supermarket, "https://mart.example" do |s|
463
+ s.preferred_for "foo"
464
+ end
465
+ EOH
466
+ end
467
+
468
+ it "emits an error" do
469
+ err = <<-MESSAGE
470
+ Multiple sources are marked as the preferred source for some cookbooks. Only one source can be preferred for a cookbook.
471
+ supermarket(https://supermarket.chef.io) and supermarket(https://mart.example) are both set as the preferred source for cookbook(s) 'foo'
472
+ MESSAGE
473
+ expect(policyfile.errors).to eq([err])
474
+ end
475
+
476
+ end
477
+
478
+ end
479
+
480
+ end
481
+
482
+ describe "assigning cookbooks to specific sources" do
483
+
484
+ before do
485
+ expect(policyfile.errors).to eq([])
486
+ end
487
+
488
+ context "when a cookbook is assigned to a local source" do
489
+
490
+ let(:policyfile_rb) do
491
+ <<-EOH
492
+ run_list "foo"
493
+ cookbook "foo", path: "local_cookbooks/foo"
494
+ EOH
495
+ end
496
+
497
+ it "sets the source of the cookbook to the local path" do
498
+ expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("foo", ">= 0.0.0", { path: "local_cookbooks/foo" }, storage_config)
499
+ expect(policyfile.cookbook_location_specs).to eq("foo" => expected_cb_spec)
500
+ end
501
+
502
+ end
503
+
504
+ context "when a cookbook is assigned to a git source" do
505
+ let(:policyfile_rb) do
506
+ <<-EOH
507
+ run_list "foo"
508
+ cookbook "foo", git: "git://example.com:me/foo-cookbook.git"
509
+ EOH
510
+ end
511
+
512
+ it "sets the source of the cookbook to the git URL" do
513
+ expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("foo", ">= 0.0.0", { git: "git://example.com:me/foo-cookbook.git" }, storage_config)
514
+ expect(policyfile.cookbook_location_specs).to eq("foo" => expected_cb_spec)
515
+ end
516
+
517
+ end
518
+
519
+ context "when a cookbook is assigned to a chef_server source" do
520
+ let(:policyfile_rb) do
521
+ <<-EOH
522
+ run_list "foo"
523
+ cookbook "foo", chef_server: "https://mychefserver.example.com"
524
+ EOH
525
+ end
526
+
527
+ it "sets the source of the cookbook to the git URL" do
528
+ expected_cb_spec = ChefDK::Policyfile::CookbookLocationSpecification.new("foo", ">= 0.0.0", { chef_server: "https://mychefserver.example.com" }, storage_config)
529
+ expect(policyfile.cookbook_location_specs).to eq("foo" => expected_cb_spec)
530
+ end
531
+
532
+ end
533
+
534
+ end
535
+
536
+ describe "assigning a cookbook to conflicting sources" do
537
+ let(:policyfile_rb) do
538
+ <<-EOH
539
+ run_list "foo"
540
+ cookbook "foo", path: "local_cookbooks/foo"
541
+ cookbook "foo", chef_server: "https://mychefserver.example.com"
542
+ EOH
543
+ end
544
+
545
+ it "has a conflicting sources error" do
546
+ expected = <<-EOH
547
+ Cookbook 'foo' assigned to conflicting sources
548
+
549
+ Previous source: {:path=>"local_cookbooks/foo"}
550
+ Conflicts with: {:chef_server=>"https://mychefserver.example.com"}
551
+ EOH
552
+ expect(policyfile.errors.size).to eq(1)
553
+ expect(policyfile.errors.first).to eq(expected)
554
+ end
555
+
556
+ end
557
+
558
+ describe "defining attributes" do
559
+
560
+ let(:policyfile_rb) do
561
+ <<-EOH
562
+ name "policy-with-attrs"
563
+ run_list "foo"
564
+
565
+ # basic attribute setting:
566
+ default["foo"] = "bar"
567
+
568
+ # auto-vivify
569
+ default["abc"]["def"]["ghi"] = "xyz"
570
+
571
+ # literal data structures
572
+ default["baz"] = {
573
+ "more_nested_stuff" => "yup"
574
+ }
575
+
576
+ # Array literals work and we merge rather than overwrite:
577
+ default["baz"]["an_array"] = ["a", "b", "c"]
578
+
579
+ # all the same stuff works with overrides:
580
+
581
+ override["foo"] = "bar"
582
+
583
+ override["abc"]["def"]["ghi"] = "xyz"
584
+
585
+ override["baz_override"] = {
586
+ "more_nested_stuff" => "yup"
587
+ }
588
+
589
+ override["baz_override"]["an_array"] = ["a", "b", "c"]
590
+ EOH
591
+ end
592
+
593
+ let(:expected_combined_default_attrs) do
594
+ {
595
+ "foo" => "bar",
596
+ "abc" => { "def" => { "ghi" => "xyz" } },
597
+ "baz" => {
598
+ "more_nested_stuff" => "yup",
599
+ "an_array" => %w{a b c},
600
+ },
601
+ }
602
+ end
603
+
604
+ let(:expected_combined_override_attrs) do
605
+ {
606
+ "foo" => "bar",
607
+ "abc" => { "def" => { "ghi" => "xyz" } },
608
+ "baz_override" => {
609
+ "more_nested_stuff" => "yup",
610
+ "an_array" => %w{a b c},
611
+ },
612
+ }
613
+ end
614
+
615
+ it "defines default attributes" do
616
+ expect(policyfile.errors).to eq([])
617
+ expect(policyfile.default_attributes).to eq(expected_combined_default_attrs)
618
+ end
619
+
620
+ it "defines override attributes" do
621
+ expect(policyfile.errors).to eq([])
622
+ expect(policyfile.override_attributes).to eq(expected_combined_override_attrs)
623
+ end
624
+ end
625
+
626
+ end
627
+
628
+ end