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
@@ -82,17 +82,6 @@ describe Chef::Resource::Mount do
82
82
  @resource.options.should be_a_kind_of(Array)
83
83
  end
84
84
 
85
- it "should allow options to be sent as a delayed evaluator" do
86
- @resource.options Chef::DelayedEvaluator.new {["rw", "noexec"]}
87
- @resource.options.should eql(["rw", "noexec"])
88
- end
89
-
90
- it "should allow options to be sent as a delayed evaluator, and convert to array" do
91
- @resource.options Chef::DelayedEvaluator.new {"rw,noexec"}
92
- @resource.options.should be_a_kind_of(Array)
93
- @resource.options.should eql(["rw", "noexec"])
94
- end
95
-
96
85
  it "should accept true for mounted" do
97
86
  @resource.mounted(true)
98
87
  @resource.mounted.should eql(true)
@@ -0,0 +1,171 @@
1
+ #
2
+ # Author:: Lamont Granquist (<lamont@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
+
21
+ describe Chef::Resource::RegistryKey, "initialize" do
22
+ before(:each) do
23
+ @resource = Chef::Resource::RegistryKey.new('HKCU\Software\Raxicoricofallapatorius')
24
+ end
25
+
26
+ it "should create a new Chef::Resource::RegistryKey" do
27
+ @resource.should be_a_kind_of(Chef::Resource)
28
+ @resource.should be_a_kind_of(Chef::Resource::RegistryKey)
29
+ end
30
+
31
+ it "should set the resource_name to :registry_key" do
32
+ @resource.resource_name.should eql(:registry_key)
33
+ end
34
+
35
+ it "should set the key equal to the argument to initialize" do
36
+ @resource.key.should eql('HKCU\Software\Raxicoricofallapatorius')
37
+ end
38
+
39
+ it "should default recursive to false" do
40
+ @resource.recursive.should eql(false)
41
+ end
42
+
43
+ it "should default architecture to :machine" do
44
+ @resource.architecture.should eql(:machine)
45
+ end
46
+
47
+ it "should set action to :create" do
48
+ @resource.action.should eql(:create)
49
+ end
50
+
51
+ %w{create create_if_missing delete delete_key}.each do |action|
52
+ it "should allow action #{action}" do
53
+ @resource.allowed_actions.detect { |a| a == action.to_sym }.should eql(action.to_sym)
54
+ end
55
+ end
56
+ end
57
+
58
+ describe Chef::Resource::RegistryKey, "key" do
59
+ before(:each) do
60
+ @resource = Chef::Resource::RegistryKey.new('HKCU\Software\Raxicoricofallapatorius')
61
+ end
62
+
63
+ it "should allow a string" do
64
+ @resource.key 'HKCU\Software\Poosh'
65
+ @resource.key.should eql('HKCU\Software\Poosh')
66
+ end
67
+
68
+ it "should not allow an integer" do
69
+ lambda { @resource.send(:key, 100) }.should raise_error(ArgumentError)
70
+ end
71
+
72
+ it "should not allow a hash" do
73
+ lambda { @resource.send(:key, { :sonic => "screwdriver" }) }.should raise_error(ArgumentError)
74
+ end
75
+ end
76
+
77
+ describe Chef::Resource::RegistryKey, "values" do
78
+ before(:each) do
79
+ @resource = Chef::Resource::RegistryKey.new('HKCU\Software\Raxicoricofallapatorius')
80
+ end
81
+
82
+ it "should allow a single proper hash of registry values" do
83
+ @resource.values( { :name => 'poosh', :type => :string, :data => 'carmen' } )
84
+ @resource.values.should eql([ { :name => 'poosh', :type => :string, :data => 'carmen' } ])
85
+ end
86
+
87
+ it "should allow an array of proper hashes of registry values" do
88
+ @resource.values [ { :name => 'poosh', :type => :string, :data => 'carmen' } ]
89
+ @resource.values.should eql([ { :name => 'poosh', :type => :string, :data => 'carmen' } ])
90
+ end
91
+
92
+ it "should throw an exception if the name field is missing" do
93
+ lambda { @resource.values [ { :type => :string, :data => 'carmen' } ] }.should raise_error(ArgumentError)
94
+ end
95
+
96
+ it "should throw an exception if the type field is missing" do
97
+ lambda { @resource.values [ { :name => 'poosh', :data => 'carmen' } ] }.should raise_error(ArgumentError)
98
+ end
99
+
100
+ it "should throw an exception if the data field is missing" do
101
+ lambda { @resource.values [ { :name => 'poosh', :type => :string } ] }.should raise_error(ArgumentError)
102
+ end
103
+
104
+ it "should throw an exception if extra fields are present" do
105
+ lambda { @resource.values [ { :name => 'poosh', :type => :string, :data => 'carmen', :screwdriver => 'sonic' } ] }.should raise_error(ArgumentError)
106
+ end
107
+
108
+ it "should not allow a string" do
109
+ lambda { @resource.send(:values, 'souffle') }.should raise_error(ArgumentError)
110
+ end
111
+
112
+ it "should not allow an integer" do
113
+ lambda { @resource.send(:values, 100) }.should raise_error(ArgumentError)
114
+ end
115
+ end
116
+
117
+ describe Chef::Resource::RegistryKey, "recursive" do
118
+ before(:each) do
119
+ @resource = Chef::Resource::RegistryKey.new('HKCU\Software\Raxicoricofallapatorius')
120
+ end
121
+
122
+ it "should allow a boolean" do
123
+ @resource.recursive(true)
124
+ @resource.recursive.should eql(true)
125
+ end
126
+
127
+ it "should not allow a hash" do
128
+ lambda { @resource.recursive({:sonic => :screwdriver}) }.should raise_error(ArgumentError)
129
+ end
130
+
131
+ it "should not allow an array" do
132
+ lambda { @resource.recursive([:nose, :chin]) }.should raise_error(ArgumentError)
133
+ end
134
+
135
+ it "should not allow a string" do
136
+ lambda { @resource.recursive('souffle') }.should raise_error(ArgumentError)
137
+ end
138
+
139
+ it "should not allow an integer" do
140
+ lambda { @resource.recursive(100) }.should raise_error(ArgumentError)
141
+ end
142
+ end
143
+
144
+ describe Chef::Resource::RegistryKey, "architecture" do
145
+ before(:each) do
146
+ @resource = Chef::Resource::RegistryKey.new('HKCU\Software\Raxicoricofallapatorius')
147
+ end
148
+
149
+ [ :i386, :x86_64, :machine ].each do |arch|
150
+ it "should allow #{arch} as a symbol" do
151
+ @resource.architecture(arch)
152
+ @resource.architecture.should eql(arch)
153
+ end
154
+ end
155
+
156
+ it "should not allow a hash" do
157
+ lambda { @resource.architecture({:sonic => :screwdriver}) }.should raise_error(ArgumentError)
158
+ end
159
+
160
+ it "should not allow an array" do
161
+ lambda { @resource.architecture([:nose, :chin]) }.should raise_error(ArgumentError)
162
+ end
163
+
164
+ it "should not allow a string" do
165
+ lambda { @resource.architecture('souffle') }.should raise_error(ArgumentError)
166
+ end
167
+
168
+ it "should not allow an integer" do
169
+ lambda { @resource.architecture(100) }.should raise_error(ArgumentError)
170
+ end
171
+ end
@@ -39,37 +39,35 @@ describe Chef::Resource::RemoteFile do
39
39
  Chef::Platform.find_provider(:noplatform, 'noversion', @resource).should == Chef::Provider::RemoteFile
40
40
  end
41
41
 
42
- it "says its provider is CookbookFile when the source is a relative URI" do
43
- @resource.source('seattle.txt')
44
- @resource.provider.should == Chef::Provider::CookbookFile
45
- Chef::Platform.find_provider(:noplatform, 'noversion', @resource).should == Chef::Provider::CookbookFile
46
- end
47
-
42
+
48
43
  describe "source" do
49
- it "should accept a string for the remote file source" do
50
- @resource.source "something"
51
- @resource.source.should eql("something")
44
+ it "does not have a default value for 'source'" do
45
+ @resource.source.should be_nil
52
46
  end
53
47
 
54
- it "should have a default based on the param name" do
55
- @resource.source.should eql("fakey_fakerton")
48
+ it "should accept a URI for the remote file source" do
49
+ @resource.source "http://opscode.com/"
50
+ @resource.source.should eql([ "http://opscode.com/" ])
56
51
  end
57
52
 
58
- it "should use only the basename of the file as the default" do
59
- r = Chef::Resource::RemoteFile.new("/tmp/obit/fakey_fakerton")
60
- r.source.should eql("fakey_fakerton")
53
+ it "should accept an array of URIs for the remote file source" do
54
+ @resource.source([ "http://opscode.com/", "http://puppetlabs.com/" ])
55
+ @resource.source.should eql([ "http://opscode.com/", "http://puppetlabs.com/" ])
61
56
  end
62
- end
63
-
64
- describe "cookbook" do
65
- it "should accept a string for the cookbook name" do
66
- @resource.cookbook "something"
67
- @resource.cookbook.should eql("something")
57
+
58
+ it "should accept an multiple URIs as arguments for the remote file source" do
59
+ @resource.source("http://opscode.com/", "http://puppetlabs.com/")
60
+ @resource.source.should eql([ "http://opscode.com/", "http://puppetlabs.com/" ])
68
61
  end
69
-
70
- it "should default to nil" do
71
- @resource.cookbook.should == nil
62
+
63
+ it "does not accept a non-URI as the source" do
64
+ lambda { @resource.source("not-a-uri") }.should raise_error(Chef::Exceptions::InvalidRemoteFileURI)
72
65
  end
66
+
67
+ it "should raise and exception when source is an empty array" do
68
+ lambda { @resource.source([]) }.should raise_error(ArgumentError)
69
+ end
70
+
73
71
  end
74
72
 
75
73
  describe "checksum" do
@@ -23,7 +23,7 @@ describe Chef::Resource::RubyBlock do
23
23
 
24
24
  before(:each) do
25
25
  @resource = Chef::Resource::RubyBlock.new("fakey_fakerton")
26
- end
26
+ end
27
27
 
28
28
  it "should create a new Chef::Resource::RubyBlock" do
29
29
  @resource.should be_a_kind_of(Chef::Resource)
@@ -31,7 +31,7 @@ describe Chef::Resource::RubyBlock do
31
31
  end
32
32
 
33
33
  it "should have a default action of 'create'" do
34
- @resource.action.should eql("create")
34
+ @resource.action.should eql("run")
35
35
  end
36
36
 
37
37
  it "should have a resource name of :ruby_block" do
@@ -44,6 +44,11 @@ describe Chef::Resource::RubyBlock do
44
44
  end.call.should eql("foo")
45
45
  end
46
46
 
47
+ it "allows the action to be 'create'" do
48
+ @resource.action :create
49
+ @resource.action.should == [:create]
50
+ end
51
+
47
52
  describe "when it has been initialized with block code" do
48
53
  before do
49
54
  @resource.block_name("puts 'harrrr'")
@@ -53,5 +58,4 @@ describe Chef::Resource::RubyBlock do
53
58
  @resource.identity.should == "puts 'harrrr'"
54
59
  end
55
60
  end
56
-
57
61
  end
@@ -109,6 +109,17 @@ describe Chef::Resource::Service do
109
109
  }.should raise_error(ArgumentError)
110
110
  end
111
111
 
112
+ it "should accept a string for the service init command" do
113
+ @resource.init_command "/etc/init.d/chef"
114
+ @resource.init_command.should eql("/etc/init.d/chef")
115
+ end
116
+
117
+ it "should not accept a regexp for the service init command" do
118
+ lambda {
119
+ @resource.init_command /.*/
120
+ }.should raise_error(ArgumentError)
121
+ end
122
+
112
123
  %w{enabled running}.each do |attrib|
113
124
  it "should accept true for #{attrib}" do
114
125
  @resource.send(attrib, true)
@@ -35,21 +35,6 @@ describe Chef::Resource do
35
35
  @resource = Chef::Resource.new("funk", @run_context)
36
36
  end
37
37
 
38
- describe "when inherited" do
39
-
40
- it "adds an entry to a list of subclasses" do
41
- subclass = Class.new(Chef::Resource)
42
- Chef::Resource.resource_classes.should include(subclass)
43
- end
44
-
45
- it "keeps track of subclasses of subclasses" do
46
- subclass = Class.new(Chef::Resource)
47
- subclass_of_subclass = Class.new(subclass)
48
- Chef::Resource.resource_classes.should include(subclass_of_subclass)
49
- end
50
-
51
- end
52
-
53
38
  describe "when declaring the identity attribute" do
54
39
  it "has no identity attribute by default" do
55
40
  Chef::Resource.identity_attr.should be_nil
@@ -440,8 +425,8 @@ describe Chef::Resource do
440
425
  before do
441
426
  @resource = Chef::Resource.new("provided", @run_context)
442
427
  @resource.provider = Chef::Provider::SnakeOil
443
- @node[:platform] = "fubuntu"
444
- @node[:platform_version] = '10.04'
428
+ @node.automatic_attrs[:platform] = "fubuntu"
429
+ @node.automatic_attrs[:platform_version] = '10.04'
445
430
  end
446
431
 
447
432
  it "does not run only_if if no only_if command is given" do
@@ -537,8 +522,8 @@ describe Chef::Resource do
537
522
  before(:each) do
538
523
  @node = Chef::Node.new
539
524
  @node.name("bumblebee")
540
- @node.platform("autobots")
541
- @node.platform_version("6.1")
525
+ @node.automatic[:platform] = "autobots"
526
+ @node.automatic[:platform_version] = "6.1"
542
527
  Object.const_set('Soundwave', Class.new(Chef::Resource))
543
528
  Object.const_set('Grimlock', Class.new(Chef::Resource){ provides :dinobot, :on_platforms => ['autobots'] })
544
529
  end
@@ -57,11 +57,8 @@ Y6S6MeZ69Rp89ma4ttMZ+kwi1+XyHqC/dlcVRW42Zl5Dc7BALRlJjQ==
57
57
  describe Chef::REST::AuthCredentials do
58
58
  before do
59
59
  @key_file_fixture = CHEF_SPEC_DATA + '/ssl/private_key.pem'
60
- @auth_credentials = Chef::REST::AuthCredentials.new("client-name", @key_file_fixture)
61
- end
62
-
63
- it "has a key file value" do
64
- @auth_credentials.key_file.should == @key_file_fixture
60
+ @key = OpenSSL::PKey::RSA.new(IO.read(@key_file_fixture).strip)
61
+ @auth_credentials = Chef::REST::AuthCredentials.new("client-name", @key)
65
62
  end
66
63
 
67
64
  it "has a client name" do
@@ -74,15 +71,6 @@ describe Chef::REST::AuthCredentials do
74
71
  end
75
72
 
76
73
  describe "when loading the private key" do
77
- it "raises PrivateKeyMissing when the key file doesn't exist" do
78
- lambda {Chef::REST::AuthCredentials.new("client-name", "/dev/null/nothing_here")}.should raise_error(Chef::Exceptions::PrivateKeyMissing)
79
- end
80
-
81
- it "raises InvalidPrivateKey when the key file doesnt' look like a key" do
82
- invalid_key_file = CHEF_SPEC_DATA + "/bad-config.rb"
83
- lambda {Chef::REST::AuthCredentials.new("client-name", invalid_key_file)}.should raise_error(Chef::Exceptions::InvalidPrivateKey)
84
- end
85
-
86
74
  it "strips extra whitespace before checking the key" do
87
75
  key_file_fixture = CHEF_SPEC_DATA + '/ssl/private_key_with_whitespace.pem'
88
76
  lambda {Chef::REST::AuthCredentials.new("client-name", @key_file_fixture)}.should_not raise_error
@@ -211,11 +199,6 @@ describe Chef::REST::RESTRequest do
211
199
  new_request.http_client.read_timeout.should == 9001
212
200
  end
213
201
 
214
- it "configures the HTTP client with the open timeout set in the config file" do
215
- Chef::Config[:rest_timeout] = 9001
216
- new_request.http_client.read_timeout.should == 9001
217
- end
218
-
219
202
  describe "for SSL" do
220
203
  before do
221
204
  Chef::Config[:ssl_client_cert] = nil
@@ -130,6 +130,23 @@ describe Chef::REST do
130
130
  @rest.sign_requests?.should be_false
131
131
  end
132
132
 
133
+ it "raises PrivateKeyMissing when the key file doesn't exist" do
134
+ lambda {Chef::REST.new(@url, "client-name", "/dev/null/nothing_here")}.should raise_error(Chef::Exceptions::PrivateKeyMissing)
135
+ end
136
+
137
+ it "raises InvalidPrivateKey when the key file doesnt' look like a key" do
138
+ invalid_key_file = CHEF_SPEC_DATA + "/bad-config.rb"
139
+ lambda {Chef::REST.new(@url, "client-name", invalid_key_file)}.should raise_error(Chef::Exceptions::InvalidPrivateKey)
140
+ end
141
+
142
+ it "can take private key as a sting :raw_key in options during initializaton" do
143
+ Chef::REST.new(@url, "client-name", nil, :raw_key => SIGNING_KEY_DOT_PEM).signing_key.should == SIGNING_KEY_DOT_PEM
144
+ end
145
+
146
+ it "raises InvalidPrivateKey when the key passed as string :raw_key in options doesnt' look like a key" do
147
+ lambda {Chef::REST.new(@url, "client-name", nil, :raw_key => "bad key string")}.should raise_error(Chef::Exceptions::InvalidPrivateKey)
148
+ end
149
+
133
150
  end
134
151
 
135
152
  context "when making REST requests" do
@@ -137,7 +154,6 @@ describe Chef::REST do
137
154
  Chef::Config[:ssl_client_cert] = nil
138
155
  Chef::Config[:ssl_client_key] = nil
139
156
  @url = URI.parse("https://one:80/?foo=bar")
140
- @expected_host_header = "one:80"
141
157
 
142
158
  @http_response = Net::HTTPSuccess.new("1.1", "200", "successful rest req")
143
159
  @http_response.stub!(:read_body)
@@ -150,188 +166,63 @@ describe Chef::REST do
150
166
 
151
167
  @base_headers = { 'Accept' => 'application/json',
152
168
  'X-Chef-Version' => Chef::VERSION,
153
- 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
154
- 'Host' => @expected_host_header }
169
+ 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
155
170
  @req_with_body_headers = @base_headers.merge("Content-Type" => "application/json", "Content-Length" => '13')
156
171
  end
157
172
 
158
- describe "using the run_request API" do
159
- it "should build a new HTTP GET request" do
160
- request = Net::HTTP::Get.new(@url.path)
161
- Net::HTTP::Get.should_receive(:new).with("/?foo=bar", @base_headers).and_return(request)
162
- @rest.run_request(:GET, @url, {})
163
- end
164
-
165
- it "should build a new HTTP POST request" do
166
- request = Net::HTTP::Post.new(@url.path)
167
-
168
- Net::HTTP::Post.should_receive(:new).with("/?foo=bar", @req_with_body_headers).and_return(request)
169
- @rest.run_request(:POST, @url, {}, {:one=>:two})
170
- request.body.should == '{"one":"two"}'
171
- end
172
-
173
- it "should build a new HTTP PUT request" do
174
- request = Net::HTTP::Put.new(@url.path)
175
- expected_headers = @base_headers.merge("Content-Length" => '13')
176
- Net::HTTP::Put.should_receive(:new).with("/?foo=bar", @req_with_body_headers).and_return(request)
177
- @rest.run_request(:PUT, @url, {}, {:one=>:two})
178
- request.body.should == '{"one":"two"}'
179
- end
180
-
181
- it "should build a new HTTP DELETE request" do
182
- request = Net::HTTP::Delete.new(@url.path)
183
- Net::HTTP::Delete.should_receive(:new).with("/?foo=bar", @base_headers).and_return(request)
184
- @rest.run_request(:DELETE, @url)
185
- end
186
-
187
- it "should raise an error if the method is not GET/PUT/POST/DELETE" do
188
- lambda { @rest.api_request(:MONKEY, @url) }.should raise_error(ArgumentError)
189
- end
173
+ describe "streaming downloads to a tempfile" do
174
+ before do
175
+ @tempfile = Tempfile.open("chef-rspec-rest_spec-line-#{__LINE__}--")
176
+ Tempfile.stub!(:new).with("chef-rest").and_return(@tempfile)
177
+ Tempfile.stub!(:open).and_return(@tempfile)
190
178
 
191
- it "returns the response body when the response is successful but content-type is not JSON" do
192
- @rest.run_request(:GET, @url).should == "ninja"
193
- end
179
+ @request_mock = {}
180
+ Net::HTTP::Get.stub!(:new).and_return(@request_mock)
194
181
 
195
- it "should call read_body without a block if the request is not raw" do
196
- @http_response.should_receive(:body)
197
- @rest.run_request(:GET, @url, {}, nil, false)
182
+ @http_response_mock = mock("Net::HTTP Response mock")
198
183
  end
199
184
 
200
- it "should inflate the body as to an object if JSON is returned" do
201
- @http_response.add_field("content-type", "application/json")
202
- Chef::JSONCompat.should_receive(:from_json).with("ninja").and_return("ohai2u_success")
203
- @rest.run_request(:GET, @url, {}).should == "ohai2u_success"
185
+ after do
186
+ @tempfile.rspec_reset
187
+ @tempfile.close!
204
188
  end
205
189
 
206
- it "should return false on a Not Modified response" do
207
- http_response = Net::HTTPNotModified.new("1.1", "304", "It's old Bob")
208
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
209
- http_response.stub!(:read_body)
210
- @rest.run_request(:GET, @url).should be_false
190
+ it "should build a new HTTP GET request without the application/json accept header" do
191
+ expected_headers = {'X-Chef-Version' => Chef::VERSION, 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
192
+ Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(@request_mock)
193
+ @rest.streaming_request(@url, {})
211
194
  end
212
195
 
213
- %w[ HTTPFound HTTPMovedPermanently HTTPSeeOther HTTPUseProxy HTTPTemporaryRedirect HTTPMultipleChoice ].each do |resp_name|
214
- it "should call run_request again on a #{resp_name} response" do
215
- resp_cls = Net.const_get(resp_name)
216
- resp_code = Net::HTTPResponse::CODE_TO_OBJ.keys.detect { |k| Net::HTTPResponse::CODE_TO_OBJ[k] == resp_cls }
217
- http_response = resp_cls.new("1.1", resp_code, "bob somewhere else")
218
- http_response.add_field("location", @url.path)
219
- http_response.stub!(:read_body)
220
-
221
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
222
- lambda { @rest.run_request(:GET, @url) }.should raise_error(Chef::Exceptions::RedirectLimitExceeded)
223
- end
196
+ it "should create a tempfile for the output of a raw request" do
197
+ @rest.streaming_request(@url, {}).should equal(@tempfile)
224
198
  end
225
199
 
226
- # CHEF-3140
227
- context "when configured to disable compression" do
228
- before do
229
- @rest = Chef::REST.new(@base_url, nil, nil, :disable_gzip => true)
230
- end
231
-
232
- it "does not accept encoding gzip" do
233
- @rest.send(:build_headers, :GET, @url, {}).should_not have_key("Accept-Encoding")
234
- end
235
-
236
- it "does not decompress a response encoded as gzip" do
237
- @http_response.add_field("content-encoding", "gzip")
238
- request = Net::HTTP::Get.new(@url.path)
239
- Net::HTTP::Get.should_receive(:new).and_return(request)
240
- # will raise a Zlib error if incorrect
241
- @rest.api_request(:GET, @url, {}).should == "ninja"
242
- end
200
+ it "should read the body of the response in chunks on a raw request" do
201
+ @http_response.should_receive(:read_body).and_return(true)
202
+ @rest.streaming_request(@url, {})
243
203
  end
244
204
 
245
- it "should show the JSON error message on an unsuccessful request" do
246
- http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
247
- http_response.add_field("content-type", "application/json")
248
- http_response.stub!(:body).and_return('{ "error":[ "Ears get sore!", "Not even four" ] }')
249
- http_response.stub!(:read_body)
250
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
251
- @rest.stub!(:sleep)
252
- lambda {@rest.run_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
253
- @log_stringio.string.should match(Regexp.escape('WARN: HTTP Request Returned 500 drooling from inside of mouth: Ears get sore!, Not even four'))
205
+ it "should populate the tempfile with the value of the raw request" do
206
+ @http_response_mock.stub!(:read_body).and_yield("ninja")
207
+ @tempfile.should_receive(:write).with("ninja").once.and_return(true)
208
+ @rest.streaming_request(@url, {})
254
209
  end
255
210
 
256
- it "should raise an exception on an unsuccessful request" do
257
- @http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
258
- http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
259
- http_response.stub!(:read_body)
260
- @rest.stub!(:sleep)
261
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
262
- lambda {@rest.run_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
211
+ it "should close the tempfile if we're doing a raw request" do
212
+ @tempfile.should_receive(:close).once.and_return(true)
213
+ @rest.streaming_request(@url, {})
263
214
  end
264
215
 
265
- it "adds the rest_request object to any http exception raised" do
266
- @http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
267
- http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
268
- http_response.stub!(:read_body)
269
- @rest.stub!(:sleep)
270
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
271
- exception = begin
272
- @rest.api_request(:GET, @url, {})
273
- rescue => e
274
- e
275
- end
276
-
277
- e.chef_rest_request.url.should == @url
278
- e.chef_rest_request.method.should == :GET
216
+ it "should not raise a divide by zero exception if the size is 0" do
217
+ @http_response_mock.stub!(:header).and_return({ 'Content-Length' => "5" })
218
+ @http_response_mock.stub!(:read_body).and_yield('')
219
+ lambda { @rest.streaming_request(@url, {}) }.should_not raise_error(ZeroDivisionError)
279
220
  end
280
221
 
281
- describe "streaming downloads to a tempfile" do
282
- before do
283
- @tempfile = StringIO.new
284
- @tempfile.stub(:close!)
285
- @tempfile.stub(:path).and_return("/tmp/this-is-a-stringio-not-a-real-file")
286
- Tempfile.stub(:new).with("chef-rest").and_return(@tempfile)
287
- Tempfile.stub(:open).and_return(@tempfile)
288
-
289
- @request_mock = {}
290
- Net::HTTP::Get.stub!(:new).and_return(@request_mock)
291
-
292
- @http_response_mock = mock("Net::HTTP Response mock")
293
- end
294
-
295
- it "should build a new HTTP GET request without the application/json accept header" do
296
- expected_headers = { 'X-Chef-Version' => Chef::VERSION,
297
- 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
298
- 'Host' => @expected_host_header }
299
- Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(@request_mock)
300
- @rest.run_request(:GET, @url, {}, false, nil, true)
301
- end
302
-
303
- it "should create a tempfile for the output of a raw request" do
304
- @rest.run_request(:GET, @url, {}, false, nil, true).should equal(@tempfile)
305
- end
306
-
307
- it "should read the body of the response in chunks on a raw request" do
308
- @http_response.should_receive(:read_body).and_return(true)
309
- @rest.run_request(:GET, @url, {}, false, nil, true)
310
- end
311
-
312
- it "should populate the tempfile with the value of the raw request" do
313
- @http_response.should_receive(:read_body).and_yield("ninja")
314
- @rest.run_request(:GET, @url, {}, false, nil, true)
315
- @tempfile.string.should include("ninja")
316
- end
317
-
318
- it "should close the tempfile if we're doing a raw request" do
319
- @tempfile.should_receive(:close).once.and_return(true)
320
- @rest.run_request(:GET, @url, {}, false, nil, true)
321
- end
322
-
323
- it "should not raise a divide by zero exception if the size is 0" do
324
- @http_response_mock.stub!(:header).and_return({ 'Content-Length' => "5" })
325
- @http_response_mock.stub!(:read_body).and_yield('')
326
- lambda { @rest.run_request(:GET, @url, {}, false, nil, true) }.should_not raise_error(ZeroDivisionError)
327
- end
328
-
329
- it "should not raise a divide by zero exception if the Content-Length is 0" do
330
- @http_response_mock.stub!(:header).and_return({ 'Content-Length' => "0" })
331
- @http_response_mock.stub!(:read_body).and_yield("ninja")
332
- lambda { @rest.run_request(:GET, @url, {}, false, nil, true) }.should_not raise_error(ZeroDivisionError)
333
- end
334
-
222
+ it "should not raise a divide by zero exception if the Content-Length is 0" do
223
+ @http_response_mock.stub!(:header).and_return({ 'Content-Length' => "0" })
224
+ @http_response_mock.stub!(:read_body).and_yield("ninja")
225
+ lambda { @rest.streaming_request(@url, {}) }.should_not raise_error(ZeroDivisionError)
335
226
  end
336
227
 
337
228
  end
@@ -343,8 +234,7 @@ describe Chef::REST do
343
234
 
344
235
  @base_headers = {"Accept" => "application/json",
345
236
  "X-Chef-Version" => Chef::VERSION,
346
- "Accept-Encoding" => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
347
- "Host" => @expected_host_header
237
+ "Accept-Encoding" => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE
348
238
  }
349
239
  end
350
240
 
@@ -360,6 +250,24 @@ describe Chef::REST do
360
250
  @request_mock['User-Agent'].should match /^Chef Client\/#{Chef::VERSION}/
361
251
  end
362
252
 
253
+ # CHEF-3140
254
+ context "when configured to disable compression" do
255
+ before do
256
+ @rest = Chef::REST.new(@base_url, nil, nil, :disable_gzip => true)
257
+ end
258
+
259
+ it "does not accept encoding gzip" do
260
+ @rest.send(:build_headers, :GET, @url, {}).should_not have_key("Accept-Encoding")
261
+ end
262
+
263
+ it "does not decompress a response encoded as gzip" do
264
+ @http_response.add_field("content-encoding", "gzip")
265
+ request = Net::HTTP::Get.new(@url.path)
266
+ Net::HTTP::Get.should_receive(:new).and_return(request)
267
+ # will raise a Zlib error if incorrect
268
+ @rest.api_request(:GET, @url, {}).should == "ninja"
269
+ end
270
+ end
363
271
  context "when configured with custom http headers" do
364
272
  before(:each) do
365
273
  @custom_headers = {
@@ -422,146 +330,86 @@ describe Chef::REST do
422
330
  @rest.api_request(:GET, @url).should == "ninja"
423
331
  end
424
332
 
425
- it "returns nil when the response is a 204 and the content-type is JSON" do
426
-
427
- @http_response = Net::HTTPNoContent.new("1.1", "204", "successful rest req")
428
- @http_response.stub!(:read_body)
429
- @http_response.stub!(:body).and_return(nil)
430
- @http_response.add_field("Content-Length", "0")
431
- @http_response.add_field("Content-Type", "application/json")
432
-
433
- @http_client = Net::HTTP.new(@url.host, @url.port)
434
- Net::HTTP.stub!(:new).and_return(@http_client)
435
- @http_client.stub!(:request).and_yield(@http_response).and_return(@http_response)
436
-
437
- @rest.api_request(:GET, @url).should be_nil
438
- end
439
-
440
333
  it "should inflate the body as to an object if JSON is returned" do
441
334
  @http_response.add_field('content-type', "application/json")
442
335
  @http_response.stub!(:body).and_return('{"ohai2u":"json_api"}')
443
336
  @rest.api_request(:GET, @url, {}).should == {"ohai2u"=>"json_api"}
444
337
  end
445
338
 
446
- context "when sending a request with a body and the content-type isn't JSON" do
447
-
448
- let(:expected_headers) do
449
- @base_headers.merge("content-type" => 'application/x-binary', 'Content-Length' => '13')
450
- end
339
+ %w[ HTTPFound HTTPMovedPermanently HTTPSeeOther HTTPUseProxy HTTPTemporaryRedirect HTTPMultipleChoice ].each do |resp_name|
340
+ it "should call api_request again on a #{resp_name} response" do
341
+ resp_cls = Net.const_get(resp_name)
342
+ resp_code = Net::HTTPResponse::CODE_TO_OBJ.keys.detect { |k| Net::HTTPResponse::CODE_TO_OBJ[k] == resp_cls }
343
+ http_response = Net::HTTPFound.new("1.1", resp_code, "bob is somewhere else again")
344
+ http_response.add_field("location", @url.path)
345
+ http_response.stub!(:read_body)
451
346
 
452
- let(:request_headers) do
453
- {"content-type" => 'application/x-binary'}
454
- end
347
+ @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
455
348
 
456
- let(:request_body) do
457
- Chef::JSONCompat.to_json({:one=>:two})
349
+ lambda { @rest.api_request(:GET, @url) }.should raise_error(Chef::Exceptions::RedirectLimitExceeded)
458
350
  end
351
+ end
459
352
 
460
- it "should build a new HTTP POST request" do
461
- request = Net::HTTP::Post.new(@url.path)
462
- Net::HTTP::Post.should_receive(:new).with("/?foo=bar", expected_headers).and_return(request)
463
- @rest.raw_http_request(:POST, @url, request_headers, request_body)
464
- request.body.should == '{"one":"two"}'
465
- end
353
+ it "should return `false` when response is 304 NotModified" do
354
+ http_response = Net::HTTPNotModified.new("1.1", "304", "it's the same as when you asked 5 minutes ago")
355
+ http_response.stub!(:read_body)
466
356
 
467
- it "should build a new HTTP PUT request" do
468
- request = Net::HTTP::Put.new(@url.path)
469
- Net::HTTP::Put.should_receive(:new).with("/?foo=bar",expected_headers).and_return(request)
470
- @rest.raw_http_request(:PUT, @url, request_headers, request_body)
471
- request.body.should == '{"one":"two"}'
472
- end
357
+ @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
473
358
 
359
+ @rest.api_request(:GET, @url).should be_false
474
360
  end
475
361
 
476
- describe "when the server returns a redirect response" do
477
- let(:redirected_url) { "https://chef.example.com:8443/foo" }
478
- let(:redirected_uri) { URI.parse(redirected_url) }
479
-
480
- def redirect_with(response_name)
481
- resp_cls = Net.const_get(response_name)
482
- resp_code = Net::HTTPResponse::CODE_TO_OBJ.keys.detect { |k| Net::HTTPResponse::CODE_TO_OBJ[k] == resp_cls }
483
- redirect = Net::HTTPFound.new("1.1", resp_code, "bob is somewhere else again")
484
- redirect.add_field("location", redirected_url)
485
- redirect.stub!(:read_body).and_return('')
486
- redirect
362
+ describe "when the request fails" do
363
+ before do
364
+ @original_log_level = Chef::Log.level
365
+ Chef::Log.level = :info
487
366
  end
488
367
 
489
- %w[ HTTPFound HTTPMovedPermanently HTTPSeeOther HTTPUseProxy HTTPTemporaryRedirect HTTPMultipleChoice ].each do |response_name|
490
-
491
- it "should call api_request again on a #{response_name} response" do
492
- redirect = redirect_with(response_name)
493
-
494
- headers = { "X-Auth-Header" => "foo" }
495
- auto_headers = { "Accept"=>"application/json",
496
- "Accept-Encoding"=>"gzip;q=1.0,deflate;q=0.6,identity;q=0.3",
497
- "Host" => @expected_host_header}
498
- expected_headers = auto_headers.merge(headers)
499
- expected_headers_on_redirect = expected_headers.dup
500
- expected_headers_on_redirect["Host"] = "chef.example.com:8443"
501
-
502
- success = Net::HTTPSuccess.new("1.1",200, "it-works")
503
- success.stub!(:read_body).and_return('{"foo": "bar"}')
504
- success['content-type'] = "application/json"
368
+ after do
369
+ Chef::Log.level = @original_log_level
370
+ end
505
371
 
506
- @http_client.should_receive(:request).and_yield(redirect).and_return(redirect)
507
- @http_client.should_receive(:request).and_yield(success).and_return(success)
372
+ it "should show the JSON error message on an unsuccessful request" do
373
+ http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
374
+ http_response.add_field("content-type", "application/json")
375
+ http_response.stub!(:body).and_return('{ "error":[ "Ears get sore!", "Not even four" ] }')
376
+ http_response.stub!(:read_body)
377
+ @rest.stub!(:sleep)
378
+ @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
508
379
 
509
- # CHEF-1848: verify that headers get passed to redirects
510
- @rest.should_receive(:retriable_rest_request).with(:GET, @url, nil, expected_headers).and_call_original
511
- @rest.should_receive(:retriable_rest_request).with(:GET, redirected_uri, nil, expected_headers_on_redirect).and_call_original
380
+ lambda {@rest.api_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
381
+ @log_stringio.string.should match(Regexp.escape('INFO: HTTP Request Returned 500 drooling from inside of mouth: Ears get sore!, Not even four'))
382
+ end
512
383
 
513
- @rest.api_request(:GET, @url, headers).should == {"foo" => "bar"}
514
- end
384
+ it "decompresses the JSON error message on an unsuccessful request" do
385
+ http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
386
+ http_response.add_field("content-type", "application/json")
387
+ http_response.add_field("content-encoding", "deflate")
388
+ unzipped_body = '{ "error":[ "Ears get sore!", "Not even four" ] }'
389
+ gzipped_body = Zlib::Deflate.deflate(unzipped_body)
390
+ gzipped_body.force_encoding(Encoding::BINARY) if "strings".respond_to?(:force_encoding)
515
391
 
516
- context "when making a request for a method other than GET" do
392
+ http_response.stub!(:body).and_return gzipped_body
393
+ http_response.stub!(:read_body)
394
+ @rest.stub!(:sleep)
395
+ @rest.stub!(:http_retry_count).and_return(0)
396
+ @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
517
397
 
518
- [:PUT, :POST, :DELETE].each do |method|
519
- it "raises an error" do
520
- redirect = redirect_with(response_name)
521
- @http_client.should_receive(:request).and_yield(redirect).and_return(redirect)
522
- lambda { @rest.api_request(method, @url) }.should raise_error(Chef::Exceptions::InvalidRedirect)
523
- end
524
- end
525
- end
398
+ lambda {@rest.api_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
399
+ @log_stringio.string.should match(Regexp.escape('INFO: HTTP Request Returned 500 drooling from inside of mouth: Ears get sore!, Not even four'))
526
400
  end
527
401
 
402
+ it "should raise an exception on an unsuccessful request" do
403
+ http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
404
+ http_response.stub!(:body)
405
+ http_response.stub!(:read_body)
406
+ @rest.stub!(:sleep)
407
+ @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
408
+ lambda {@rest.api_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
409
+ end
528
410
  end
529
411
 
530
- it "should show the JSON error message on an unsuccessful request" do
531
- http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
532
- http_response.add_field("content-type", "application/json")
533
- http_response.stub!(:body).and_return('{ "error":[ "Ears get sore!", "Not even four" ] }')
534
- http_response.stub!(:read_body)
535
- @rest.stub!(:sleep)
536
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
537
412
 
538
- lambda {@rest.run_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
539
- @log_stringio.string.should match(Regexp.escape('WARN: HTTP Request Returned 500 drooling from inside of mouth: Ears get sore!, Not even four'))
540
- end
541
-
542
- it "decompresses the JSON error message on an unsuccessful request" do
543
- http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
544
- http_response.add_field("content-type", "application/json")
545
- http_response.add_field("content-encoding", "deflate")
546
- unzipped_body = '{ "error":[ "Ears get sore!", "Not even four" ] }'
547
- gzipped_body = Zlib::Deflate.deflate(unzipped_body, 1)
548
- http_response.stub!(:body).and_return gzipped_body
549
- http_response.stub!(:read_body)
550
- @rest.stub!(:sleep)
551
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
552
-
553
- lambda {@rest.run_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
554
- @log_stringio.string.should match(Regexp.escape('WARN: HTTP Request Returned 500 drooling from inside of mouth: Ears get sore!, Not even four'))
555
- end
556
-
557
- it "should raise an exception on an unsuccessful request" do
558
- http_response = Net::HTTPServerError.new("1.1", "500", "drooling from inside of mouth")
559
- http_response.stub!(:body)
560
- http_response.stub!(:read_body)
561
- @rest.stub!(:sleep)
562
- @http_client.stub!(:request).and_yield(http_response).and_return(http_response)
563
- lambda {@rest.api_request(:GET, @url)}.should raise_error(Net::HTTPFatalError)
564
- end
565
413
  end
566
414
 
567
415
  context "when streaming downloads to a tempfile" do
@@ -577,13 +425,12 @@ describe Chef::REST do
577
425
  end
578
426
 
579
427
  after do
428
+ @tempfile.rspec_reset
580
429
  @tempfile.close!
581
430
  end
582
431
 
583
432
  it " build a new HTTP GET request without the application/json accept header" do
584
- expected_headers = { 'X-Chef-Version' => Chef::VERSION,
585
- 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE,
586
- 'Host' => @expected_host_header }
433
+ expected_headers = {'X-Chef-Version' => Chef::VERSION, 'Accept-Encoding' => Chef::REST::RESTRequest::ENCODING_GZIP_DEFLATE}
587
434
  Net::HTTP::Get.should_receive(:new).with("/?foo=bar", expected_headers).and_return(@request_mock)
588
435
  @rest.streaming_request(@url, {})
589
436
  end
@@ -645,6 +492,7 @@ describe Chef::REST do
645
492
  end
646
493
 
647
494
  it "closes and unlinks the tempfile when the response is a redirect" do
495
+ Tempfile.rspec_reset
648
496
  tempfile = mock("die", :path => "/tmp/ragefist", :close => true, :binmode => nil)
649
497
  tempfile.should_receive(:close!).at_least(2).times
650
498
  Tempfile.stub!(:new).with("chef-rest").and_return(tempfile)
@@ -658,9 +506,7 @@ describe Chef::REST do
658
506
  end
659
507
 
660
508
  it "passes the original block to the redirected request" do
661
- tempfile = mock("die", :path => "/tmp/ragefist", :close => true, :binmode => nil)
662
- tempfile.should_receive(:close!).at_least(2).times
663
- Tempfile.stub!(:new).with("chef-rest").and_return(tempfile)
509
+ Tempfile.rspec_reset
664
510
 
665
511
  http_response = Net::HTTPFound.new("1.1", "302", "bob is taking care of that one for me today")
666
512
  http_response.add_field("location","/that-thing-is-here-now")