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.
- data/CONTRIBUTING.md +155 -0
- data/README.md +89 -0
- data/Rakefile +2 -2
- data/bin/chef-apply +25 -0
- data/bin/chef-shell +34 -0
- data/bin/chef-solo +0 -2
- data/bin/shef +6 -5
- data/lib/chef.rb +2 -4
- data/spec/data/big_json.json +2 -1
- data/spec/data/big_json_plus_one.json +2 -1
- data/spec/data/cookbooks/chefignore +2 -0
- data/spec/data/cookbooks/openldap/attributes/default.rb +10 -9
- data/spec/data/cookbooks/openldap/attributes/smokey.rb +1 -1
- data/spec/data/git_bundles/sinatra-test-app-with-callback-files.gitbundle +0 -0
- data/spec/data/git_bundles/sinatra-test-app-with-symlinks.gitbundle +0 -0
- data/spec/data/git_bundles/sinatra-test-app.gitbundle +0 -0
- data/spec/data/lwrp/providers/inline_compiler.rb +26 -0
- data/spec/data/nodes/default.rb +3 -3
- data/spec/data/nodes/test.example.com.rb +3 -3
- data/spec/data/nodes/test.rb +3 -3
- data/spec/data/partial_one.erb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep1/attributes/default.rb +4 -0
- data/spec/data/run_context/cookbooks/circular-dep1/definitions/circular_dep1_res.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep1/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep1/metadata.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep1/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep1/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/circular-dep1/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep2/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/circular-dep2/definitions/circular_dep2_res.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep2/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep2/metadata.rb +2 -0
- data/spec/data/run_context/cookbooks/circular-dep2/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/circular-dep2/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/circular-dep2/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency1/attributes/aa_first.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency1/attributes/default.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency1/attributes/zz_last.rb +3 -0
- data/spec/data/run_context/cookbooks/dependency1/definitions/dependency1_res.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency1/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency1/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency1/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/dependency1/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency2/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/dependency2/definitions/dependency2_res.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency2/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/dependency2/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/dependency2/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/dependency2/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/no-default-attr/attributes/server.rb +3 -0
- data/spec/data/run_context/cookbooks/no-default-attr/definitions/no_default-attr_res.rb +1 -0
- data/spec/data/run_context/cookbooks/no-default-attr/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/no-default-attr/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/no-default-attr/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/definitions/test_with-circular-deps_res.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/libraries/lib.rb +2 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/metadata.rb +2 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/test-with-circular-deps/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/attributes/default.rb +3 -0
- data/spec/data/run_context/cookbooks/test-with-deps/definitions/test_with-deps_res.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/libraries/lib.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/metadata.rb +3 -0
- data/spec/data/run_context/cookbooks/test-with-deps/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/test-with-deps/recipes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/test-with-deps/recipes/server.rb +0 -0
- data/spec/data/run_context/cookbooks/test-with-deps/resources/resource.rb +1 -0
- data/spec/data/run_context/cookbooks/test/attributes/default.rb +0 -0
- data/spec/data/run_context/cookbooks/test/attributes/george.rb +1 -1
- data/spec/data/run_context/cookbooks/test/definitions/test_res.rb +1 -0
- data/spec/data/run_context/cookbooks/test/providers/provider.rb +1 -0
- data/spec/data/run_context/cookbooks/test/resources/resource.rb +1 -0
- data/spec/data/shef-config.rb +10 -0
- data/spec/functional/dsl/registry_helper_spec.rb +63 -0
- data/spec/functional/knife/cookbook_delete_spec.rb +0 -2
- data/spec/functional/knife/exec_spec.rb +4 -6
- data/spec/functional/knife/smoke_test.rb +34 -0
- data/spec/functional/knife/ssh_spec.rb +64 -3
- data/spec/functional/resource/cookbook_file_spec.rb +33 -2
- data/spec/functional/resource/deploy_revision_spec.rb +515 -0
- data/spec/functional/resource/directory_spec.rb +4 -0
- data/spec/functional/resource/file_spec.rb +56 -22
- data/spec/functional/resource/link_spec.rb +12 -10
- data/spec/functional/resource/registry_spec.rb +572 -0
- data/spec/functional/resource/remote_directory_spec.rb +142 -36
- data/spec/functional/resource/remote_file_spec.rb +28 -3
- data/spec/functional/resource/template_spec.rb +23 -2
- data/spec/functional/run_lock_spec.rb +238 -0
- data/spec/functional/shell_spec.rb +101 -0
- data/spec/functional/tiny_server_spec.rb +5 -4
- data/spec/functional/win32/registry_helper_spec.rb +632 -0
- data/spec/functional/win32/security_spec.rb +37 -0
- data/spec/spec_helper.rb +15 -3
- data/spec/stress/win32/security_spec.rb +5 -5
- data/spec/support/chef_helpers.rb +14 -3
- data/spec/support/lib/chef/resource/cat.rb +3 -5
- data/spec/support/lib/chef/resource/one_two_three_four.rb +8 -10
- data/spec/support/lib/chef/resource/zen_master.rb +8 -10
- data/spec/support/matchers/leak.rb +1 -1
- data/spec/support/platform_helpers.rb +18 -0
- data/spec/support/shared/functional/directory_resource.rb +85 -23
- data/spec/support/shared/functional/file_resource.rb +198 -53
- data/spec/support/shared/functional/securable_resource.rb +140 -105
- data/spec/support/shared/functional/securable_resource_with_reporting.rb +375 -0
- data/spec/support/shared/unit/file_system_support.rb +110 -0
- data/spec/support/shared/unit/platform_introspector.rb +162 -0
- data/spec/tiny_server.rb +29 -10
- data/spec/unit/api_client/registration_spec.rb +172 -0
- data/spec/unit/api_client_spec.rb +156 -103
- data/spec/unit/application/apply.rb +84 -0
- data/spec/unit/application/knife_spec.rb +5 -0
- data/spec/unit/application_spec.rb +57 -2
- data/spec/unit/chef_fs/diff_spec.rb +329 -0
- data/spec/unit/chef_fs/file_pattern_spec.rb +526 -0
- data/spec/unit/chef_fs/file_system/chef_server_root_dir_spec.rb +237 -0
- data/spec/unit/chef_fs/file_system/cookbooks_dir_spec.rb +568 -0
- data/spec/unit/chef_fs/file_system/data_bags_dir_spec.rb +220 -0
- data/spec/unit/chef_fs/file_system_spec.rb +136 -0
- data/spec/unit/client_spec.rb +188 -16
- data/spec/unit/config_spec.rb +54 -4
- data/spec/unit/cookbook/chefignore_spec.rb +2 -1
- data/spec/unit/cookbook/syntax_check_spec.rb +48 -109
- data/spec/unit/cookbook_loader_spec.rb +153 -91
- data/spec/unit/cookbook_manifest_spec.rb +81 -81
- data/spec/unit/cookbook_spec.rb +3 -20
- data/spec/unit/cookbook_version_spec.rb +23 -122
- data/spec/unit/digester_spec.rb +50 -0
- data/spec/unit/dsl/data_query_spec.rb +66 -0
- data/spec/unit/dsl/platform_introspection_spec.rb +130 -0
- data/spec/unit/dsl/regsitry_helper_spec.rb +55 -0
- data/spec/unit/encrypted_data_bag_item_spec.rb +126 -10
- data/spec/unit/environment_spec.rb +0 -130
- data/spec/unit/exceptions_spec.rb +2 -3
- data/spec/unit/formatters/error_inspectors/resource_failure_inspector_spec.rb +23 -3
- data/spec/unit/json_compat_spec.rb +69 -0
- data/spec/unit/knife/bootstrap_spec.rb +81 -28
- data/spec/unit/knife/client_reregister_spec.rb +23 -22
- data/spec/unit/knife/configure_spec.rb +29 -26
- data/spec/unit/knife/cookbook_metadata_spec.rb +11 -4
- data/spec/unit/knife/cookbook_site_install_spec.rb +12 -2
- data/spec/unit/knife/cookbook_test_spec.rb +1 -0
- data/spec/unit/knife/cookbook_upload_spec.rb +41 -2
- data/spec/unit/knife/core/bootstrap_context_spec.rb +8 -1
- data/spec/unit/knife/core/ui_spec.rb +156 -7
- data/spec/unit/knife/data_bag_create_spec.rb +14 -0
- data/spec/unit/knife/data_bag_edit_spec.rb +14 -4
- data/spec/unit/knife/data_bag_from_file_spec.rb +17 -5
- data/spec/unit/knife/data_bag_show_spec.rb +11 -4
- data/spec/unit/knife/index_rebuild_spec.rb +96 -33
- data/spec/unit/knife/knife_help.rb +7 -7
- data/spec/unit/knife/node_run_list_remove_spec.rb +2 -1
- data/spec/unit/knife/ssh_spec.rb +121 -15
- data/spec/unit/knife/status_spec.rb +2 -2
- data/spec/unit/knife/user_create_spec.rb +86 -0
- data/spec/unit/knife/user_delete_spec.rb +39 -0
- data/spec/unit/knife/user_edit_spec.rb +42 -0
- data/spec/unit/knife/user_list_spec.rb +32 -0
- data/spec/unit/knife/user_reregister_spec.rb +53 -0
- data/spec/unit/knife/user_show_spec.rb +41 -0
- data/spec/unit/knife_spec.rb +53 -0
- data/spec/unit/lwrp_spec.rb +59 -17
- data/spec/unit/mixin/checksum_spec.rb +2 -2
- data/spec/unit/mixin/deep_merge_spec.rb +56 -491
- data/spec/unit/mixin/deprecation_spec.rb +23 -0
- data/spec/unit/mixin/enforce_ownership_and_permissions_spec.rb +6 -1
- data/spec/unit/mixin/params_validate_spec.rb +4 -2
- data/spec/unit/mixin/securable_spec.rb +5 -3
- data/spec/unit/mixin/template_spec.rb +119 -0
- data/spec/unit/node/attribute_spec.rb +272 -137
- data/spec/unit/node/immutable_collections_spec.rb +139 -0
- data/spec/unit/node_spec.rb +411 -339
- data/spec/unit/platform_spec.rb +8 -8
- data/spec/unit/provider/breakpoint_spec.rb +8 -8
- data/spec/unit/provider/cookbook_file_spec.rb +4 -8
- data/spec/unit/provider/deploy/revision_spec.rb +2 -8
- data/spec/unit/provider/deploy_spec.rb +6 -40
- data/spec/unit/provider/directory_spec.rb +103 -68
- data/spec/unit/provider/erl_call_spec.rb +0 -2
- data/spec/unit/provider/file_spec.rb +69 -59
- data/spec/unit/provider/git_spec.rb +0 -10
- data/spec/unit/provider/group/groupadd_spec.rb +1 -1
- data/spec/unit/provider/group/usermod_spec.rb +2 -2
- data/spec/unit/provider/http_request_spec.rb +28 -69
- data/spec/unit/provider/ifconfig_spec.rb +2 -2
- data/spec/unit/provider/link_spec.rb +1 -1
- data/spec/unit/provider/ohai_spec.rb +4 -4
- data/spec/unit/provider/package/apt_spec.rb +0 -1
- data/spec/unit/provider/package/ips_spec.rb +0 -1
- data/spec/unit/provider/package/rubygems_spec.rb +0 -18
- data/spec/unit/provider/package/yum_spec.rb +79 -15
- data/spec/unit/provider/package_spec.rb +7 -5
- data/spec/unit/provider/registry_key_spec.rb +269 -0
- data/spec/unit/provider/remote_directory_spec.rb +24 -7
- data/spec/unit/provider/remote_file_spec.rb +36 -0
- data/spec/unit/provider/route_spec.rb +3 -6
- data/spec/unit/provider/ruby_block_spec.rb +8 -0
- data/spec/unit/provider/service/arch_service_spec.rb +4 -4
- data/spec/unit/provider/service/debian_service_spec.rb +1 -1
- data/spec/unit/provider/service/freebsd_service_spec.rb +4 -4
- data/spec/unit/provider/service/init_service_spec.rb +26 -3
- data/spec/unit/provider/service/insserv_service_spec.rb +1 -1
- data/spec/unit/provider/service/invokercd_service_spec.rb +3 -3
- data/spec/unit/provider/service/redhat_spec.rb +1 -1
- data/spec/unit/provider/service/simple_service_spec.rb +3 -3
- data/spec/unit/provider/service/upstart_service_spec.rb +7 -7
- data/spec/unit/provider/service_spec.rb +2 -2
- data/spec/unit/provider/subversion_spec.rb +1 -1
- data/spec/unit/provider/template_spec.rb +35 -11
- data/spec/unit/provider/user/dscl_spec.rb +57 -31
- data/spec/unit/provider/user_spec.rb +7 -16
- data/spec/unit/provider_spec.rb +4 -3
- data/spec/unit/recipe_spec.rb +10 -8
- data/spec/unit/registry_helper_spec.rb +376 -0
- data/spec/unit/resource/log_spec.rb +9 -0
- data/spec/unit/resource/registry_key_spec.rb +171 -0
- data/spec/unit/resource/remote_file_spec.rb +21 -23
- data/spec/unit/resource/ruby_block_spec.rb +7 -3
- data/spec/unit/resource/service_spec.rb +11 -0
- data/spec/unit/resource_spec.rb +27 -4
- data/spec/unit/rest/auth_credentials_spec.rb +2 -14
- data/spec/unit/rest_spec.rb +122 -187
- data/spec/unit/run_context/cookbook_compiler_spec.rb +181 -0
- data/spec/unit/run_context_spec.rb +18 -4
- data/spec/unit/run_list_spec.rb +0 -209
- data/spec/unit/run_lock_spec.rb +37 -0
- data/spec/unit/runner_spec.rb +101 -2
- data/spec/unit/scan_access_control_spec.rb +4 -4
- data/spec/unit/{shef → shell}/model_wrapper_spec.rb +5 -5
- data/spec/unit/{shef/shef_ext_spec.rb → shell/shell_ext_spec.rb} +21 -21
- data/spec/unit/{shef/shef_session_spec.rb → shell/shell_session_spec.rb} +12 -12
- data/spec/unit/shell_out_spec.rb +18 -0
- data/spec/unit/{shef_spec.rb → shell_spec.rb} +20 -20
- data/spec/unit/user_spec.rb +255 -0
- metadata +162 -157
- data/README.rdoc +0 -177
- data/spec/unit/certificate_spec.rb +0 -76
- data/spec/unit/checksum_cache_spec.rb +0 -209
- data/spec/unit/checksum_spec.rb +0 -94
- data/spec/unit/couchdb_spec.rb +0 -274
- data/spec/unit/index_queue_spec.rb +0 -391
- data/spec/unit/json_compat_spect.rb +0 -53
- data/spec/unit/mixin/language_spec.rb +0 -305
- data/spec/unit/openid_registration_spec.rb +0 -153
- data/spec/unit/solr_query/query_transform_spec.rb +0 -454
- data/spec/unit/solr_query/solr_http_request_spec.rb +0 -244
- data/spec/unit/solr_query_spec.rb +0 -203
- data/spec/unit/webui_user_spec.rb +0 -238
@@ -22,12 +22,15 @@ describe Chef::Resource::RemoteDirectory do
|
|
22
22
|
include_context Chef::Resource::Directory
|
23
23
|
|
24
24
|
let(:directory_base) { "directory_spec" }
|
25
|
+
let(:default_mode) { "755" }
|
25
26
|
|
26
27
|
def create_resource
|
27
28
|
cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks"))
|
28
29
|
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, cookbook_repo) }
|
29
30
|
node = Chef::Node.new
|
30
|
-
|
31
|
+
cl = Chef::CookbookLoader.new(cookbook_repo)
|
32
|
+
cl.load_cookbooks
|
33
|
+
cookbook_collection = Chef::CookbookCollection.new(cl)
|
31
34
|
events = Chef::EventDispatch::Dispatcher.new
|
32
35
|
run_context = Chef::RunContext.new(node, cookbook_collection, events)
|
33
36
|
|
@@ -37,57 +40,90 @@ describe Chef::Resource::RemoteDirectory do
|
|
37
40
|
resource
|
38
41
|
end
|
39
42
|
|
43
|
+
def create_extraneous_files
|
44
|
+
FileUtils.mkdir_p(File.join(path, 'remotesubdir'))
|
45
|
+
@existing1 = File.join(path, 'marked_for_death.txt')
|
46
|
+
@existing2 = File.join(path, 'remotesubdir', 'marked_for_death_again.txt')
|
47
|
+
FileUtils.touch(@existing1)
|
48
|
+
FileUtils.touch(@existing2)
|
49
|
+
end
|
50
|
+
|
40
51
|
let!(:resource) do
|
41
52
|
create_resource
|
42
53
|
end
|
43
54
|
|
55
|
+
let(:resource_second_pass) do
|
56
|
+
create_resource
|
57
|
+
end
|
58
|
+
|
59
|
+
# See spec/data/cookbooks/openldap/files/default
|
60
|
+
let(:expected_files) do
|
61
|
+
[
|
62
|
+
File.join(path, 'remote_dir_file1.txt'),
|
63
|
+
File.join(path, 'remote_dir_file2.txt'),
|
64
|
+
File.join(path, 'remotesubdir', 'remote_subdir_file1.txt'),
|
65
|
+
File.join(path, 'remotesubdir', 'remote_subdir_file2.txt'),
|
66
|
+
File.join(path, 'remotesubdir', '.a_dotfile'),
|
67
|
+
File.join(path, '.a_dotdir', '.a_dotfile_in_a_dotdir')
|
68
|
+
]
|
69
|
+
end
|
70
|
+
|
44
71
|
it_behaves_like "a directory resource"
|
45
72
|
|
46
|
-
|
47
|
-
it "transfers the directory with all contents" do
|
48
|
-
resource.run_action(:create)
|
49
|
-
File.should exist(File.join(path, 'remote_dir_file1.txt'))
|
50
|
-
File.should exist(File.join(path, 'remote_dir_file2.txt'))
|
51
|
-
File.should exist(File.join(path, 'remotesubdir', 'remote_subdir_file1.txt'))
|
52
|
-
File.should exist(File.join(path, 'remotesubdir', 'remote_subdir_file2.txt'))
|
53
|
-
File.should exist(File.join(path, 'remotesubdir', '.a_dotfile'))
|
54
|
-
File.should exist(File.join(path, '.a_dotdir', '.a_dotfile_in_a_dotdir'))
|
55
|
-
end
|
73
|
+
it_behaves_like "a securable resource with reporting"
|
56
74
|
|
57
|
-
|
58
|
-
|
59
|
-
|
75
|
+
context "when creating the remote directory with purging disabled" do
|
76
|
+
|
77
|
+
context "and the directory does not yet exist" do
|
78
|
+
before do
|
79
|
+
resource.run_action(:create)
|
60
80
|
end
|
61
81
|
|
62
|
-
it "
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
82
|
+
it "transfers the directory with all contents" do
|
83
|
+
expected_files.each do |file_path|
|
84
|
+
File.should exist(file_path)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
it "is marked as updated by last action" do
|
89
|
+
resource.should be_updated_by_last_action
|
90
|
+
end
|
91
|
+
end
|
68
92
|
|
93
|
+
context "and there are extraneous files in the directory" do
|
94
|
+
before do
|
95
|
+
create_extraneous_files
|
69
96
|
resource.run_action(:create)
|
70
|
-
File.should_not exist(existing1)
|
71
|
-
File.should_not exist(existing2)
|
72
97
|
end
|
73
98
|
|
74
|
-
it "
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
existing4 = File.join(path, 'a', 'multiply', 'nested', 'directory', 'qux.txt')
|
80
|
-
FileUtils.touch(existing1)
|
81
|
-
FileUtils.touch(existing2)
|
82
|
-
FileUtils.touch(existing3)
|
83
|
-
FileUtils.touch(existing4)
|
99
|
+
it "does not modify the expected state of the directory" do
|
100
|
+
expected_files.each do |file_path|
|
101
|
+
File.should exist(file_path)
|
102
|
+
end
|
103
|
+
end
|
84
104
|
|
105
|
+
it "does not remove unmanaged files" do
|
106
|
+
File.should exist(@existing1)
|
107
|
+
File.should exist(@existing2)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
context "and the directory is in the desired state" do
|
112
|
+
before do
|
85
113
|
resource.run_action(:create)
|
86
|
-
|
87
|
-
File.should_not exist(existing2)
|
88
|
-
File.should_not exist(existing3)
|
89
|
-
File.should_not exist(existing4)
|
114
|
+
resource_second_pass.run_action(:create)
|
90
115
|
end
|
116
|
+
|
117
|
+
it "does not modify the expected state of the directory" do
|
118
|
+
expected_files.each do |file_path|
|
119
|
+
File.should exist(file_path)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
it "is not marked as updated by last action" do
|
124
|
+
resource_second_pass.should_not be_updated_by_last_action
|
125
|
+
end
|
126
|
+
|
91
127
|
end
|
92
128
|
|
93
129
|
describe "with overwrite disabled" do
|
@@ -111,4 +147,74 @@ describe Chef::Resource::RemoteDirectory do
|
|
111
147
|
end
|
112
148
|
end
|
113
149
|
end
|
150
|
+
|
151
|
+
context "when creating the directory with purging enabled" do
|
152
|
+
before(:each) do
|
153
|
+
resource.purge(true)
|
154
|
+
end
|
155
|
+
|
156
|
+
context "and there are no extraneous files in the directory" do
|
157
|
+
before do
|
158
|
+
resource.run_action(:create)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "creates the directory contents as normal" do
|
162
|
+
expected_files.each do |file_path|
|
163
|
+
File.should exist(file_path)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
context "and there are extraneous files in the directory" do
|
170
|
+
before do
|
171
|
+
create_extraneous_files
|
172
|
+
resource.run_action(:create)
|
173
|
+
end
|
174
|
+
|
175
|
+
it "removes unmanaged files" do
|
176
|
+
File.should_not exist(@existing1)
|
177
|
+
File.should_not exist(@existing2)
|
178
|
+
end
|
179
|
+
|
180
|
+
it "does not modify managed files" do
|
181
|
+
expected_files.each do |file_path|
|
182
|
+
File.should exist(file_path)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
it "is marked as updated by last action" do
|
187
|
+
resource.should be_updated_by_last_action
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "and there are deeply nested extraneous files in the directory" do
|
192
|
+
before do
|
193
|
+
FileUtils.mkdir_p(File.join(path, 'a', 'multiply', 'nested', 'directory'))
|
194
|
+
@existing1 = File.join(path, 'a', 'foo.txt')
|
195
|
+
@existing2 = File.join(path, 'a', 'multiply', 'bar.txt')
|
196
|
+
@existing3 = File.join(path, 'a', 'multiply', 'nested', 'baz.txt')
|
197
|
+
@existing4 = File.join(path, 'a', 'multiply', 'nested', 'directory', 'qux.txt')
|
198
|
+
FileUtils.touch(@existing1)
|
199
|
+
FileUtils.touch(@existing2)
|
200
|
+
FileUtils.touch(@existing3)
|
201
|
+
FileUtils.touch(@existing4)
|
202
|
+
|
203
|
+
resource.run_action(:create)
|
204
|
+
end
|
205
|
+
|
206
|
+
it "removes files in subdirectories before files above" do
|
207
|
+
File.should_not exist(@existing1)
|
208
|
+
File.should_not exist(@existing2)
|
209
|
+
File.should_not exist(@existing3)
|
210
|
+
File.should_not exist(@existing4)
|
211
|
+
end
|
212
|
+
|
213
|
+
it "is marked as updated by last action" do
|
214
|
+
resource.should be_updated_by_last_action
|
215
|
+
end
|
216
|
+
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
114
220
|
end
|
@@ -24,7 +24,13 @@ describe Chef::Resource::RemoteFile do
|
|
24
24
|
|
25
25
|
let(:file_base) { "remote_file_spec" }
|
26
26
|
let(:source) { 'http://localhost:9000/nyan_cat.png' }
|
27
|
-
let(:expected_content)
|
27
|
+
let(:expected_content) do
|
28
|
+
content = File.open(File.join(CHEF_SPEC_DATA, 'remote_file', 'nyan_cat.png'), "rb") do |f|
|
29
|
+
f.read
|
30
|
+
end
|
31
|
+
content.force_encoding(Encoding::BINARY) if content.respond_to?(:force_encoding)
|
32
|
+
content
|
33
|
+
end
|
28
34
|
|
29
35
|
def create_resource
|
30
36
|
node = Chef::Node.new
|
@@ -39,14 +45,31 @@ describe Chef::Resource::RemoteFile do
|
|
39
45
|
create_resource
|
40
46
|
end
|
41
47
|
|
48
|
+
let(:default_mode) do
|
49
|
+
# TODO: Lots of ugly here :(
|
50
|
+
# RemoteFile uses FileUtils.cp. FileUtils does a copy by opening the
|
51
|
+
# destination file and writing to it. Before 1.9.3, it does not preserve
|
52
|
+
# the mode of the copied file. In 1.9.3 and after, it does. So we have to
|
53
|
+
# figure out what the default mode ought to be via heuristic.
|
54
|
+
|
55
|
+
t = Tempfile.new("get-the-mode")
|
56
|
+
path = t.path
|
57
|
+
path_2 = t.path + "fileutils-mode-test"
|
58
|
+
FileUtils.cp(path, path_2)
|
59
|
+
t.close
|
60
|
+
m = File.stat(path_2).mode
|
61
|
+
(07777 & m).to_s(8)
|
62
|
+
end
|
63
|
+
|
42
64
|
before(:all) do
|
43
|
-
Thin::Logging.silent = false
|
44
65
|
@server = TinyServer::Manager.new
|
45
66
|
@server.start
|
46
67
|
@api = TinyServer::API.instance
|
47
68
|
@api.clear
|
48
69
|
@api.get("/nyan_cat.png", 200) {
|
49
|
-
|
70
|
+
File.open(File.join(CHEF_SPEC_DATA, 'remote_file', 'nyan_cat.png'), "rb") do |f|
|
71
|
+
f.read
|
72
|
+
end
|
50
73
|
}
|
51
74
|
end
|
52
75
|
|
@@ -55,4 +78,6 @@ describe Chef::Resource::RemoteFile do
|
|
55
78
|
end
|
56
79
|
|
57
80
|
it_behaves_like "a file resource"
|
81
|
+
|
82
|
+
it_behaves_like "a securable resource with reporting"
|
58
83
|
end
|
@@ -27,14 +27,16 @@ describe Chef::Resource::Template do
|
|
27
27
|
|
28
28
|
let(:node) do
|
29
29
|
node = Chef::Node.new
|
30
|
-
node[:slappiness] = "a warm gun"
|
30
|
+
node.normal[:slappiness] = "a warm gun"
|
31
31
|
node
|
32
32
|
end
|
33
33
|
|
34
34
|
def create_resource
|
35
35
|
cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks"))
|
36
36
|
Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, cookbook_repo) }
|
37
|
-
|
37
|
+
cl = Chef::CookbookLoader.new(cookbook_repo)
|
38
|
+
cl.load_cookbooks
|
39
|
+
cookbook_collection = Chef::CookbookCollection.new(cl)
|
38
40
|
events = Chef::EventDispatch::Dispatcher.new
|
39
41
|
run_context = Chef::RunContext.new(node, cookbook_collection, events)
|
40
42
|
resource = Chef::Resource::Template.new(path, run_context)
|
@@ -47,8 +49,27 @@ describe Chef::Resource::Template do
|
|
47
49
|
create_resource
|
48
50
|
end
|
49
51
|
|
52
|
+
let(:default_mode) do
|
53
|
+
# TODO: Lots of ugly here :(
|
54
|
+
# RemoteFile uses FileUtils.cp. FileUtils does a copy by opening the
|
55
|
+
# destination file and writing to it. Before 1.9.3, it does not preserve
|
56
|
+
# the mode of the copied file. In 1.9.3 and after, it does. So we have to
|
57
|
+
# figure out what the default mode ought to be via heuristic.
|
58
|
+
|
59
|
+
t = Tempfile.new("get-the-mode")
|
60
|
+
path = t.path
|
61
|
+
path_2 = t.path + "fileutils-mode-test"
|
62
|
+
FileUtils.cp(path, path_2)
|
63
|
+
t.close
|
64
|
+
m = File.stat(path_2).mode
|
65
|
+
(07777 & m).to_s(8)
|
66
|
+
end
|
67
|
+
|
68
|
+
|
50
69
|
it_behaves_like "a file resource"
|
51
70
|
|
71
|
+
it_behaves_like "a securable resource with reporting"
|
72
|
+
|
52
73
|
context "when the target file does not exist" do
|
53
74
|
it "creates the template with the rendered content using the variable attribute when the :create action is run" do
|
54
75
|
resource.source('openldap_variable_stuff.conf.erb')
|
@@ -0,0 +1,238 @@
|
|
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
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
19
|
+
require 'chef/client'
|
20
|
+
|
21
|
+
describe Chef::RunLock do
|
22
|
+
|
23
|
+
# This behavior is believed to work on windows, but the tests use UNIX APIs.
|
24
|
+
describe "when locking the chef-client run", :unix_only => true do
|
25
|
+
|
26
|
+
##
|
27
|
+
# Lockfile location and helpers
|
28
|
+
|
29
|
+
let(:random_temp_root) do
|
30
|
+
Kernel.srand(Time.now.to_i + Process.pid)
|
31
|
+
"/tmp/#{Kernel.rand(Time.now.to_i + Process.pid)}"
|
32
|
+
end
|
33
|
+
|
34
|
+
let(:file_cache_path){ "/var/chef/cache" }
|
35
|
+
let(:lockfile){ "#{random_temp_root}/this/long/path/does/not/exist/chef-client-running.pid" }
|
36
|
+
|
37
|
+
# make sure to start with a clean slate.
|
38
|
+
before(:each){ FileUtils.rm_r(random_temp_root) if File.exist?(random_temp_root) }
|
39
|
+
after(:each){ FileUtils.rm_r(random_temp_root) }
|
40
|
+
|
41
|
+
def wait_on_lock
|
42
|
+
tries = 0
|
43
|
+
until File.exist?(lockfile)
|
44
|
+
raise "Lockfile never created, abandoning test" if tries > 10
|
45
|
+
tries += 1
|
46
|
+
sleep 0.1
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Side channel via a pipe allows child processes to send errors to the parent
|
52
|
+
|
53
|
+
# Don't lazy create the pipe or else we might not share it with subprocesses
|
54
|
+
let!(:error_pipe) do
|
55
|
+
r,w = IO.pipe
|
56
|
+
w.sync = true
|
57
|
+
[r,w]
|
58
|
+
end
|
59
|
+
|
60
|
+
let(:error_read) { error_pipe[0] }
|
61
|
+
let(:error_write) { error_pipe[1] }
|
62
|
+
|
63
|
+
after do
|
64
|
+
error_read.close unless error_read.closed?
|
65
|
+
error_write.close unless error_write.closed?
|
66
|
+
end
|
67
|
+
|
68
|
+
# Send a RuntimeError from the child process to the parent process. Also
|
69
|
+
# prints error to $stdout, just in case something goes wrong with the error
|
70
|
+
# marshaling stuff.
|
71
|
+
def send_side_channel_error(message)
|
72
|
+
$stderr.puts(message)
|
73
|
+
$stderr.puts(caller)
|
74
|
+
e = RuntimeError.new(message)
|
75
|
+
error_write.print(Marshal.dump(e))
|
76
|
+
end
|
77
|
+
|
78
|
+
# Read the error (if any) from the error channel. If a marhaled error is
|
79
|
+
# present, it is unmarshaled and raised (which will fail the test)
|
80
|
+
def raise_side_channel_error!
|
81
|
+
error_write.close
|
82
|
+
err = error_read.read
|
83
|
+
error_read.close
|
84
|
+
begin
|
85
|
+
# ArgumentError from Marshal.load indicates no data, which we assume
|
86
|
+
# means no error in child process.
|
87
|
+
raise Marshal.load(err)
|
88
|
+
rescue ArgumentError
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
##
|
94
|
+
# Interprocess synchronization via a pipe. This allows us to control the
|
95
|
+
# state of the processes competing over the lock without relying on sleep.
|
96
|
+
|
97
|
+
let!(:sync_pipe) do
|
98
|
+
r,w = IO.pipe
|
99
|
+
w.sync = true
|
100
|
+
[r,w]
|
101
|
+
end
|
102
|
+
let(:sync_read) { sync_pipe[0] }
|
103
|
+
let(:sync_write) { sync_pipe[1] }
|
104
|
+
|
105
|
+
after do
|
106
|
+
sync_read.close unless sync_read.closed?
|
107
|
+
sync_write.close unless sync_write.closed?
|
108
|
+
end
|
109
|
+
|
110
|
+
# Wait on synchronization signal. If not received within the timeout, an
|
111
|
+
# error is sent via the error channel, and the process exits.
|
112
|
+
def sync_wait
|
113
|
+
if IO.select([sync_read], nil, nil, 20).nil?
|
114
|
+
# timeout reading from the sync pipe.
|
115
|
+
send_side_channel_error("Error syncing processes in run lock test (timeout)")
|
116
|
+
exit!(1)
|
117
|
+
else
|
118
|
+
sync_read.getc
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
# Sends a character in the sync pipe, which wakes ("unlocks") another
|
123
|
+
# process that is waiting on the sync signal
|
124
|
+
def sync_send
|
125
|
+
sync_write.putc("!")
|
126
|
+
sync_write.flush
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# IPC to record test results in a pipe. Tests can read pipe contents to
|
131
|
+
# check that operations occur in the expected order.
|
132
|
+
|
133
|
+
let!(:results_pipe) do
|
134
|
+
r,w = IO.pipe
|
135
|
+
w.sync = true
|
136
|
+
[r,w]
|
137
|
+
end
|
138
|
+
let(:results_read) { results_pipe[0] }
|
139
|
+
let(:results_write) { results_pipe[1] }
|
140
|
+
|
141
|
+
after do
|
142
|
+
results_read.close unless results_read.closed?
|
143
|
+
results_write.close unless results_write.closed?
|
144
|
+
end
|
145
|
+
|
146
|
+
# writes the message to the results pipe for later checking.
|
147
|
+
# note that nothing accounts for the pipe filling and waiting forever on a
|
148
|
+
# read or write call, so don't put too much data in.
|
149
|
+
def record(message)
|
150
|
+
results_write.puts(message)
|
151
|
+
results_write.flush
|
152
|
+
end
|
153
|
+
|
154
|
+
def results
|
155
|
+
results_write.flush
|
156
|
+
results_write.close
|
157
|
+
message = results_read.read
|
158
|
+
results_read.close
|
159
|
+
message
|
160
|
+
end
|
161
|
+
|
162
|
+
##
|
163
|
+
# Run lock is the system under test
|
164
|
+
let!(:run_lock) { Chef::RunLock.new(:file_cache_path => file_cache_path, :lockfile => lockfile) }
|
165
|
+
|
166
|
+
it "creates the full path to the lockfile" do
|
167
|
+
lambda { run_lock.acquire }.should_not raise_error(Errno::ENOENT)
|
168
|
+
File.should exist(lockfile)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "allows only one chef client run per lockfile" do
|
172
|
+
# First process, gets the lock and keeps it.
|
173
|
+
p1 = fork do
|
174
|
+
run_lock.acquire
|
175
|
+
record "p1 has lock"
|
176
|
+
# Wait until the other process is trying to get the lock:
|
177
|
+
sync_wait
|
178
|
+
# sleep a little bit to make process p2 wait on the lock
|
179
|
+
sleep 2
|
180
|
+
record "p1 releasing lock"
|
181
|
+
run_lock.release
|
182
|
+
exit!(0)
|
183
|
+
end
|
184
|
+
|
185
|
+
# Wait until p1 creates the lockfile
|
186
|
+
wait_on_lock
|
187
|
+
|
188
|
+
p2 = fork do
|
189
|
+
# inform process p1 that we're trying to get the lock
|
190
|
+
sync_send
|
191
|
+
run_lock.acquire
|
192
|
+
record "p2 has lock"
|
193
|
+
run_lock.release
|
194
|
+
exit!(0)
|
195
|
+
end
|
196
|
+
|
197
|
+
Process.waitpid2(p1)
|
198
|
+
Process.waitpid2(p2)
|
199
|
+
|
200
|
+
raise_side_channel_error!
|
201
|
+
|
202
|
+
expected=<<-E
|
203
|
+
p1 has lock
|
204
|
+
p1 releasing lock
|
205
|
+
p2 has lock
|
206
|
+
E
|
207
|
+
results.should == expected
|
208
|
+
end
|
209
|
+
|
210
|
+
it "clears the lock if the process dies unexpectedly" do
|
211
|
+
p1 = fork do
|
212
|
+
run_lock.acquire
|
213
|
+
record "p1 has lock"
|
214
|
+
sleep 60
|
215
|
+
record "p1 still has lock"
|
216
|
+
exit! 1
|
217
|
+
end
|
218
|
+
|
219
|
+
wait_on_lock
|
220
|
+
Process.kill(:KILL, p1)
|
221
|
+
Process.waitpid2(p1)
|
222
|
+
|
223
|
+
|
224
|
+
p2 = fork do
|
225
|
+
run_lock.acquire
|
226
|
+
record "p2 has lock"
|
227
|
+
run_lock.release
|
228
|
+
exit! 0
|
229
|
+
end
|
230
|
+
|
231
|
+
Process.waitpid2(p2)
|
232
|
+
|
233
|
+
results.should =~ /p2 has lock\Z/
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
|