summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Robinson <matt@puppetlabs.com>2011-02-01 15:30:28 -0800
committerMatt Robinson <matt@puppetlabs.com>2011-02-01 15:30:28 -0800
commitfd73874147a1aaa3a047f904a0bc1ae67780a2e4 (patch)
tree3a987a1d31fedeb1efc04b19df63b0e85a299002
parentf135a6436084629d47c6b3b590dadb14952e4d69 (diff)
downloadpuppet-fd73874147a1aaa3a047f904a0bc1ae67780a2e4.tar.gz
puppet-fd73874147a1aaa3a047f904a0bc1ae67780a2e4.tar.xz
puppet-fd73874147a1aaa3a047f904a0bc1ae67780a2e4.zip
(#6107) Fix an error when auditing a file with empty content
The manifest: file { "/tmp/foo" : ensure => present, audit => content, } produced the error: err: /Stage[main]//File[/tmp/foo]/ensure: change from absent to present failed: Could not retrieve content for from filebucket: private method `sub' called for nil:NilClass at /Users/matthewrobinson/work/puppet/test.pp:4 This was due to logic in content assuming that if you didn't specify content while you were auditing it you must have specified a source. The code paths in the file type badly need a cleanup so that these sorts of errors aren't so difficult to track down and things are easier to test. Paired-with: Daniel Pittman
-rwxr-xr-xlib/puppet/type/file/content.rb2
-rwxr-xr-xspec/unit/type/file/content_spec.rb49
-rwxr-xr-xspec/unit/type/file_spec.rb12
3 files changed, 63 insertions, 0 deletions
diff --git a/lib/puppet/type/file/content.rb b/lib/puppet/type/file/content.rb
index 04b917a7e..cf924f371 100755
--- a/lib/puppet/type/file/content.rb
+++ b/lib/puppet/type/file/content.rb
@@ -167,6 +167,8 @@ module Puppet
def each_chunk_from(source_or_content)
if source_or_content.is_a?(String)
yield source_or_content
+ elsif source_or_content.nil? && resource.parameter(:ensure) && [:present, :file].include?(resource.parameter(:ensure).value)
+ yield ''
elsif source_or_content.nil?
yield read_file_from_filebucket
elsif self.class.standalone?
diff --git a/spec/unit/type/file/content_spec.rb b/spec/unit/type/file/content_spec.rb
index 3ec57f00e..9178c94bf 100755
--- a/spec/unit/type/file/content_spec.rb
+++ b/spec/unit/type/file/content_spec.rb
@@ -461,5 +461,54 @@ describe content do
describe "from a filebucket" do
end
+
+ # These are testing the implementation rather than the desired behaviour; while that bites, there are a whole
+ # pile of other methods in the File type that depend on intimate details of this implementation and vice-versa.
+ # If these blow up, you are gonna have to review the callers to make sure they don't explode! --daniel 2011-02-01
+ describe "each_chunk_from should work" do
+ before do
+ @content = content.new(:resource => @resource)
+ end
+
+ it "when content is a string" do
+ @content.each_chunk_from('i_am_a_string') { |chunk| chunk.should == 'i_am_a_string' }
+ end
+
+ it "when no content, source, but ensure present" do
+ @resource[:ensure] = :present
+ @content.each_chunk_from(nil) { |chunk| chunk.should == '' }
+ end
+
+ it "when no content, source, but ensure file" do
+ @resource[:ensure] = :file
+ @content.each_chunk_from(nil) { |chunk| chunk.should == '' }
+ end
+
+ it "when no content or source" do
+ @content.expects(:read_file_from_filebucket).once.returns('im_a_filebucket')
+ @content.each_chunk_from(nil) { |chunk| chunk.should == 'im_a_filebucket' }
+ end
+
+ it "when running as puppet apply" do
+ @content.class.expects(:standalone?).returns true
+ source_or_content = stubs('source_or_content')
+ source_or_content.expects(:content).once.returns :whoo
+ @content.each_chunk_from(source_or_content) { |chunk| chunk.should == :whoo }
+ end
+
+ it "when running from source with a local file" do
+ source_or_content = stubs('source_or_content')
+ source_or_content.expects(:local?).returns true
+ @content.expects(:chunk_file_from_disk).with(source_or_content).once.yields 'woot'
+ @content.each_chunk_from(source_or_content) { |chunk| chunk.should == 'woot' }
+ end
+
+ it "when running from source with a remote file" do
+ source_or_content = stubs('source_or_content')
+ source_or_content.expects(:local?).returns false
+ @content.expects(:chunk_file_from_source).with(source_or_content).once.yields 'woot'
+ @content.each_chunk_from(source_or_content) { |chunk| chunk.should == 'woot' }
+ end
+ end
end
end
diff --git a/spec/unit/type/file_spec.rb b/spec/unit/type/file_spec.rb
index db0fa9f34..d5cde5f9b 100755
--- a/spec/unit/type/file_spec.rb
+++ b/spec/unit/type/file_spec.rb
@@ -1095,5 +1095,17 @@ describe Puppet::Type.type(:file) do
transaction.report.resource_statuses["File[#{@path}]"].failed.should == false
File.exists?(@path).should == true
end
+
+ it "should not log errors if creating a new file with ensure present and no content" do
+ File.exists?(@path).should == false
+ file = Puppet::Type::File.new(:name => @path, :audit => "content", :ensure => "present")
+ catalog = Puppet::Resource::Catalog.new
+ catalog.add_resource(file)
+
+ Puppet::Util::Storage.stubs(:store) # to prevent the catalog from trying to write state.yaml
+
+ catalog.apply
+ @logs.reject {|l| l.level == :notice }.should be_empty
+ end
end
end