Whoops, forgot to update some spec tests to adapt to the new change.  One of
the spec tests needed to be changed; the others were redundant (and
excessively stubbed) so we deleted them.

Amended the following patch:

diff --git a/spec/unit/file_bucket/dipper_spec.rb
b/spec/unit/file_bucket/dipper_spec.rb
index db40c62..c40d795 100755
--- a/spec/unit/file_bucket/dipper_spec.rb
+++ b/spec/unit/file_bucket/dipper_spec.rb
@@ -92,7 +92,7 @@ describe Puppet::FileBucket::Dipper do
     [request1, request2].each do |r|
       r.server.should == 'puppetmaster'
       r.port.should == 31337
-      r.key.should == "md5/#{checksum}"
+      r.key.should == "md5/#{checksum}#{real_path}"
     end
   end

diff --git a/spec/unit/file_bucket/file_spec.rb
b/spec/unit/file_bucket/file_spec.rb
index 82063c2..f80b162 100644
--- a/spec/unit/file_bucket/file_spec.rb
+++ b/spec/unit/file_bucket/file_spec.rb
@@ -64,30 +64,6 @@ describe Puppet::FileBucket::File do
     end
   end

-  describe "when saving files" do
-    it "should save the contents to the calculated path" do
-      ::File.stubs(:directory?).with(@dir).returns(true)
-      ::File.expects(:exist?).with("#{@dir}/contents").returns false
-
-      mockfile = mock "file"
-      mockfile.expects(:print).with(@contents)
-      ::File.expects(:open).with("#{@dir}/contents",
::File::WRONLY|::File::CREAT, 0440).yields(mockfile)
-
-      Puppet::FileBucket::File.new(@contents).save
-    end
-
-    it "should make any directories necessary for storage" do
-      FileUtils.expects(:mkdir_p).with do |arg|
-        ::File.umask == 0007 and arg == @dir
-      end
-      ::File.expects(:directory?).with(@dir).returns(false)
-      ::File.expects(:open).with("#{@dir}/contents",
::File::WRONLY|::File::CREAT, 0440)
-      ::File.expects(:exist?).with("#{@dir}/contents").returns false
-
-      Puppet::FileBucket::File.new(@contents).save
-    end
-  end
-
   it "should return a url-ish name" do
     Puppet::FileBucket::File.new(@contents).name.should ==
"md5/4a8ec4fa5f01b4ab1a0ab8cbccb709f0"
   end
@@ -105,17 +81,6 @@ describe Puppet::FileBucket::File do
     Puppet::FileBucket::File.from_pson({"contents"=>"file
contents"}).contents.should == "file contents"
   end

-  it "should save a file" do
-    ::File.expects(:exist?).with("#{@dir}/contents").returns false
-    ::File.expects(:directory?).with(@dir).returns false
-    ::FileUtils.expects(:mkdir_p).with(@dir)
-    ::File.expects(:open).with("#{@dir}/contents",
 ::File::WRONLY|::File::CREAT, 0440)
-
-    bucketfile = Puppet::FileBucket::File.new(@contents)
-    bucketfile.save
-
-  end
-
   def make_bucketed_file
     FileUtils.mkdir_p(@dir)
     File.open("#{@dir}/contents", 'w') { |f| f.write @contents }


On Mon, Feb 21, 2011 at 1:39 PM, Paul Berry <[email protected]> wrote:

> Commit 2274d5104f6e413a2b8899a3c3111a17bbb2f4d7 optimized network
> usage for the case where a file is already in the filebucket.
> However, it took away the ability to store paths.
>
> This change restores the ability to store paths while maintaining
> optimal network usage for the case where the file is already in the
> filebucket with the given path.  This is expected to be the most
> common case.
>
> Paired-with: Jesse Wolfe <[email protected]>
> Signed-off-by: Paul Berry <[email protected]>
> ---
>  lib/puppet/file_bucket/dipper.rb                   |    5 +-
>  lib/puppet/indirector/file_bucket_file/file.rb     |   55 ++++++++---
>  spec/unit/indirector/file_bucket_file/file_spec.rb |  109
> ++++++++++++++++++--
>  3 files changed, 144 insertions(+), 25 deletions(-)
>
> diff --git a/lib/puppet/file_bucket/dipper.rb
> b/lib/puppet/file_bucket/dipper.rb
> index f4bef28..de4c01b 100644
> --- a/lib/puppet/file_bucket/dipper.rb
> +++ b/lib/puppet/file_bucket/dipper.rb
> @@ -34,11 +34,12 @@ class Puppet::FileBucket::Dipper
>     contents = ::File.read(file)
>     begin
>       file_bucket_file = Puppet::FileBucket::File.new(contents,
> :bucket_path => @local_path)
> -      dest_path = "#{@rest_path}#{file_bucket_file.name}"
> +      files_original_path = absolutize_path(file)
> +      dest_path = "#{@rest_path}#{file_bucket_file.name
> }#{files_original_path}"
>
>       # Make a HEAD request for the file so that we don't waste time
>       # uploading it if it already exists in the bucket.
> -      unless
> Puppet::FileBucket::File.head("#{@rest_path}#{file_bucket_file.checksum_type}/#{file_bucket_file.checksum_data}")
> +      unless
> Puppet::FileBucket::File.head("#{@rest_path}#{file_bucket_file.checksum_type}/#{file_bucket_file.checksum_data}#{files_original_path}")
>         file_bucket_file.save(dest_path)
>       end
>
> diff --git a/lib/puppet/indirector/file_bucket_file/file.rb
> b/lib/puppet/indirector/file_bucket_file/file.rb
> index 8bea2d7..0fd8a91 100644
> --- a/lib/puppet/indirector/file_bucket_file/file.rb
> +++ b/lib/puppet/indirector/file_bucket_file/file.rb
> @@ -14,10 +14,12 @@ module Puppet::FileBucketFile
>     end
>
>     def find( request )
> -      checksum = request_to_checksum( request )
> -      file_path = path_for(request.options[:bucket_path], checksum,
> 'contents')
> +      checksum, files_original_path = request_to_checksum_and_path(
> request )
> +      dir_path = path_for(request.options[:bucket_path], checksum)
> +      file_path = ::File.join(dir_path, 'contents')
>
>       return nil unless ::File.exists?(file_path)
> +      return nil unless path_match(dir_path, files_original_path)
>
>       if request.options[:diff_with]
>         hash_protocol = sumtype(checksum)
> @@ -32,32 +34,47 @@ module Puppet::FileBucketFile
>     end
>
>     def head(request)
> -      checksum = request_to_checksum(request)
> -      file_path = path_for(request.options[:bucket_path], checksum,
> 'contents')
> -      ::File.exists?(file_path)
> +      checksum, files_original_path =
> request_to_checksum_and_path(request)
> +      dir_path = path_for(request.options[:bucket_path], checksum)
> +
> +      ::File.exists?(::File.join(dir_path, 'contents')) and
> path_match(dir_path, files_original_path)
>     end
>
>     def save( request )
>       instance = request.instance
> +      checksum, files_original_path =
> request_to_checksum_and_path(request)
>
> -      save_to_disk(instance)
> +      save_to_disk(instance, files_original_path)
>       instance.to_s
>     end
>
>     private
>
> -    def save_to_disk( bucket_file )
> +    def path_match(dir_path, files_original_path)
> +      return true unless files_original_path # if no path was provided,
> it's a match
> +      paths_path = ::File.join(dir_path, 'paths')
> +      return false unless ::File.exists?(paths_path)
> +      ::File.open(paths_path) do |f|
> +        f.each do |line|
> +          return true if line.chomp == files_original_path
> +        end
> +      end
> +      return false
> +    end
> +
> +    def save_to_disk( bucket_file, files_original_path )
>       filename = path_for(bucket_file.bucket_path,
> bucket_file.checksum_data, 'contents')
> -      dirname = path_for(bucket_file.bucket_path,
> bucket_file.checksum_data)
> +      dir_path = path_for(bucket_file.bucket_path,
> bucket_file.checksum_data)
> +      paths_path = ::File.join(dir_path, 'paths')
>
>       # If the file already exists, do nothing.
>       if ::File.exist?(filename)
>         verify_identical_file!(bucket_file)
>       else
>         # Make the directories if necessary.
> -        unless ::File.directory?(dirname)
> +        unless ::File.directory?(dir_path)
>           Puppet::Util.withumask(0007) do
> -            ::FileUtils.mkdir_p(dirname)
> +            ::FileUtils.mkdir_p(dir_path)
>           end
>         end
>
> @@ -68,15 +85,27 @@ module Puppet::FileBucketFile
>           ::File.open(filename, ::File::WRONLY|::File::CREAT, 0440) do |of|
>             of.print bucket_file.contents
>           end
> +          ::File.open(paths_path, ::File::WRONLY|::File::CREAT, 0640) do
> |of|
> +            # path will be written below
> +          end
> +        end
> +      end
> +
> +      unless path_match(dir_path, files_original_path)
> +        ::File.open(paths_path, 'a') do |f|
> +          f.puts(files_original_path)
>         end
>       end
>     end
>
> -    def request_to_checksum( request )
> -      checksum_type, checksum, path = request.key.split(/\//, 3) # Note:
> we ignore path if present.
> +    def request_to_checksum_and_path( request )
> +      checksum_type, checksum, path = request.key.split(/\//, 3)
> +      if path == '' # Treat "md5/<checksum>/" like "md5/<checksum>"
> +        path = nil
> +      end
>       raise "Unsupported checksum type #{checksum_type.inspect}" if
> checksum_type != 'md5'
>       raise "Invalid checksum #{checksum.inspect}" if checksum !~
> /^[0-9a-f]{32}$/
> -      checksum
> +      [checksum, path]
>     end
>
>     def path_for(bucket_path, digest, subfile = nil)
> diff --git a/spec/unit/indirector/file_bucket_file/file_spec.rb
> b/spec/unit/indirector/file_bucket_file/file_spec.rb
> index 9187f4d..0c33593 100755
> --- a/spec/unit/indirector/file_bucket_file/file_spec.rb
> +++ b/spec/unit/indirector/file_bucket_file/file_spec.rb
> @@ -22,13 +22,97 @@ describe Puppet::FileBucketFile::File do
>       Puppet[:bucketdir] = tmpdir('bucketdir')
>     end
>
> -    describe "when diffing files" do
> -      def save_bucket_file(contents)
> -        bucket_file = Puppet::FileBucket::File.new(contents)
> -        bucket_file.save
> -        bucket_file.checksum_data
> +    def save_bucket_file(contents, path = "/who_cares")
> +      bucket_file = Puppet::FileBucket::File.new(contents)
> +      bucket_file.save("md5/#{Digest::MD5.hexdigest(contents)}#{path}")
> +      bucket_file.checksum_data
> +    end
> +
> +    describe "when servicing a save request" do
> +      describe "when supplying a path" do
> +        it "should store the path if not already stored" do
> +          checksum = save_bucket_file("stuff", "/foo/bar")
> +          dir_path =
> "#{Puppet[:bucketdir]}/c/1/3/d/8/8/c/b/c13d88cb4cb02003daedb8a84e5d272a"
> +          File.read("#{dir_path}/contents").should == "stuff"
> +          File.read("#{dir_path}/paths").should == "foo/bar\n"
> +        end
> +
> +        it "should leave the paths file alone if the path is already
> stored" do
> +          checksum = save_bucket_file("stuff", "/foo/bar")
> +          checksum = save_bucket_file("stuff", "/foo/bar")
> +          dir_path =
> "#{Puppet[:bucketdir]}/c/1/3/d/8/8/c/b/c13d88cb4cb02003daedb8a84e5d272a"
> +          File.read("#{dir_path}/contents").should == "stuff"
> +          File.read("#{dir_path}/paths").should == "foo/bar\n"
> +        end
> +
> +        it "should store an additional path if the new path differs from
> those already stored" do
> +          checksum = save_bucket_file("stuff", "/foo/bar")
> +          checksum = save_bucket_file("stuff", "/foo/baz")
> +          dir_path =
> "#{Puppet[:bucketdir]}/c/1/3/d/8/8/c/b/c13d88cb4cb02003daedb8a84e5d272a"
> +          File.read("#{dir_path}/contents").should == "stuff"
> +          File.read("#{dir_path}/paths").should == "foo/bar\nfoo/baz\n"
> +        end
> +      end
> +
> +      describe "when not supplying a path" do
> +        it "should save the file and create an empty paths file" do
> +          checksum = save_bucket_file("stuff", "")
> +          dir_path =
> "#{Puppet[:bucketdir]}/c/1/3/d/8/8/c/b/c13d88cb4cb02003daedb8a84e5d272a"
> +          File.read("#{dir_path}/contents").should == "stuff"
> +          File.read("#{dir_path}/paths").should == ""
> +        end
> +      end
> +    end
> +
> +    describe "when servicing a head/find request" do
> +      describe "when supplying a path" do
> +        it "should return false/nil if the file isn't bucketed" do
> +
>  
> Puppet::FileBucket::File.head("md5/0ae2ec1980410229885fe72f7b44fe55/foo/bar").should
> == false
> +
>  
> Puppet::FileBucket::File.find("md5/0ae2ec1980410229885fe72f7b44fe55/foo/bar").should
> == nil
> +        end
> +
> +        it "should return false/nil if the file is bucketed but with a
> different path" do
> +          checksum = save_bucket_file("I'm the contents of a file",
> '/foo/bar')
> +          Puppet::FileBucket::File.head("md5/#{checksum}/foo/baz").should
> == false
> +          Puppet::FileBucket::File.find("md5/#{checksum}/foo/baz").should
> == nil
> +        end
> +
> +        it "should return true/file if the file is already bucketed with
> the given path" do
> +          contents = "I'm the contents of a file"
> +          checksum = save_bucket_file(contents, '/foo/bar')
> +          Puppet::FileBucket::File.head("md5/#{checksum}/foo/bar").should
> == true
> +          find_result =
> Puppet::FileBucket::File.find("md5/#{checksum}/foo/bar")
> +          find_result.should be_a(Puppet::FileBucket::File)
> +          find_result.checksum.should == "{md5}#{checksum}"
> +          find_result.to_s.should == contents
> +        end
> +      end
> +
> +      describe "when not supplying a path" do
> +        [false, true].each do |trailing_slash|
> +          describe "#{trailing_slash ? 'with' : 'without'} a trailing
> slash" do
> +            trailing_string = trailing_slash ? '/' : ''
> +
> +            it "should return false/nil if the file isn't bucketed" do
> +
>  
> Puppet::FileBucket::File.head("md5/0ae2ec1980410229885fe72f7b44fe55#{trailing_string}").should
> == false
> +
>  
> Puppet::FileBucket::File.find("md5/0ae2ec1980410229885fe72f7b44fe55#{trailing_string}").should
> == nil
> +            end
> +
> +            it "should return true/file if the file is already bucketed"
> do
> +              contents = "I'm the contents of a file"
> +              checksum = save_bucket_file(contents, '/foo/bar')
> +
>  Puppet::FileBucket::File.head("md5/#{checksum}#{trailing_string}").should
> == true
> +              find_result =
> Puppet::FileBucket::File.find("md5/#{checksum}#{trailing_string}")
> +              find_result.should be_a(Puppet::FileBucket::File)
> +              find_result.checksum.should == "{md5}#{checksum}"
> +              find_result.to_s.should == contents
> +            end
> +          end
> +        end
>       end
> +    end
>
> +    describe "when diffing files" do
>       it "should generate an empty string if there is no diff" do
>         checksum = save_bucket_file("I'm the contents of a file")
>         Puppet::FileBucket::File.find("md5/#{checksum}", :diff_with =>
> checksum).should == ''
> @@ -102,7 +186,7 @@ HERE
>
>               key = "md5/#{@digest}"
>               if supply_path
> -                key += "//path/to/file"
> +                key += "/path/to/file"
>               end
>
>               @request = Puppet::Indirector::Request.new(:indirection_name,
> :find, key, request_options)
> @@ -116,10 +200,15 @@ HERE
>             it "should return an instance of Puppet::FileBucket::File
> created with the content if the file exists" do
>               make_bucketed_file
>
> -              bucketfile = @store.find(@request)
> -              bucketfile.should be_a(Puppet::FileBucket::File)
> -              bucketfile.contents.should == @contents
> -              @store.head(@request).should == true
> +              if supply_path
> +                @store.find(@request).should == nil
> +                @store.head(@request).should == false # because path
> didn't match
> +              else
> +                bucketfile = @store.find(@request)
> +                bucketfile.should be_a(Puppet::FileBucket::File)
> +                bucketfile.contents.should == @contents
> +                @store.head(@request).should == true
> +              end
>             end
>
>             it "should return nil if no file is found" do
> --
> 1.7.2
>
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Developers" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/puppet-dev?hl=en.
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/puppet-dev?hl=en.

Reply via email to