chef 10.34.6 → 11.0.0.beta.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 (506) hide show
  1. data/CONTRIBUTING.md +155 -0
  2. data/README.md +89 -0
  3. data/Rakefile +4 -12
  4. data/bin/chef-apply +25 -0
  5. data/bin/chef-shell +34 -0
  6. data/bin/shef +6 -5
  7. data/distro/common/html/chef-client.8.html +4 -4
  8. data/distro/common/html/chef-expander.8.html +4 -4
  9. data/distro/common/html/chef-expanderctl.8.html +4 -4
  10. data/distro/common/html/chef-server-webui.8.html +4 -4
  11. data/distro/common/html/chef-server.8.html +4 -4
  12. data/distro/common/html/{shef.1.html → chef-shell.1.html} +49 -46
  13. data/distro/common/html/chef-solo.8.html +18 -12
  14. data/distro/common/html/chef-solr.8.html +4 -4
  15. data/distro/common/html/knife-bootstrap.1.html +4 -4
  16. data/distro/common/html/knife-client.1.html +4 -4
  17. data/distro/common/html/knife-configure.1.html +4 -4
  18. data/distro/common/html/knife-cookbook-site.1.html +4 -4
  19. data/distro/common/html/knife-cookbook.1.html +10 -7
  20. data/distro/common/html/knife-data-bag.1.html +10 -7
  21. data/distro/common/html/knife-environment.1.html +8 -6
  22. data/distro/common/html/knife-exec.1.html +9 -9
  23. data/distro/common/html/knife-index.1.html +4 -4
  24. data/distro/common/html/knife-node.1.html +4 -4
  25. data/distro/common/html/knife-role.1.html +4 -4
  26. data/distro/common/html/knife-search.1.html +4 -4
  27. data/distro/common/html/knife-ssh.1.html +4 -4
  28. data/distro/common/html/knife-status.1.html +4 -4
  29. data/distro/common/html/knife-tag.1.html +4 -4
  30. data/distro/common/html/knife.1.html +8 -13
  31. data/distro/common/man/man1/{shef.1 → chef-shell.1} +21 -57
  32. data/distro/common/man/man1/knife-bootstrap.1 +1 -1
  33. data/distro/common/man/man1/knife-client.1 +1 -1
  34. data/distro/common/man/man1/knife-configure.1 +1 -1
  35. data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
  36. data/distro/common/man/man1/knife-cookbook.1 +15 -2
  37. data/distro/common/man/man1/knife-data-bag.1 +15 -2
  38. data/distro/common/man/man1/knife-environment.1 +12 -2
  39. data/distro/common/man/man1/knife-exec.1 +4 -7
  40. data/distro/common/man/man1/knife-index.1 +1 -1
  41. data/distro/common/man/man1/knife-node.1 +1 -1
  42. data/distro/common/man/man1/knife-role.1 +1 -1
  43. data/distro/common/man/man1/knife-search.1 +1 -1
  44. data/distro/common/man/man1/knife-ssh.1 +1 -1
  45. data/distro/common/man/man1/knife-status.1 +1 -1
  46. data/distro/common/man/man1/knife-tag.1 +1 -1
  47. data/distro/common/man/man1/knife.1 +3 -6
  48. data/distro/common/man/man8/chef-client.8 +1 -1
  49. data/distro/common/man/man8/chef-expander.8 +1 -1
  50. data/distro/common/man/man8/chef-expanderctl.8 +1 -1
  51. data/distro/common/man/man8/chef-server-webui.8 +1 -1
  52. data/distro/common/man/man8/chef-server.8 +1 -1
  53. data/distro/common/man/man8/chef-solo.8 +36 -4
  54. data/distro/common/man/man8/chef-solr.8 +1 -1
  55. data/distro/common/markdown/man1/{shef.mkd → chef-shell.mkd} +49 -43
  56. data/distro/common/markdown/man1/knife-exec.mkd +11 -6
  57. data/distro/common/markdown/man1/knife.mkd +4 -9
  58. data/distro/debian/etc/default/chef-client +0 -1
  59. data/distro/debian/etc/init.d/chef-client +2 -2
  60. data/lib/chef.rb +2 -5
  61. data/lib/chef/api_client.rb +20 -130
  62. data/lib/chef/api_client/registration.rb +126 -0
  63. data/lib/chef/application.rb +71 -14
  64. data/lib/chef/application/apply.rb +160 -0
  65. data/lib/chef/application/client.rb +25 -18
  66. data/lib/chef/application/knife.rb +0 -2
  67. data/lib/chef/application/solo.rb +23 -8
  68. data/lib/chef/application/windows_service.rb +5 -2
  69. data/lib/chef/applications.rb +1 -0
  70. data/lib/chef/chef_fs.rb +11 -0
  71. data/lib/chef/chef_fs/command_line.rb +232 -0
  72. data/lib/chef/chef_fs/file_pattern.rb +312 -0
  73. data/lib/chef/chef_fs/file_system.rb +358 -0
  74. data/lib/chef/chef_fs/file_system/base_fs_dir.rb +47 -0
  75. data/lib/chef/chef_fs/file_system/base_fs_object.rb +121 -0
  76. data/lib/chef/chef_fs/file_system/chef_repository_file_system_entry.rb +109 -0
  77. data/{spec/unit/monkey_patches/uri_spec.rb → lib/chef/chef_fs/file_system/chef_repository_file_system_root_dir.rb} +12 -15
  78. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +84 -0
  79. data/lib/chef/chef_fs/file_system/cookbook_dir.rb +188 -0
  80. data/lib/chef/chef_fs/file_system/cookbook_file.rb +78 -0
  81. data/lib/chef/chef_fs/file_system/cookbook_subdir.rb +54 -0
  82. data/lib/chef/chef_fs/file_system/cookbooks_dir.rb +68 -0
  83. data/lib/chef/chef_fs/file_system/data_bag_dir.rb +78 -0
  84. data/lib/chef/chef_fs/file_system/data_bag_item.rb +59 -0
  85. data/lib/chef/chef_fs/file_system/data_bags_dir.rb +66 -0
  86. data/lib/chef/chef_fs/file_system/file_system_entry.rb +90 -0
  87. data/lib/chef/{index_queue.rb → chef_fs/file_system/file_system_error.rb} +14 -12
  88. data/lib/chef/{resource/whyrun_safe_ruby_block.rb → chef_fs/file_system/file_system_root_dir.rb} +10 -10
  89. data/lib/chef/chef_fs/file_system/must_delete_recursively_error.rb +31 -0
  90. data/lib/chef/chef_fs/file_system/nodes_dir.rb +47 -0
  91. data/lib/chef/{provider/whyrun_safe_ruby_block.rb → chef_fs/file_system/nonexistent_fs_object.rb} +19 -9
  92. data/lib/chef/chef_fs/file_system/not_found_error.rb +31 -0
  93. data/lib/chef/chef_fs/file_system/rest_list_dir.rb +84 -0
  94. data/lib/chef/chef_fs/file_system/rest_list_entry.rb +123 -0
  95. data/lib/chef/chef_fs/knife.rb +77 -0
  96. data/lib/chef/chef_fs/path_utils.rb +64 -0
  97. data/lib/chef/client.rb +44 -21
  98. data/lib/chef/config.rb +52 -43
  99. data/lib/chef/cookbook/synchronizer.rb +6 -8
  100. data/lib/chef/cookbook/syntax_check.rb +61 -14
  101. data/lib/chef/cookbook_loader.rb +39 -26
  102. data/lib/chef/cookbook_uploader.rb +17 -19
  103. data/lib/chef/cookbook_version.rb +3 -302
  104. data/lib/chef/daemon.rb +3 -18
  105. data/lib/chef/data_bag.rb +4 -97
  106. data/lib/chef/data_bag_item.rb +2 -65
  107. data/lib/chef/digester.rb +73 -0
  108. data/lib/chef/dsl.rb +6 -0
  109. data/lib/chef/dsl/data_query.rb +66 -0
  110. data/lib/chef/dsl/include_attribute.rb +60 -0
  111. data/lib/chef/dsl/include_recipe.rb +42 -0
  112. data/lib/chef/dsl/platform_introspection.rb +213 -0
  113. data/lib/chef/dsl/recipe.rb +84 -0
  114. data/lib/chef/dsl/registry_helper.rb +59 -0
  115. data/lib/chef/encrypted_data_bag_item.rb +74 -19
  116. data/lib/chef/environment.rb +9 -180
  117. data/lib/chef/exceptions.rb +87 -14
  118. data/lib/chef/formatters/base.rb +4 -1
  119. data/lib/chef/formatters/error_inspectors/registration_error_inspector.rb +0 -4
  120. data/lib/chef/json_compat.rb +1 -97
  121. data/lib/chef/knife.rb +90 -41
  122. data/lib/chef/knife/bootstrap/archlinux-gems.erb +2 -2
  123. data/lib/chef/knife/bootstrap/centos5-gems.erb +2 -2
  124. data/lib/chef/knife/bootstrap/chef-full.erb +3 -3
  125. data/lib/chef/knife/bootstrap/fedora13-gems.erb +2 -2
  126. data/lib/chef/knife/bootstrap/ubuntu10.04-apt.erb +2 -2
  127. data/lib/chef/knife/bootstrap/ubuntu10.04-gems.erb +2 -2
  128. data/lib/chef/knife/bootstrap/ubuntu12.04-gems.erb +2 -2
  129. data/lib/chef/knife/configure.rb +1 -2
  130. data/lib/chef/knife/cookbook_metadata.rb +1 -0
  131. data/lib/chef/knife/cookbook_test.rb +3 -2
  132. data/lib/chef/knife/cookbook_upload.rb +12 -7
  133. data/lib/chef/knife/core/bootstrap_context.rb +1 -1
  134. data/lib/chef/knife/core/generic_presenter.rb +26 -13
  135. data/lib/chef/knife/core/node_editor.rb +36 -16
  136. data/lib/chef/knife/core/node_presenter.rb +1 -1
  137. data/lib/chef/knife/core/text_formatter.rb +23 -37
  138. data/lib/chef/knife/core/ui.rb +15 -9
  139. data/lib/chef/knife/delete.rb +39 -0
  140. data/lib/chef/knife/diff.rb +46 -0
  141. data/lib/chef/knife/download.rb +50 -0
  142. data/lib/chef/knife/environment_show.rb +7 -0
  143. data/lib/chef/knife/exec.rb +5 -5
  144. data/lib/chef/knife/help_topics.rb +1 -1
  145. data/lib/chef/knife/index_rebuild.rb +91 -7
  146. data/lib/chef/knife/list.rb +109 -0
  147. data/lib/chef/knife/raw.rb +108 -0
  148. data/lib/chef/knife/search.rb +40 -22
  149. data/lib/chef/knife/show.rb +32 -0
  150. data/lib/chef/knife/ssh.rb +6 -2
  151. data/lib/chef/knife/upload.rb +50 -0
  152. data/lib/chef/mixin/checksum.rb +3 -3
  153. data/lib/chef/mixin/deep_merge.rb +55 -197
  154. data/lib/chef/mixin/language.rb +9 -222
  155. data/lib/chef/mixin/language_include_attribute.rb +6 -38
  156. data/lib/chef/mixin/language_include_recipe.rb +3 -35
  157. data/lib/chef/mixin/params_validate.rb +6 -19
  158. data/lib/chef/mixin/recipe_definition_dsl_core.rb +8 -61
  159. data/lib/chef/mixin/securable.rb +32 -7
  160. data/lib/chef/mixin/template.rb +40 -0
  161. data/lib/chef/mixins.rb +0 -4
  162. data/lib/chef/monkey_patches/net_http.rb +0 -34
  163. data/lib/chef/node.rb +133 -309
  164. data/lib/chef/node/attribute.rb +333 -473
  165. data/lib/chef/node/attribute_collections.rb +199 -0
  166. data/lib/chef/node/immutable_collections.rb +186 -0
  167. data/lib/chef/platform.rb +7 -22
  168. data/lib/chef/provider.rb +2 -49
  169. data/lib/chef/provider/breakpoint.rb +6 -6
  170. data/lib/chef/provider/cookbook_file.rb +5 -33
  171. data/lib/chef/provider/deploy.rb +2 -1
  172. data/lib/chef/provider/directory.rb +14 -17
  173. data/lib/chef/provider/file.rb +19 -52
  174. data/lib/chef/provider/group.rb +31 -51
  175. data/lib/chef/provider/group/dscl.rb +13 -53
  176. data/lib/chef/provider/group/gpasswd.rb +19 -14
  177. data/lib/chef/provider/group/groupadd.rb +1 -41
  178. data/lib/chef/provider/group/groupmod.rb +36 -46
  179. data/lib/chef/provider/group/pw.rb +16 -59
  180. data/lib/chef/provider/group/suse.rb +13 -16
  181. data/lib/chef/provider/group/usermod.rb +18 -40
  182. data/lib/chef/provider/group/windows.rb +6 -13
  183. data/lib/chef/provider/http_request.rb +25 -42
  184. data/lib/chef/provider/link.rb +2 -0
  185. data/lib/chef/provider/lwrp_base.rb +150 -0
  186. data/lib/chef/provider/package/portage.rb +4 -9
  187. data/lib/chef/provider/package/rpm.rb +2 -2
  188. data/lib/chef/provider/package/rubygems.rb +9 -41
  189. data/lib/chef/provider/package/yum.rb +12 -19
  190. data/lib/chef/provider/registry_key.rb +156 -0
  191. data/lib/chef/provider/remote_directory.rb +2 -0
  192. data/lib/chef/provider/remote_file.rb +21 -12
  193. data/lib/chef/provider/ruby_block.rb +5 -2
  194. data/lib/chef/provider/service.rb +15 -0
  195. data/lib/chef/provider/service/init.rb +9 -7
  196. data/lib/chef/provider/service/macosx.rb +15 -73
  197. data/lib/chef/provider/service/simple.rb +1 -1
  198. data/lib/chef/provider/service/solaris.rb +3 -3
  199. data/lib/chef/provider/template.rb +22 -25
  200. data/lib/chef/provider/template_finder.rb +61 -0
  201. data/lib/chef/provider/user.rb +0 -1
  202. data/lib/chef/provider/user/dscl.rb +175 -568
  203. data/lib/chef/provider/user/useradd.rb +30 -47
  204. data/lib/chef/providers.rb +3 -2
  205. data/lib/chef/recipe.rb +14 -8
  206. data/lib/chef/resource.rb +13 -154
  207. data/lib/chef/resource/group.rb +1 -11
  208. data/lib/chef/resource/http_request.rb +2 -1
  209. data/lib/chef/resource/lwrp_base.rb +127 -0
  210. data/lib/chef/resource/mount.rb +10 -11
  211. data/lib/chef/resource/registry_key.rb +86 -0
  212. data/lib/chef/resource/remote_directory.rb +6 -5
  213. data/lib/chef/resource/remote_file.rb +22 -31
  214. data/lib/chef/resource/ruby_block.rb +2 -2
  215. data/lib/chef/resource/service.rb +14 -0
  216. data/lib/chef/resource/user.rb +0 -18
  217. data/lib/chef/resource_collection.rb +25 -21
  218. data/lib/chef/resources.rb +2 -1
  219. data/lib/chef/rest.rb +50 -131
  220. data/lib/chef/rest/auth_credentials.rb +4 -20
  221. data/lib/chef/rest/rest_request.rb +2 -7
  222. data/lib/chef/role.rb +1 -97
  223. data/lib/chef/run_context.rb +108 -130
  224. data/lib/chef/run_context/cookbook_compiler.rb +280 -0
  225. data/lib/chef/run_list.rb +0 -2
  226. data/lib/chef/run_list/run_list_expansion.rb +0 -15
  227. data/lib/chef/run_lock.rb +90 -0
  228. data/lib/chef/runner.rb +28 -5
  229. data/lib/chef/sandbox.rb +15 -148
  230. data/lib/chef/scan_access_control.rb +2 -4
  231. data/lib/chef/shef/ext.rb +3 -575
  232. data/lib/chef/{shef.rb → shell.rb} +35 -40
  233. data/lib/chef/shell/ext.rb +593 -0
  234. data/lib/chef/{shef → shell}/model_wrapper.rb +3 -3
  235. data/lib/chef/{shef/shef_rest.rb → shell/shell_rest.rb} +4 -4
  236. data/lib/chef/{shef/shef_session.rb → shell/shell_session.rb} +17 -15
  237. data/lib/chef/shell_out.rb +7 -0
  238. data/lib/chef/util/windows/net_group.rb +1 -5
  239. data/lib/chef/version.rb +3 -3
  240. data/lib/chef/win32/api/process.rb +0 -1
  241. data/lib/chef/win32/handle.rb +1 -8
  242. data/lib/chef/win32/registry.rb +371 -0
  243. data/spec/data/big_json.json +1 -2
  244. data/spec/data/big_json_plus_one.json +1 -2
  245. data/spec/data/cookbooks/openldap/attributes/default.rb +10 -9
  246. data/spec/data/cookbooks/openldap/attributes/smokey.rb +1 -1
  247. data/spec/data/lwrp/providers/inline_compiler.rb +26 -0
  248. data/spec/data/nodes/default.rb +3 -3
  249. data/spec/data/nodes/test.example.com.rb +3 -3
  250. data/spec/data/nodes/test.rb +3 -3
  251. data/spec/data/partial_one.erb +1 -0
  252. data/spec/data/run_context/cookbooks/circular-dep1/attributes/default.rb +4 -0
  253. data/spec/data/run_context/cookbooks/circular-dep1/definitions/circular_dep1_res.rb +1 -0
  254. data/spec/data/run_context/cookbooks/circular-dep1/libraries/lib.rb +2 -0
  255. data/spec/data/run_context/cookbooks/circular-dep1/metadata.rb +2 -0
  256. data/spec/data/run_context/cookbooks/circular-dep1/providers/provider.rb +1 -0
  257. data/spec/data/{knife-home/.chef/plugins/knife/example_home_subcommand.rb → run_context/cookbooks/circular-dep1/recipes/default.rb} +0 -0
  258. data/spec/data/run_context/cookbooks/circular-dep1/resources/resource.rb +1 -0
  259. data/spec/data/run_context/cookbooks/circular-dep2/attributes/default.rb +3 -0
  260. data/spec/data/run_context/cookbooks/circular-dep2/definitions/circular_dep2_res.rb +1 -0
  261. data/spec/data/run_context/cookbooks/circular-dep2/libraries/lib.rb +2 -0
  262. data/spec/data/run_context/cookbooks/circular-dep2/metadata.rb +2 -0
  263. data/spec/data/run_context/cookbooks/circular-dep2/providers/provider.rb +1 -0
  264. data/spec/data/{lwrp_const_scoping/resources/conflict.rb → run_context/cookbooks/circular-dep2/recipes/default.rb} +0 -0
  265. data/spec/data/run_context/cookbooks/circular-dep2/resources/resource.rb +1 -0
  266. data/spec/data/run_context/cookbooks/dependency1/attributes/aa_first.rb +2 -0
  267. data/spec/data/run_context/cookbooks/dependency1/attributes/default.rb +2 -0
  268. data/spec/data/run_context/cookbooks/dependency1/attributes/zz_last.rb +3 -0
  269. data/spec/data/run_context/cookbooks/dependency1/definitions/dependency1_res.rb +1 -0
  270. data/spec/data/run_context/cookbooks/dependency1/libraries/lib.rb +2 -0
  271. data/spec/data/run_context/cookbooks/dependency1/providers/provider.rb +1 -0
  272. data/spec/data/run_context/cookbooks/dependency1/recipes/default.rb +0 -0
  273. data/spec/data/run_context/cookbooks/dependency1/resources/resource.rb +1 -0
  274. data/spec/data/run_context/cookbooks/dependency2/attributes/default.rb +3 -0
  275. data/spec/data/run_context/cookbooks/dependency2/definitions/dependency2_res.rb +1 -0
  276. data/spec/data/run_context/cookbooks/dependency2/libraries/lib.rb +2 -0
  277. data/spec/data/run_context/cookbooks/dependency2/providers/provider.rb +1 -0
  278. data/spec/data/run_context/cookbooks/dependency2/recipes/default.rb +0 -0
  279. data/spec/data/run_context/cookbooks/dependency2/resources/resource.rb +1 -0
  280. data/spec/data/run_context/cookbooks/no-default-attr/attributes/server.rb +3 -0
  281. data/spec/data/run_context/cookbooks/no-default-attr/definitions/no_default-attr_res.rb +1 -0
  282. data/spec/data/run_context/cookbooks/no-default-attr/providers/provider.rb +1 -0
  283. data/spec/data/run_context/cookbooks/no-default-attr/recipes/default.rb +0 -0
  284. data/spec/data/run_context/cookbooks/no-default-attr/resources/resource.rb +1 -0
  285. data/spec/data/run_context/cookbooks/test-with-circular-deps/attributes/default.rb +3 -0
  286. data/spec/data/run_context/cookbooks/test-with-circular-deps/definitions/test_with-circular-deps_res.rb +1 -0
  287. data/spec/data/run_context/cookbooks/test-with-circular-deps/libraries/lib.rb +2 -0
  288. data/spec/data/run_context/cookbooks/test-with-circular-deps/metadata.rb +2 -0
  289. data/spec/data/run_context/cookbooks/test-with-circular-deps/providers/provider.rb +1 -0
  290. data/spec/data/run_context/cookbooks/test-with-circular-deps/recipes/default.rb +0 -0
  291. data/spec/data/run_context/cookbooks/test-with-circular-deps/resources/resource.rb +1 -0
  292. data/spec/data/run_context/cookbooks/test-with-deps/attributes/default.rb +3 -0
  293. data/spec/data/run_context/cookbooks/test-with-deps/definitions/test_with-deps_res.rb +1 -0
  294. data/spec/data/run_context/cookbooks/test-with-deps/libraries/lib.rb +1 -0
  295. data/spec/data/run_context/cookbooks/test-with-deps/metadata.rb +3 -0
  296. data/spec/data/run_context/cookbooks/test-with-deps/providers/provider.rb +1 -0
  297. data/spec/data/run_context/cookbooks/test-with-deps/recipes/default.rb +0 -0
  298. data/spec/data/run_context/cookbooks/test-with-deps/recipes/server.rb +0 -0
  299. data/spec/data/run_context/cookbooks/test-with-deps/resources/resource.rb +1 -0
  300. data/spec/data/run_context/cookbooks/test/attributes/default.rb +0 -0
  301. data/spec/data/run_context/cookbooks/test/attributes/george.rb +1 -1
  302. data/spec/data/run_context/cookbooks/test/definitions/test_res.rb +1 -0
  303. data/spec/data/run_context/cookbooks/test/providers/provider.rb +1 -0
  304. data/spec/data/run_context/cookbooks/test/resources/resource.rb +1 -0
  305. data/spec/data/shef-config.rb +7 -0
  306. data/spec/functional/dsl/registry_helper_spec.rb +63 -0
  307. data/spec/functional/knife/cookbook_delete_spec.rb +1 -1
  308. data/spec/functional/knife/exec_spec.rb +2 -2
  309. data/spec/functional/knife/ssh_spec.rb +5 -1
  310. data/spec/functional/resource/cookbook_file_spec.rb +7 -19
  311. data/spec/functional/resource/directory_spec.rb +4 -0
  312. data/spec/functional/resource/file_spec.rb +56 -22
  313. data/spec/functional/resource/link_spec.rb +2 -0
  314. data/spec/functional/resource/registry_spec.rb +576 -0
  315. data/spec/functional/resource/remote_directory_spec.rb +142 -36
  316. data/spec/functional/resource/remote_file_spec.rb +18 -0
  317. data/spec/functional/resource/template_spec.rb +23 -2
  318. data/spec/functional/run_lock_spec.rb +106 -0
  319. data/spec/functional/shell_spec.rb +100 -0
  320. data/spec/functional/win32/registry_helper_spec.rb +632 -0
  321. data/spec/spec_helper.rb +5 -29
  322. data/spec/stress/win32/security_spec.rb +1 -1
  323. data/spec/support/chef_helpers.rb +0 -2
  324. data/spec/support/platform_helpers.rb +8 -15
  325. data/spec/support/shared/functional/directory_resource.rb +84 -22
  326. data/spec/support/shared/functional/file_resource.rb +169 -71
  327. data/spec/support/shared/functional/securable_resource.rb +143 -119
  328. data/spec/support/shared/functional/securable_resource_with_reporting.rb +375 -0
  329. data/spec/support/shared/unit/file_system_support.rb +110 -0
  330. data/spec/support/shared/unit/platform_introspector.rb +162 -0
  331. data/spec/unit/api_client/registration_spec.rb +175 -0
  332. data/spec/unit/api_client_spec.rb +78 -156
  333. data/spec/unit/application/apply.rb +84 -0
  334. data/spec/unit/application/client_spec.rb +1 -37
  335. data/spec/unit/application/knife_spec.rb +5 -0
  336. data/spec/unit/application_spec.rb +57 -2
  337. data/spec/unit/checksum/storage/filesystem_spec.rb +1 -1
  338. data/spec/unit/chef_fs/diff_spec.rb +328 -0
  339. data/spec/unit/chef_fs/file_pattern_spec.rb +526 -0
  340. data/spec/unit/chef_fs/file_system/chef_server_root_dir_spec.rb +237 -0
  341. data/spec/unit/chef_fs/file_system/cookbooks_dir_spec.rb +568 -0
  342. data/spec/unit/chef_fs/file_system/data_bags_dir_spec.rb +220 -0
  343. data/spec/unit/chef_fs/file_system_spec.rb +136 -0
  344. data/spec/unit/client_spec.rb +124 -33
  345. data/spec/unit/config_spec.rb +46 -13
  346. data/spec/unit/cookbook/synchronizer_spec.rb +1 -49
  347. data/spec/unit/cookbook/syntax_check_spec.rb +48 -109
  348. data/spec/unit/cookbook_loader_spec.rb +153 -91
  349. data/spec/unit/cookbook_manifest_spec.rb +81 -81
  350. data/spec/unit/cookbook_spec.rb +3 -20
  351. data/spec/unit/cookbook_version_spec.rb +23 -122
  352. data/spec/unit/daemon_spec.rb +3 -24
  353. data/spec/unit/data_bag_spec.rb +6 -4
  354. data/spec/unit/digester_spec.rb +50 -0
  355. data/spec/unit/dsl/data_query_spec.rb +66 -0
  356. data/spec/unit/dsl/platform_introspection_spec.rb +130 -0
  357. data/spec/unit/dsl/regsitry_helper_spec.rb +55 -0
  358. data/spec/unit/encrypted_data_bag_item_spec.rb +50 -105
  359. data/spec/unit/environment_spec.rb +0 -130
  360. data/spec/unit/exceptions_spec.rb +2 -3
  361. data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +3 -3
  362. data/spec/unit/json_compat_spec.rb +15 -7
  363. data/spec/unit/knife/bootstrap_spec.rb +2 -0
  364. data/spec/unit/knife/configure_spec.rb +20 -14
  365. data/spec/unit/knife/cookbook_metadata_spec.rb +11 -4
  366. data/spec/unit/knife/cookbook_test_spec.rb +1 -0
  367. data/spec/unit/knife/cookbook_upload_spec.rb +43 -8
  368. data/spec/unit/knife/core/bootstrap_context_spec.rb +1 -1
  369. data/spec/unit/knife/core/ui_spec.rb +156 -125
  370. data/spec/unit/knife/data_bag_create_spec.rb +9 -0
  371. data/spec/unit/knife/data_bag_edit_spec.rb +1 -4
  372. data/spec/unit/knife/data_bag_from_file_spec.rb +4 -6
  373. data/spec/unit/knife/data_bag_show_spec.rb +11 -4
  374. data/spec/unit/knife/index_rebuild_spec.rb +96 -33
  375. data/spec/unit/knife/knife_help.rb +7 -7
  376. data/spec/unit/knife/node_edit_spec.rb +6 -33
  377. data/spec/unit/knife/node_run_list_remove_spec.rb +2 -1
  378. data/spec/unit/knife/ssh_spec.rb +12 -15
  379. data/spec/unit/knife/status_spec.rb +2 -2
  380. data/spec/unit/knife_spec.rb +53 -0
  381. data/spec/unit/lwrp_spec.rb +59 -42
  382. data/spec/unit/mixin/checksum_spec.rb +2 -2
  383. data/spec/unit/mixin/deep_merge_spec.rb +101 -799
  384. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +6 -1
  385. data/spec/unit/mixin/params_validate_spec.rb +4 -37
  386. data/spec/unit/mixin/securable_spec.rb +5 -3
  387. data/spec/unit/mixin/template_spec.rb +119 -0
  388. data/spec/unit/node/attribute_spec.rb +195 -173
  389. data/spec/unit/node/immutable_collections_spec.rb +139 -0
  390. data/spec/unit/node_spec.rb +366 -370
  391. data/spec/unit/platform_spec.rb +9 -10
  392. data/spec/unit/provider/breakpoint_spec.rb +8 -8
  393. data/spec/unit/provider/cookbook_file_spec.rb +4 -8
  394. data/spec/unit/provider/directory_spec.rb +96 -64
  395. data/spec/unit/provider/env_spec.rb +2 -2
  396. data/spec/unit/provider/file_spec.rb +48 -39
  397. data/spec/unit/provider/group/dscl_spec.rb +0 -36
  398. data/spec/unit/provider/group/gpasswd_spec.rb +9 -16
  399. data/spec/unit/provider/group/groupadd_spec.rb +4 -3
  400. data/spec/unit/provider/group/groupmod_spec.rb +1 -0
  401. data/spec/unit/provider/group/pw_spec.rb +15 -12
  402. data/spec/unit/provider/group/usermod_spec.rb +6 -21
  403. data/spec/unit/provider/group/windows_spec.rb +8 -0
  404. data/spec/unit/provider/group_spec.rb +6 -28
  405. data/spec/unit/provider/http_request_spec.rb +28 -69
  406. data/spec/unit/provider/ifconfig_spec.rb +2 -2
  407. data/spec/unit/provider/ohai_spec.rb +4 -4
  408. data/spec/unit/provider/package/apt_spec.rb +0 -1
  409. data/spec/unit/provider/package/ips_spec.rb +0 -1
  410. data/spec/unit/provider/package/portage_spec.rb +0 -44
  411. data/spec/unit/provider/package/rpm_spec.rb +0 -12
  412. data/spec/unit/provider/package/rubygems_spec.rb +1 -44
  413. data/spec/unit/provider/package/yum_spec.rb +39 -36
  414. data/spec/unit/provider/package_spec.rb +7 -5
  415. data/spec/unit/provider/registry_key_spec.rb +269 -0
  416. data/spec/unit/provider/remote_directory_spec.rb +7 -3
  417. data/spec/unit/provider/remote_file_spec.rb +36 -0
  418. data/spec/unit/provider/route_spec.rb +4 -3
  419. data/spec/unit/provider/ruby_block_spec.rb +8 -0
  420. data/spec/unit/provider/service/arch_service_spec.rb +5 -5
  421. data/spec/unit/provider/service/debian_service_spec.rb +1 -1
  422. data/spec/unit/provider/service/freebsd_service_spec.rb +5 -5
  423. data/spec/unit/provider/service/init_service_spec.rb +27 -4
  424. data/spec/unit/provider/service/insserv_service_spec.rb +1 -1
  425. data/spec/unit/provider/service/invokercd_service_spec.rb +4 -4
  426. data/spec/unit/provider/service/macosx_spec.rb +11 -66
  427. data/spec/unit/provider/service/redhat_spec.rb +1 -1
  428. data/spec/unit/provider/service/simple_service_spec.rb +3 -3
  429. data/spec/unit/provider/service/upstart_service_spec.rb +9 -9
  430. data/spec/unit/provider/subversion_spec.rb +1 -1
  431. data/spec/unit/provider/template_spec.rb +35 -11
  432. data/spec/unit/provider/user/dscl_spec.rb +285 -681
  433. data/spec/unit/provider/user/useradd_spec.rb +1 -22
  434. data/spec/unit/provider/user_spec.rb +1 -1
  435. data/spec/unit/recipe_spec.rb +10 -8
  436. data/spec/unit/registry_helper_spec.rb +374 -0
  437. data/spec/unit/resource/mount_spec.rb +0 -11
  438. data/spec/unit/resource/registry_key_spec.rb +171 -0
  439. data/spec/unit/resource/remote_file_spec.rb +21 -23
  440. data/spec/unit/resource/ruby_block_spec.rb +7 -3
  441. data/spec/unit/resource/service_spec.rb +11 -0
  442. data/spec/unit/resource_spec.rb +4 -19
  443. data/spec/unit/rest/auth_credentials_spec.rb +2 -19
  444. data/spec/unit/rest_spec.rb +130 -284
  445. data/spec/unit/run_context/cookbook_compiler_spec.rb +181 -0
  446. data/spec/unit/run_context_spec.rb +18 -4
  447. data/spec/unit/run_list_spec.rb +0 -209
  448. data/spec/unit/run_lock_spec.rb +37 -0
  449. data/spec/unit/runner_spec.rb +101 -2
  450. data/spec/unit/scan_access_control_spec.rb +4 -4
  451. data/spec/unit/{shef → shell}/model_wrapper_spec.rb +5 -5
  452. data/spec/unit/{shef/shef_ext_spec.rb → shell/shell_ext_spec.rb} +21 -21
  453. data/spec/unit/{shef/shef_session_spec.rb → shell/shell_session_spec.rb} +14 -69
  454. data/spec/unit/shell_out_spec.rb +18 -0
  455. data/spec/unit/{shef_spec.rb → shell_spec.rb} +20 -20
  456. metadata +275 -234
  457. checksums.yaml +0 -15
  458. data/README.rdoc +0 -177
  459. data/distro/common/html/knife-recipe.1.html +0 -92
  460. data/lib/chef/certificate.rb +0 -161
  461. data/lib/chef/checksum.rb +0 -167
  462. data/lib/chef/checksum_cache.rb +0 -190
  463. data/lib/chef/cookbook_version_selector.rb +0 -168
  464. data/lib/chef/couchdb.rb +0 -246
  465. data/lib/chef/index_queue/amqp_client.rb +0 -116
  466. data/lib/chef/index_queue/consumer.rb +0 -76
  467. data/lib/chef/index_queue/indexable.rb +0 -109
  468. data/lib/chef/knife/bootstrap/ubuntu12.10-gems.erb +0 -60
  469. data/lib/chef/monkey_patches/moneta.rb +0 -50
  470. data/lib/chef/monkey_patches/uri.rb +0 -70
  471. data/lib/chef/openid_registration.rb +0 -187
  472. data/lib/chef/provider/user/solaris.rb +0 -90
  473. data/lib/chef/solr_query.rb +0 -187
  474. data/lib/chef/solr_query/lucene.treetop +0 -150
  475. data/lib/chef/solr_query/lucene_nodes.rb +0 -285
  476. data/lib/chef/solr_query/query_transform.rb +0 -65
  477. data/lib/chef/solr_query/solr_http_request.rb +0 -132
  478. data/lib/chef/webui_user.rb +0 -231
  479. data/spec/data/cookbooks/openldap/files/default/.dotfile +0 -1
  480. data/spec/data/cookbooks/openldap/files/default/.ssh/id_rsa +0 -1
  481. data/spec/data/cookbooks/openldap/files/default/remotedir/.a_dotdir/.a_dotfile_in_a_dotdir +0 -1
  482. data/spec/data/cookbooks/openldap/files/default/remotedir/remotesubdir/.a_dotfile +0 -1
  483. data/spec/data/mac_users/10.7-8.plist.xml +0 -559
  484. data/spec/data/mac_users/10.7-8.shadow.xml +0 -11
  485. data/spec/data/mac_users/10.7.plist.xml +0 -559
  486. data/spec/data/mac_users/10.7.shadow.xml +0 -11
  487. data/spec/data/mac_users/10.8.plist.xml +0 -559
  488. data/spec/data/mac_users/10.8.shadow.xml +0 -21
  489. data/spec/data/mac_users/10.9.plist.xml +0 -560
  490. data/spec/data/mac_users/10.9.shadow.xml +0 -21
  491. data/spec/functional/resource/base.rb +0 -40
  492. data/spec/functional/resource/group_spec.rb +0 -343
  493. data/spec/functional/resource/user/dscl_spec.rb +0 -199
  494. data/spec/unit/certificate_spec.rb +0 -76
  495. data/spec/unit/checksum_cache_spec.rb +0 -209
  496. data/spec/unit/checksum_spec.rb +0 -94
  497. data/spec/unit/couchdb_spec.rb +0 -274
  498. data/spec/unit/index_queue_spec.rb +0 -391
  499. data/spec/unit/mixin/language_spec.rb +0 -305
  500. data/spec/unit/openid_registration_spec.rb +0 -153
  501. data/spec/unit/provider/user/solaris_spec.rb +0 -414
  502. data/spec/unit/provider/whyrun_safe_ruby_block_spec.rb +0 -47
  503. data/spec/unit/solr_query/query_transform_spec.rb +0 -454
  504. data/spec/unit/solr_query/solr_http_request_spec.rb +0 -244
  505. data/spec/unit/solr_query_spec.rb +0 -203
  506. data/spec/unit/webui_user_spec.rb +0 -238
@@ -0,0 +1,139 @@
1
+ #
2
+ # Author:: Daniel DeLeo (<dan@opscode.com>)
3
+ # Copyright:: Copyright (c) 2012 Opscode, 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 "chef/node/immutable_collections"
21
+
22
+ describe Chef::Node::ImmutableMash do
23
+ before do
24
+ @data_in = {:top => {:second_level => "some value"},
25
+ "top_level_2" => %w[array of values],
26
+ :top_level_3 => [{:hash_array => 1, :hash_array_b => 2}],
27
+ :top_level_4 => {:level2 => {:key => "value"}}
28
+ }
29
+ @immutable_mash = Chef::Node::ImmutableMash.new(@data_in)
30
+ end
31
+
32
+ it "element references like regular hash" do
33
+ @immutable_mash[:top][:second_level].should == "some value"
34
+ end
35
+
36
+ it "elelment references like a regular Mash" do
37
+ @immutable_mash[:top_level_2].should == %w[array of values]
38
+ end
39
+
40
+ it "converts Hash-like inputs into ImmutableMash's" do
41
+ @immutable_mash[:top].should be_a(Chef::Node::ImmutableMash)
42
+ end
43
+
44
+ it "converts array inputs into ImmutableArray's" do
45
+ @immutable_mash[:top_level_2].should be_a(Chef::Node::ImmutableArray)
46
+ end
47
+
48
+ it "converts arrays of hashes to ImmutableArray's of ImmutableMashes" do
49
+ @immutable_mash[:top_level_3].first.should be_a(Chef::Node::ImmutableMash)
50
+ end
51
+
52
+ it "converts nested hashes to ImmutableMashes" do
53
+ @immutable_mash[:top_level_4].should be_a(Chef::Node::ImmutableMash)
54
+ @immutable_mash[:top_level_4][:level2].should be_a(Chef::Node::ImmutableMash)
55
+ end
56
+
57
+
58
+ [
59
+ :[]=,
60
+ :clear,
61
+ :default=,
62
+ :default_proc=,
63
+ :delete,
64
+ :delete_if,
65
+ :keep_if,
66
+ :merge!,
67
+ :update,
68
+ :reject!,
69
+ :replace,
70
+ :select!,
71
+ :shift
72
+ ].each do |mutator|
73
+ it "doesn't allow mutation via `#{mutator}'" do
74
+ lambda { @immutable_mash.send(mutator) }.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
75
+ end
76
+ end
77
+
78
+ it "returns a mutable version of itself when duped" do
79
+ mutable = @immutable_mash.dup
80
+ mutable[:new_key] = :value
81
+ mutable[:new_key].should == :value
82
+ end
83
+
84
+ end
85
+
86
+ describe Chef::Node::ImmutableArray do
87
+
88
+ before do
89
+ @immutable_array = Chef::Node::ImmutableArray.new(%w[foo bar baz])
90
+ end
91
+
92
+ ##
93
+ # Note: other behaviors, such as immutibilizing input data, are tested along
94
+ # with ImmutableMash, above
95
+ ###
96
+
97
+ [
98
+ :<<,
99
+ :[]=,
100
+ :clear,
101
+ :collect!,
102
+ :compact!,
103
+ :default=,
104
+ :default_proc=,
105
+ :delete,
106
+ :delete_at,
107
+ :delete_if,
108
+ :fill,
109
+ :flatten!,
110
+ :insert,
111
+ :keep_if,
112
+ :map!,
113
+ :merge!,
114
+ :pop,
115
+ :push,
116
+ :update,
117
+ :reject!,
118
+ :reverse!,
119
+ :replace,
120
+ :select!,
121
+ :shift,
122
+ :slice!,
123
+ :sort!,
124
+ :sort_by!,
125
+ :uniq!,
126
+ :unshift
127
+ ].each do |mutator|
128
+ it "does not allow mutation via `#{mutator}" do
129
+ lambda { @immutable_array.send(mutator)}.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
130
+ end
131
+ end
132
+
133
+ it "returns a mutable version of itself when duped" do
134
+ mutable = @immutable_array.dup
135
+ mutable[0] = :value
136
+ mutable[0].should == :value
137
+ end
138
+ end
139
+
@@ -20,10 +20,11 @@ require 'spec_helper'
20
20
  require 'ostruct'
21
21
 
22
22
  describe Chef::Node do
23
- before(:each) do
24
- Chef::Config.node_path(File.expand_path(File.join(CHEF_SPEC_DATA, "nodes")))
25
- @node = Chef::Node.new()
26
- end
23
+
24
+ let(:node) { Chef::Node.new() }
25
+ let(:platform_introspector) { node }
26
+
27
+ it_behaves_like "a platform introspector"
27
28
 
28
29
  it "creates a node and assigns it a name" do
29
30
  node = Chef::Node.build('solo-node')
@@ -39,36 +40,33 @@ describe Chef::Node do
39
40
  response = OpenStruct.new(:code => '404')
40
41
  exception = Net::HTTPServerException.new("404 not found", response)
41
42
  Chef::Node.stub!(:load).and_raise(exception)
42
- @node.name("created-node")
43
+ node.name("created-node")
43
44
  end
44
45
 
45
46
  it "creates a new node for find_or_create" do
46
- Chef::Node.stub!(:new).and_return(@node)
47
- @node.should_receive(:create).and_return(@node)
47
+ Chef::Node.stub!(:new).and_return(node)
48
+ node.should_receive(:create).and_return(node)
48
49
  node = Chef::Node.find_or_create("created-node")
49
50
  node.name.should == 'created-node'
50
- node.should equal(@node)
51
+ node.should equal(node)
51
52
  end
52
53
  end
53
54
 
54
55
  describe "when the node exists on the server" do
55
56
  before do
56
- @node.name('existing-node')
57
- Chef::Node.stub!(:load).and_return(@node)
57
+ node.name('existing-node')
58
+ Chef::Node.stub!(:load).and_return(node)
58
59
  end
59
60
 
60
61
  it "loads the node via the REST API for find_or_create" do
61
- Chef::Node.find_or_create('existing-node').should equal(@node)
62
+ Chef::Node.find_or_create('existing-node').should equal(node)
62
63
  end
63
64
  end
64
65
 
65
66
  describe "run_state" do
66
- it "should have a template_cache hash" do
67
- @node.run_state[:template_cache].should be_a_kind_of(Hash)
68
- end
69
-
70
- it "should have a seen_recipes hash" do
71
- @node.run_state[:seen_recipes].should be_a_kind_of(Hash)
67
+ it "is an empty hash" do
68
+ node.run_state.should respond_to(:keys)
69
+ node.run_state.should be_empty
72
70
  end
73
71
  end
74
72
 
@@ -81,180 +79,180 @@ describe Chef::Node do
81
79
 
82
80
  describe "name" do
83
81
  it "should allow you to set a name with name(something)" do
84
- lambda { @node.name("latte") }.should_not raise_error
82
+ lambda { node.name("latte") }.should_not raise_error
85
83
  end
86
84
 
87
85
  it "should return the name with name()" do
88
- @node.name("latte")
89
- @node.name.should eql("latte")
86
+ node.name("latte")
87
+ node.name.should eql("latte")
90
88
  end
91
89
 
92
90
  it "should always have a string for name" do
93
- lambda { @node.name(Hash.new) }.should raise_error(ArgumentError)
91
+ lambda { node.name(Hash.new) }.should raise_error(ArgumentError)
94
92
  end
95
93
 
96
94
  it "cannot be blank" do
97
- lambda { @node.name("")}.should raise_error(Chef::Exceptions::ValidationFailed)
95
+ lambda { node.name("")}.should raise_error(Chef::Exceptions::ValidationFailed)
98
96
  end
99
97
 
100
98
  it "should not accept name doesn't match /^[\-[:alnum:]_:.]+$/" do
101
- lambda { @node.name("space in it")}.should raise_error(Chef::Exceptions::ValidationFailed)
99
+ lambda { node.name("space in it")}.should raise_error(Chef::Exceptions::ValidationFailed)
102
100
  end
103
101
  end
104
102
 
105
103
  describe "chef_environment" do
106
104
  it "should set an environment with chef_environment(something)" do
107
- lambda { @node.chef_environment("latte") }.should_not raise_error
105
+ lambda { node.chef_environment("latte") }.should_not raise_error
108
106
  end
109
107
 
110
108
  it "should return the chef_environment with chef_environment()" do
111
- @node.chef_environment("latte")
112
- @node.chef_environment.should == "latte"
109
+ node.chef_environment("latte")
110
+ node.chef_environment.should == "latte"
113
111
  end
114
112
 
115
113
  it "should disallow non-strings" do
116
- lambda { @node.chef_environment(Hash.new) }.should raise_error(ArgumentError)
117
- lambda { @node.chef_environment(42) }.should raise_error(ArgumentError)
114
+ lambda { node.chef_environment(Hash.new) }.should raise_error(ArgumentError)
115
+ lambda { node.chef_environment(42) }.should raise_error(ArgumentError)
118
116
  end
119
117
 
120
118
  it "cannot be blank" do
121
- lambda { @node.chef_environment("")}.should raise_error(Chef::Exceptions::ValidationFailed)
119
+ lambda { node.chef_environment("")}.should raise_error(Chef::Exceptions::ValidationFailed)
122
120
  end
123
121
  end
124
122
 
125
123
  describe "attributes" do
126
- it "should be loaded from the node's cookbooks" do
127
- @cookbook_repo = File.expand_path(File.join(File.dirname(__FILE__), "..", "data", "cookbooks"))
128
- @node.cookbook_collection = Chef::CookbookCollection.new(Chef::CookbookLoader.new(@cookbook_repo))
129
- @node.load_attributes
130
- @node.ldap_server.should eql("ops1prod")
131
- @node.ldap_basedn.should eql("dc=hjksolutions,dc=com")
132
- @node.ldap_replication_password.should eql("forsure")
133
- @node.smokey.should eql("robinson")
134
- end
135
-
136
124
  it "should have attributes" do
137
- @node.attribute.should be_a_kind_of(Hash)
125
+ node.attribute.should be_a_kind_of(Hash)
138
126
  end
139
127
 
140
128
  it "should allow attributes to be accessed by name or symbol directly on node[]" do
141
- @node.attribute["locust"] = "something"
142
- @node[:locust].should eql("something")
143
- @node["locust"].should eql("something")
129
+ node.default["locust"] = "something"
130
+ node[:locust].should eql("something")
131
+ node["locust"].should eql("something")
144
132
  end
145
133
 
146
134
  it "should return nil if it cannot find an attribute with node[]" do
147
- @node["secret"].should eql(nil)
135
+ node["secret"].should eql(nil)
148
136
  end
149
137
 
150
- it "should allow you to set an attribute via node[]=" do
151
- @node["secret"] = "shush"
152
- @node["secret"].should eql("shush")
138
+ it "does not allow you to set an attribute via node[]=" do
139
+ lambda { node["secret"] = "shush" }.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
153
140
  end
154
141
 
155
142
  it "should allow you to query whether an attribute exists with attribute?" do
156
- @node.attribute["locust"] = "something"
157
- @node.attribute?("locust").should eql(true)
158
- @node.attribute?("no dice").should eql(false)
143
+ node.default["locust"] = "something"
144
+ node.attribute?("locust").should eql(true)
145
+ node.attribute?("no dice").should eql(false)
159
146
  end
160
147
 
161
148
  it "should let you go deep with attribute?" do
162
- @node.set["battles"]["people"]["wonkey"] = true
163
- @node["battles"]["people"].attribute?("wonkey").should == true
164
- @node["battles"]["people"].attribute?("snozzberry").should == false
149
+ node.set["battles"]["people"]["wonkey"] = true
150
+ node["battles"]["people"].attribute?("wonkey").should == true
151
+ node["battles"]["people"].attribute?("snozzberry").should == false
165
152
  end
166
153
 
167
- it "should allow you to set an attribute via method_missing" do
168
- @node.sunshine "is bright"
169
- @node.attribute[:sunshine].should eql("is bright")
154
+ it "does not allow you to set an attribute via method_missing" do
155
+ lambda { node.sunshine = "is bright"}.should raise_error(Chef::Exceptions::ImmutableAttributeModification)
170
156
  end
171
157
 
172
158
  it "should allow you get get an attribute via method_missing" do
173
- @node.sunshine "is bright"
174
- @node.sunshine.should eql("is bright")
159
+ node.default.sunshine = "is bright"
160
+ node.sunshine.should eql("is bright")
175
161
  end
176
162
 
177
163
  describe "normal attributes" do
178
164
  it "should allow you to set an attribute with set, without pre-declaring a hash" do
179
- @node.set[:snoopy][:is_a_puppy] = true
180
- @node[:snoopy][:is_a_puppy].should == true
165
+ node.set[:snoopy][:is_a_puppy] = true
166
+ node[:snoopy][:is_a_puppy].should == true
181
167
  end
182
168
 
183
169
  it "should allow you to set an attribute with set_unless" do
184
- @node.set_unless[:snoopy][:is_a_puppy] = false
185
- @node[:snoopy][:is_a_puppy].should == false
170
+ node.set_unless[:snoopy][:is_a_puppy] = false
171
+ node[:snoopy][:is_a_puppy].should == false
186
172
  end
187
173
 
188
174
  it "should not allow you to set an attribute with set_unless if it already exists" do
189
- @node.set[:snoopy][:is_a_puppy] = true
190
- @node.set_unless[:snoopy][:is_a_puppy] = false
191
- @node[:snoopy][:is_a_puppy].should == true
175
+ node.set[:snoopy][:is_a_puppy] = true
176
+ node.set_unless[:snoopy][:is_a_puppy] = false
177
+ node[:snoopy][:is_a_puppy].should == true
192
178
  end
193
179
 
194
180
  it "auto-vivifies attributes created via method syntax" do
195
- @node.set.fuu.bahrr.baz = "qux"
196
- @node.fuu.bahrr.baz.should == "qux"
181
+ node.set.fuu.bahrr.baz = "qux"
182
+ node.fuu.bahrr.baz.should == "qux"
197
183
  end
198
184
 
199
185
  end
200
186
 
201
187
  describe "default attributes" do
202
188
  it "should be set with default, without pre-declaring a hash" do
203
- @node.default[:snoopy][:is_a_puppy] = true
204
- @node[:snoopy][:is_a_puppy].should == true
189
+ node.default[:snoopy][:is_a_puppy] = true
190
+ node[:snoopy][:is_a_puppy].should == true
205
191
  end
206
192
 
207
193
  it "should allow you to set with default_unless without pre-declaring a hash" do
208
- @node.default_unless[:snoopy][:is_a_puppy] = false
209
- @node[:snoopy][:is_a_puppy].should == false
194
+ node.default_unless[:snoopy][:is_a_puppy] = false
195
+ node[:snoopy][:is_a_puppy].should == false
210
196
  end
211
197
 
212
198
  it "should not allow you to set an attribute with default_unless if it already exists" do
213
- @node.default[:snoopy][:is_a_puppy] = true
214
- @node.default_unless[:snoopy][:is_a_puppy] = false
215
- @node[:snoopy][:is_a_puppy].should == true
199
+ node.default[:snoopy][:is_a_puppy] = true
200
+ node.default_unless[:snoopy][:is_a_puppy] = false
201
+ node[:snoopy][:is_a_puppy].should == true
216
202
  end
217
203
 
218
204
  it "auto-vivifies attributes created via method syntax" do
219
- @node.default.fuu.bahrr.baz = "qux"
220
- @node.fuu.bahrr.baz.should == "qux"
205
+ node.default.fuu.bahrr.baz = "qux"
206
+ node.fuu.bahrr.baz.should == "qux"
207
+ end
208
+
209
+ it "accesses force defaults via default!" do
210
+ node.default![:foo] = "wet bar"
211
+ node.default[:foo] = "bar"
212
+ node[:foo].should == "wet bar"
221
213
  end
222
214
 
223
215
  end
224
216
 
225
217
  describe "override attributes" do
226
218
  it "should be set with override, without pre-declaring a hash" do
227
- @node.override[:snoopy][:is_a_puppy] = true
228
- @node[:snoopy][:is_a_puppy].should == true
219
+ node.override[:snoopy][:is_a_puppy] = true
220
+ node[:snoopy][:is_a_puppy].should == true
229
221
  end
230
222
 
231
223
  it "should allow you to set with override_unless without pre-declaring a hash" do
232
- @node.override_unless[:snoopy][:is_a_puppy] = false
233
- @node[:snoopy][:is_a_puppy].should == false
224
+ node.override_unless[:snoopy][:is_a_puppy] = false
225
+ node[:snoopy][:is_a_puppy].should == false
234
226
  end
235
227
 
236
228
  it "should not allow you to set an attribute with override_unless if it already exists" do
237
- @node.override[:snoopy][:is_a_puppy] = true
238
- @node.override_unless[:snoopy][:is_a_puppy] = false
239
- @node[:snoopy][:is_a_puppy].should == true
229
+ node.override[:snoopy][:is_a_puppy] = true
230
+ node.override_unless[:snoopy][:is_a_puppy] = false
231
+ node[:snoopy][:is_a_puppy].should == true
240
232
  end
241
233
 
242
234
  it "auto-vivifies attributes created via method syntax" do
243
- @node.override.fuu.bahrr.baz = "qux"
244
- @node.fuu.bahrr.baz.should == "qux"
235
+ node.override.fuu.bahrr.baz = "qux"
236
+ node.fuu.bahrr.baz.should == "qux"
237
+ end
238
+
239
+ it "sets force_overrides via override!" do
240
+ node.override![:foo] = "wet bar"
241
+ node.override[:foo] = "bar"
242
+ node[:foo].should == "wet bar"
245
243
  end
246
244
 
247
245
  end
248
246
 
249
247
  it "should raise an ArgumentError if you ask for an attribute that doesn't exist via method_missing" do
250
- lambda { @node.sunshine }.should raise_error(ArgumentError)
248
+ lambda { node.sunshine }.should raise_error(NoMethodError)
251
249
  end
252
250
 
253
251
  it "should allow you to iterate over attributes with each_attribute" do
254
- @node.sunshine "is bright"
255
- @node.canada "is a nice place"
252
+ node.default.sunshine = "is bright"
253
+ node.default.canada = "is a nice place"
256
254
  seen_attributes = Hash.new
257
- @node.each_attribute do |a,v|
255
+ node.each_attribute do |a,v|
258
256
  seen_attributes[a] = v
259
257
  end
260
258
  seen_attributes.should have_key("sunshine")
@@ -272,62 +270,62 @@ describe Chef::Node do
272
270
 
273
271
  it "consumes the run list portion of a collection of attributes and returns the remainder" do
274
272
  attrs = {"run_list" => [ "role[base]", "recipe[chef::server]" ], "foo" => "bar"}
275
- @node.consume_run_list(attrs).should == {"foo" => "bar"}
276
- @node.run_list.should == [ "role[base]", "recipe[chef::server]" ]
273
+ node.consume_run_list(attrs).should == {"foo" => "bar"}
274
+ node.run_list.should == [ "role[base]", "recipe[chef::server]" ]
277
275
  end
278
276
 
279
277
  it "should overwrites the run list with the run list it consumes" do
280
- @node.consume_run_list "recipes" => [ "one", "two" ]
281
- @node.consume_run_list "recipes" => [ "three" ]
282
- @node.run_list.should == [ "three" ]
278
+ node.consume_run_list "recipes" => [ "one", "two" ]
279
+ node.consume_run_list "recipes" => [ "three" ]
280
+ node.run_list.should == [ "three" ]
283
281
  end
284
282
 
285
283
  it "should not add duplicate recipes from the json attributes" do
286
- @node.run_list << "one"
287
- @node.consume_run_list "recipes" => [ "one", "two", "three" ]
288
- @node.run_list.should == [ "one", "two", "three" ]
284
+ node.run_list << "one"
285
+ node.consume_run_list "recipes" => [ "one", "two", "three" ]
286
+ node.run_list.should == [ "one", "two", "three" ]
289
287
  end
290
288
 
291
289
  it "doesn't change the run list if no run_list is specified in the json" do
292
- @node.run_list << "role[database]"
293
- @node.consume_run_list "foo" => "bar"
294
- @node.run_list.should == ["role[database]"]
290
+ node.run_list << "role[database]"
291
+ node.consume_run_list "foo" => "bar"
292
+ node.run_list.should == ["role[database]"]
295
293
  end
296
294
 
297
295
  it "raises an exception if you provide both recipe and run_list attributes, since this is ambiguous" do
298
- lambda { @node.consume_run_list "recipes" => "stuff", "run_list" => "other_stuff" }.should raise_error(Chef::Exceptions::AmbiguousRunlistSpecification)
296
+ lambda { node.consume_run_list "recipes" => "stuff", "run_list" => "other_stuff" }.should raise_error(Chef::Exceptions::AmbiguousRunlistSpecification)
299
297
  end
300
298
 
301
299
  it "should add json attributes to the node" do
302
- @node.consume_external_attrs(@ohai_data, {"one" => "two", "three" => "four"})
303
- @node.one.should eql("two")
304
- @node.three.should eql("four")
300
+ node.consume_external_attrs(@ohai_data, {"one" => "two", "three" => "four"})
301
+ node.one.should eql("two")
302
+ node.three.should eql("four")
305
303
  end
306
304
 
307
305
  it "should set the tags attribute to an empty array if it is not already defined" do
308
- @node.consume_external_attrs(@ohai_data, {})
309
- @node.tags.should eql([])
306
+ node.consume_external_attrs(@ohai_data, {})
307
+ node.tags.should eql([])
310
308
  end
311
309
 
312
310
  it "should not set the tags attribute to an empty array if it is already defined" do
313
- @node[:tags] = [ "radiohead" ]
314
- @node.consume_external_attrs(@ohai_data, {})
315
- @node.tags.should eql([ "radiohead" ])
311
+ node.normal[:tags] = [ "radiohead" ]
312
+ node.consume_external_attrs(@ohai_data, {})
313
+ node.tags.should eql([ "radiohead" ])
316
314
  end
317
315
 
318
316
  it "deep merges attributes instead of overwriting them" do
319
- @node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "four"}})
320
- @node.one.to_hash.should == {"two" => {"three" => "four"}}
321
- @node.consume_external_attrs(@ohai_data, "one" => {"abc" => "123"})
322
- @node.consume_external_attrs(@ohai_data, "one" => {"two" => {"foo" => "bar"}})
323
- @node.one.to_hash.should == {"two" => {"three" => "four", "foo" => "bar"}, "abc" => "123"}
317
+ node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "four"}})
318
+ node.one.to_hash.should == {"two" => {"three" => "four"}}
319
+ node.consume_external_attrs(@ohai_data, "one" => {"abc" => "123"})
320
+ node.consume_external_attrs(@ohai_data, "one" => {"two" => {"foo" => "bar"}})
321
+ node.one.to_hash.should == {"two" => {"three" => "four", "foo" => "bar"}, "abc" => "123"}
324
322
  end
325
323
 
326
324
  it "gives attributes from JSON priority when deep merging" do
327
- @node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "four"}})
328
- @node.one.to_hash.should == {"two" => {"three" => "four"}}
329
- @node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "forty-two"}})
330
- @node.one.to_hash.should == {"two" => {"three" => "forty-two"}}
325
+ node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "four"}})
326
+ node.one.to_hash.should == {"two" => {"three" => "four"}}
327
+ node.consume_external_attrs(@ohai_data, "one" => {"two" => {"three" => "forty-two"}})
328
+ node.one.to_hash.should == {"two" => {"three" => "forty-two"}}
331
329
  end
332
330
 
333
331
  end
@@ -338,161 +336,249 @@ describe Chef::Node do
338
336
  end
339
337
 
340
338
  it "sets its platform according to platform detection" do
341
- @node.consume_external_attrs(@ohai_data, {})
342
- @node.automatic_attrs[:platform].should == 'foobuntu'
343
- @node.automatic_attrs[:platform_version].should == '23.42'
339
+ node.consume_external_attrs(@ohai_data, {})
340
+ node.automatic_attrs[:platform].should == 'foobuntu'
341
+ node.automatic_attrs[:platform_version].should == '23.42'
344
342
  end
345
343
 
346
344
  it "consumes the run list from provided json attributes" do
347
- @node.consume_external_attrs(@ohai_data, {"run_list" => ['recipe[unicorn]']})
348
- @node.run_list.should == ['recipe[unicorn]']
345
+ node.consume_external_attrs(@ohai_data, {"run_list" => ['recipe[unicorn]']})
346
+ node.run_list.should == ['recipe[unicorn]']
349
347
  end
350
348
 
351
349
  it "saves non-runlist json attrs for later" do
352
350
  expansion = Chef::RunList::RunListExpansion.new('_default', [])
353
- @node.run_list.stub!(:expand).and_return(expansion)
354
- @node.consume_external_attrs(@ohai_data, {"foo" => "bar"})
355
- @node.expand!
356
- @node.normal_attrs.should == {"foo" => "bar", "tags" => []}
351
+ node.run_list.stub!(:expand).and_return(expansion)
352
+ node.consume_external_attrs(@ohai_data, {"foo" => "bar"})
353
+ node.expand!
354
+ node.normal_attrs.should == {"foo" => "bar", "tags" => []}
357
355
  end
358
356
 
359
357
  end
360
358
 
361
359
  describe "when expanding its run list and merging attributes" do
362
360
  before do
363
- @expansion = Chef::RunList::RunListExpansion.new("_default", [])
364
- @node.run_list.stub!(:expand).and_return(@expansion)
361
+ @environment = Chef::Environment.new.tap do |e|
362
+ e.name('rspec_env')
363
+ e.default_attributes("env default key" => "env default value")
364
+ e.override_attributes("env override key" => "env override value")
365
+ end
366
+ Chef::Environment.should_receive(:load).with("rspec_env").and_return(@environment)
367
+ @expansion = Chef::RunList::RunListExpansion.new("rspec_env", [])
368
+ node.chef_environment("rspec_env")
369
+ node.run_list.stub!(:expand).and_return(@expansion)
365
370
  end
366
371
 
367
372
  it "sets the 'recipes' automatic attribute to the recipes in the expanded run_list" do
368
373
  @expansion.recipes << 'recipe[chef::client]' << 'recipe[nginx::default]'
369
- @node.expand!
370
- @node.automatic_attrs[:recipes].should == ['recipe[chef::client]', 'recipe[nginx::default]']
374
+ node.expand!
375
+ node.automatic_attrs[:recipes].should == ['recipe[chef::client]', 'recipe[nginx::default]']
371
376
  end
372
377
 
373
378
  it "sets the 'roles' automatic attribute to the expanded role list" do
374
379
  @expansion.instance_variable_set(:@applied_roles, {'arf' => nil, 'countersnark' => nil})
375
- @node.expand!
376
- @node.automatic_attrs[:roles].sort.should == ['arf', 'countersnark']
380
+ node.expand!
381
+ node.automatic_attrs[:roles].sort.should == ['arf', 'countersnark']
382
+ end
383
+
384
+ it "applies default attributes from the environment as environment defaults" do
385
+ node.expand!
386
+ node.attributes.env_default["env default key"].should == "env default value"
387
+ end
388
+
389
+ it "applies override attributes from the environment as env overrides" do
390
+ node.expand!
391
+ node.attributes.env_override["env override key"].should == "env override value"
392
+ end
393
+
394
+ it "applies default attributes from roles as role defaults" do
395
+ @expansion.default_attrs["role default key"] = "role default value"
396
+ node.expand!
397
+ node.attributes.role_default["role default key"].should == "role default value"
398
+ end
399
+
400
+ it "applies override attributes from roles as role overrides" do
401
+ @expansion.override_attrs["role override key"] = "role override value"
402
+ node.expand!
403
+ node.attributes.role_override["role override key"].should == "role override value"
404
+ end
405
+ end
406
+
407
+ describe "when querying for recipes in the run list" do
408
+ context "when a recipe is in the top level run list" do
409
+ before do
410
+ node.run_list << "recipe[nginx::module]"
411
+ end
412
+
413
+ it "finds the recipe" do
414
+ node.recipe?("nginx::module").should be_true
415
+ end
416
+
417
+ it "does not find a recipe not in the run list" do
418
+ node.recipe?("nginx::other_module").should be_false
419
+ end
420
+ end
421
+ context "when a recipe is in the expanded run list only" do
422
+ before do
423
+ node.run_list << "role[base]"
424
+ node.automatic_attrs[:recipes] = [ "nginx::module" ]
425
+ end
426
+
427
+ it "finds a recipe in the expanded run list" do
428
+ node.recipe?("nginx::module").should be_true
429
+ end
430
+
431
+ it "does not find a recipe that's not in the run list" do
432
+ node.recipe?("nginx::other_module").should be_false
433
+ end
434
+ end
435
+ end
436
+
437
+ describe "when clearing computed state at the beginning of a run" do
438
+ before do
439
+ node.default[:foo] = "default"
440
+ node.normal[:foo] = "normal"
441
+ node.override[:foo] = "override"
442
+ node.reset_defaults_and_overrides
443
+ end
444
+
445
+ it "removes default attributes" do
446
+ node.default.should be_empty
447
+ end
448
+
449
+ it "removes override attributes" do
450
+ node.override.should be_empty
451
+ end
452
+
453
+ it "leaves normal level attributes untouched" do
454
+ node[:foo].should == "normal"
455
+ end
456
+
457
+ end
458
+
459
+ describe "when merging environment attributes" do
460
+ before do
461
+ node.chef_environment = "rspec"
462
+ @expansion = Chef::RunList::RunListExpansion.new("rspec", [])
463
+ @expansion.default_attrs.replace({:default => "from role", :d_role => "role only"})
464
+ @expansion.override_attrs.replace({:override => "from role", :o_role => "role only"})
465
+
466
+
467
+ @environment = Chef::Environment.new
468
+ @environment.default_attributes = {:default => "from env", :d_env => "env only" }
469
+ @environment.override_attributes = {:override => "from env", :o_env => "env only"}
470
+ Chef::Environment.stub!(:load).and_return(@environment)
471
+ node.apply_expansion_attributes(@expansion)
472
+ end
473
+
474
+ it "does not nuke role-only default attrs" do
475
+ node[:d_role].should == "role only"
476
+ end
477
+
478
+ it "does not nuke role-only override attrs" do
479
+ node[:o_role].should == "role only"
480
+ end
481
+
482
+ it "does not nuke env-only default attrs" do
483
+ node[:o_env].should == "env only"
484
+ end
485
+
486
+ it "does not nuke role-only override attrs" do
487
+ node[:o_env].should == "env only"
488
+ end
489
+
490
+ it "gives role defaults precedence over env defaults" do
491
+ node[:default].should == "from role"
377
492
  end
378
493
 
494
+ it "gives env overrides precedence over role overrides" do
495
+ node[:override].should == "from env"
496
+ end
379
497
  end
380
498
 
381
- # TODO: timh, cw: 2010-5-19: Node.recipe? deprecated. See node.rb
382
- # describe "recipes" do
383
- # it "should have a RunList of recipes that should be applied" do
384
- # @node.recipes.should be_a_kind_of(Chef::RunList)
385
- # end
386
- #
387
- # it "should allow you to query whether or not it has a recipe applied with recipe?" do
388
- # @node.recipes << "sunrise"
389
- # @node.recipe?("sunrise").should eql(true)
390
- # @node.recipe?("not at home").should eql(false)
391
- # end
392
- #
393
- # it "should allow you to query whether or not a recipe has been applied, even if it was included" do
394
- # @node.run_state[:seen_recipes]["snakes"] = true
395
- # @node.recipe?("snakes").should eql(true)
396
- # end
397
- #
398
- # it "should return false if a recipe has not been seen" do
399
- # @node.recipe?("snakes").should eql(false)
400
- # end
401
- #
402
- # it "should allow you to set recipes with arguments" do
403
- # @node.recipes "one", "two"
404
- # @node.recipe?("one").should eql(true)
405
- # @node.recipe?("two").should eql(true)
406
- # end
407
- # end
499
+ describe "when evaluating attributes files" do
500
+ before do
501
+ @cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks"))
502
+ @cookbook_loader = Chef::CookbookLoader.new(@cookbook_repo)
503
+ @cookbook_loader.load_cookbooks
504
+
505
+ @cookbook_collection = Chef::CookbookCollection.new(@cookbook_loader.cookbooks_by_name)
506
+
507
+ @events = Chef::EventDispatch::Dispatcher.new
508
+ @run_context = Chef::RunContext.new(node, @cookbook_collection, @events)
509
+
510
+ node.include_attribute("openldap::default")
511
+ node.include_attribute("openldap::smokey")
512
+ end
513
+
514
+ it "sets attributes from the files" do
515
+ node.ldap_server.should eql("ops1prod")
516
+ node.ldap_basedn.should eql("dc=hjksolutions,dc=com")
517
+ node.ldap_replication_password.should eql("forsure")
518
+ node.smokey.should eql("robinson")
519
+ end
520
+
521
+ it "gives a sensible error when attempting to load a missing attributes file" do
522
+ lambda { node.include_attribute("nope-this::doesnt-exist") }.should raise_error(Chef::Exceptions::CookbookNotFound)
523
+ end
524
+ end
408
525
 
409
526
  describe "roles" do
410
527
  it "should allow you to query whether or not it has a recipe applied with role?" do
411
- @node.run_list << "role[sunrise]"
412
- @node.role?("sunrise").should eql(true)
413
- @node.role?("not at home").should eql(false)
528
+ node.run_list << "role[sunrise]"
529
+ node.role?("sunrise").should eql(true)
530
+ node.role?("not at home").should eql(false)
414
531
  end
415
532
 
416
533
  it "should allow you to set roles with arguments" do
417
- @node.run_list << "role[one]"
418
- @node.run_list << "role[two]"
419
- @node.role?("one").should eql(true)
420
- @node.role?("two").should eql(true)
534
+ node.run_list << "role[one]"
535
+ node.run_list << "role[two]"
536
+ node.role?("one").should eql(true)
537
+ node.role?("two").should eql(true)
421
538
  end
422
539
  end
423
540
 
424
541
  describe "run_list" do
425
542
  it "should have a Chef::RunList of recipes and roles that should be applied" do
426
- @node.run_list.should be_a_kind_of(Chef::RunList)
543
+ node.run_list.should be_a_kind_of(Chef::RunList)
427
544
  end
428
545
 
429
546
  it "should allow you to query the run list with arguments" do
430
- @node.run_list "recipe[baz]"
431
- @node.run_list?("recipe[baz]").should eql(true)
547
+ node.run_list "recipe[baz]"
548
+ node.run_list?("recipe[baz]").should eql(true)
432
549
  end
433
550
 
434
551
  it "should allow you to set the run list with arguments" do
435
- @node.run_list "recipe[baz]", "role[foo]"
436
- @node.run_list?("recipe[baz]").should eql(true)
437
- @node.run_list?("role[foo]").should eql(true)
552
+ node.run_list "recipe[baz]", "role[foo]"
553
+ node.run_list?("recipe[baz]").should eql(true)
554
+ node.run_list?("role[foo]").should eql(true)
438
555
  end
439
556
  end
440
557
 
441
558
  describe "from file" do
442
559
  it "should load a node from a ruby file" do
443
- @node.from_file(File.expand_path(File.join(CHEF_SPEC_DATA, "nodes", "test.rb")))
444
- @node.name.should eql("test.example.com-short")
445
- @node.sunshine.should eql("in")
446
- @node.something.should eql("else")
447
- @node.recipes.should == ["operations-master", "operations-monitoring"]
560
+ node.from_file(File.expand_path(File.join(CHEF_SPEC_DATA, "nodes", "test.rb")))
561
+ node.name.should eql("test.example.com-short")
562
+ node.sunshine.should eql("in")
563
+ node.something.should eql("else")
564
+ node.run_list.should == ["operations-master", "operations-monitoring"]
448
565
  end
449
566
 
450
567
  it "should raise an exception if the file cannot be found or read" do
451
- lambda { @node.from_file("/tmp/monkeydiving") }.should raise_error(IOError)
452
- end
453
- end
454
-
455
- describe "find_file" do
456
- it "should load a node from a file by fqdn" do
457
- @node.find_file("test.example.com")
458
- @node.name.should == "test.example.com"
459
- @node.chef_environment.should == "dev"
460
- end
461
-
462
- it "should load a node from a file by hostname" do
463
- File.stub!(:exists?).and_return(true)
464
- File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "test.example.com.rb")).and_return(false)
465
- @node.find_file("test.example.com")
466
- @node.name.should == "test.example.com-short"
467
- end
468
-
469
- it "should load a node from the default file" do
470
- File.stub!(:exists?).and_return(true)
471
- File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "test.example.com.rb")).and_return(false)
472
- File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "test.rb")).and_return(false)
473
- @node.find_file("test.example.com")
474
- @node.name.should == "test.example.com-default"
475
- end
476
-
477
- it "should raise an ArgumentError if it cannot find any node file at all" do
478
- File.stub!(:exists?).and_return(true)
479
- File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "test.example.com.rb")).and_return(false)
480
- File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "test.rb")).and_return(false)
481
- File.should_receive(:exists?).with(File.join(Chef::Config[:node_path], "default.rb")).and_return(false)
482
- lambda { @node.find_file("test.example.com") }.should raise_error(ArgumentError)
568
+ lambda { node.from_file("/tmp/monkeydiving") }.should raise_error(IOError)
483
569
  end
484
570
  end
485
571
 
486
572
  describe "update_from!" do
487
573
  before(:each) do
488
- @node.name("orig")
489
- @node.chef_environment("dev")
490
- @node.default_attrs = { "one" => { "two" => "three", "four" => "five", "eight" => "nine" } }
491
- @node.override_attrs = { "one" => { "two" => "three", "four" => "six" } }
492
- @node.normal_attrs = { "one" => { "two" => "seven" } }
493
- @node.run_list << "role[marxist]"
494
- @node.run_list << "role[leninist]"
495
- @node.run_list << "recipe[stalinist]"
574
+ node.name("orig")
575
+ node.chef_environment("dev")
576
+ node.default_attrs = { "one" => { "two" => "three", "four" => "five", "eight" => "nine" } }
577
+ node.override_attrs = { "one" => { "two" => "three", "four" => "six" } }
578
+ node.normal_attrs = { "one" => { "two" => "seven" } }
579
+ node.run_list << "role[marxist]"
580
+ node.run_list << "role[leninist]"
581
+ node.run_list << "recipe[stalinist]"
496
582
 
497
583
  @example = Chef::Node.new()
498
584
  @example.name("newname")
@@ -506,31 +592,31 @@ describe Chef::Node do
506
592
  end
507
593
 
508
594
  it "allows update of everything except name" do
509
- @node.update_from!(@example)
510
- @node.name.should == "orig"
511
- @node.chef_environment.should == @example.chef_environment
512
- @node.default_attrs.should == @example.default_attrs
513
- @node.override_attrs.should == @example.override_attrs
514
- @node.normal_attrs.should == @example.normal_attrs
515
- @node.run_list.should == @example.run_list
595
+ node.update_from!(@example)
596
+ node.name.should == "orig"
597
+ node.chef_environment.should == @example.chef_environment
598
+ node.default_attrs.should == @example.default_attrs
599
+ node.override_attrs.should == @example.override_attrs
600
+ node.normal_attrs.should == @example.normal_attrs
601
+ node.run_list.should == @example.run_list
516
602
  end
517
603
 
518
604
  it "should not update the name of the node" do
519
- @node.should_not_receive(:name).with(@example.name)
520
- @node.update_from!(@example)
605
+ node.should_not_receive(:name).with(@example.name)
606
+ node.update_from!(@example)
521
607
  end
522
608
  end
523
609
 
524
610
  describe "to_hash" do
525
611
  it "should serialize itself as a hash" do
526
- @node.chef_environment("dev")
527
- @node.default_attrs = { "one" => { "two" => "three", "four" => "five", "eight" => "nine" } }
528
- @node.override_attrs = { "one" => { "two" => "three", "four" => "six" } }
529
- @node.normal_attrs = { "one" => { "two" => "seven" } }
530
- @node.run_list << "role[marxist]"
531
- @node.run_list << "role[leninist]"
532
- @node.run_list << "recipe[stalinist]"
533
- h = @node.to_hash
612
+ node.chef_environment("dev")
613
+ node.default_attrs = { "one" => { "two" => "three", "four" => "five", "eight" => "nine" } }
614
+ node.override_attrs = { "one" => { "two" => "three", "four" => "six" } }
615
+ node.normal_attrs = { "one" => { "two" => "seven" } }
616
+ node.run_list << "role[marxist]"
617
+ node.run_list << "role[leninist]"
618
+ node.run_list << "recipe[stalinist]"
619
+ h = node.to_hash
534
620
  h["one"]["two"].should == "three"
535
621
  h["one"]["four"].should == "six"
536
622
  h["one"]["eight"].should == "nine"
@@ -543,10 +629,10 @@ describe Chef::Node do
543
629
  end
544
630
  end
545
631
 
546
- describe "json" do
632
+ describe "converting to or from json" do
547
633
  it "should serialize itself as json", :json => true do
548
- @node.find_file("test.example.com")
549
- json = Chef::JSONCompat.to_json(@node)
634
+ node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA))
635
+ json = Chef::JSONCompat.to_json(node)
550
636
  json.should =~ /json_class/
551
637
  json.should =~ /name/
552
638
  json.should =~ /chef_environment/
@@ -556,33 +642,50 @@ describe Chef::Node do
556
642
  json.should =~ /run_list/
557
643
  end
558
644
 
559
- it 'should serialze valid json with a run list', :json => true do
645
+ it 'should serialize valid json with a run list', :json => true do
560
646
  #This test came about because activesupport mucks with Chef json serialization
561
647
  #Test should pass with and without Activesupport
562
- @node.run_list << {"type" => "role", "name" => 'Cthulu'}
563
- @node.run_list << {"type" => "role", "name" => 'Hastur'}
564
- json = Chef::JSONCompat.to_json(@node)
648
+ node.run_list << {"type" => "role", "name" => 'Cthulu'}
649
+ node.run_list << {"type" => "role", "name" => 'Hastur'}
650
+ json = Chef::JSONCompat.to_json(node)
565
651
  json.should =~ /\"run_list\":\[\"role\[Cthulu\]\",\"role\[Hastur\]\"\]/
566
652
  end
567
653
 
654
+ it "merges the override components into a combined override object" do
655
+ node.attributes.role_override["role override"] = "role override"
656
+ node.attributes.env_override["env override"] = "env override"
657
+ node_for_json = node.for_json
658
+ node_for_json["override"]["role override"].should == "role override"
659
+ node_for_json["override"]["env override"].should == "env override"
660
+ end
661
+
662
+ it "merges the default components into a combined default object" do
663
+ node.attributes.role_default["role default"] = "role default"
664
+ node.attributes.env_default["env default"] = "env default"
665
+ node_for_json = node.for_json
666
+ node_for_json["default"]["role default"].should == "role default"
667
+ node_for_json["default"]["env default"].should == "env default"
668
+ end
669
+
670
+
568
671
  it "should deserialize itself from json", :json => true do
569
- @node.find_file("test.example.com")
570
- json = Chef::JSONCompat.to_json(@node)
672
+ node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA))
673
+ json = Chef::JSONCompat.to_json(node)
571
674
  serialized_node = Chef::JSONCompat.from_json(json)
572
675
  serialized_node.should be_a_kind_of(Chef::Node)
573
- serialized_node.name.should eql(@node.name)
574
- serialized_node.chef_environment.should eql(@node.chef_environment)
575
- @node.each_attribute do |k,v|
676
+ serialized_node.name.should eql(node.name)
677
+ serialized_node.chef_environment.should eql(node.chef_environment)
678
+ node.each_attribute do |k,v|
576
679
  serialized_node[k].should eql(v)
577
680
  end
578
- serialized_node.run_list.should == @node.run_list
681
+ serialized_node.run_list.should == node.run_list
579
682
  end
580
683
  end
581
684
 
582
685
  describe "to_s" do
583
686
  it "should turn into a string like node[name]" do
584
- @node.name("airplane")
585
- @node.to_s.should eql("node[airplane]")
687
+ node.name("airplane")
688
+ node.to_s.should eql("node[airplane]")
586
689
  end
587
690
  end
588
691
 
@@ -621,31 +724,31 @@ describe Chef::Node do
621
724
  describe "destroy" do
622
725
  it "should destroy a node" do
623
726
  @rest.should_receive(:delete_rest).with("nodes/monkey").and_return("foo")
624
- @node.name("monkey")
625
- @node.destroy
727
+ node.name("monkey")
728
+ node.destroy
626
729
  end
627
730
  end
628
731
 
629
732
  describe "save" do
630
733
  it "should update a node if it already exists" do
631
- @node.name("monkey")
632
- @rest.should_receive(:put_rest).with("nodes/monkey", @node).and_return("foo")
633
- @node.save
734
+ node.name("monkey")
735
+ @rest.should_receive(:put_rest).with("nodes/monkey", node).and_return("foo")
736
+ node.save
634
737
  end
635
738
 
636
739
  it "should not try and create if it can update" do
637
- @node.name("monkey")
638
- @rest.should_receive(:put_rest).with("nodes/monkey", @node).and_return("foo")
740
+ node.name("monkey")
741
+ @rest.should_receive(:put_rest).with("nodes/monkey", node).and_return("foo")
639
742
  @rest.should_not_receive(:post_rest)
640
- @node.save
743
+ node.save
641
744
  end
642
745
 
643
746
  it "should create if it cannot update" do
644
- @node.name("monkey")
747
+ node.name("monkey")
645
748
  exception = mock("404 error", :code => "404")
646
749
  @rest.should_receive(:put_rest).and_raise(Net::HTTPServerException.new("foo", exception))
647
- @rest.should_receive(:post_rest).with("nodes", @node)
648
- @node.save
750
+ @rest.should_receive(:post_rest).with("nodes", node)
751
+ node.save
649
752
  end
650
753
 
651
754
  describe "when whyrun mode is enabled" do
@@ -656,120 +759,13 @@ describe Chef::Node do
656
759
  Chef::Config[:why_run] = false
657
760
  end
658
761
  it "should not save" do
659
- @node.name("monkey")
762
+ node.name("monkey")
660
763
  @rest.should_not_receive(:put_rest)
661
764
  @rest.should_not_receive(:post_rest)
662
- @node.save
765
+ node.save
663
766
  end
664
767
  end
665
768
  end
666
769
  end
667
770
 
668
- describe "acting as a CouchDB-backed model" do
669
- before(:each) do
670
- @couchdb = Chef::CouchDB.new
671
- @mock_couch = mock('couch mock')
672
- end
673
-
674
- describe "list" do
675
- before(:each) do
676
- @mock_couch.stub!(:list).and_return(
677
- { "rows" => [ { "value" => "a", "key" => "avenue" } ] }
678
- )
679
- Chef::CouchDB.stub!(:new).and_return(@mock_couch)
680
- end
681
-
682
- it "should retrieve a list of nodes from CouchDB" do
683
- Chef::Node.cdb_list.should eql(["avenue"])
684
- end
685
-
686
- it "should return just the ids if inflate is false" do
687
- Chef::Node.cdb_list(false).should eql(["avenue"])
688
- end
689
-
690
- it "should return the full objects if inflate is true" do
691
- Chef::Node.cdb_list(true).should eql(["a"])
692
- end
693
- end
694
-
695
- describe "when loading a given node" do
696
- it "should load a node from couchdb by name" do
697
- @couchdb.should_receive(:load).with("node", "coffee").and_return(true)
698
- Chef::CouchDB.stub!(:new).and_return(@couchdb)
699
- Chef::Node.cdb_load("coffee")
700
- end
701
- end
702
-
703
- describe "when destroying a Node" do
704
- it "should delete this node from couchdb" do
705
- @couchdb.should_receive(:delete).with("node", "bob", 1).and_return(true)
706
- Chef::CouchDB.stub!(:new).and_return(@couchdb)
707
- node = Chef::Node.new
708
- node.name "bob"
709
- node.couchdb_rev = 1
710
- node.cdb_destroy
711
- end
712
- end
713
-
714
- describe "when saving a Node" do
715
- before(:each) do
716
- @couchdb.stub!(:store).and_return({ "rev" => 33 })
717
- Chef::CouchDB.stub!(:new).and_return(@couchdb)
718
- @node = Chef::Node.new
719
- @node.name "bob"
720
- @node.couchdb_rev = 1
721
- end
722
-
723
- it "should save the node to couchdb" do
724
- @couchdb.should_receive(:store).with("node", "bob", @node).and_return({ "rev" => 33 })
725
- @node.cdb_save
726
- end
727
-
728
- it "should store the new couchdb_rev" do
729
- @node.cdb_save
730
- @node.couchdb_rev.should eql(33)
731
- end
732
- end
733
-
734
- describe "create_design_document" do
735
- it "should create our design document" do
736
- @couchdb.should_receive(:create_design_document).with("nodes", Chef::Node::DESIGN_DOCUMENT)
737
- Chef::CouchDB.stub!(:new).and_return(@couchdb)
738
- Chef::Node.create_design_document
739
- end
740
- end
741
-
742
- end
743
-
744
- describe "regression test for CHEF-4631" do
745
- before(:each) do
746
- @node.stub!(:chef_environment).and_return("_default")
747
- end
748
-
749
- it "array values in the role default attributes should be concatanated to the nodes default attributes" do
750
- @node.default_attrs = {"foo" => {"bar" => ["1", "2"]}}
751
- expansion = mock("Expansion", :default_attrs => { "foo" => {"bar" => ["3", "2"]}}, :override_attrs => { })
752
- @node.apply_expansion_attributes(expansion)
753
- @node["foo"]["bar"].should == ["1", "2", "3", "2"]
754
- @node["foo"].to_hash["bar"].should == ["1", "2", "3", "2"]
755
- end
756
-
757
- it "array values in the role override attributes should override the nodes default attributes" do
758
- @node.default_attrs = {"foo" => {"bar" => ["1", "2"]}}
759
- expansion = mock("Expansion", :default_attrs => { "foo" => {"bar" => ["3", "2"]}}, :override_attrs => { "foo" => {"bar" => ["5"] } })
760
- @node.apply_expansion_attributes(expansion)
761
- @node["foo"]["bar"].should == ["5"]
762
- @node["foo"].to_hash["bar"].should == ["5"]
763
- end
764
-
765
- it "array values in the role override attributes should merge with the nodes override attributes" do
766
- @node.default_attrs = {"foo" => {"bar" => ["1", "2"]}}
767
- @node.override_attrs = {"foo" => {"bar" => ["5", "0"]}}
768
- expansion = mock("Expansion", :default_attrs => { "foo" => {"bar" => ["3", "2"]}}, :override_attrs => { "foo" => {"bar" => ["5"] } })
769
- @node.apply_expansion_attributes(expansion)
770
- @node["foo"]["bar"].should == ["5", "0", "5"]
771
- @node["foo"].to_hash["bar"].should == ["5", "0", "5"]
772
- end
773
- end
774
-
775
771
  end