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
@@ -24,14 +24,26 @@ describe Chef::Resource::CookbookFile do
24
24
  let(:file_base) { 'cookbook_file_spec' }
25
25
  let(:source) { 'java.response' }
26
26
  let(:cookbook_name) { 'java' }
27
- let(:expected_content) { IO.read(File.join(CHEF_SPEC_DATA, 'cookbooks', 'java', 'files', 'default', 'java.response')) }
27
+ let(:expected_content) do
28
+ content = File.open(File.join(CHEF_SPEC_DATA, 'cookbooks', 'java', 'files', 'default', 'java.response'), "rb") do |f|
29
+ f.read
30
+ end
31
+ content.force_encoding(Encoding::BINARY) if content.respond_to?(:force_encoding)
32
+ content
33
+ end
34
+
35
+ let(:default_mode) { "600" }
36
+
37
+ it_behaves_like "a securable resource with reporting"
28
38
 
29
39
  def create_resource
30
40
  # set up cookbook collection for this run to use, based on our
31
41
  # spec data.
32
42
  cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, 'cookbooks'))
33
43
  Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, cookbook_repo) }
34
- cookbook_collection = Chef::CookbookCollection.new(Chef::CookbookLoader.new(cookbook_repo))
44
+ loader = Chef::CookbookLoader.new(cookbook_repo)
45
+ loader.load_cookbooks
46
+ cookbook_collection = Chef::CookbookCollection.new(loader)
35
47
 
36
48
  node = Chef::Node.new
37
49
  events = Chef::EventDispatch::Dispatcher.new
@@ -48,4 +60,23 @@ describe Chef::Resource::CookbookFile do
48
60
  end
49
61
 
50
62
  it_behaves_like "a file resource"
63
+
64
+ # These examples cover CHEF-3467 where unexpected and incorrect
65
+ # permissions can result on Windows because CookbookFile's
66
+ # implementation
67
+ # stages files in temp.
68
+ context "targets a file outside of the system temp directory" do
69
+ let(:windows_non_temp_dir) { File.join(ENV['systemdrive'], make_tmpname(file_base, "non-temp")) }
70
+ let(:path) { File.join(windows_non_temp_dir, make_tmpname(file_base)) }
71
+
72
+ before do
73
+ FileUtils::mkdir_p(windows_non_temp_dir) if Chef::Platform.windows?
74
+ end
75
+
76
+ after do
77
+ FileUtils.rm_r(windows_non_temp_dir) if Chef::Platform.windows? && File.exists?(windows_non_temp_dir)
78
+ end
79
+
80
+ it_behaves_like "a file that inherits permissions from a parent directory"
81
+ end
51
82
  end
@@ -0,0 +1,515 @@
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 'tmpdir'
21
+
22
+ # Deploy relies heavily on symlinks, so it doesn't work on windows.
23
+ describe Chef::Resource::DeployRevision, :unix_only => true do
24
+
25
+ let(:file_cache_path) { Dir.mktmpdir }
26
+ let(:deploy_directory) { Dir.mktmpdir }
27
+
28
+ # By making restart or other operations write to this file, we can externally
29
+ # track the order in which those operations happened.
30
+ let(:observe_order_file) { Tempfile.new("deploy-resource-observe-operations") }
31
+
32
+ before do
33
+ @old_file_cache_path = Chef::Config[:file_cache_path]
34
+ Chef::Config[:file_cache_path] = file_cache_path
35
+ end
36
+
37
+ after do
38
+ Chef::Config[:file_cache_path] = @old_file_cache_path
39
+ FileUtils.remove_entry_secure deploy_directory if File.exist?(deploy_directory)
40
+ FileUtils.remove_entry_secure file_cache_path
41
+ observe_order_file.close
42
+ FileUtils.remove_entry_secure observe_order_file.path
43
+ end
44
+
45
+ before(:all) do
46
+ @ohai = Ohai::System.new
47
+ @ohai.require_plugin("os")
48
+ end
49
+
50
+ let(:node) do
51
+
52
+ Chef::Node.new.tap do |n|
53
+ n.name "rspec-test"
54
+ n.consume_external_attrs(@ohai.data, {})
55
+ end
56
+ end
57
+
58
+ let(:event_dispatch) { Chef::EventDispatch::Dispatcher.new }
59
+ let(:run_context) { Chef::RunContext.new(node, {}, event_dispatch) }
60
+
61
+
62
+ # These tests use git's bundle feature, which is a way to export an entire
63
+ # git repo (or subset of commits) as a single file.
64
+ #
65
+ # Generally you can treat a git bundle as a regular git remote.
66
+ #
67
+ # See also: http://git-scm.com/2010/03/10/bundles.html
68
+ let(:git_bundle_repo) { File.expand_path("git_bundles/sinatra-test-app.gitbundle", CHEF_SPEC_DATA) }
69
+
70
+ let(:git_bundle_with_in_repo_callbacks) { File.expand_path("git_bundles/sinatra-test-app-with-callback-files.gitbundle", CHEF_SPEC_DATA) }
71
+
72
+ let(:git_bundle_with_in_repo_symlinks) { File.expand_path("git_bundles/sinatra-test-app-with-symlinks.gitbundle", CHEF_SPEC_DATA) }
73
+
74
+ # This is the fourth version
75
+ let(:latest_rev) { "3eb5ca6c353c83d9179dd3b29347539829b401f3" }
76
+
77
+ # This is the third version
78
+ let(:previous_rev) { "6d19a6dbecc8e37f5b2277345885c0c783eb8fb1" }
79
+
80
+ # This is the sixth version, it is on the "with-deploy-scripts" branch
81
+ let(:rev_with_in_repo_callbacks) { "2404d015882659754bdb93ad6e4b4d3d02691a82" }
82
+
83
+ # This is the fifth version in the "with-symlinks" branch
84
+ let(:rev_with_in_repo_symlinks) { "5a4748c52aaea8250b4346a9b8ede95ee3755e28" }
85
+
86
+ # Read values from the +observe_order_file+ and split each line. This way you
87
+ # can see in which order things really happened.
88
+ def actual_operations_order
89
+ IO.read(observe_order_file.path).split("\n").map(&:strip)
90
+ end
91
+
92
+ # 1. touch `restart.txt` in cwd so we know that the command is run with the
93
+ # right cwd.
94
+ # 2. Append +tag+ to the `observe_order_file` so we can check the order in
95
+ # which operations happen later in the test.
96
+ def shell_restart_command(tag)
97
+ "touch restart.txt && echo '#{tag}' >> #{observe_order_file.path}"
98
+ end
99
+
100
+ let(:basic_deploy_resource) do
101
+ Chef::Resource::DeployRevision.new(deploy_directory, run_context).tap do |r|
102
+ r.repo git_bundle_repo
103
+ r.symlink_before_migrate({})
104
+ r.symlinks({})
105
+ end
106
+ end
107
+
108
+ let(:deploy_to_latest_rev) do
109
+ basic_deploy_resource.dup.tap do |r|
110
+ r.revision(latest_rev)
111
+ r.restart_command shell_restart_command(:deploy_to_latest_rev)
112
+ end
113
+ end
114
+
115
+ let(:deploy_to_previous_rev) do
116
+ basic_deploy_resource.dup.tap do |r|
117
+ r.revision(previous_rev)
118
+ r.restart_command shell_restart_command(:deploy_to_previous_rev)
119
+ end
120
+ end
121
+
122
+ let(:deploy_to_latest_rev_again) do
123
+ basic_deploy_resource.dup.tap do |r|
124
+ r.revision(latest_rev)
125
+ r.restart_command shell_restart_command(:deploy_to_latest_rev_again)
126
+ end
127
+ end
128
+
129
+ # Computes the full path for +path+ relative to the deploy directory
130
+ def rel_path(path)
131
+ File.expand_path(path, deploy_directory)
132
+ end
133
+
134
+ def actual_current_rev
135
+ Dir.chdir(rel_path("current")) do
136
+ `git rev-parse HEAD`.strip
137
+ end
138
+ end
139
+
140
+ def self.the_app_is_deployed_at_revision(target_rev_spec)
141
+ it "deploys the app to the target revision (#{target_rev_spec})" do
142
+ target_rev = send(target_rev_spec)
143
+
144
+ File.should exist(rel_path("current"))
145
+
146
+ actual_current_rev.should == target_rev
147
+
148
+ # Is the app code actually there?
149
+ File.should exist(rel_path("current/app/app.rb"))
150
+ end
151
+ end
152
+
153
+ context "when deploying a simple app" do
154
+ describe "for the first time, with the required directory layout precreated" do
155
+ before do
156
+ FileUtils.mkdir_p(rel_path("releases"))
157
+ FileUtils.mkdir_p(rel_path("shared"))
158
+ deploy_to_latest_rev.run_action(:deploy)
159
+ end
160
+
161
+ the_app_is_deployed_at_revision(:latest_rev)
162
+
163
+ it "restarts the application" do
164
+ File.should exist(rel_path("current/restart.txt"))
165
+ actual_operations_order.should == %w[deploy_to_latest_rev]
166
+ end
167
+
168
+ it "is marked as updated" do
169
+ deploy_to_latest_rev.should be_updated_by_last_action
170
+ end
171
+ end
172
+
173
+ describe "back to a previously deployed revision, with the directory structure precreated" do
174
+ before do
175
+ FileUtils.mkdir_p(rel_path("releases"))
176
+ FileUtils.mkdir_p(rel_path("shared"))
177
+
178
+ deploy_to_latest_rev.run_action(:deploy)
179
+ deploy_to_previous_rev.run_action(:deploy)
180
+ deploy_to_latest_rev_again.run_action(:deploy)
181
+ end
182
+
183
+ the_app_is_deployed_at_revision(:latest_rev)
184
+
185
+ it "restarts the application after rolling back" do
186
+ actual_operations_order.should == %w[deploy_to_latest_rev deploy_to_previous_rev deploy_to_latest_rev_again]
187
+ end
188
+
189
+ it "is marked updated" do
190
+ deploy_to_latest_rev_again.should be_updated_by_last_action
191
+ end
192
+
193
+ it "deploys the right code" do
194
+ IO.read(rel_path("current/app/app.rb")).should include("this is the fourth version of the app")
195
+ end
196
+ end
197
+
198
+ describe "for the first time, with no existing directory layout" do
199
+ before do
200
+ deploy_to_latest_rev.run_action(:deploy)
201
+ end
202
+
203
+ it "creates the required directory tree" do
204
+ File.should be_directory(rel_path("releases"))
205
+ File.should be_directory(rel_path("shared"))
206
+ File.should be_directory(rel_path("releases/#{latest_rev}"))
207
+
208
+ File.should be_directory(rel_path("current/tmp"))
209
+ File.should be_directory(rel_path("current/config"))
210
+ File.should be_directory(rel_path("current/public"))
211
+
212
+ File.should be_symlink(rel_path("current"))
213
+ File.readlink(rel_path("current")).should == rel_path("releases/#{latest_rev}")
214
+ end
215
+
216
+ the_app_is_deployed_at_revision(:latest_rev)
217
+
218
+ it "restarts the application" do
219
+ File.should exist(rel_path("current/restart.txt"))
220
+ actual_operations_order.should == %w[deploy_to_latest_rev]
221
+ end
222
+
223
+ it "is marked as updated" do
224
+ deploy_to_latest_rev.should be_updated_by_last_action
225
+ end
226
+ end
227
+
228
+ describe "again to the current revision" do
229
+ before do
230
+ deploy_to_latest_rev.run_action(:deploy)
231
+ deploy_to_latest_rev.run_action(:deploy)
232
+ end
233
+
234
+ the_app_is_deployed_at_revision(:latest_rev)
235
+
236
+ it "does not restart the app" do
237
+ actual_operations_order.should == %w[deploy_to_latest_rev]
238
+ end
239
+
240
+ it "is not marked updated" do
241
+ deploy_to_latest_rev.should_not be_updated_by_last_action
242
+ end
243
+
244
+ end
245
+
246
+ describe "again with force_deploy" do
247
+ before do
248
+ deploy_to_latest_rev.run_action(:force_deploy)
249
+ deploy_to_latest_rev_again.run_action(:force_deploy)
250
+ end
251
+
252
+ the_app_is_deployed_at_revision(:latest_rev)
253
+
254
+ it "restarts the app" do
255
+ actual_operations_order.should == %w[deploy_to_latest_rev deploy_to_latest_rev_again]
256
+ end
257
+
258
+ it "is marked updated" do
259
+ deploy_to_latest_rev.should be_updated_by_last_action
260
+ end
261
+
262
+ end
263
+
264
+ describe "again to a new revision" do
265
+ before do
266
+ deploy_to_previous_rev.run_action(:deploy)
267
+ deploy_to_latest_rev.run_action(:deploy)
268
+ end
269
+
270
+ the_app_is_deployed_at_revision(:latest_rev)
271
+
272
+ it "restarts the application after the new deploy" do
273
+ actual_operations_order.should == %w[deploy_to_previous_rev deploy_to_latest_rev]
274
+ end
275
+
276
+ it "is marked updated" do
277
+ deploy_to_previous_rev.should be_updated_by_last_action
278
+ end
279
+ end
280
+
281
+ describe "back to a previously deployed revision (implicit rollback)" do
282
+ before do
283
+ deploy_to_latest_rev.run_action(:deploy)
284
+ deploy_to_previous_rev.run_action(:deploy)
285
+ deploy_to_latest_rev_again.run_action(:deploy)
286
+ end
287
+
288
+ the_app_is_deployed_at_revision(:latest_rev)
289
+
290
+ it "restarts the application after rolling back" do
291
+ actual_operations_order.should == %w[deploy_to_latest_rev deploy_to_previous_rev deploy_to_latest_rev_again]
292
+ end
293
+
294
+ it "is marked updated" do
295
+ deploy_to_latest_rev_again.should be_updated_by_last_action
296
+ end
297
+
298
+ it "deploys the right code" do
299
+ IO.read(rel_path("current/app/app.rb")).should include("this is the fourth version of the app")
300
+ end
301
+ end
302
+
303
+ # CHEF-3435
304
+ describe "to a deploy_to path that does not yet exist" do
305
+
306
+ let(:top_level_tmpdir) { Dir.mktmpdir }
307
+
308
+ # override top level deploy_directory let block with one that is two
309
+ # directories deeper
310
+ let(:deploy_directory) { File.expand_path("nested/deeper", top_level_tmpdir) }
311
+
312
+ after do
313
+ FileUtils.remove_entry_secure top_level_tmpdir
314
+ end
315
+
316
+ before do
317
+ File.should_not exist(deploy_directory)
318
+ deploy_to_latest_rev.run_action(:deploy)
319
+ end
320
+
321
+ it "creates the required directory tree" do
322
+ File.should be_directory(rel_path("releases"))
323
+ File.should be_directory(rel_path("shared"))
324
+ File.should be_directory(rel_path("releases/#{latest_rev}"))
325
+
326
+ File.should be_directory(rel_path("current/tmp"))
327
+ File.should be_directory(rel_path("current/config"))
328
+ File.should be_directory(rel_path("current/public"))
329
+
330
+ File.should be_symlink(rel_path("current"))
331
+ File.readlink(rel_path("current")).should == rel_path("releases/#{latest_rev}")
332
+ end
333
+
334
+ the_app_is_deployed_at_revision(:latest_rev)
335
+
336
+ end
337
+ end
338
+
339
+ context "when deploying an app with inline recipe callbacks" do
340
+
341
+ # Use closures to capture and mutate this variable. This allows us to track
342
+ # ordering of operations.
343
+ callback_order = []
344
+
345
+ let(:deploy_to_latest_with_inline_recipes) do
346
+ deploy_to_latest_rev.dup.tap do |r|
347
+ r.symlink_before_migrate "config/config.ru" => "config.ru"
348
+ r.before_migrate do
349
+ callback_order << :before_migrate
350
+
351
+ file "#{release_path}/before_migrate.txt" do
352
+ # The content here isn't relevant, but it gets printed when running
353
+ # the tests. Could be handy for debugging.
354
+ content callback_order.inspect
355
+ end
356
+ end
357
+ r.before_symlink do
358
+ callback_order << :before_symlink
359
+
360
+ current_release_path = release_path
361
+ ruby_block "ensure before symlink" do
362
+ block do
363
+ if ::File.exist?(::File.join(current_release_path, "/tmp"))
364
+ raise "Ordering issue with provider, expected symlinks to not have been created"
365
+ end
366
+ end
367
+ end
368
+
369
+ file "#{release_path}/before_symlink.txt" do
370
+ content callback_order.inspect
371
+ end
372
+ end
373
+ r.before_restart do
374
+ callback_order << :before_restart
375
+
376
+ current_release_path = release_path
377
+ ruby_block "ensure after symlink" do
378
+ block do
379
+ unless ::File.exist?(::File.join(current_release_path, "/tmp"))
380
+ raise "Ordering issue with provider, expected symlinks to have been created"
381
+ end
382
+ end
383
+ end
384
+
385
+ file "#{release_path}/tmp/before_restart.txt" do
386
+ content callback_order.inspect
387
+ end
388
+ end
389
+ r.after_restart do
390
+ callback_order << :after_restart
391
+ file "#{release_path}/tmp/after_restart.txt" do
392
+ content callback_order.inspect
393
+ end
394
+ end
395
+ end
396
+ end
397
+
398
+ before do
399
+ callback_order.clear # callback_order variable is global for this context group
400
+ deploy_to_latest_with_inline_recipes.run_action(:deploy)
401
+ end
402
+
403
+ the_app_is_deployed_at_revision(:latest_rev)
404
+
405
+ it "is marked updated" do
406
+ deploy_to_latest_with_inline_recipes.should be_updated_by_last_action
407
+ end
408
+
409
+ it "calls the callbacks in order" do
410
+ callback_order.should == [:before_migrate, :before_symlink, :before_restart, :after_restart]
411
+ end
412
+
413
+ it "runs chef resources in the callbacks" do
414
+ File.should exist(rel_path("current/before_migrate.txt"))
415
+ File.should exist(rel_path("current/before_symlink.txt"))
416
+ File.should exist(rel_path("current/tmp/before_restart.txt"))
417
+ File.should exist(rel_path("current/tmp/after_restart.txt"))
418
+ end
419
+ end
420
+
421
+ context "when deploying an app with in-repo callback scripts" do
422
+ let(:deploy_with_in_repo_callbacks) do
423
+ basic_deploy_resource.dup.tap do |r|
424
+ r.repo git_bundle_with_in_repo_callbacks
425
+ r.revision rev_with_in_repo_callbacks
426
+ end
427
+ end
428
+
429
+ before do
430
+ deploy_with_in_repo_callbacks.run_action(:deploy)
431
+ end
432
+
433
+ the_app_is_deployed_at_revision(:rev_with_in_repo_callbacks)
434
+
435
+ it "runs chef resources in the callbacks" do
436
+ File.should exist(rel_path("current/before_migrate.txt"))
437
+ File.should exist(rel_path("current/before_symlink.txt"))
438
+ File.should exist(rel_path("current/tmp/before_restart.txt"))
439
+ File.should exist(rel_path("current/tmp/after_restart.txt"))
440
+ end
441
+
442
+ end
443
+
444
+ context "when deploying an app with migrations" do
445
+ let(:deploy_with_migration) do
446
+ basic_deploy_resource.dup.tap do |r|
447
+
448
+ # Need this so we can call methods from this test inside the inline
449
+ # recipe callbacks
450
+ spec_context = self
451
+
452
+ r.revision latest_rev
453
+
454
+ # enable migrations
455
+ r.migrate true
456
+ # abuse `shell_restart_command` so we can observe order of when the
457
+ # miration command gets run
458
+ r.migration_command shell_restart_command("migration")
459
+ r.before_migrate do
460
+
461
+ # inline recipe callbacks don't cwd, so you have to get the release
462
+ # directory as a local and "capture" it in the closure.
463
+ current_release = release_path
464
+ execute spec_context.shell_restart_command("before_migrate") do
465
+ cwd current_release
466
+ end
467
+ end
468
+ r.before_symlink do
469
+ current_release = release_path
470
+ execute spec_context.shell_restart_command("before_symlink") do
471
+ cwd current_release
472
+ end
473
+ end
474
+
475
+ r.before_restart do
476
+ current_release = release_path
477
+ execute spec_context.shell_restart_command("before_restart") do
478
+ cwd current_release
479
+ end
480
+ end
481
+
482
+ r.after_restart do
483
+ current_release = release_path
484
+ execute spec_context.shell_restart_command("after_restart") do
485
+ cwd current_release
486
+ end
487
+ end
488
+
489
+ end
490
+ end
491
+
492
+ before do
493
+ deploy_with_migration.run_action(:deploy)
494
+ end
495
+
496
+ it "runs migrations in between the before_migrate and before_symlink steps" do
497
+ actual_operations_order.should == %w[before_migrate migration before_symlink before_restart after_restart]
498
+ end
499
+ end
500
+
501
+ context "when deploying an app with in-repo symlinks" do
502
+ let(:deploy_with_in_repo_symlinks) do
503
+ basic_deploy_resource.dup.tap do |r|
504
+ r.repo git_bundle_with_in_repo_symlinks
505
+ r.revision rev_with_in_repo_symlinks
506
+ end
507
+ end
508
+
509
+ it "should not raise an exception calling File.utime on symlinks" do
510
+ lambda { deploy_with_in_repo_symlinks.run_action(:deploy) }.should_not raise_error
511
+ end
512
+ end
513
+ end
514
+
515
+