[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, upstream, updated. 0.25.5-639-g8f94f35
test branch
puppet-dev at googlegroups.com
Wed Jul 14 10:33:25 UTC 2010
The following commit has been merged in the upstream branch:
commit 2cf7222df889981313c6955cc9220ce160dd90f6
Author: Brice Figureau <brice-puppet at daysofwonder.com>
Date: Sat Apr 10 12:02:53 2010 +0200
Fix #3373 - Client side file streaming
This patch moves file content writing to the content properties and
always write (or read) contents by chunks.
This reduces drastically puppetd memory consumption when handling large
sourced files.
Signed-off-by: Brice Figureau <brice-puppet at daysofwonder.com>
diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb
index 67bba5c..e947615 100644
--- a/lib/puppet/type/file.rb
+++ b/lib/puppet/type/file.rb
@@ -719,35 +719,33 @@ Puppet::Type.newtype(:file) do
obj
end
- # Write out the file. Requires the content to be written,
- # the property name for logging, and the checksum for validation.
- def write(content, property, checksum = nil)
+ # Write out the file. Requires the property name for logging.
+ # Write will be done by the content property, along with checksum computation
+ def write(property)
remove_existing(:file)
- use_temporary_file = (content.length != 0)
+ use_temporary_file = write_temporary_file?
if use_temporary_file
path = "#{self[:path]}.puppettmp_#{rand(10000)}"
while File.exists?(path) or File.symlink?(path)
path = "#{self[:path]}.puppettmp_#{rand(10000)}"
- end
- else
+ end
+ else
path = self[:path]
- end
+ end
mode = self.should(:mode) # might be nil
umask = mode ? 000 : 022
- Puppet::Util.withumask(umask) do
- File.open(path, File::CREAT|File::WRONLY|File::TRUNC, mode) { |f| f.print content }
- end
+ content_checksum = Puppet::Util.withumask(umask) { File.open(path, 'w', mode) { |f| write_content(f) } }
# And put our new file in place
if use_temporary_file # This is only not true when our file is empty.
begin
- fail_if_checksum_is_wrong(path, content) if validate_checksum?
+ fail_if_checksum_is_wrong(path, content_checksum) if validate_checksum?
File.rename(path, self[:path])
rescue => detail
- fail "Could not rename temporary file %s to %s : %s" % [path, self[:path], detail]
+ fail "Could not rename temporary file %s to %s: %s" % [path, self[:path], detail]
ensure
# Make sure the created file gets removed
File.unlink(path) if FileTest.exists?(path)
@@ -761,19 +759,32 @@ Puppet::Type.newtype(:file) do
private
+ # Should we validate the checksum of the file we're writing?
def validate_checksum?
- false
+ self[:checksum] !~ /time/
end
# Make sure the file we wrote out is what we think it is.
- def fail_if_checksum_is_wrong(path, checksum)
- # Use the appropriate checksum type -- md5, md5lite, etc.
- checksum = parameter(:checksum).sum(content)
-
+ def fail_if_checksum_is_wrong(path, content_checksum)
newsum = parameter(:checksum).sum_file(path)
- return if [:absent, nil, checksum].include?(newsum)
+ return if [:absent, nil, content_checksum].include?(newsum)
+
+ self.fail "File written to disk did not match checksum; discarding changes (%s vs %s)" % [content_checksum, newsum]
+ end
+
+ # write the current content. Note that if there is no content property
+ # simply opening the file with 'w' as done in write is enough to truncate
+ # or write an empty length file.
+ def write_content(file)
+ (content = property(:content)) && content.write(file)
+ end
+
+ private
- self.fail "File written to disk did not match checksum; discarding changes (%s vs %s)" % [checksum, newsum]
+ def write_temporary_file?
+ # unfortunately we don't know the source file size before fetching it
+ # so let's assume the file won't be empty
+ (c = property(:content) and c.length) || (s = @parameters[:source] and 1)
end
# There are some cases where all of the work does not get done on
diff --git a/lib/puppet/type/file/checksum.rb b/lib/puppet/type/file/checksum.rb
index d4c2488..3e2fdbf 100755
--- a/lib/puppet/type/file/checksum.rb
+++ b/lib/puppet/type/file/checksum.rb
@@ -23,4 +23,11 @@ Puppet::Type.type(:file).newparam(:checksum) do
method = type.to_s + "_file"
"{#{type}}" + send(method, path).to_s
end
+
+ def sum_stream(&block)
+ type = value || :md5 # same comment as above
+ method = type.to_s + "_stream"
+ checksum = send(method, &block)
+ "{#{type}}#{checksum}"
+ end
end
diff --git a/lib/puppet/type/file/content.rb b/lib/puppet/type/file/content.rb
index cc2494b..1817d56 100755
--- a/lib/puppet/type/file/content.rb
+++ b/lib/puppet/type/file/content.rb
@@ -1,9 +1,16 @@
+require 'net/http'
+require 'uri'
+
require 'puppet/util/checksums'
+require 'puppet/network/http/api/v1'
module Puppet
Puppet::Type.type(:file).newproperty(:content) do
include Puppet::Util::Diff
include Puppet::Util::Checksums
+ include Puppet::Network::HTTP::API::V1
+
+ attr_reader :actual_content
desc "Specify the contents of a file as a string. Newlines, tabs, and
spaces can be specified using the escaped syntax (e.g., \\n for a
@@ -68,21 +75,12 @@ module Puppet
end
end
- # If content was specified, return that; else try to return the source content;
- # else, return nil.
- def actual_content
- if defined?(@actual_content) and @actual_content
- return @actual_content
- end
-
- if s = resource.parameter(:source)
- return s.content
- end
- fail "Could not find actual content from checksum"
+ def length
+ (actual_content and actual_content.length) || 0
end
def content
- self.should || (s = resource.parameter(:source) and s.content)
+ self.should
end
# Override this method to provide diffs if asked for.
@@ -132,9 +130,46 @@ module Puppet
# We're safe not testing for the 'source' if there's no 'should'
# because we wouldn't have gotten this far if there weren't at least
# one valid value somewhere.
- @resource.write(actual_content, :content)
+ @resource.write(:content)
return return_event
end
+
+ def write(file)
+ self.fail "Writing content that wasn't provided" unless actual_content || resource.parameter(:source)
+ resource.parameter(:checksum).sum_stream { |sum|
+ each_chunk_from(actual_content || resource.parameter(:source)) { |chunk|
+ sum << chunk
+ file.print chunk
+ }
+ }
+ end
+
+ def each_chunk_from(source_or_content)
+ if source_or_content.is_a?(String)
+ yield source_or_content
+ elsif source_or_content.nil?
+ nil
+ elsif source_or_content.local?
+ File.open(source_or_content.full_path, "r") do |src|
+ while chunk = src.read(8192)
+ yield chunk
+ end
+ end
+ else
+ request = Puppet::Indirector::Request.new(:file_content, :find, source_or_content.full_path)
+ connection = Puppet::Network::HttpPool.http_instance(source_or_content.server, source_or_content.port)
+ connection.request_get(indirection2uri(request), {"Accept" => "raw"}) do |response|
+ case response.code
+ when "404"; nil
+ when /^2/; response.read_body { |chunk| yield chunk }
+ else
+ # Raise the http error if we didn't get a 'success' of some kind.
+ message = "Error %s on SERVER: %s" % [response.code, (response.body||'').empty? ? response.message : response.body]
+ raise Net::HTTPError.new(message, response)
+ end
+ end
+ end
+ end
end
end
diff --git a/lib/puppet/type/file/ensure.rb b/lib/puppet/type/file/ensure.rb
index b2dd394..83f3d3e 100755
--- a/lib/puppet/type/file/ensure.rb
+++ b/lib/puppet/type/file/ensure.rb
@@ -45,7 +45,7 @@ module Puppet
if property = @resource.property(:content)
property.sync
else
- @resource.write("", :ensure)
+ @resource.write(:ensure)
mode = @resource.should(:mode)
end
end
diff --git a/lib/puppet/type/file/source.rb b/lib/puppet/type/file/source.rb
index b3d9b3e..1eb418e 100755
--- a/lib/puppet/type/file/source.rb
+++ b/lib/puppet/type/file/source.rb
@@ -96,16 +96,6 @@ module Puppet
metadata && metadata.checksum
end
- # Look up (if necessary) and return remote content.
- cached_attr(:content) do
- raise Puppet::DevError, "No source for content was stored with the metadata" unless metadata.source
-
- unless tmp = Puppet::FileServing::Content.find(metadata.source)
- fail "Could not find any content at %s" % metadata.source
- end
- tmp.content
- end
-
# Copy the values from the source to the resource. Yay.
def copy_source_values
devfail "Somehow got asked to copy source values without any metadata" unless metadata
@@ -175,5 +165,29 @@ module Puppet
resource[:check] = checks
resource[:checksum] = :md5 unless resource.property(:checksum)
end
+
+ def local?
+ found? and uri and (uri.scheme || "file") == "file"
+ end
+
+ def full_path
+ if found? and uri
+ return URI.unescape(uri.path)
+ end
+ end
+
+ def server
+ (uri and uri.host) or Puppet.settings[:server]
+ end
+
+ def port
+ (uri and uri.port) or Puppet.settings[:masterport]
+ end
+
+ private
+
+ def uri
+ @uri ||= URI.parse(URI.escape(metadata.source))
+ end
end
end
diff --git a/lib/puppet/util/checksums.rb b/lib/puppet/util/checksums.rb
index f68f776..e534fb0 100644
--- a/lib/puppet/util/checksums.rb
+++ b/lib/puppet/util/checksums.rb
@@ -39,11 +39,27 @@ module Puppet::Util::Checksums
md5_file(filename, true)
end
+ def md5_stream(&block)
+ require 'digest/md5'
+ digest = Digest::MD5.new()
+ yield digest
+ return digest.hexdigest
+ end
+
+ alias :md5lite_stream :md5_stream
+
# Return the :mtime timestamp of a file.
def mtime_file(filename)
File.stat(filename).send(:mtime)
end
+ # by definition this doesn't exist
+ def mtime_stream
+ nil
+ end
+
+ alias :ctime_stream :mtime_stream
+
# Calculate a checksum using Digest::SHA1.
def sha1(content)
require 'digest/sha1'
@@ -68,6 +84,15 @@ module Puppet::Util::Checksums
sha1_file(filename, true)
end
+ def sha1_stream
+ require 'digest/sha1'
+ digest = Digest::SHA1.new()
+ yield digest
+ return digest.hexdigest
+ end
+
+ alias :sha1lite_stream :sha1_stream
+
# Return the :ctime of a file.
def ctime_file(filename)
File.stat(filename).send(:ctime)
diff --git a/spec/integration/type/file.rb b/spec/integration/type/file.rb
index 6222f0a..0724467 100755
--- a/spec/integration/type/file.rb
+++ b/spec/integration/type/file.rb
@@ -134,7 +134,7 @@ describe Puppet::Type.type(:file) do
File.expects(:rename).raises ArgumentError
- lambda { file.write("something", :content) }.should raise_error(Puppet::Error)
+ lambda { file.write(:content) }.should raise_error(Puppet::Error)
File.read(file[:path]).should == "bar"
end
end
diff --git a/spec/unit/type/file.rb b/spec/unit/type/file.rb
index f9c691b..4213753 100755
--- a/spec/unit/type/file.rb
+++ b/spec/unit/type/file.rb
@@ -43,18 +43,39 @@ describe Puppet::Type.type(:file) do
File.expects(:rename).raises ArgumentError
file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
- lambda { file.write("something", :content) }.should raise_error(Puppet::Error)
+ file.stubs(:validate_checksum?).returns(false)
+
+ property = stub('content_property', :actual_content => "something", :length => "something".length)
+ file.stubs(:property).with(:content).returns(property)
+
+ lambda { file.write(:content) }.should raise_error(Puppet::Error)
+ end
+
+ it "should delegate writing to the content property" do
+ filehandle = stub_everything 'fh'
+ File.stubs(:open).yields(filehandle)
+ File.stubs(:rename)
+ property = stub('content_property', :actual_content => "something", :length => "something".length)
+ file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
+ file.stubs(:validate_checksum?).returns(false)
+ file.stubs(:property).with(:content).returns(property)
+
+ property.expects(:write).with(filehandle)
+
+ file.write(:content)
end
describe "when validating the checksum" do
before { @file.stubs(:validate_checksum?).returns(true) }
- it "should fail if the checksum property and content checksums do not match" do
- property = stub('checksum_property', :checktype => :md5, :md5 => 'checksum_a', :getsum => 'checksum_b')
- @file.stubs(:property).with(:checksum).returns(property)
+ it "should fail if the checksum parameter and content checksums do not match" do
+ checksum = stub('checksum_parameter', :sum => 'checksum_b')
+ @file.stubs(:parameter).with(:checksum).returns(checksum)
- @file.stubs(:validate_checksum?).returns(true)
- lambda { @file.write "something", :NOTUSED }.should raise_error(Puppet::Error)
+ property = stub('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a')
+ @file.stubs(:property).with(:content).returns(property)
+
+ lambda { @file.write :NOTUSED }.should raise_error(Puppet::Error)
end
end
@@ -62,10 +83,13 @@ describe Puppet::Type.type(:file) do
before { @file.stubs(:validate_checksum?).returns(false) }
it "should not fail if the checksum property and content checksums do not match" do
- property = stub('checksum_property', :checktype => :md5, :md5 => 'checksum_a', :getsum => 'checksum_b')
- @file.stubs(:property).with(:checksum).returns(property)
+ checksum = stub('checksum_parameter', :sum => 'checksum_b')
+ @file.stubs(:parameter).with(:checksum).returns(checksum)
+
+ property = stub('content_property', :actual_content => "something", :length => "something".length, :write => 'checksum_a')
+ @file.stubs(:property).with(:content).returns(property)
- lambda { @file.write "something", :NOTUSED }.should_not raise_error(Puppet::Error)
+ lambda { @file.write :NOTUSED }.should_not raise_error(Puppet::Error)
end
end
@@ -840,17 +864,6 @@ describe Puppet::Type.type(:file) do
end
end
- describe "when writing the file" do
- it "should propagate failures encountered when renaming the temporary file" do
- File.stubs(:open)
-
- File.expects(:rename).raises ArgumentError
- file = Puppet::Type::File.new(:name => "/my/file", :backup => "puppet")
-
- lambda { file.write("something", :content) }.should raise_error(Puppet::Error)
- end
- end
-
describe "when retrieving the current file state" do
it "should copy the source values if the 'source' parameter is set" do
file = Puppet::Type::File.new(:name => "/my/file", :source => "/foo/bar")
diff --git a/spec/unit/type/file/checksum.rb b/spec/unit/type/file/checksum.rb
index 8f0f842..e6a8530 100644
--- a/spec/unit/type/file/checksum.rb
+++ b/spec/unit/type/file/checksum.rb
@@ -56,4 +56,18 @@ describe checksum do
@checksum.expects(:md5_file).returns "mysum"
@checksum.sum_file("/foo/bar").should == "{md5}mysum"
end
+
+ it "should return the summed contents of a stream with a checksum label" do
+ @resource[:checksum] = :md5
+ @checksum.expects(:md5_stream).returns "mysum"
+ @checksum.sum_stream.should == "{md5}mysum"
+ end
+
+ it "should yield the sum_stream block to the underlying checksum" do
+ @resource[:checksum] = :md5
+ @checksum.expects(:md5_stream).yields("something").returns("mysum")
+ @checksum.sum_stream do |sum|
+ sum.should == "something"
+ end
+ end
end
diff --git a/spec/unit/type/file/content.rb b/spec/unit/type/file/content.rb
index 5a3a859..96f037f 100755
--- a/spec/unit/type/file/content.rb
+++ b/spec/unit/type/file/content.rb
@@ -44,19 +44,13 @@ describe content do
@content.actual_content.should == "ehness"
end
- it "should use the content from the source if the source is set" do
+ it "should not use the content from the source if the source is set" do
source = mock 'source'
- source.expects(:content).returns "scont"
- @resource.expects(:parameter).with(:source).returns source
+ @resource.expects(:parameter).never.with(:source).returns source
@content = content.new(:resource => @resource)
- @content.actual_content.should == "scont"
- end
-
- it "should fail if no source is available and no content is set" do
- @content = content.new(:resource => @resource)
- lambda { @content.actual_content }.should raise_error(Puppet::Error)
+ @content.actual_content.should be_nil
end
end
@@ -236,7 +230,7 @@ describe content do
end
it "should use the file's :write method to write the content" do
- @resource.expects(:write).with("some content", :content)
+ @resource.expects(:write).with(:content)
@content.sync
end
@@ -253,4 +247,140 @@ describe content do
@content.sync.should == :file_created
end
end
+
+ describe "when writing" do
+ before do
+ @content = content.new(:resource => @resource)
+ @fh = stub_everything
+ end
+
+ it "should fail if no actual content nor source exists" do
+ lambda { @content.write(@fh) }.should raise_error
+ end
+
+ describe "from actual content" do
+ before(:each) do
+ @content.stubs(:actual_content).returns("this is content")
+ end
+
+ it "should write to the given file handle" do
+ @fh.expects(:print).with("this is content")
+ @content.write(@fh)
+ end
+
+ it "should return the current checksum value" do
+ @resource.parameter(:checksum).expects(:sum_stream).returns "checksum"
+ @content.write(@fh).should == "checksum"
+ end
+ end
+
+ describe "from local source" do
+ before(:each) do
+ @content.stubs(:actual_content).returns(nil)
+ @source = stub_everything 'source', :local? => true, :full_path => "/path/to/source"
+ @resource.stubs(:parameter).with(:source).returns @source
+
+ @sum = stub_everything 'sum'
+ @resource.stubs(:parameter).with(:checksum).returns(@sum)
+
+ @digest = stub_everything 'digest'
+ @sum.stubs(:sum_stream).yields(@digest)
+
+ @file = stub_everything 'file'
+ File.stubs(:open).yields(@file)
+ @file.stubs(:read).with(8192).returns("chunk1").then.returns("chunk2").then.returns(nil)
+ end
+
+ it "should open the local file" do
+ File.expects(:open).with("/path/to/source", "r")
+ @content.write(@fh)
+ end
+
+ it "should read the local file by chunks" do
+ @file.expects(:read).with(8192).returns("chunk1").then.returns(nil)
+ @content.write(@fh)
+ end
+
+ it "should write each chunk to the file" do
+ @fh.expects(:print).with("chunk1").then.with("chunk2")
+ @content.write(@fh)
+ end
+
+ it "should pass each chunk to the current sum stream" do
+ @digest.expects(:<<).with("chunk1").then.with("chunk2")
+ @content.write(@fh)
+ end
+
+ it "should return the checksum computed" do
+ @sum.stubs(:sum_stream).yields(@digest).returns("checksum")
+ @content.write(@fh).should == "checksum"
+ end
+ end
+
+ describe "from remote source" do
+ before(:each) do
+ @response = stub_everything 'mock response', :code => "404"
+ @conn = stub_everything 'connection'
+ @conn.stubs(:request_get).yields(@response)
+ Puppet::Network::HttpPool.stubs(:http_instance).returns @conn
+
+ @content.stubs(:actual_content).returns(nil)
+ @source = stub_everything 'source', :local? => false, :full_path => "/path/to/source", :server => "server", :port => 1234
+ @resource.stubs(:parameter).with(:source).returns @source
+
+ @sum = stub_everything 'sum'
+ @resource.stubs(:parameter).with(:checksum).returns(@sum)
+
+ @digest = stub_everything 'digest'
+ @sum.stubs(:sum_stream).yields(@digest)
+ end
+
+ it "should open a network connection to source server and port" do
+ Puppet::Network::HttpPool.expects(:http_instance).with("server", 1234).returns @conn
+ @content.write(@fh)
+ end
+
+ it "should send the correct indirection uri" do
+ @conn.expects(:request_get).with { |uri,headers| uri == "/production/file_content//path/to/source" }.yields(@response)
+ @content.write(@fh)
+ end
+
+ it "should return nil if source is not found" do
+ @response.expects(:code).returns("404")
+ @content.write(@fh).should == nil
+ end
+
+ it "should not write anything if source is not found" do
+ @response.expects(:code).returns("404")
+ @fh.expects(:print).never
+ @content.write(@fh).should == nil
+ end
+
+ it "should raise an HTTP error in case of server error" do
+ @response.expects(:code).returns("500")
+ lambda { @content.write(@fh) }.should raise_error
+ end
+
+ it "should write content by chunks" do
+ @response.expects(:code).returns("200")
+ @response.expects(:read_body).multiple_yields("chunk1","chunk2")
+ @fh.expects(:print).with("chunk1").then.with("chunk2")
+ @content.write(@fh)
+ end
+
+ it "should pass each chunk to the current sum stream" do
+ @response.expects(:code).returns("200")
+ @response.expects(:read_body).multiple_yields("chunk1","chunk2")
+ @digest.expects(:<<).with("chunk1").then.with("chunk2")
+ @content.write(@fh)
+ end
+
+ it "should return the checksum computed" do
+ @response.expects(:code).returns("200")
+ @response.expects(:read_body).multiple_yields("chunk1","chunk2")
+ @sum.expects(:sum_stream).yields(@digest).returns("checksum")
+ @content.write(@fh).should == "checksum"
+ end
+ end
+ end
end
diff --git a/spec/unit/type/file/source.rb b/spec/unit/type/file/source.rb
index e4e9ad9..b9bb222 100755
--- a/spec/unit/type/file/source.rb
+++ b/spec/unit/type/file/source.rb
@@ -198,51 +198,75 @@ describe Puppet::Type.type(:file).attrclass(:source) do
end
end
- it "should have a method for returning the content" do
- source.new(:resource => @resource).must respond_to(:content)
+ it "should have a local? method" do
+ source.new(:resource => @resource).must be_respond_to(:local?)
end
- describe "when looking up the content" do
- before do
+ context "when accessing source properties" do
+ before(:each) do
@source = source.new(:resource => @resource)
- @metadata = stub 'metadata', :source => "/my/source"
- @source.stubs(:metadata).returns @metadata
-
- @content = stub 'content', :content => "foobar"
+ @metadata = stub_everything
+ @source.stubs(:metadata).returns(@metadata)
end
- it "should fail if the metadata does not have a source set" do
- @metadata.stubs(:source).returns nil
- lambda { @source.content }.should raise_error(Puppet::DevError)
- end
+ describe "for local sources" do
+ before(:each) do
+ @metadata.stubs(:ftype).returns "file"
+ @metadata.stubs(:source).returns("file:///path/to/source")
+ end
- it "should look the content up from the Content class using the metadata source if no content is set" do
- Puppet::FileServing::Content.expects(:find).with("/my/source").returns @content
- @source.content.should == "foobar"
- end
+ it "should be local" do
+ @source.must be_local
+ end
- it "should return previously found content" do
- Puppet::FileServing::Content.expects(:find).with("/my/source").returns @content
- @source.content.should == "foobar"
- @source.content.should == "foobar"
- end
+ it "should be local if there is no scheme" do
+ @metadata.stubs(:source).returns("/path/to/source")
+ @source.must be_local
+ end
- it "should fail if no content can be retrieved" do
- Puppet::FileServing::Content.expects(:find).with("/my/source").returns nil
- @source.expects(:fail).raises RuntimeError
- lambda { @source.content }.should raise_error(RuntimeError)
+ it "should be able to return the metadata source full path" do
+ @source.full_path.should == "/path/to/source"
+ end
end
- it "should expire the content appropriately" do
- expirer = stub 'expired', :dependent_data_expired? => true
+ describe "for remote sources" do
+ before(:each) do
+ @metadata.stubs(:ftype).returns "file"
+ @metadata.stubs(:source).returns("puppet://server:8192/path/to/source")
+ end
- content2 = stub 'content', :content => "secondrun"
- Puppet::FileServing::Content.expects(:find).with("/my/source").times(2).returns(@content).then.returns(content2)
- @source.content.should == "foobar"
+ it "should not be local" do
+ @source.should_not be_local
+ end
- @source.stubs(:expirer).returns expirer
+ it "should be able to return the metadata source full path" do
+ @source.full_path.should == "/path/to/source"
+ end
+
+ it "should be able to return the source server" do
+ @source.server.should == "server"
+ end
+
+ it "should be able to return the source port" do
+ @source.port.should == 8192
+ end
- @source.content.should == "secondrun"
+ describe "which don't specify server or port" do
+ before(:each) do
+ @metadata.stubs(:source).returns("puppet:///path/to/source")
+ end
+
+ it "should return the default source server" do
+ Puppet.settings.expects(:[]).with(:server).returns("myserver")
+ @source.server.should == "myserver"
+ end
+
+ it "should return the default source port" do
+ Puppet.settings.expects(:[]).with(:masterport).returns(1234)
+ @source.port.should == 1234
+ end
+ end
end
end
+
end
diff --git a/spec/unit/util/checksums.rb b/spec/unit/util/checksums.rb
index e0c9909..eba5643 100755
--- a/spec/unit/util/checksums.rb
+++ b/spec/unit/util/checksums.rb
@@ -28,6 +28,12 @@ describe Puppet::Util::Checksums do
end
end
+ [content_sums, file_only].flatten.each do |sumtype|
+ it "should be able to calculate %s sums from stream" % sumtype do
+ @summer.should be_respond_to(sumtype.to_s + "_stream")
+ end
+ end
+
it "should have a method for determining whether a given string is a checksum" do
@summer.should respond_to(:checksum?)
end
@@ -78,6 +84,16 @@ describe Puppet::Util::Checksums do
@summer.send(sum.to_s + "_file", file).should == :mydigest
end
+
+ it "should yield #{klass} to the given block to calculate stream checksums" do
+ digest = mock 'digest'
+ klass.expects(:new).returns digest
+ digest.expects(:hexdigest).returns :mydigest
+
+ @summer.send(sum.to_s + "_stream") do |sum|
+ sum.should == digest
+ end.should == :mydigest
+ end
end
end
@@ -118,6 +134,10 @@ describe Puppet::Util::Checksums do
@summer.send(sum.to_s + "_file", file).should == "mysum"
end
+
+ it "should return nil for streams" do
+ @summer.send(sum.to_s + "_stream").should be_nil
+ end
end
end
--
Puppet packaging for Debian
More information about the Pkg-puppet-devel
mailing list