summaryrefslogtreecommitdiff
path: root/spec/unit/provider/remote_directory_spec.rb
diff options
context:
space:
mode:
Diffstat (limited to 'spec/unit/provider/remote_directory_spec.rb')
-rw-r--r--spec/unit/provider/remote_directory_spec.rb204
1 files changed, 204 insertions, 0 deletions
diff --git a/spec/unit/provider/remote_directory_spec.rb b/spec/unit/provider/remote_directory_spec.rb
new file mode 100644
index 0000000000..19a17c269f
--- /dev/null
+++ b/spec/unit/provider/remote_directory_spec.rb
@@ -0,0 +1,204 @@
+#
+# Author:: Daniel DeLeo (<dan@kallistec.com>)
+# Copyright:: Copyright (c) 2010 Daniel DeLeo
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'spec_helper'
+require 'digest/md5'
+require 'tmpdir'
+require 'chef/mixin/file_class'
+
+class Chef::CFCCheck
+ include Chef::Mixin::FileClass
+end
+
+describe Chef::Provider::RemoteDirectory do
+ before do
+ Chef::FileAccessControl.any_instance.stub(:set_all)
+ #Terrible, but we need to implement a pseduo-filesystem for testing
+ #to not have this line. Only affects updating state fields.
+ Chef::Provider::CookbookFile.any_instance.stub(:update_new_file_state)
+
+ @resource = Chef::Resource::RemoteDirectory.new("/tmp/tafty")
+ # in CHEF_SPEC_DATA/cookbooks/openldap/files/default/remotedir
+ @resource.source "remotedir"
+ @resource.cookbook('openldap')
+
+ @cookbook_repo = ::File.expand_path(::File.join(CHEF_SPEC_DATA, "cookbooks"))
+ Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, @cookbook_repo) }
+
+ @node = Chef::Node.new
+ cl = Chef::CookbookLoader.new(@cookbook_repo)
+ cl.load_cookbooks
+ @cookbook_collection = Chef::CookbookCollection.new(cl)
+
+ @events = Chef::EventDispatch::Dispatcher.new
+ @run_context = Chef::RunContext.new(@node, @cookbook_collection, @events)
+
+ @provider = Chef::Provider::RemoteDirectory.new(@resource, @run_context)
+ @provider.current_resource = @resource.clone
+ end
+
+ describe "when access control is configured on the resource" do
+ before do
+ @resource.mode "0750"
+ @resource.group "wheel"
+ @resource.owner "root"
+
+ @resource.files_mode "0640"
+ @resource.files_group "staff"
+ @resource.files_owner "toor"
+ @resource.files_backup 23
+
+ @resource.source "remotedir_root"
+ end
+
+ it "configures access control on intermediate directorys" do
+ directory_resource = @provider.send(:resource_for_directory, "/tmp/intermediate_dir")
+ directory_resource.path.should == "/tmp/intermediate_dir"
+ directory_resource.mode.should == "0750"
+ directory_resource.group.should == "wheel"
+ directory_resource.owner.should == "root"
+ directory_resource.recursive.should be_true
+ end
+
+ it "configures access control on files in the directory" do
+ @resource.cookbook "berlin_style_tasty_cupcakes"
+ cookbook_file = @provider.send(:cookbook_file_resource,
+ "/target/destination/path.txt",
+ "relative/source/path.txt")
+ cookbook_file.cookbook_name.should == "berlin_style_tasty_cupcakes"
+ cookbook_file.source.should == "remotedir_root/relative/source/path.txt"
+ cookbook_file.mode.should == "0640"
+ cookbook_file.group.should == "staff"
+ cookbook_file.owner.should == "toor"
+ cookbook_file.backup.should == 23
+ end
+ end
+
+ describe "when creating the remote directory" do
+ before do
+ @node.automatic_attrs[:platform] = :just_testing
+ @node.automatic_attrs[:platform_version] = :just_testing
+
+ @destination_dir = Dir.mktmpdir << "/remote_directory_test"
+ @resource.path(@destination_dir)
+ end
+
+ after {FileUtils.rm_rf(@destination_dir)}
+
+ it "transfers the directory with all contents" do
+ @provider.run_action(:create)
+ ::File.exist?(@destination_dir + '/remote_dir_file1.txt').should be_true
+ ::File.exist?(@destination_dir + '/remote_dir_file2.txt').should be_true
+ ::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file1.txt').should be_true
+ ::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file2.txt').should be_true
+ ::File.exist?(@destination_dir + '/remotesubdir/.a_dotfile').should be_true
+ ::File.exist?(@destination_dir + '/.a_dotdir/.a_dotfile_in_a_dotdir').should be_true
+ end
+
+ describe "only if it is missing" do
+ it "should not overwrite existing files" do
+ @resource.overwrite(true)
+ @provider.run_action(:create)
+
+ File.open(@destination_dir + '/remote_dir_file1.txt', 'a') {|f| f.puts "blah blah blah" }
+ File.open(@destination_dir + '/remotesubdir/remote_subdir_file1.txt', 'a') {|f| f.puts "blah blah blah" }
+ file1md5 = Digest::MD5.hexdigest(File.read(@destination_dir + '/remote_dir_file1.txt'))
+ subdirfile1md5 = Digest::MD5.hexdigest(File.read(@destination_dir + '/remotesubdir/remote_subdir_file1.txt'))
+
+ @provider.run_action(:create_if_missing)
+
+ file1md5.eql?(Digest::MD5.hexdigest(File.read(@destination_dir + '/remote_dir_file1.txt'))).should be_true
+ subdirfile1md5.eql?(Digest::MD5.hexdigest(File.read(@destination_dir + '/remotesubdir/remote_subdir_file1.txt'))).should be_true
+ end
+ end
+
+ describe "with purging enabled" do
+ before {@resource.purge(true)}
+
+ it "removes existing files if purge is true" do
+ @provider.run_action(:create)
+ FileUtils.touch(@destination_dir + '/marked_for_death.txt')
+ FileUtils.touch(@destination_dir + '/remotesubdir/marked_for_death_again.txt')
+ @provider.run_action(:create)
+
+ ::File.exist?(@destination_dir + '/remote_dir_file1.txt').should be_true
+ ::File.exist?(@destination_dir + '/remote_dir_file2.txt').should be_true
+ ::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file1.txt').should be_true
+ ::File.exist?(@destination_dir + '/remotesubdir/remote_subdir_file2.txt').should be_true
+
+ ::File.exist?(@destination_dir + '/marked_for_death.txt').should be_false
+ ::File.exist?(@destination_dir + '/remotesubdir/marked_for_death_again.txt').should be_false
+ end
+
+ it "removes files in subdirectories before files above" do
+ @provider.run_action(:create)
+ FileUtils.mkdir_p(@destination_dir + '/a/multiply/nested/directory/')
+ FileUtils.touch(@destination_dir + '/a/foo.txt')
+ FileUtils.touch(@destination_dir + '/a/multiply/bar.txt')
+ FileUtils.touch(@destination_dir + '/a/multiply/nested/baz.txt')
+ FileUtils.touch(@destination_dir + '/a/multiply/nested/directory/qux.txt')
+ @provider.run_action(:create)
+ ::File.exist?(@destination_dir + '/a/foo.txt').should be_false
+ ::File.exist?(@destination_dir + '/a/multiply/bar.txt').should be_false
+ ::File.exist?(@destination_dir + '/a/multiply/nested/baz.txt').should be_false
+ ::File.exist?(@destination_dir + '/a/multiply/nested/directory/qux.txt').should be_false
+ end
+
+ it "removes directory symlinks properly" do
+ symlinked_dir_path = @destination_dir + '/symlinked_dir'
+ @provider.action = :create
+ @provider.run_action
+
+ @fclass = Chef::CFCCheck.new
+
+ Dir.mktmpdir do |tmp_dir|
+ begin
+ @fclass.file_class.symlink(tmp_dir.dup, symlinked_dir_path)
+ ::File.exist?(symlinked_dir_path).should be_true
+
+ @provider.run_action
+
+ ::File.exist?(symlinked_dir_path).should be_false
+ ::File.exist?(tmp_dir).should be_true
+ rescue Chef::Exceptions::Win32APIError => e
+ pending "This must be run as an Administrator to create symlinks"
+ end
+ end
+ end
+ end
+
+ describe "with overwrite disabled" do
+ before {@resource.purge(false)}
+ before {@resource.overwrite(false)}
+
+ it "leaves modifications alone" do
+ @provider.run_action(:create)
+ ::File.open(@destination_dir + '/remote_dir_file1.txt', 'a') {|f| f.puts "blah blah blah" }
+ ::File.open(@destination_dir + '/remotesubdir/remote_subdir_file1.txt', 'a') {|f| f.puts "blah blah blah" }
+ file1md5 = Digest::MD5.hexdigest(::File.read(@destination_dir + '/remote_dir_file1.txt'))
+ subdirfile1md5 = Digest::MD5.hexdigest(::File.read(@destination_dir + '/remotesubdir/remote_subdir_file1.txt'))
+ @provider.stub!(:update_new_file_state)
+ @provider.run_action(:create)
+ file1md5.eql?(Digest::MD5.hexdigest(::File.read(@destination_dir + '/remote_dir_file1.txt'))).should be_true
+ subdirfile1md5.eql?(Digest::MD5.hexdigest(::File.read(@destination_dir + '/remotesubdir/remote_subdir_file1.txt'))).should be_true
+ end
+ end
+
+ end
+end
+