On Oct 6, 11:00 am, Luke Kanies <[email protected]> wrote:
> On Oct 5, 2009, at 8:56 AM, Michael Gliwinski wrote:
>
>
Attached is a patch, which I thought to float to get some comments.
I'll polish it some more and add tests.
* autorequire all file resources using the bucket, is this the right/
clean way to ensure a commit/tag is done @ the end
* Don't like the bounce of addfile from one class to the other I
suppose ProxyClient would help
* will factor out more common bits out of the 2 repo classes.
* Don't like the way the filebucket resource logs dirty -> commit, but
don't know how to suppress it
*

>
>
>
> > On Monday 28 September 2009 09:16:37 sam wrote:
> >> On Sep 28, 3:02 pm, Luke Kanies <[email protected]> wrote:
> >>> On Sep 27, 2009, at 5:41 PM, sam wrote:
> >>>> Hello,
> >>>>  I am thinking of wiring filebucket to save to a git repo.
> >>>> It would allow diffs and history, is that something worthwhile for
> >>>> inclusion ?
>
> >>> I think it's a great idea.  In fact, I've written a prototype of it:
>
> >>>http://gist.github.com/77811
>
> >>> It's just a thin executable, without the Puppet integration, and
> >>> it's
> >>> all execs rather than library calls.  It also doesn't do any of the
> >>> history, which you'd obviously want -- it's just the blobs, with no
> >>> branches or anything.
>
> >>> I'd love to have this supported.  How were you thinking of doing it?
>
> >> the filebucket would store the replaced files in a git repo on the
> >> local host, using rubygem-git and commit at the end of a puppet
> >> run, a
> >> file would be placed into $GITROOT/$FULLPATH of original file. no
> >> symlinks.
> >> filebucket { main: path => git://$gitpath }
>
> >> A centralized git server I suppose is nice, keep a branch per server
> >> (all lost on server renames). Would the best way be keep a git
> >> clone -
> >> l per server, then pull, add the file, then push back to the branch ?
> >> sounds like a bottle neck. if there is interest I would prefer to
> >> keep
> >> it as a stage 2.
>
> >> The history/diffs would be something a person would run on the git
> >> repo themselves, I don't have good ideas of integrating that part
> >> into
> >> puppet or it's usability. it's so much easier to use git to find the
> >> rev you want and you would need to add the file back to puppetmaster
> >> manually as the restored file would have been a puppet template or a
> >> file resource (tidy aside)
>
> >> did you expect more or have a more thought out idea?
> > This is a very good idea in general.  I would however urge you to
> > consider
> > having a thin "glue" layer between the client code and the actual
> > VCS (in
> > this case git).  In other words what I mean is, regardless if you call
> > commands or use a library to talk to git, do it through an
> > abstraction layer.
> > This way it would be possible for ppl to use different VC systems.
>
This patch makes git and the current filebucket as SCM providers so
it's trivial (if Luke's concerns are addressed) to add a 3rd or 4th
but yeah it could be made easier.

> > In my company we use bazaar for example and I know some ppl on the
> > list use
> > subversion, it would be better to allow them to use their VCS of
> > choice.
>
> I've thought about this a bit, and if it's possible I'd like to do so,
> but I'm not sure it is actually possible.
>
> The problem is that git actually works really well as a content-
> addressable file system -- you can provide content and get a checksum
> back, and provide a checksum and get content back.  While other VCSes
> do well at the basic interactions, git's design as a CAF first and VCS
> second gives it additional functionality here.
>
true, can we not make do with md5 as the uri for content in the
"filebucket directory hashing" SCM and path + version is the uri for
svn?
> I'd like to be proven wrong, though.
>
> --
> One of the Ten Commandments for Technicians:
>      (7) Work thou not on energized equipment, for if thou dost, thy
>      fellow workers will surely buy beers for thy widow and
>      console her in other ways.
> ---------------------------------------------------------------------
> Luke Kanies |http://reductivelabs.com|http://madstop.com

diff --git a/lib/puppet/application/filebucket.rb b/lib/puppet/
application/filebucket.rb
index 0723054..f1da359 100644
--- a/lib/puppet/application/filebucket.rb
+++ b/lib/puppet/application/filebucket.rb
@@ -70,10 +70,10 @@ Puppet::Application.new(:filebucket) do
         begin
             if options[:local] or options[:bucket]
                 path = options[:bucket] || Puppet[:bucketdir]
-                @client = Puppet::Network::Client.dipper.new(:Path =>
path)
+                @client = Puppet::Network::Client.dipper.new(:Path =>
path, :Scheme => :dhash)
             else
                 require 'puppet/network/handler'
-                @client = Puppet::Network::Client.dipper.new(:Server
=> Puppet[:server])
+                @client = Puppet::Network::Client.dipper.new(:Server
=> Puppet[:server], :Scheme => :dhash)
             end
         rescue => detail
             $stderr.puts detail
diff --git a/lib/puppet/network/client/dipper.rb b/lib/puppet/network/
client/dipper.rb
index 0e2dc14..b16187a 100644
--- a/lib/puppet/network/client/dipper.rb
+++ b/lib/puppet/network/client/dipper.rb
@@ -4,15 +4,14 @@ class Puppet::Network::Client::Dipper <
Puppet::Network::Client
     @drivername = :Bucket

     attr_accessor :name
-
     # Create our bucket client
     def initialize(hash = {})
         if hash.include?(:Path)
-            bucket = self.class.handler.new(:Path => hash[:Path])
+            bucket = self.class.handler.new(:Path => hash
[:Path], :Scheme => hash[:Scheme])
             hash.delete(:Path)
+            hash.delete(:Server)
             hash[:Bucket] = bucket
         end
-
         super(hash)
     end

@@ -81,5 +80,8 @@ class Puppet::Network::Client::Dipper <
Puppet::Network::Client
             return nil
         end
     end
-end

+    def commit(version)
+        return @driver.commit(version) if local?
+    end
+end
diff --git a/lib/puppet/network/handler/filebucket.rb b/lib/puppet/
network/handler/filebucket.rb
index 4973886..b81ebe5 100755
--- a/lib/puppet/network/handler/filebucket.rb
+++ b/lib/puppet/network/handler/filebucket.rb
@@ -1,6 +1,8 @@
 require 'fileutils'
 require 'digest/md5'
 require 'puppet/external/base64'
+require 'puppet/util/dhashbucket'
+require 'puppet/util/gitbucket'

 class Puppet::Network::Handler # :nodoc:
     class BucketError < RuntimeError; end
@@ -17,27 +19,10 @@ class Puppet::Network::Handler # :nodoc:
         }

         Puppet::Util.logmethods(self, true)
-        attr_reader :name, :path
-
-        # this doesn't work for relative paths
-        def self.oldpaths(base,md5)
-            return [
-                File.join(base, md5),
-                File.join(base, md5, "contents"),
-                File.join(base, md5, "paths")
-            ]
-        end
+        attr_reader :name, :path, :scheme
+
+        @@schemeList = { :dhash => DhashBucket, :git => GitBucket }

-        # this doesn't work for relative paths
-        def self.paths(base,md5)
-            dir = File.join(md5[0..7].split(""))
-            basedir = File.join(base, dir, md5)
-            return [
-                basedir,
-                File.join(basedir, "contents"),
-                File.join(basedir, "paths")
-            ]
-        end

         # Should we check each file as it comes in to make sure the
md5
         # sums match?  Defaults to false.
@@ -46,6 +31,9 @@ class Puppet::Network::Handler # :nodoc:
         end

         def initialize(hash)
+            hash[:Scheme] = hash[:Scheme] || :dhash
+            @scheme = @@schemeList[ hash[:Scheme] ]
+
             if hash.include?(:ConflictCheck)
                 @conflictchk = hash[:ConflictCheck]
                 hash.delete(:ConflictCheck)
@@ -67,6 +55,7 @@ class Puppet::Network::Handler # :nodoc:
             Puppet.settings.use(:filebucket)

             @name = "filebucket...@path}]"
+
         end

         # Accept a file from a client and store it by md5 sum,
returning
@@ -75,108 +64,20 @@ class Puppet::Network::Handler # :nodoc:
             if client
                 contents = Base64.decode64(contents)
             end
-            md5 = Digest::MD5.hexdigest(contents)
-
-            bpath, bfile, pathpath = FileBucket.paths(@path,md5)
-
-            # If the file already exists, just return the md5 sum.
-            if FileTest.exists?(bfile)
-                # If verification is enabled, then make sure the text
matches.
-                if conflict_check?
-                    verify(contents, md5, bfile)
-                end
-                return md5
-            end
-
-            # Make the directories if necessary.
-            unless FileTest.directory?(bpath)
-                Puppet::Util.withumask(0007) do
-                    FileUtils.mkdir_p(bpath)
-                end
-            end
-
-            # Write the file to disk.
-            msg = "Adding %s(%s)" % [path, md5]
-            msg += " from #{client}" if client
-            self.info msg
-
-            # ...then just create the file
-            Puppet::Util.withumask(0007) do
-                File.open(bfile, File::WRONLY|File::CREAT, 0440) { |
of|
-                    of.print contents
-                }
-            end
-
-            # Write the path to the paths file.
-            add_path(path, pathpath)

-            return md5
+            return @scheme.addfile(contents, path, client,
conflict_check?, @path, self )
         end

-        # Return the contents associated with a given md5 sum.
-        def getfile(md5, client = nil, clientip = nil)
-            bpath, bfile, bpaths = FileBucket.paths(@path,md5)
-
-            unless FileTest.exists?(bfile)
-                # Try the old flat style.
-                bpath, bfile, bpaths = FileBucket.oldpaths(@path,md5)
-                unless FileTest.exists?(bfile)
-                    return false
-                end
-            end
-
-            contents = nil
-            File.open(bfile) { |of|
-                contents = of.read
-            }
-
-            if client
-                return Base64.encode64(contents)
-            else
-                return contents
-            end
-        end
-
-        def paths(md5)
-            self.class(@path, md5)
+        def getfile(filetag, client = nil, clientip = nil)
+             return @scheme.getfile(filetag, @path, client, clientip,
self)
         end

         def to_s
             self.name
         end

-        private
-
-        # Add our path to the paths file if necessary.
-        def add_path(path, file)
-            if FileTest.exists?(file)
-                File.open(file) { |of|
-                    return if of.readlines.collect { |l|
l.chomp }.include?(path)
-                }
+        def commit(version)
+            @scheme.commit(@path, version)
             end
-
-            # if it's a new file, or if our path isn't in the file
yet, add it
-            File.open(file, File::WRONLY|File::CREAT|File::APPEND) { |
of|
-                of.puts path
-            }
         end
-
-        # If conflict_check is enabled, verify that the passed text
is
-        # the same as the text in our file.
-        def verify(content, md5, bfile)
-            curfile = File.read(bfile)
-
-            # If the contents don't match, then we've found a
conflict.
-            # Unlikely, but quite bad.
-            if curfile != contents
-                raise(BucketError,
-                    "Got passed new contents for sum %s" % md5,
caller)
-            else
-                msg = "Got duplicate %s(%s)" % [path, md5]
-                msg += " from #{client}" if client
-                self.info msg
             end
-        end
-    end
-end
-
diff --git a/lib/puppet/type/filebucket.rb b/lib/puppet/type/
filebucket.rb
index 468f926..68ebb08 100755
--- a/lib/puppet/type/filebucket.rb
+++ b/lib/puppet/type/filebucket.rb
@@ -56,6 +56,27 @@ module Puppet
             defaultto { Puppet[:clientbucketdir] }
         end

+        newparam(:uri) do
+            desc "The destination URI for the bucket. Implemented URI
schemes are
+                dhash and git.
+                scheme://[hostname|localhost]/[path]
+                localhost signifies a repository on the client.
+                if no host field is specified the puppetmaster"
+
+            validate do |dest|
+                begin
+                  uri = URI.parse(URI.escape(dest))
+                rescue => detail
+                    self.fail "Could not understand dest %s: %s" %
[dest, detail.to_s]
+                end
+
+                unless uri.scheme.nil? or %w{dhash git}.include?
(uri.scheme)
+                    self.fail "Cannot use URLs of type '%s' as dest
for filebucket" % [uri.scheme]
+                end
+            end
+        end
+
+
         # Create a default filebucket.
         def self.mkdefaultbucket
             new(:name => "puppet", :path => Puppet[:clientbucketdir])
@@ -66,6 +87,35 @@ module Puppet
             return @bucket
         end

+        newproperty(:commit) do
+            desc "Commit repo"
+            defaultto :commited
+
+            def retrieve
+                @resource.bucket
+                return :dirty
+            end
+
+            def sync
+                #puts "SYNCingiiiiiiiiiiiiiiii #
{self.resource.title}"
+                @resource.bucket.commit
(self.resource.catalog.version)
+                return :commit
+            end
+
+        end
+
+        autorequire(:file) do
+            # Autorequire all files using the filebucket
+            autos = []
+            catalog.resources.each { |r|
+                res = catalog.resource(r)
+                if ( res.is_a?(Puppet::Type.type(:file)) and
(res.parameter(:backup).value() == self.name) )
+                        autos << res
+                end
+            }
+            autos
+        end
+
         private

         def mkbucket
@@ -75,11 +125,25 @@ module Puppet

             type = "local"
             args = {}
-            if self[:path]
+
+            if self[:uri]
+                uri = URI.parse(self[:uri])
+                args[:Server] = uri.host || self
[:server]
+
+                args[:Port]   = uri.port || self[:port]
+                args[:Scheme] = uri.scheme.to_sym
+                args[:Path]   = uri.path #no default to avoid mixing
schemes in the same dir
+            elsif self[:path]
                 args[:Path] = self[:path]
+                args[:Scheme] = :dhash
             else
                 args[:Server] = self[:server]
                 args[:Port] = self[:port]
+                args[:Scheme] = :dhash
+            end
+
+            if ( args[:Server] && args[:Server]!= :localhost.to_s()
&& ( args[:Scheme] == :git ) )
+                self.fail("Scheme %s not implemented for remote
buckets" %[args[:Scheme]])
             end

             begin
@@ -93,4 +157,3 @@ module Puppet
         end
     end
 end
-
diff --git a/lib/puppet/util/dhashbucket.rb b/lib/puppet/util/
dhashbucket.rb
new file mode 100644
index 0000000..8b7dc08
--- /dev/null
+++ b/lib/puppet/util/dhashbucket.rb
@@ -0,0 +1,119 @@
+class DhashBucket
+    def self.addfile(contents, path, client, validate, savebasepath,
fb)
+        md5 = Digest::MD5.hexdigest(contents)
+        bpath, cfile, pfile = paths(savebasepath, md5)
+
+        # If the file already exists, just return the md5 sum.
+        if FileTest.exists?(cfile)
+            # If verification is enabled, then make sure the text
matches.
+            if validate
+                verify(contents, client, cfile, md5, bpath, fb)
+            end
+            return md5
+        end
+
+        # Make the directories if necessary.
+        unless FileTest.directory?(bpath)
+            Puppet::Util.withumask(0007) do
+                FileUtils.mkdir_p(bpath)
+            end
+        end
+
+        self.logmessage(path, md5, client, fb)
+        self.createfile(cfile, contents)
+
+        #SA how would the paths file already exist with the
shortcircuit above
+        # Write the path to the paths file.
+        if FileTest.exists?(pfile)
+            File.open(pfile) { |of|
+                return md5 if of.readlines.collect { |l|
l.chomp }.include?(path)
+            }
+        end
+
+        # if it's a new file, or if our path isn't in the file yet,
add it
+        File.open(pfile, File::WRONLY|File::CREAT|File::APPEND) { |
of|
+            of.puts path
+        }
+
+        return md5
+    end
+
+    # Return the contents associated with a given md5 sum.
+    def self.getfile(md5, savebasepath, client, clientip, fb)
+        bpath, cfile, pfile = self.paths(savebasepath, md5)
+        unless FileTest.exists?(cfile)
+            # Try the old flat style.
+            bpath, cfile, pfile = self.oldpaths(savebasepath, md5)
+            unless FileTest.exists?(cfile)
+                return false
+            end
+        end
+
+        contents = nil
+        File.open(cfile) { |of|
+            contents = of.read
+        }
+
+        if client
+            return Base64.encode64(contents)
+        else
+            return contents
+        end
+    end
+
+    # this doesn't work for relative paths
+    def self.paths(savebasepath, md5)
+        dir = File.join(md5[0..7].split(""))
+        basedir = File.join(savebasepath, dir, md5)
+        return [
+            basedir,
+            File.join(basedir, "contents"),
+            File.join(basedir, "paths")
+        ]
+    end
+
+    # this doesn't work for relative paths
+    def self.oldpaths(savebasepath,md5)
+        return [
+            File.join(savebasepath, md5),
+            File.join(savebasepath, md5, "contents"),
+            File.join(savebasepath, md5, "paths")
+        ]
+    end
+
+    # If conflict_check is enabled, verify that the passed text is
+    # the same as the text in our file.
+    def self.verify(contents, client, cfile, md5, bpath, fb)
+        curfile = File.read(cfile)
+        # If the contents don't match, then we've found a conflict.
+        # Unlikely, but quite bad.
+        if curfile != contents
+            raise(BucketError,
+                "Got passed new contents for sum %s" % md5, caller)
+        else
+            msg = "Got duplicate %s(%s)" % [bpath, md5]
+            msg += " from #{client}" if client
+            fb.info(msg)
+        end
+    end
+
+    def self.logmessage(path, description, client, fb)
+        msg = "Adding %s(%s)" % [path, description]
+        msg += " from #{client}" if client
+        fb.info(msg)
+    end
+
+    # Create the file
+    def self.createfile(destfile, contents)
+        Puppet::Util.withumask(0007) do
+            File.open(destfile, File::WRONLY|File::CREAT, 0440) { |
of|
+                of.print contents
+            }
+        end
+    end
+
+    def self.commit(savebasepath, version)
+        return
+    end
+
+end
diff --git a/lib/puppet/util/gitbucket.rb b/lib/puppet/util/
gitbucket.rb
new file mode 100644
index 0000000..90229f7
--- /dev/null
+++ b/lib/puppet/util/gitbucket.rb
@@ -0,0 +1,133 @@
+require 'fileutils'
+require 'digest/sha1'
+require 'rubygems'
+require 'git'
+
+require 'puppet'
+
+#module Puppet::Util::Bucket
+
+    class GitBucket
+        def self.addfile(contents, path, client, validate,
savebasepath, fb)
+            #TODO test
+            if (File.dirname(path) == File::SEPARATOR) &&
(File.basename(path) == ".git")
+                raise Puppet::Error, "Adding a file /.git to a
filebucket is not implemented"
+            end
+
+            bpath, cfile = paths(savebasepath, path)
+            puts "bpath = #{bpath} cfile=#{cfile}"
+            #TODO test
+            makepath(bpath, savebasepath)
+            begin
+                git = Git.open(savebasepath)
+            rescue
+                git = Git.init(savebasepath)
+            end
+
+            self.createfile(cfile, contents)
+            git.add(cfile)
+
+            checksum = self.gitchecksum(path, contents)
+
+            self.logmessage(path, checksum, client, fb)
+
+            return checksum
+        end
+
+        # Return the contents associated with a given md5 sum.
+        def self.getfile(checksum, savebasepath, client, clientip,
fb)
+            bpath, cfile, pfile = self.paths(savebasepath, md5)
+            if ! FileTest.exists?(cfile)
+                return false
+            end
+
+            contents = nil
+            git = Git.open(savebasepath)
+            contents = git.cat_file(checksum)
+
+
+            if client
+                return Base64.encode64(contents)
+            else
+                return contents
+            end
+        end
+
+        # this doesn't work for relative paths
+        def self.paths(savebasepath, path)
+            return [
+                File.join(savebasepath, File.dirname(path)),
+                File.join(savebasepath, path)
+            ]
+        end
+
+        # If conflict_check is enabled, verify that the passed text
is
+        # the same as the text in our file.
+        def self.verify(contents, client, cfile, md5, bpath, fb)
+
+        end
+
+        def self.logmessage(path, description, client, fb)
+            msg = "Adding %s(%s)" % [path, description]
+            msg += " from #{client}" if client
+            fb.info(msg)
+            puts "catalog"
+            p Puppet::Configurer.instance.catalog
+
+        end
+
+        def self.makepath(realdirname, topdir)
+            # Make the directories if necessary.
+            unless FileTest.directory?(realdirname)
+                Puppet::Util.withumask(0007) do
+                    begin
+                        FileUtils.mkdir_p(realdirname)
+                    rescue
+                        self.walkmakepath(realdirname, topdir)
+                    end
+                end
+            end
+        end
+
+        def self.walkmakepath(realdirname, topdir)
+            path = realdirname
+            stack = []
+            until path == topdir
+                stack.push path
+                path = File.dirname(path)
+            end
+
+            stack.reverse_each do |d|
+                begin
+                    # A file changed to a dir
+                    if FileTest.exist?(d) && ! FileTest.directory?(d)
+                        FileUtils.rm_f([d])
+                    end
+                end
+            end
+        end
+
+        #TODO merge with dhash
+        # Create the file
+        def self.createfile(destfile, contents)
+            Puppet::Util.withumask(0007) do
+                File.open(destfile, File::WRONLY|File::CREAT, 0440)
{ |of|
+                    of.print contents
+                }
+            end
+        end
+
+        def self.gitchecksum(path, contents)
+            size=File.size(path)
+            return Digest::SHA1.hexdigest("blob " + size.to_s + "\0"
+ contents)
+        end
+
+        def self.commit(savebasepath, version)
+            git = Git.init(savebasepath)
+            if g.status.added.length > 0
+                git.commit("run "+ version.to_s)
+                g.add_tag("catalog version "+ version.to_s)
+            end
+        end
+    end
+#end
diff --git a/test/network/handler/bucket.rb b/test/network/handler/
bucket.rb
index 24e70cf..7ff1bbd 100755
--- a/test/network/handler/bucket.rb
+++ b/test/network/handler/bucket.rb
@@ -219,7 +219,7 @@ class TestBucket < Test::Unit::TestCase
             bucket.addfile("yayness", "/my/file")
         }

-        a, b, pathfile = bucket.class.paths(bucket.path, sum)
+        a, b, pathfile = bucket.scheme.paths(bucket.path, sum)

         assert(FileTest.exists?(pathfile), "No path file at %s" %
pathfile)

@@ -249,7 +249,7 @@ class TestBucket < Test::Unit::TestCase

         dirs = File.join(md5[0..7].split(""))
         dir = File.join(@bucket, dirs, md5)
-        filedir, contents, paths = bucket.class.paths(@bucket, md5)
+        filedir, contents, paths = bucket.scheme.paths(@bucket, md5)

         assert_equal(dir, filedir, "did not use a deeper file
structure")
         assert_equal(File.join(dir, "contents"), contents,
@@ -274,40 +274,40 @@ class TestBucket < Test::Unit::TestCase
         assert_equal(text, result, "did not retrieve new content
correctly")
     end

-    def test_add_path
-        bucket = Puppet::Network::Handler.filebucket.new(:Path =>
@bucket)
-
-        file = tempfile()
-
-        assert(! FileTest.exists?(file), "file already exists")
-
-        path = "/some/thing"
-        assert_nothing_raised("Could not add path") do
-            bucket.send(:add_path, path, file)
-        end
-        assert_equal(path + "\n", File.read(file), "path was not
added")
-
-        assert_nothing_raised("Could not add path second time") do
-            bucket.send(:add_path, path, file)
-        end
-        assert_equal(path + "\n", File.read(file), "path was
duplicated")
-
-        # Now try a new path
-        newpath = "/another/path"
-        assert_nothing_raised("Could not add path second time") do
-            bucket.send(:add_path, newpath, file)
-        end
-        text = [path, newpath].join("\n") + "\n"
-        assert_equal(text, File.read(file), "path was duplicated")
-
-        assert_nothing_raised("Could not add path third time") do
-            bucket.send(:add_path, path, file)
-        end
-        assert_equal(text, File.read(file), "path was duplicated")
-        assert_nothing_raised("Could not add second path second
time") do
-            bucket.send(:add_path, newpath, file)
-        end
-        assert_equal(text, File.read(file), "path was duplicated")
-    end
+#    def test_add_path
+#        bucket = Puppet::Network::Handler.filebucket.new(:Path =>
@bucket)
+#
+#        file = tempfile()
+#
+#        assert(! FileTest.exists?(file), "file already exists")
+#
+#        path = "/some/thing"
+#        assert_nothing_raised("Could not add path") do
+#            bucket.send(:add_path, path, file)
+#        end
+#        assert_equal(path + "\n", File.read(file), "path was not
added")
+#
+#        assert_nothing_raised("Could not add path second time") do
+#            bucket.send(:add_path, path, file)
+#        end
+#        assert_equal(path + "\n", File.read(file), "path was
duplicated")
+#
+#        # Now try a new path
+#        newpath = "/another/path"
+#        assert_nothing_raised("Could not add path second time") do
+#            bucket.send(:add_path, newpath, file)
+#        end
+#        text = [path, newpath].join("\n") + "\n"
+#        assert_equal(text, File.read(file), "path was duplicated")
+#
+#        assert_nothing_raised("Could not add path third time") do
+#            bucket.send(:add_path, path, file)
+#        end
+#        assert_equal(text, File.read(file), "path was duplicated")
+#        assert_nothing_raised("Could not add second path second
time") do
+#            bucket.send(:add_path, newpath, file)
+#        end
+#        assert_equal(text, File.read(file), "path was duplicated")
+#    end
 end

--~--~---------~--~----~------------~-------~--~----~
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