microwave 1.0.4 → 11.400.2

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 (249) hide show
  1. data/CONTRIBUTING.md +155 -0
  2. data/README.md +89 -0
  3. data/Rakefile +2 -2
  4. data/bin/chef-apply +25 -0
  5. data/bin/chef-shell +34 -0
  6. data/bin/chef-solo +0 -2
  7. data/bin/shef +6 -5
  8. data/lib/chef.rb +2 -4
  9. data/spec/data/big_json.json +2 -1
  10. data/spec/data/big_json_plus_one.json +2 -1
  11. data/spec/data/cookbooks/chefignore +2 -0
  12. data/spec/data/cookbooks/openldap/attributes/default.rb +10 -9
  13. data/spec/data/cookbooks/openldap/attributes/smokey.rb +1 -1
  14. data/spec/data/git_bundles/sinatra-test-app-with-callback-files.gitbundle +0 -0
  15. data/spec/data/git_bundles/sinatra-test-app-with-symlinks.gitbundle +0 -0
  16. data/spec/data/git_bundles/sinatra-test-app.gitbundle +0 -0
  17. data/spec/data/lwrp/providers/inline_compiler.rb +26 -0
  18. data/spec/data/nodes/default.rb +3 -3
  19. data/spec/data/nodes/test.example.com.rb +3 -3
  20. data/spec/data/nodes/test.rb +3 -3
  21. data/spec/data/partial_one.erb +1 -0
  22. data/spec/data/run_context/cookbooks/circular-dep1/attributes/default.rb +4 -0
  23. data/spec/data/run_context/cookbooks/circular-dep1/definitions/circular_dep1_res.rb +1 -0
  24. data/spec/data/run_context/cookbooks/circular-dep1/libraries/lib.rb +2 -0
  25. data/spec/data/run_context/cookbooks/circular-dep1/metadata.rb +2 -0
  26. data/spec/data/run_context/cookbooks/circular-dep1/providers/provider.rb +1 -0
  27. data/spec/data/run_context/cookbooks/circular-dep1/recipes/default.rb +0 -0
  28. data/spec/data/run_context/cookbooks/circular-dep1/resources/resource.rb +1 -0
  29. data/spec/data/run_context/cookbooks/circular-dep2/attributes/default.rb +3 -0
  30. data/spec/data/run_context/cookbooks/circular-dep2/definitions/circular_dep2_res.rb +1 -0
  31. data/spec/data/run_context/cookbooks/circular-dep2/libraries/lib.rb +2 -0
  32. data/spec/data/run_context/cookbooks/circular-dep2/metadata.rb +2 -0
  33. data/spec/data/run_context/cookbooks/circular-dep2/providers/provider.rb +1 -0
  34. data/spec/data/run_context/cookbooks/circular-dep2/recipes/default.rb +0 -0
  35. data/spec/data/run_context/cookbooks/circular-dep2/resources/resource.rb +1 -0
  36. data/spec/data/run_context/cookbooks/dependency1/attributes/aa_first.rb +2 -0
  37. data/spec/data/run_context/cookbooks/dependency1/attributes/default.rb +2 -0
  38. data/spec/data/run_context/cookbooks/dependency1/attributes/zz_last.rb +3 -0
  39. data/spec/data/run_context/cookbooks/dependency1/definitions/dependency1_res.rb +1 -0
  40. data/spec/data/run_context/cookbooks/dependency1/libraries/lib.rb +2 -0
  41. data/spec/data/run_context/cookbooks/dependency1/providers/provider.rb +1 -0
  42. data/spec/data/run_context/cookbooks/dependency1/recipes/default.rb +0 -0
  43. data/spec/data/run_context/cookbooks/dependency1/resources/resource.rb +1 -0
  44. data/spec/data/run_context/cookbooks/dependency2/attributes/default.rb +3 -0
  45. data/spec/data/run_context/cookbooks/dependency2/definitions/dependency2_res.rb +1 -0
  46. data/spec/data/run_context/cookbooks/dependency2/libraries/lib.rb +2 -0
  47. data/spec/data/run_context/cookbooks/dependency2/providers/provider.rb +1 -0
  48. data/spec/data/run_context/cookbooks/dependency2/recipes/default.rb +0 -0
  49. data/spec/data/run_context/cookbooks/dependency2/resources/resource.rb +1 -0
  50. data/spec/data/run_context/cookbooks/no-default-attr/attributes/server.rb +3 -0
  51. data/spec/data/run_context/cookbooks/no-default-attr/definitions/no_default-attr_res.rb +1 -0
  52. data/spec/data/run_context/cookbooks/no-default-attr/providers/provider.rb +1 -0
  53. data/spec/data/run_context/cookbooks/no-default-attr/recipes/default.rb +0 -0
  54. data/spec/data/run_context/cookbooks/no-default-attr/resources/resource.rb +1 -0
  55. data/spec/data/run_context/cookbooks/test-with-circular-deps/attributes/default.rb +3 -0
  56. data/spec/data/run_context/cookbooks/test-with-circular-deps/definitions/test_with-circular-deps_res.rb +1 -0
  57. data/spec/data/run_context/cookbooks/test-with-circular-deps/libraries/lib.rb +2 -0
  58. data/spec/data/run_context/cookbooks/test-with-circular-deps/metadata.rb +2 -0
  59. data/spec/data/run_context/cookbooks/test-with-circular-deps/providers/provider.rb +1 -0
  60. data/spec/data/run_context/cookbooks/test-with-circular-deps/recipes/default.rb +0 -0
  61. data/spec/data/run_context/cookbooks/test-with-circular-deps/resources/resource.rb +1 -0
  62. data/spec/data/run_context/cookbooks/test-with-deps/attributes/default.rb +3 -0
  63. data/spec/data/run_context/cookbooks/test-with-deps/definitions/test_with-deps_res.rb +1 -0
  64. data/spec/data/run_context/cookbooks/test-with-deps/libraries/lib.rb +1 -0
  65. data/spec/data/run_context/cookbooks/test-with-deps/metadata.rb +3 -0
  66. data/spec/data/run_context/cookbooks/test-with-deps/providers/provider.rb +1 -0
  67. data/spec/data/run_context/cookbooks/test-with-deps/recipes/default.rb +0 -0
  68. data/spec/data/run_context/cookbooks/test-with-deps/recipes/server.rb +0 -0
  69. data/spec/data/run_context/cookbooks/test-with-deps/resources/resource.rb +1 -0
  70. data/spec/data/run_context/cookbooks/test/attributes/default.rb +0 -0
  71. data/spec/data/run_context/cookbooks/test/attributes/george.rb +1 -1
  72. data/spec/data/run_context/cookbooks/test/definitions/test_res.rb +1 -0
  73. data/spec/data/run_context/cookbooks/test/providers/provider.rb +1 -0
  74. data/spec/data/run_context/cookbooks/test/resources/resource.rb +1 -0
  75. data/spec/data/shef-config.rb +10 -0
  76. data/spec/functional/dsl/registry_helper_spec.rb +63 -0
  77. data/spec/functional/knife/cookbook_delete_spec.rb +0 -2
  78. data/spec/functional/knife/exec_spec.rb +4 -6
  79. data/spec/functional/knife/smoke_test.rb +34 -0
  80. data/spec/functional/knife/ssh_spec.rb +64 -3
  81. data/spec/functional/resource/cookbook_file_spec.rb +33 -2
  82. data/spec/functional/resource/deploy_revision_spec.rb +515 -0
  83. data/spec/functional/resource/directory_spec.rb +4 -0
  84. data/spec/functional/resource/file_spec.rb +56 -22
  85. data/spec/functional/resource/link_spec.rb +12 -10
  86. data/spec/functional/resource/registry_spec.rb +572 -0
  87. data/spec/functional/resource/remote_directory_spec.rb +142 -36
  88. data/spec/functional/resource/remote_file_spec.rb +28 -3
  89. data/spec/functional/resource/template_spec.rb +23 -2
  90. data/spec/functional/run_lock_spec.rb +238 -0
  91. data/spec/functional/shell_spec.rb +101 -0
  92. data/spec/functional/tiny_server_spec.rb +5 -4
  93. data/spec/functional/win32/registry_helper_spec.rb +632 -0
  94. data/spec/functional/win32/security_spec.rb +37 -0
  95. data/spec/spec_helper.rb +15 -3
  96. data/spec/stress/win32/security_spec.rb +5 -5
  97. data/spec/support/chef_helpers.rb +14 -3
  98. data/spec/support/lib/chef/resource/cat.rb +3 -5
  99. data/spec/support/lib/chef/resource/one_two_three_four.rb +8 -10
  100. data/spec/support/lib/chef/resource/zen_master.rb +8 -10
  101. data/spec/support/matchers/leak.rb +1 -1
  102. data/spec/support/platform_helpers.rb +18 -0
  103. data/spec/support/shared/functional/directory_resource.rb +85 -23
  104. data/spec/support/shared/functional/file_resource.rb +198 -53
  105. data/spec/support/shared/functional/securable_resource.rb +140 -105
  106. data/spec/support/shared/functional/securable_resource_with_reporting.rb +375 -0
  107. data/spec/support/shared/unit/file_system_support.rb +110 -0
  108. data/spec/support/shared/unit/platform_introspector.rb +162 -0
  109. data/spec/tiny_server.rb +29 -10
  110. data/spec/unit/api_client/registration_spec.rb +172 -0
  111. data/spec/unit/api_client_spec.rb +156 -103
  112. data/spec/unit/application/apply.rb +84 -0
  113. data/spec/unit/application/knife_spec.rb +5 -0
  114. data/spec/unit/application_spec.rb +57 -2
  115. data/spec/unit/chef_fs/diff_spec.rb +329 -0
  116. data/spec/unit/chef_fs/file_pattern_spec.rb +526 -0
  117. data/spec/unit/chef_fs/file_system/chef_server_root_dir_spec.rb +237 -0
  118. data/spec/unit/chef_fs/file_system/cookbooks_dir_spec.rb +568 -0
  119. data/spec/unit/chef_fs/file_system/data_bags_dir_spec.rb +220 -0
  120. data/spec/unit/chef_fs/file_system_spec.rb +136 -0
  121. data/spec/unit/client_spec.rb +188 -16
  122. data/spec/unit/config_spec.rb +54 -4
  123. data/spec/unit/cookbook/chefignore_spec.rb +2 -1
  124. data/spec/unit/cookbook/syntax_check_spec.rb +48 -109
  125. data/spec/unit/cookbook_loader_spec.rb +153 -91
  126. data/spec/unit/cookbook_manifest_spec.rb +81 -81
  127. data/spec/unit/cookbook_spec.rb +3 -20
  128. data/spec/unit/cookbook_version_spec.rb +23 -122
  129. data/spec/unit/digester_spec.rb +50 -0
  130. data/spec/unit/dsl/data_query_spec.rb +66 -0
  131. data/spec/unit/dsl/platform_introspection_spec.rb +130 -0
  132. data/spec/unit/dsl/regsitry_helper_spec.rb +55 -0
  133. data/spec/unit/encrypted_data_bag_item_spec.rb +126 -10
  134. data/spec/unit/environment_spec.rb +0 -130
  135. data/spec/unit/exceptions_spec.rb +2 -3
  136. data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +23 -3
  137. data/spec/unit/json_compat_spec.rb +69 -0
  138. data/spec/unit/knife/bootstrap_spec.rb +81 -28
  139. data/spec/unit/knife/client_reregister_spec.rb +23 -22
  140. data/spec/unit/knife/configure_spec.rb +29 -26
  141. data/spec/unit/knife/cookbook_metadata_spec.rb +11 -4
  142. data/spec/unit/knife/cookbook_site_install_spec.rb +12 -2
  143. data/spec/unit/knife/cookbook_test_spec.rb +1 -0
  144. data/spec/unit/knife/cookbook_upload_spec.rb +41 -2
  145. data/spec/unit/knife/core/bootstrap_context_spec.rb +8 -1
  146. data/spec/unit/knife/core/ui_spec.rb +156 -7
  147. data/spec/unit/knife/data_bag_create_spec.rb +14 -0
  148. data/spec/unit/knife/data_bag_edit_spec.rb +14 -4
  149. data/spec/unit/knife/data_bag_from_file_spec.rb +17 -5
  150. data/spec/unit/knife/data_bag_show_spec.rb +11 -4
  151. data/spec/unit/knife/index_rebuild_spec.rb +96 -33
  152. data/spec/unit/knife/knife_help.rb +7 -7
  153. data/spec/unit/knife/node_run_list_remove_spec.rb +2 -1
  154. data/spec/unit/knife/ssh_spec.rb +121 -15
  155. data/spec/unit/knife/status_spec.rb +2 -2
  156. data/spec/unit/knife/user_create_spec.rb +86 -0
  157. data/spec/unit/knife/user_delete_spec.rb +39 -0
  158. data/spec/unit/knife/user_edit_spec.rb +42 -0
  159. data/spec/unit/knife/user_list_spec.rb +32 -0
  160. data/spec/unit/knife/user_reregister_spec.rb +53 -0
  161. data/spec/unit/knife/user_show_spec.rb +41 -0
  162. data/spec/unit/knife_spec.rb +53 -0
  163. data/spec/unit/lwrp_spec.rb +59 -17
  164. data/spec/unit/mixin/checksum_spec.rb +2 -2
  165. data/spec/unit/mixin/deep_merge_spec.rb +56 -491
  166. data/spec/unit/mixin/deprecation_spec.rb +23 -0
  167. data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +6 -1
  168. data/spec/unit/mixin/params_validate_spec.rb +4 -2
  169. data/spec/unit/mixin/securable_spec.rb +5 -3
  170. data/spec/unit/mixin/template_spec.rb +119 -0
  171. data/spec/unit/node/attribute_spec.rb +272 -137
  172. data/spec/unit/node/immutable_collections_spec.rb +139 -0
  173. data/spec/unit/node_spec.rb +411 -339
  174. data/spec/unit/platform_spec.rb +8 -8
  175. data/spec/unit/provider/breakpoint_spec.rb +8 -8
  176. data/spec/unit/provider/cookbook_file_spec.rb +4 -8
  177. data/spec/unit/provider/deploy/revision_spec.rb +2 -8
  178. data/spec/unit/provider/deploy_spec.rb +6 -40
  179. data/spec/unit/provider/directory_spec.rb +103 -68
  180. data/spec/unit/provider/erl_call_spec.rb +0 -2
  181. data/spec/unit/provider/file_spec.rb +69 -59
  182. data/spec/unit/provider/git_spec.rb +0 -10
  183. data/spec/unit/provider/group/groupadd_spec.rb +1 -1
  184. data/spec/unit/provider/group/usermod_spec.rb +2 -2
  185. data/spec/unit/provider/http_request_spec.rb +28 -69
  186. data/spec/unit/provider/ifconfig_spec.rb +2 -2
  187. data/spec/unit/provider/link_spec.rb +1 -1
  188. data/spec/unit/provider/ohai_spec.rb +4 -4
  189. data/spec/unit/provider/package/apt_spec.rb +0 -1
  190. data/spec/unit/provider/package/ips_spec.rb +0 -1
  191. data/spec/unit/provider/package/rubygems_spec.rb +0 -18
  192. data/spec/unit/provider/package/yum_spec.rb +79 -15
  193. data/spec/unit/provider/package_spec.rb +7 -5
  194. data/spec/unit/provider/registry_key_spec.rb +269 -0
  195. data/spec/unit/provider/remote_directory_spec.rb +24 -7
  196. data/spec/unit/provider/remote_file_spec.rb +36 -0
  197. data/spec/unit/provider/route_spec.rb +3 -6
  198. data/spec/unit/provider/ruby_block_spec.rb +8 -0
  199. data/spec/unit/provider/service/arch_service_spec.rb +4 -4
  200. data/spec/unit/provider/service/debian_service_spec.rb +1 -1
  201. data/spec/unit/provider/service/freebsd_service_spec.rb +4 -4
  202. data/spec/unit/provider/service/init_service_spec.rb +26 -3
  203. data/spec/unit/provider/service/insserv_service_spec.rb +1 -1
  204. data/spec/unit/provider/service/invokercd_service_spec.rb +3 -3
  205. data/spec/unit/provider/service/redhat_spec.rb +1 -1
  206. data/spec/unit/provider/service/simple_service_spec.rb +3 -3
  207. data/spec/unit/provider/service/upstart_service_spec.rb +7 -7
  208. data/spec/unit/provider/service_spec.rb +2 -2
  209. data/spec/unit/provider/subversion_spec.rb +1 -1
  210. data/spec/unit/provider/template_spec.rb +35 -11
  211. data/spec/unit/provider/user/dscl_spec.rb +57 -31
  212. data/spec/unit/provider/user_spec.rb +7 -16
  213. data/spec/unit/provider_spec.rb +4 -3
  214. data/spec/unit/recipe_spec.rb +10 -8
  215. data/spec/unit/registry_helper_spec.rb +376 -0
  216. data/spec/unit/resource/log_spec.rb +9 -0
  217. data/spec/unit/resource/registry_key_spec.rb +171 -0
  218. data/spec/unit/resource/remote_file_spec.rb +21 -23
  219. data/spec/unit/resource/ruby_block_spec.rb +7 -3
  220. data/spec/unit/resource/service_spec.rb +11 -0
  221. data/spec/unit/resource_spec.rb +27 -4
  222. data/spec/unit/rest/auth_credentials_spec.rb +2 -14
  223. data/spec/unit/rest_spec.rb +122 -187
  224. data/spec/unit/run_context/cookbook_compiler_spec.rb +181 -0
  225. data/spec/unit/run_context_spec.rb +18 -4
  226. data/spec/unit/run_list_spec.rb +0 -209
  227. data/spec/unit/run_lock_spec.rb +37 -0
  228. data/spec/unit/runner_spec.rb +101 -2
  229. data/spec/unit/scan_access_control_spec.rb +4 -4
  230. data/spec/unit/{shef → shell}/model_wrapper_spec.rb +5 -5
  231. data/spec/unit/{shef/shef_ext_spec.rb → shell/shell_ext_spec.rb} +21 -21
  232. data/spec/unit/{shef/shef_session_spec.rb → shell/shell_session_spec.rb} +12 -12
  233. data/spec/unit/shell_out_spec.rb +18 -0
  234. data/spec/unit/{shef_spec.rb → shell_spec.rb} +20 -20
  235. data/spec/unit/user_spec.rb +255 -0
  236. metadata +162 -157
  237. data/README.rdoc +0 -177
  238. data/spec/unit/certificate_spec.rb +0 -76
  239. data/spec/unit/checksum_cache_spec.rb +0 -209
  240. data/spec/unit/checksum_spec.rb +0 -94
  241. data/spec/unit/couchdb_spec.rb +0 -274
  242. data/spec/unit/index_queue_spec.rb +0 -391
  243. data/spec/unit/json_compat_spect.rb +0 -53
  244. data/spec/unit/mixin/language_spec.rb +0 -305
  245. data/spec/unit/openid_registration_spec.rb +0 -153
  246. data/spec/unit/solr_query/query_transform_spec.rb +0 -454
  247. data/spec/unit/solr_query/solr_http_request_spec.rb +0 -244
  248. data/spec/unit/solr_query_spec.rb +0 -203
  249. data/spec/unit/webui_user_spec.rb +0 -238
@@ -0,0 +1,110 @@
1
+ #
2
+ # Author:: John Keiser (<jkeiser@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 'chef/chef_fs/file_system'
20
+ require 'chef/chef_fs/file_system/base_fs_dir'
21
+ require 'chef/chef_fs/file_system/base_fs_object'
22
+
23
+ module FileSystemSupport
24
+ class MemoryFile < Chef::ChefFS::FileSystem::BaseFSObject
25
+ def initialize(name, parent, value)
26
+ super(name, parent)
27
+ @value = value
28
+ end
29
+ def read
30
+ return @value
31
+ end
32
+ end
33
+
34
+ class MemoryDir < Chef::ChefFS::FileSystem::BaseFSDir
35
+ def initialize(name, parent)
36
+ super(name, parent)
37
+ @children = []
38
+ end
39
+ attr_reader :children
40
+ def child(name)
41
+ @children.select { |child| child.name == name }.first || Chef::ChefFS::FileSystem::NonexistentFSObject.new(name, self)
42
+ end
43
+ def add_child(child)
44
+ @children.push(child)
45
+ end
46
+ def can_have_child?(name, is_dir)
47
+ root.cannot_be_in_regex ? (name !~ root.cannot_be_in_regex) : true
48
+ end
49
+ end
50
+
51
+ class MemoryRoot < MemoryDir
52
+ def initialize(pretty_name, cannot_be_in_regex = nil)
53
+ super('', nil)
54
+ @pretty_name = pretty_name
55
+ @cannot_be_in_regex = cannot_be_in_regex
56
+ end
57
+
58
+ attr_reader :cannot_be_in_regex
59
+
60
+ def path_for_printing
61
+ @pretty_name
62
+ end
63
+ end
64
+
65
+ def memory_fs(pretty_name, value, cannot_be_in_regex = nil)
66
+ if !value.is_a?(Hash)
67
+ raise "memory_fs() must take a Hash"
68
+ end
69
+ dir = MemoryRoot.new(pretty_name, cannot_be_in_regex)
70
+ value.each do |key, child|
71
+ dir.add_child(memory_fs_value(child, key.to_s, dir))
72
+ end
73
+ dir
74
+ end
75
+
76
+ def memory_fs_value(value, name = '', parent = nil)
77
+ if value.is_a?(Hash)
78
+ dir = MemoryDir.new(name, parent)
79
+ value.each do |key, child|
80
+ dir.add_child(memory_fs_value(child, key.to_s, dir))
81
+ end
82
+ dir
83
+ else
84
+ MemoryFile.new(name, parent, value || "#{name}\n")
85
+ end
86
+ end
87
+
88
+ def pattern(p)
89
+ Chef::ChefFS::FilePattern.new(p)
90
+ end
91
+
92
+ def return_paths(*expected)
93
+ ReturnPaths.new(expected)
94
+ end
95
+
96
+ def no_blocking_calls_allowed
97
+ [ MemoryFile, MemoryDir ].each do |c|
98
+ [ :children, :exists?, :read ].each do |m|
99
+ c.any_instance.stub(m).and_raise("#{m.to_s} should not be called")
100
+ end
101
+ end
102
+ end
103
+
104
+ def list_should_yield_paths(fs, pattern_str, *expected_paths)
105
+ result_paths = []
106
+ Chef::ChefFS::FileSystem.list(fs, pattern(pattern_str)) { |result| result_paths << result.path }
107
+ result_paths.should =~ expected_paths
108
+ end
109
+ end
110
+
@@ -0,0 +1,162 @@
1
+ #
2
+ # Author:: Seth Falcon (<seth@opscode.com>)
3
+ # Author:: Daniel DeLeo (<dan@opscode.com>)
4
+ # Copyright:: Copyright (c) 2010, 2012 Opscode, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+
20
+
21
+ shared_examples_for "a platform introspector" do
22
+ before(:each) do
23
+ @platform_hash = {}
24
+ %w{openbsd freebsd}.each do |x|
25
+ @platform_hash[x] = {
26
+ "default" => x,
27
+ "1.2.3" => "#{x}-1.2.3"
28
+ }
29
+ end
30
+ @platform_hash["debian"] = {["5", "6"] => "debian-5/6", "default" => "debian"}
31
+ @platform_hash["default"] = "default"
32
+
33
+ @platform_family_hash = {
34
+ "debian" => "debian value",
35
+ [:rhel, :fedora] => "redhatty value",
36
+ "suse" => "suse value",
37
+ :default => "default value"
38
+ }
39
+ end
40
+
41
+ it "returns a default value when there is no known platform" do
42
+ node = Hash.new
43
+ platform_introspector.value_for_platform(@platform_hash).should == "default"
44
+ end
45
+
46
+ it "returns a default value when there is no known platform family" do
47
+ platform_introspector.value_for_platform_family(@platform_family_hash).should == "default value"
48
+ end
49
+
50
+ it "returns a default value when the current platform doesn't match" do
51
+ node.automatic_attrs[:platform] = "not-a-known-platform"
52
+ platform_introspector.value_for_platform(@platform_hash).should == "default"
53
+ end
54
+
55
+ it "returns a default value when current platform_family doesn't match" do
56
+ node.automatic_attrs[:platform_family] = "ultra-derived-linux"
57
+ platform_introspector.value_for_platform_family(@platform_family_hash).should == "default value"
58
+ end
59
+
60
+ it "returns a value based on the current platform" do
61
+ node.automatic_attrs[:platform] = "openbsd"
62
+ platform_introspector.value_for_platform(@platform_hash).should == "openbsd"
63
+ end
64
+
65
+ it "returns a value based on the current platform family" do
66
+ node.automatic_attrs[:platform_family] = "debian"
67
+ platform_introspector.value_for_platform_family(@platform_family_hash).should == "debian value"
68
+ end
69
+
70
+ it "returns a version-specific value based on the current platform" do
71
+ node.automatic_attrs[:platform] = "openbsd"
72
+ node.automatic_attrs[:platform_version] = "1.2.3"
73
+ platform_introspector.value_for_platform(@platform_hash).should == "openbsd-1.2.3"
74
+ end
75
+
76
+ it "returns a value based on the current platform if version not found" do
77
+ node.automatic_attrs[:platform] = "openbsd"
78
+ node.automatic_attrs[:platform_version] = "0.0.0"
79
+ platform_introspector.value_for_platform(@platform_hash).should == "openbsd"
80
+ end
81
+
82
+ describe "when platform versions is an array" do
83
+ it "returns a version-specific value based on the current platform" do
84
+ node.automatic_attrs[:platform] = "debian"
85
+ node.automatic_attrs[:platform_version] = "6"
86
+ platform_introspector.value_for_platform(@platform_hash).should == "debian-5/6"
87
+ end
88
+
89
+ it "returns a value based on the current platform if version not found" do
90
+ node.automatic_attrs[:platform] = "debian"
91
+ node.automatic_attrs[:platform_version] = "0.0.0"
92
+ platform_introspector.value_for_platform(@platform_hash).should == "debian"
93
+ end
94
+ end
95
+
96
+ describe "when checking platform?" do
97
+
98
+ it "returns true if the node is a provided platform and platforms are provided as symbols" do
99
+ node.automatic_attrs[:platform] = 'ubuntu'
100
+ platform_introspector.platform?([:redhat, :ubuntu]).should == true
101
+ end
102
+
103
+ it "returns true if the node is a provided platform and platforms are provided as strings" do
104
+ node.automatic_attrs[:platform] = 'ubuntu'
105
+ platform_introspector.platform?(["redhat", "ubuntu"]).should == true
106
+ end
107
+
108
+ it "returns false if the node is not of the provided platforms" do
109
+ node.automatic_attrs[:platform] = 'ubuntu'
110
+ platform_introspector.platform?(:splatlinux).should == false
111
+ end
112
+ end
113
+
114
+ describe "when checking platform_family?" do
115
+
116
+ it "returns true if the node is in a provided platform family and families are provided as symbols" do
117
+ node.automatic_attrs[:platform_family] = 'debian'
118
+ platform_introspector.platform_family?([:rhel, :debian]).should == true
119
+ end
120
+
121
+ it "returns true if the node is a provided platform and platforms are provided as strings" do
122
+ node.automatic_attrs[:platform_family] = 'rhel'
123
+ platform_introspector.platform_family?(["rhel", "debian"]).should == true
124
+ end
125
+
126
+ it "returns false if the node is not of the provided platforms" do
127
+ node.automatic_attrs[:platform_family] = 'suse'
128
+ platform_introspector.platform_family?(:splatlinux).should == false
129
+ end
130
+
131
+ it "returns false if the node is not of the provided platforms and platform_family is not set" do
132
+ platform_introspector.platform_family?(:splatlinux).should == false
133
+ end
134
+
135
+ end
136
+ # NOTE: this is a regression test for bug CHEF-1514
137
+ describe "when the value is an array" do
138
+ before do
139
+ @platform_hash = {
140
+ "debian" => { "4.0" => [ :restart, :reload ], "default" => [ :restart, :reload, :status ] },
141
+ "ubuntu" => { "default" => [ :restart, :reload, :status ] },
142
+ "centos" => { "default" => [ :restart, :reload, :status ] },
143
+ "redhat" => { "default" => [ :restart, :reload, :status ] },
144
+ "fedora" => { "default" => [ :restart, :reload, :status ] },
145
+ "default" => { "default" => [:restart, :reload ] }}
146
+ end
147
+
148
+ it "returns the correct default for a given platform" do
149
+ node.automatic_attrs[:platform] = "debian"
150
+ node.automatic_attrs[:platform_version] = '9000'
151
+ platform_introspector.value_for_platform(@platform_hash).should == [ :restart, :reload, :status ]
152
+ end
153
+
154
+ it "returns the correct platform+version specific value " do
155
+ node.automatic_attrs[:platform] = "debian"
156
+ node.automatic_attrs[:platform_version] = '4.0'
157
+ platform_introspector.value_for_platform(@platform_hash).should == [:restart, :reload]
158
+ end
159
+ end
160
+
161
+ end
162
+
data/spec/tiny_server.rb CHANGED
@@ -17,11 +17,13 @@
17
17
  #
18
18
 
19
19
  require 'rubygems'
20
+ require 'webrick'
20
21
  require 'rack'
21
- require 'thin'
22
+ #require 'thin'
22
23
  require 'singleton'
23
24
  require 'chef/json_compat'
24
25
  require 'open-uri'
26
+ require 'chef/config'
25
27
 
26
28
  module TinyServer
27
29
 
@@ -29,30 +31,42 @@ module TinyServer
29
31
 
30
32
  attr_writer :app
31
33
 
32
- def self.run(options=nil, &block)
34
+ def self.setup(options=nil, &block)
33
35
  tiny_app = new(options)
34
36
  app_code = Rack::Builder.new(&block).to_app
35
37
  tiny_app.app = app_code
36
- tiny_app.start
38
+ tiny_app
39
+ end
40
+
41
+ def shutdown
42
+ server.shutdown
37
43
  end
38
44
  end
39
45
 
40
46
  class Manager
41
47
 
42
- DEFAULT_OPTIONS = {:server => 'thin', :Port => 9000, :Host => 'localhost', :environment => :none}
48
+ # 5 == debug, 3 == warning
49
+ LOGGER = WEBrick::Log.new(STDOUT, 3)
50
+ DEFAULT_OPTIONS = {
51
+ :server => 'webrick',
52
+ :Port => 9000,
53
+ :Host => 'localhost',
54
+ :environment => :none,
55
+ :Logger => LOGGER,
56
+ :AccessLog => [] # Remove this option to enable the access log when debugging.
57
+ }
43
58
 
44
59
  def initialize(options=nil)
45
60
  @options = options ? DEFAULT_OPTIONS.merge(options) : DEFAULT_OPTIONS
46
61
  @creator = caller.first
47
-
48
- Thin::Logging.silent = !@options[:debug]
49
62
  end
50
63
 
51
64
  def start
52
65
  @server_thread = Thread.new do
53
- @server = Server.run(@options) do
66
+ @server = Server.setup(@options) do
54
67
  run API.instance
55
68
  end
69
+ @server.start
56
70
  end
57
71
  block_until_started
58
72
  end
@@ -63,8 +77,11 @@ module TinyServer
63
77
 
64
78
  def block_until_started
65
79
  200.times do
66
- return true if started?
80
+ if started? && !@server.nil?
81
+ return true
82
+ end
67
83
  end
84
+ raise "ivar weirdness" if started? && @server.nil?
68
85
  raise "TinyServer failed to boot :/"
69
86
  end
70
87
 
@@ -84,6 +101,7 @@ module TinyServer
84
101
 
85
102
  def stop
86
103
  # yes, this is terrible.
104
+ @server.shutdown
87
105
  @server_thread.kill
88
106
  @server_thread.join
89
107
  @server_thread = nil
@@ -132,7 +150,7 @@ module TinyServer
132
150
  debug_info = {:message => "no data matches the request for #{env['REQUEST_URI']}",
133
151
  :available_routes => @routes, :request => env}
134
152
  # Uncomment me for glorious debugging
135
- #pp :not_found => debug_info
153
+ # pp :not_found => debug_info
136
154
  [404, {'Content-Type' => 'application/json'}, debug_info.to_json]
137
155
  end
138
156
  end
@@ -152,6 +170,7 @@ module TinyServer
152
170
  end
153
171
 
154
172
  def matches_request?(uri)
173
+ uri = URI.parse(uri).request_uri
155
174
  @path_spec === uri
156
175
  end
157
176
 
@@ -171,7 +190,7 @@ module TinyServer
171
190
 
172
191
  def call
173
192
  data = @data || @block.call
174
- [@response_code, HEADERS, data]
193
+ [@response_code, HEADERS, Array(data)]
175
194
  end
176
195
 
177
196
  def to_s
@@ -0,0 +1,172 @@
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 'tempfile'
21
+
22
+ require 'chef/api_client/registration'
23
+
24
+ describe Chef::ApiClient::Registration do
25
+ let(:key_location) do
26
+ make_tmpname("client-registration-key")
27
+ end
28
+
29
+ let(:registration) { Chef::ApiClient::Registration.new("silent-bob", key_location) }
30
+
31
+ let :private_key_data do
32
+ File.open(Chef::Config[:validation_key], "r") {|f| f.read.chomp }
33
+ end
34
+
35
+ before do
36
+ Chef::Config[:validation_client_name] = "test-validator"
37
+ Chef::Config[:validation_key] = File.expand_path('ssl/private_key.pem', CHEF_SPEC_DATA)
38
+ end
39
+
40
+ after do
41
+ File.unlink(key_location) if File.exist?(key_location)
42
+ Chef::Config[:validation_client_name] = nil
43
+ Chef::Config[:validation_key] = nil
44
+ end
45
+
46
+ it "has an HTTP client configured with validator credentials" do
47
+ registration.http_api.should be_a_kind_of(Chef::REST)
48
+ registration.http_api.client_name.should == "test-validator"
49
+ registration.http_api.signing_key.should == private_key_data
50
+ end
51
+
52
+ describe "when creating/updating the client on the server" do
53
+ let(:http_mock) { mock("Chef::REST mock") }
54
+
55
+ before do
56
+ registration.stub!(:http_api).and_return(http_mock)
57
+ end
58
+
59
+ it "creates a new ApiClient on the server using the validator identity" do
60
+ response = {"uri" => "https://chef.local/clients/silent-bob",
61
+ "private_key" => "--begin rsa key etc--"}
62
+ http_mock.should_receive(:post).
63
+ with("clients", :name => 'silent-bob', :admin => false).
64
+ and_return(response)
65
+ registration.create_or_update.should == response
66
+ registration.private_key.should == "--begin rsa key etc--"
67
+ end
68
+
69
+ context "and the client already exists on a Chef 10 server" do
70
+ it "requests a new key from the server and saves it" do
71
+ response = {"name" => "silent-bob", "private_key" => "--begin rsa key etc--" }
72
+
73
+ response_409 = Net::HTTPConflict.new("1.1", "409", "Conflict")
74
+ exception_409 = Net::HTTPServerException.new("409 conflict", response_409)
75
+
76
+ http_mock.should_receive(:post).and_raise(exception_409)
77
+ http_mock.should_receive(:put).
78
+ with("clients/silent-bob", :name => 'silent-bob', :admin => false, :private_key => true).
79
+ and_return(response)
80
+ registration.create_or_update.should == response
81
+ registration.private_key.should == "--begin rsa key etc--"
82
+ end
83
+ end
84
+
85
+ context "and the client already exists on a Chef 11 server" do
86
+ it "requests a new key from the server and saves it" do
87
+ response = Chef::ApiClient.new
88
+ response.name("silent-bob")
89
+ response.private_key("--begin rsa key etc--")
90
+
91
+ response_409 = Net::HTTPConflict.new("1.1", "409", "Conflict")
92
+ exception_409 = Net::HTTPServerException.new("409 conflict", response_409)
93
+
94
+ http_mock.should_receive(:post).and_raise(exception_409)
95
+ http_mock.should_receive(:put).
96
+ with("clients/silent-bob", :name => 'silent-bob', :admin => false, :private_key => true).
97
+ and_return(response)
98
+ registration.create_or_update.should == response
99
+ registration.private_key.should == "--begin rsa key etc--"
100
+ end
101
+ end
102
+ end
103
+
104
+ describe "when writing the private key to disk" do
105
+ before do
106
+ registration.stub!(:private_key).and_return('--begin rsa key etc--')
107
+ end
108
+
109
+ # Permission read via File.stat is busted on windows, though creating the
110
+ # file with 0600 has the desired effect of giving access rights to the
111
+ # owner only. A platform-specific functional test would be helpful.
112
+ it "creates the file with 0600 permissions", :unix_only do
113
+ File.should_not exist(key_location)
114
+ registration.write_key
115
+ File.should exist(key_location)
116
+ stat = File.stat(key_location)
117
+ (stat.mode & 07777).should == 0600
118
+ end
119
+
120
+ it "writes the private key content to the file" do
121
+ registration.write_key
122
+ IO.read(key_location).should == "--begin rsa key etc--"
123
+ end
124
+ end
125
+
126
+ describe "when registering a client" do
127
+
128
+ let(:http_mock) { mock("Chef::REST mock") }
129
+
130
+ before do
131
+ registration.stub!(:http_api).and_return(http_mock)
132
+ end
133
+
134
+ it "creates the client on the server and writes the key" do
135
+ response = {"uri" => "http://chef.local/clients/silent-bob",
136
+ "private_key" => "--begin rsa key etc--" }
137
+ http_mock.should_receive(:post).ordered.and_return(response)
138
+ registration.run
139
+ IO.read(key_location).should == "--begin rsa key etc--"
140
+ end
141
+
142
+ it "retries up to 5 times" do
143
+ response_500 = Net::HTTPInternalServerError.new("1.1", "500", "Internal Server Error")
144
+ exception_500 = Net::HTTPFatalError.new("500 Internal Server Error", response_500)
145
+
146
+ http_mock.should_receive(:post).ordered.and_raise(exception_500) # 1
147
+ http_mock.should_receive(:post).ordered.and_raise(exception_500) # 2
148
+ http_mock.should_receive(:post).ordered.and_raise(exception_500) # 3
149
+ http_mock.should_receive(:post).ordered.and_raise(exception_500) # 4
150
+ http_mock.should_receive(:post).ordered.and_raise(exception_500) # 5
151
+
152
+ response = {"uri" => "http://chef.local/clients/silent-bob",
153
+ "private_key" => "--begin rsa key etc--" }
154
+ http_mock.should_receive(:post).ordered.and_return(response)
155
+ registration.run
156
+ IO.read(key_location).should == "--begin rsa key etc--"
157
+ end
158
+
159
+ it "gives up retrying after the max attempts" do
160
+ response_500 = Net::HTTPInternalServerError.new("1.1", "500", "Internal Server Error")
161
+ exception_500 = Net::HTTPFatalError.new("500 Internal Server Error", response_500)
162
+
163
+ http_mock.should_receive(:post).exactly(6).times.and_raise(exception_500)
164
+
165
+ lambda {registration.run}.should raise_error(Net::HTTPFatalError)
166
+ end
167
+
168
+ end
169
+
170
+ end
171
+
172
+