diff options
author | Lamont Granquist <lamont@opscode.com> | 2013-03-22 16:01:08 -0700 |
---|---|---|
committer | Lamont Granquist <lamont@opscode.com> | 2013-03-22 16:01:08 -0700 |
commit | db72ae9f28a3eaf27c8e8af5815f7b030186ef07 (patch) | |
tree | 055e49530c404d70ac4b998999630797722ef0dc | |
parent | 675e0c7cca37a32189fd00cdf421363c7d0d2f46 (diff) | |
download | chef-db72ae9f28a3eaf27c8e8af5815f7b030186ef07.tar.gz |
more spec test work
-rw-r--r-- | lib/chef/provider/template/content.rb | 8 | ||||
-rw-r--r-- | spec/support/shared/unit/provider/file.rb | 32 | ||||
-rw-r--r-- | spec/unit/provider/cookbook_file/content_spec.rb | 40 | ||||
-rw-r--r-- | spec/unit/provider/cookbook_file_spec.rb | 156 | ||||
-rw-r--r-- | spec/unit/provider/directory_spec.rb | 6 | ||||
-rw-r--r-- | spec/unit/provider/template/content_spec.rb | 70 | ||||
-rw-r--r-- | spec/unit/provider/template_spec.rb | 202 |
7 files changed, 161 insertions, 353 deletions
diff --git a/lib/chef/provider/template/content.rb b/lib/chef/provider/template/content.rb index e03fca20bf..1d9b33fdb9 100644 --- a/lib/chef/provider/template/content.rb +++ b/lib/chef/provider/template/content.rb @@ -28,8 +28,8 @@ class Chef def template_location @template_file_cache_location ||= begin - template_finder.find(@new_resource.source, :local => @new_resource.local, :cookbook => @new_resource.cookbook) - end + template_finder.find(@new_resource.source, :local => @new_resource.local, :cookbook => @new_resource.cookbook) + end end private @@ -46,8 +46,8 @@ class Chef def template_finder @template_finder ||= begin - TemplateFinder.new(run_context, @new_resource.cookbook_name, @run_context.node) - end + TemplateFinder.new(run_context, @new_resource.cookbook_name, @run_context.node) + end end end end diff --git a/spec/support/shared/unit/provider/file.rb b/spec/support/shared/unit/provider/file.rb index ebb90d11ae..e86addbe3f 100644 --- a/spec/support/shared/unit/provider/file.rb +++ b/spec/support/shared/unit/provider/file.rb @@ -19,23 +19,6 @@ require 'spec_helper' require 'tmpdir' -shared_examples_for Chef::Provider::File do - # Mocksplosion - - let(:node) { double('Chef::Node') } - let(:events) { double('Chef::Events').as_null_object } # mock all the methods - let(:run_context) { double('Chef::RunContext', :node => node, :events => events) } - let(:enclosing_directory) { File.expand_path(File.join(CHEF_SPEC_DATA, "templates")) } - let(:resource_path) { File.expand_path(File.join(enclosing_directory, "seattle.txt")) } - - # Subject - - let(:provider) do - provider = described_class.new(resource, run_context) - provider.stub!(:content).and_return(content) - provider - end - # Filesystem stubs def setup_normal_file @@ -78,7 +61,20 @@ shared_examples_for Chef::Provider::File do File.stub!(:symlink?).with(resource_path).and_return(false) end - # Tests +shared_examples_for Chef::Provider::File do + let(:node) { double('Chef::Node') } + let(:events) { double('Chef::Events').as_null_object } # mock all the methods + let(:run_context) { double('Chef::RunContext', :node => node, :events => events) } + let(:enclosing_directory) { File.expand_path(File.join(CHEF_SPEC_DATA, "templates")) } + let(:resource_path) { File.expand_path(File.join(enclosing_directory, "seattle.txt")) } + + # Subject + + let(:provider) do + provider = described_class.new(resource, run_context) + provider.stub!(:content).and_return(content) + provider + end it "should return a #{described_class}" do provider.should be_a_kind_of(described_class) diff --git a/spec/unit/provider/cookbook_file/content_spec.rb b/spec/unit/provider/cookbook_file/content_spec.rb new file mode 100644 index 0000000000..b771b76aae --- /dev/null +++ b/spec/unit/provider/cookbook_file/content_spec.rb @@ -0,0 +1,40 @@ +# +# Author:: Lamont Granquist (<lamont@opscode.com>) +# Copyright:: Copyright (c) 2013 Opscode, Inc. +# 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' + +describe Chef::Provider::CookbookFile::Content do + + let(:new_resource) { mock('Chef::Resource::CookbookFile (new)', :cookbook_name => 'apache2', :cookbook => 'apache2') } + let(:content) do + @run_context = mock('Chef::RunContext') + @current_resource = mock('Chef::Resource::CookbookFile (current)') + Chef::Provider::CookbookFile::Content.new(new_resource, @current_resource, @run_context) + end + + it "prefers the explicit cookbook name on the resource to the implicit one" do + new_resource.stub!(:cookbook).and_return('nginx') + content.send(:resource_cookbook).should == 'nginx' + end + + it "falls back to the implicit cookbook name on the resource" do + content.send(:resource_cookbook).should == 'apache2' + end + +end + diff --git a/spec/unit/provider/cookbook_file_spec.rb b/spec/unit/provider/cookbook_file_spec.rb index 66fdd9871d..35025ee970 100644 --- a/spec/unit/provider/cookbook_file_spec.rb +++ b/spec/unit/provider/cookbook_file_spec.rb @@ -61,39 +61,22 @@ describe Chef::Provider::CookbookFile do # # end - it "prefers the explicit cookbook name on the resource to the implicit one" do - @new_resource.cookbook('nginx') - @provider.resource_cookbook.should == 'nginx' - end - - it "falls back to the implicit cookbook name on the resource" do - @provider.resource_cookbook.should == 'apache2' - end - - describe "when loading the current file state" do - - it "converts windows-y filenames to unix-y ones" do - @new_resource.path('windows\stuff') - @provider.load_current_resource - @new_resource.path.should == 'windows/stuff' - end - - it "sets the current resources path to the same as the new resource" do - @new_resource.path('/tmp/file') - @provider.load_current_resource - @provider.current_resource.path.should == '/tmp/file' - end - end - - describe "when the enclosing directory of the target file location doesn't exist" do - before do - @new_resource.path("/tmp/no/such/intermediate/path/file.txt") - end +# FIXME: move to Chef::Provider::File +# describe "when loading the current file state" do +# +# it "converts windows-y filenames to unix-y ones" do +# @new_resource.path('windows\stuff') +# @provider.load_current_resource +# @new_resource.path.should == 'windows/stuff' +# end +# +# it "sets the current resources path to the same as the new resource" do +# @new_resource.path('/tmp/file') +# @provider.load_current_resource +# @provider.current_resource.path.should == '/tmp/file' +# end +# end - it "raises a specific error alerting the user to the problem" do - lambda {@provider.run_action(:create)}.should raise_error(Chef::Exceptions::EnclosingDirectoryDoesNotExist) - end - end describe "when the file doesn't yet exist" do before do @install_to = Dir.tmpdir + '/apache2_modconf.pl' @@ -104,11 +87,6 @@ describe Chef::Provider::CookbookFile do after { ::File.exist?(File.dirname(@install_to)) && FileUtils.rm_rf(@install_to) } - it "loads the current file state" do - @provider.load_current_resource - @provider.current_resource.checksum.should be_nil - end - it "looks up a file from the cookbook cache" do expected = CHEF_SPEC_DATA + "/cookbooks/apache2/files/default/apache2_module_conf_generate.pl" @provider.file_cache_location.should == expected @@ -122,110 +100,6 @@ describe Chef::Provider::CookbookFile do actual = IO.read(@install_to) actual.should == @file_content end - - it "installs the file for create_if_missing --> from Provider::File" do - @new_resource.path(@install_to) - @provider.should_receive(:backup_new_resource) - @provider.stub!(:update_new_file_state) - @provider.run_action(:create_if_missing) - actual = IO.read(@install_to) - actual.should == @file_content - end - - it "marks the resource as updated by the last action --> being tested in the converge framework" do - @new_resource.path(@install_to) - @provider.stub!(:backup_new_resource) - @provider.stub!(:set_file_access_controls) - @provider.stub!(:update_new_file_state) - @provider.run_action(:create) - @new_resource.should be_updated - @new_resource.should be_updated_by_last_action - end - - end - - describe "when the file exists but has incorrect content" do - before do - @tempfile = Tempfile.open('cookbook_file_spec') - @new_resource.path(@target_file = @tempfile.path) - @tempfile.puts "the wrong content" - @tempfile.close - @current_resource = @new_resource.dup - @provider.current_resource = @current_resource - end - - it "stages the cookbook to a temporary file" do - # prevents file backups where we might not have write access - @provider.should_receive(:backup_new_resource) - @new_resource.path(@install_to) - @provider.should_receive(:deploy_tempfile) - @provider.run_action(:create) - end - - it "overwrites it when the create action is called" do - @provider.should_receive(:backup_new_resource) - @provider.run_action(:create) - actual = IO.read(@target_file) - actual.should == @file_content - end - - it "marks the resource as updated by the last action" do - @provider.should_receive(:backup_new_resource) - @provider.run_action(:create) - @new_resource.should be_updated - @new_resource.should be_updated_by_last_action - end - - it "doesn't overwrite when the create if missing action is called" do - @provider.should_not_receive(:set_file_access_controls) - @provider.run_action(:create_if_missing) - actual = IO.read(@target_file) - actual.should == "the wrong content\n" - end - - it "doesn't mark the resource as updated by the action for create_if_missing" do - @provider.run_action(:create_if_missing) - @new_resource.should_not be_updated - @new_resource.should_not be_updated_by_last_action - end - - after { @tempfile && @tempfile.close! } end - describe "when the file has the correct content" do - before do - Chef::FileAccessControl.any_instance.stub(:modified?).and_return(false) - @tempfile = Tempfile.open('cookbook_file_spec') - # CHEF-2991: We handle CRLF very poorly and we don't know what line endings - # our source file is going to have, so we use binary mode to preserve CRLF if needed. - source_file = CHEF_SPEC_DATA + "/cookbooks/apache2/files/default/apache2_module_conf_generate.pl" - @tempfile.binmode unless File.open(source_file, "rb") { |f| f.read =~ /\r/ } - @new_resource.path(@target_file = @tempfile.path) - @tempfile.write(@file_content) - @tempfile.close - @current_resource = @new_resource.dup - @provider.current_resource = @current_resource - end - - after { @tempfile && @tempfile.unlink} - - it "checks access control but does not alter content when action is create" do - @provider.should_receive(:set_all_access_controls) - @provider.should_not_receive(:stage_file_to_tmpdir) - @provider.run_action(:create) - end - - it "does not mark the resource as updated by the last action" do - @provider.run_action(:create) - @new_resource.should_not be_updated - @new_resource.should_not be_updated_by_last_action - end - - it "does not alter content or access control when action is create if missing" do - @provider.should_not_receive(:set_all_access_controls) - @provider.should_not_receive(:stage_file_to_tmpdir) - @provider.run_action(:create_if_missing) - end - - end end diff --git a/spec/unit/provider/directory_spec.rb b/spec/unit/provider/directory_spec.rb index 43c31f8cde..3936525903 100644 --- a/spec/unit/provider/directory_spec.rb +++ b/spec/unit/provider/directory_spec.rb @@ -96,10 +96,10 @@ describe Chef::Provider::Directory do @directory.new_resource.should be_updated end - it "should raise an exception if the parent directory does not exist and recursive is false" do + it "should raise an exception if the parent directory does not exist and recursive is false" do @new_resource.path "/tmp/some/dir" @new_resource.recursive false - lambda { @directory.run_action(:create) }.should raise_error(Chef::Exceptions::EnclosingDirectoryDoesNotExist) + lambda { @directory.run_action(:create) }.should raise_error(Chef::Exceptions::EnclosingDirectoryDoesNotExist) end # Unix only for now. While file security attribute reporting for windows is @@ -115,7 +115,7 @@ describe Chef::Provider::Directory do File.should_receive(:writable?).with('/path').ordered.and_return(true) File.should_receive(:exist?).with(@new_resource.path).ordered.and_return(false) - FileUtils.should_receive(:mkdir_p).with(@new_resource.path).and_return(true) + FileUtils.should_receive(:mkdir_p).with(@new_resource.path).and_return(true) @directory.should_receive(:set_all_access_controls) @directory.stub!(:update_new_file_state) @directory.run_action(:create) diff --git a/spec/unit/provider/template/content_spec.rb b/spec/unit/provider/template/content_spec.rb new file mode 100644 index 0000000000..946549238c --- /dev/null +++ b/spec/unit/provider/template/content_spec.rb @@ -0,0 +1,70 @@ +# +# Author:: Lamont Granquist (<lamont@opscode.com>) +# Copyright:: Copyright (c) 2013 Opscode, Inc. +# 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' + +describe Chef::Provider::Template::Content do + + let(:new_resource) do + mock("Chef::Resource::Template (new)", :cookbook_name => 'openldap', :source => 'openldap_stuff.conf.erb', :local => false, :cookbook => nil, :variables => {}) + end + + let(:rendered_file_location) { Dir.tmpdir + '/openldap_stuff.conf' } + + let(:run_context) do + cookbook_repo = File.expand_path(File.join(CHEF_SPEC_DATA, "cookbooks")) + Chef::Cookbook::FileVendor.on_create { |manifest| Chef::Cookbook::FileSystemFileVendor.new(manifest, cookbook_repo) } + cl = Chef::CookbookLoader.new(cookbook_repo) + cl.load_cookbooks + cookbook_collection = Chef::CookbookCollection.new(cl) + node = Chef::Node.new + mock("Chef::Resource::RunContext", :node => node, :cookbook_collection => cookbook_collection) + end + + let(:content) do + current_resource = mock("Chef::Resource::Template (current)") + Chef::Provider::Template::Content.new(new_resource, current_resource, run_context) + end + + after do + FileUtils.rm(rendered_file_location) if ::File.exist?(rendered_file_location) + end + + it "finds the template file in the cookbook cache if it isn't local" do + content.template_location.should == CHEF_SPEC_DATA + '/cookbooks/openldap/templates/default/openldap_stuff.conf.erb' + end + + it "finds the template file locally if it is local" do + new_resource.stub!(:local).and_return(true) + new_resource.stub!(:source).and_return('/tmp/its_on_disk.erb') + content.template_location.should == '/tmp/its_on_disk.erb' + end + + it "should use the cookbook name if defined in the template resource" do + new_resource.stub!(:cookbook_name).and_return('apache2') + new_resource.stub!(:cookbook).and_return('openldap') + new_resource.stub!(:source).and_return("test.erb") + content.template_location.should == CHEF_SPEC_DATA + '/cookbooks/openldap/templates/default/test.erb' + end + + it "creates the template with the rendered content" do + run_context.node.normal[:slappiness] = "a warm gun" + IO.read(content.tempfile.path).should == "slappiness is a warm gun" + end + +end diff --git a/spec/unit/provider/template_spec.rb b/spec/unit/provider/template_spec.rb index 321864b4d8..4d9b6183ac 100644 --- a/spec/unit/provider/template_spec.rb +++ b/spec/unit/provider/template_spec.rb @@ -40,199 +40,27 @@ describe Chef::Provider::Template do it_behaves_like Chef::Provider::File -# before(:each) do -# @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) -# -# @rendered_file_location = Dir.tmpdir + '/openldap_stuff.conf' -# -# @resource = Chef::Resource::Template.new(@rendered_file_location) -# @resource.cookbook_name = 'openldap' -# -# @provider = Chef::Provider::Template.new(@resource, @run_context) -# @current_resource = @resource.dup -# @provider.current_resource = @current_resource -# @access_controls = mock("access controls") -# @provider.stub!(:access_controls).and_return(@access_controls) -# passwd_struct = if windows? -# Struct::Passwd.new("root", "x", 0, 0, "/root", "/bin/bash") -# else -# Struct::Passwd.new("root", "x", 0, 0, "root", "/root", "/bin/bash") -# end -# group_struct = mock("Group Ent", :name => "root", :passwd => "x", :gid => 0) -# Etc.stub!(:getpwuid).and_return(passwd_struct) -# Etc.stub!(:getgrgid).and_return(group_struct) -# end - - describe "when creating the template" do - - before do - end + context "when creating the template" do - after do - FileUtils.rm(@rendered_file_location) if ::File.exist?(@rendered_file_location) - end + let(:node) { double('Chef::Node') } + let(:events) { double('Chef::Events').as_null_object } # mock all the methods + let(:run_context) { double('Chef::RunContext', :node => node, :events => events) } + let(:enclosing_directory) { File.expand_path(File.join(CHEF_SPEC_DATA, "templates")) } + let(:resource_path) { File.expand_path(File.join(enclosing_directory, "seattle.txt")) } - it "finds the template file in the coobook cache if it isn't local" do - @provider.template_location.should == CHEF_SPEC_DATA + '/cookbooks/openldap/templates/default/openldap_stuff.conf.erb' - end + # Subject - it "finds the template file locally if it is local" do - @resource.local(true) - @resource.source('/tmp/its_on_disk.erb') - @provider.template_location.should == '/tmp/its_on_disk.erb' + let(:provider) do + provider = described_class.new(resource, run_context) + provider.stub!(:content).and_return(content) + provider end it "stops executing when the local template source can't be found" do - @access_controls.stub!(:requires_changes?).and_return(false) - @resource.source "invalid.erb" - @resource.local true - lambda { @provider.run_action(:create) } .should raise_error Chef::Mixin::WhyRun::ResourceRequirements::Assertion::AssertionFailure - end - - it "should use the cookbook name if defined in the template resource" do - @resource.cookbook_name = 'apache2' - @resource.cookbook('openldap') - @resource.source "test.erb" - @provider.template_location.should == CHEF_SPEC_DATA + '/cookbooks/openldap/templates/default/test.erb' - end - - describe "when the target file does not exist" do - it "creates the template with the rendered content" do - @access_controls.stub!(:requires_changes?).and_return(true) - @access_controls.should_receive(:set_all!) - @node.normal[:slappiness] = "a warm gun" - @provider.should_receive(:backup) - @provider.run_action(:create) - IO.read(@rendered_file_location).should == "slappiness is a warm gun" - @resource.should be_updated_by_last_action - end - - it "should set the file access control as specified in the resource" do - @access_controls.stub!(:requires_changes?).and_return(false) - @access_controls.should_receive(:set_all!) - @resource.owner("adam") - @resource.group("wheel") - @resource.mode(00644) - @provider.run_action(:create) - @resource.should be_updated_by_last_action - end - - it "creates the template with the rendered content for the create if missing action" do - @access_controls.stub!(:requires_changes?).and_return(true) - @access_controls.should_receive(:set_all!) - @node.normal[:slappiness] = "happiness" - @provider.should_receive(:backup) - @provider.run_action(:create_if_missing) - IO.read(@rendered_file_location).should == "slappiness is happiness" - @resource.should be_updated_by_last_action - end - - context "and no access control settings are set on the resource" do - context "on a Unix system" do - before do - Chef::Platform.stub!(:windows?).and_return(false) - end - - it "sets access control metadata on the new resource" do - @access_controls.stub!(:requires_changes?).and_return(false) - @access_controls.should_receive(:set_all!) - @node.normal[:slappiness] = "happiness" - @provider.should_receive(:backup) - @provider.run_action(:create) - IO.read(@rendered_file_location).should == "slappiness is happiness" - @resource.should be_updated_by_last_action - - # Veracity of actual data checked in functional tests - @resource.owner.should be_a_kind_of(String) - @resource.group.should be_a_kind_of(String) - @resource.mode.should be_a_kind_of(String) - end - end - end - end - - describe "when the target file has the wrong content" do - before do - File.open(@rendered_file_location, "w+") { |f| f.print "blargh" } - end - - it "overwrites the file with the updated content when the create action is run" do - @node.normal[:slappiness] = "a warm gun" - @access_controls.stub!(:requires_changes?).and_return(false) - @access_controls.should_receive(:set_all!) - @provider.should_receive(:backup) - @provider.run_action(:create) - IO.read(@rendered_file_location).should == "slappiness is a warm gun" - @resource.should be_updated_by_last_action - end - - it "should set the file access control as specified in the resource" do - @access_controls.stub!(:requires_changes?).and_return(true) - @access_controls.should_receive(:set_all!) - @resource.owner("adam") - @resource.group("wheel") - @resource.mode(00644) - @provider.should_receive(:backup) - @provider.run_action(:create) - @resource.should be_updated_by_last_action - end - - it "doesn't overwrite the file when the create if missing action is run" do - @access_controls.stub!(:requires_changes?).and_return(false) - @access_controls.should_not_receive(:set_all!) - @node.normal[:slappiness] = "a warm gun" - @provider.should_not_receive(:backup) - @provider.run_action(:create_if_missing) - IO.read(@rendered_file_location).should == "blargh" - @resource.should_not be_updated_by_last_action - end - end - - describe "when the target has the correct content" do - before do - File.open(@rendered_file_location, "w") { |f| f.print "slappiness is a warm gun" } - @current_resource.checksum('4ff94a87794ed9aefe88e734df5a66fc8727a179e9496cbd88e3b5ec762a5ee9') - @access_controls = mock("access controls") - @provider.stub!(:access_controls).and_return(@access_controls) - end - - it "does not backup the original or overwrite it" do - @node.normal[:slappiness] = "a warm gun" - @access_controls.stub!(:requires_changes?).and_return(false) - @provider.should_not_receive(:backup) - FileUtils.should_not_receive(:mv) - @provider.run_action(:create) - @resource.should_not be_updated_by_last_action - end - - it "does not backup the original or overwrite it on create if missing" do - @node.normal[:slappiness] = "a warm gun" - @access_controls.stub!(:requires_changes?).and_return(false) - @provider.should_not_receive(:backup) - FileUtils.should_not_receive(:mv) - @provider.run_action(:create) - @resource.should_not be_updated_by_last_action - end - - it "sets the file access controls if they have diverged" do - @provider.stub!(:backup).and_return(true) - @access_controls.stub!(:requires_changes?).and_return(true) - @access_controls.should_receive(:set_all!) - @resource.owner("adam") - @resource.group("wheel") - @resource.mode(00644) - @provider.should_receive(:backup) - @provider.run_action(:create) - @resource.should be_updated_by_last_action - end + setup_normal_file + content.stub!(:template_location).and_return("/baz/bar/foo") + File.stub(:exists?).with("/baz/bar/foo").and_return(false) + lambda { provider.run_action(:create) }.should raise_error Chef::Mixin::WhyRun::ResourceRequirements::Assertion::AssertionFailure end end |