diff options
author | Luke Kanies <luke@madstop.com> | 2005-07-22 17:34:42 +0000 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2005-07-22 17:34:42 +0000 |
commit | 64b55c1cc9b0c4ec0c47912bad2633ba581c67d0 (patch) | |
tree | 6287b5c34769d26a3c1821285385592a655bf522 | |
parent | 9d8f7548d69f60a7c3352d9e957d6faf85645c77 (diff) | |
download | puppet-64b55c1cc9b0c4ec0c47912bad2633ba581c67d0.tar.gz puppet-64b55c1cc9b0c4ec0c47912bad2633ba581c67d0.tar.xz puppet-64b55c1cc9b0c4ec0c47912bad2633ba581c67d0.zip |
creating FileTesting module in puppettest.rb, and getting recursion working with symlinks
git-svn-id: https://reductivelabs.com/svn/puppet/library/trunk@448 980ebf18-57e1-0310-9a29-db15c13687c0
-rw-r--r-- | lib/puppet/type.rb | 3 | ||||
-rw-r--r-- | lib/puppet/type/pfile.rb | 134 | ||||
-rwxr-xr-x | lib/puppet/type/symlink.rb | 222 | ||||
-rw-r--r-- | test/puppettest.rb | 260 | ||||
-rw-r--r-- | test/types/tc_file.rb | 258 | ||||
-rwxr-xr-x | test/types/tc_symlink.rb | 107 |
6 files changed, 574 insertions, 410 deletions
diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index 40c276a99..44818630f 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -262,7 +262,6 @@ class Type < Puppet::Element # remove all type instances; this is mostly only useful for testing def self.allclear @@typeary.each { |subtype| - Puppet.debug "Clearing %s of objects" % subtype subtype.clear } end @@ -1023,7 +1022,7 @@ end require 'puppet/type/service' require 'puppet/type/exec' require 'puppet/type/pfile' -#require 'puppet/type/symlink' +require 'puppet/type/symlink' require 'puppet/type/package' require 'puppet/type/component' require 'puppet/statechange' diff --git a/lib/puppet/type/pfile.rb b/lib/puppet/type/pfile.rb index 5a3392016..f47806ebf 100644 --- a/lib/puppet/type/pfile.rb +++ b/lib/puppet/type/pfile.rb @@ -46,14 +46,28 @@ module Puppet def sync event = nil + mode = nil + if mstate = @parent.state(:mode) + mode = mstate.should + end begin case @should when "file": - File.open(@parent[:path],"w") { # just create an empty file - } + # just create an empty file + if mode + File.open(@parent[:path],"w", mode) { + } + else + File.open(@parent[:path],"w") { + } + end event = :file_created when "directory": - Dir.mkdir(@parent.name) + if mode + Dir.mkdir(@parent.name,mode) + else + Dir.mkdir(@parent.name) + end event = :directory_created else error = Puppet::Error.new( @@ -240,89 +254,6 @@ module Puppet end end - class PFileLink < Puppet::State - require 'etc' - attr_reader :link - - @name = :link - - # create the link - def self.create(file,link) - begin - Puppet.debug("Creating symlink '%s' to '%s'" % [file, link]) - unless File.symlink(file,link) - raise Puppet::Error.new( - "Could not create symlink '%s'" % link - ) - end - rescue => detail - raise Puppet::Error.new( - "Cannot create symlink '%s': %s" % [file,detail] - ) - end - end - - # remove an existing link - def self.remove(link) - if FileTest.symlink?(link) - Puppet.debug("Removing symlink '%s'" % link) - begin - File.unlink(link) - rescue - raise Puppet::Error.new( - "Failed to remove symlink '%s'" % link - ) - end - elsif FileTest.exists?(link) - error = Puppet::Error.new( - "Cannot remove normal file '%s'" % link) - raise error - else - Puppet.debug("Symlink '%s' does not exist" % link) - end - end - - def retrieve - if FileTest.symlink?(@link) - self.is = File.readlink(@link) - return - elsif FileTest.exists?(@link) - Puppet.err "Cannot replace %s with a link" % @link - @should = nil - @is = nil - else - self.is = nil - return - end - end - - # we know the link should exist, but it should also point back - # to us - def should=(link) - @link = link - @should = @parent[:path] - - # unless we're fully qualified or we've specifically allowed - # relative links. Relative links are currently disabled, until - # someone actually asks for them - #unless @should =~ /^\// or @parent[:relativelinks] - unless @should =~ /^\// - @should = File.expand_path @should - end - end - - # this is somewhat complicated, because it could exist and be - # a file - def sync - if @is - self.class.remove(@link) - end - self.class.create(@should,@link) - - return :link_created - end - end - class PFileUID < Puppet::State require 'etc' @name = :owner @@ -481,6 +412,9 @@ module Puppet def retrieve if stat = @parent.stat(true) self.is = stat.mode & 007777 + unless defined? @fixed + self.dirfix + end else self.is = -1 end @@ -506,7 +440,7 @@ module Puppet end begin - File.chmod(self.should,@parent[:path]) + File.chmod(@should,@parent[:path]) rescue => detail error = Puppet::Error.new("failed to chmod %s: %s" % [@parent.name, detail.message]) @@ -805,13 +739,13 @@ module Puppet Puppet::State::PFileUID, Puppet::State::PFileGroup, Puppet::State::PFileMode, - Puppet::State::PFileSetUID, - Puppet::State::PFileLink + Puppet::State::PFileSetUID ] @parameters = [ :path, :backup, + :linkmaker, :recurse, :source, :filebucket @@ -945,7 +879,22 @@ module Puppet #end child = nil - if child = self.class[path] + klass = nil + if @parameters[:linkmaker] and args.include?(:source) and + ! FileTest.directory?(args[:source]) + klass = Puppet::Type::Symlink + + Puppet.debug "%s is a link" % path + # clean up the args a lot for links + old = args.dup + args = { + :target => old[:source], + :path => path + } + else + klass = Puppet::Type::PFile + end + if child = klass[path] #raise "Ruh-roh" args.each { |var,value| next if var == :path @@ -955,7 +904,7 @@ module Puppet else # create it anew #notice "Creating new file with args %s" % args.inspect begin - child = self.class.new(args) + child = klass.new(args) rescue Puppet::Error => detail Puppet.notice( "Cannot manage %s: %s" % @@ -1219,7 +1168,6 @@ module Puppet added = [] Dir.foreach(self.name) { |file| next if file =~ /^\.\.?/ # skip . and .. - # XXX it's right here if child = self.newchild(file, :recurse => recurse) if @children.include?(child) Puppet.notice "Child already included" @@ -1238,7 +1186,7 @@ module Puppet @parameters[:source]) end Dir.foreach(@parameters[:source]) { |file| - next if file =~ /^\.\.?/ # skip . and .. + next if file =~ /^\.\.?$/ # skip . and .. unless added.include?(file) Puppet.notice "Adding absent source-file %s" % file if child = self.newchild(file, diff --git a/lib/puppet/type/symlink.rb b/lib/puppet/type/symlink.rb index dca2da9a5..3c0140401 100755 --- a/lib/puppet/type/symlink.rb +++ b/lib/puppet/type/symlink.rb @@ -10,6 +10,89 @@ module Puppet # okay, how do we deal with parameters that don't have operations # associated with them? class State + class PFileLink < Puppet::State + require 'etc' + attr_reader :link + + @name = :link + + # create the link + def self.create(file,link) + begin + Puppet.debug("Creating symlink '%s' to '%s'" % [file, link]) + unless File.symlink(file,link) + raise Puppet::Error.new( + "Could not create symlink '%s'" % link + ) + end + rescue => detail + raise Puppet::Error.new( + "Cannot create symlink '%s': %s" % [file,detail] + ) + end + end + + # remove an existing link + def self.remove(link) + if FileTest.symlink?(link) + Puppet.debug("Removing symlink '%s'" % link) + begin + File.unlink(link) + rescue + raise Puppet::Error.new( + "Failed to remove symlink '%s'" % link + ) + end + elsif FileTest.exists?(link) + error = Puppet::Error.new( + "Cannot remove normal file '%s'" % link) + raise error + else + Puppet.debug("Symlink '%s' does not exist" % link) + end + end + + def retrieve + if FileTest.symlink?(@link) + self.is = File.readlink(@link) + return + elsif FileTest.exists?(@link) + Puppet.err "Cannot replace %s with a link" % @link + @should = nil + @is = nil + else + self.is = nil + return + end + end + + # we know the link should exist, but it should also point back + # to us + def should=(link) + @link = link + @should = @parent[:path] + + # unless we're fully qualified or we've specifically allowed + # relative links. Relative links are currently disabled, until + # someone actually asks for them + #unless @should =~ /^\// or @parent[:relativelinks] + unless @should =~ /^\// + @should = File.expand_path @should + end + end + + # this is somewhat complicated, because it could exist and be + # a file + def sync + if @is + self.class.remove(@link) + end + self.class.create(@should,@link) + + return :link_created + end + end + class SymlinkTarget < Puppet::State require 'etc' attr_accessor :file @@ -91,19 +174,148 @@ module Puppet attr_reader :stat, :path, :params # class instance variable @states = [ - Puppet::State::PFileUID, - Puppet::State::PFileGroup, - Puppet::State::PFileMode, Puppet::State::SymlinkTarget ] @parameters = [ - :path + :path, + :recurse ] @name = :symlink @namevar = :path + + def initialize(hash) + @arghash = self.argclean(hash.dup) + @arghash.delete(self.class.namevar) + + super + end + + def newchild(path, hash = {}) + if path =~ %r{^#{File::SEPARATOR}} + raise Puppet::DevError.new( + "Must pass relative paths to Symlink#newchild()" + ) + else + path = File.join(self.name, path) + end + + args = @arghash.dup + + args[:path] = path + + unless hash.include?(:recurse) + if args.include?(:recurse) + if args[:recurse].is_a?(Integer) + Puppet.notice "Decrementing recurse on %s" % path + args[:recurse] -= 1 # reduce the level of recursion + end + end + + end + + hash.each { |key,value| + args[key] = value + } + + child = nil + if child = self.class[path] + #raise "Ruh-roh" + args.each { |var,value| + next if var == :path + next if var == :name + child[var] = value + } + else # create it anew + #notice "Creating new file with args %s" % args.inspect + begin + child = self.class.new(args) + rescue Puppet::Error => detail + Puppet.notice( + "Cannot manage %s: %s" % + [path,detail.message] + ) + Puppet.debug args.inspect + child = nil + rescue => detail + Puppet.notice( + "Cannot manage %s: %s" % + [path,detail] + ) + Puppet.debug args.inspect + child = nil + end + end + if child + child.parent = self + end + return child + end + + def newsource(source) + end + + def paramrecurse=(value) + @stat = nil + @target = self.state(:target).should + + # we want to remove our state, because we're creating children + # to do the links + if FileTest.exist?(@target) + @stat = File.stat(@target) + else + Puppet.info "Target %s must exist for recursive links" % + @target + return + end + + # if we're a directory, then we descend into it; we only actually + # link to real files + unless @stat.directory? + return + end + + self.delete(:target) + + recurse = value + # we might have a string, rather than a number + if recurse.is_a?(String) + if recurse =~ /^[0-9]+$/ + recurse = Integer(recurse) + #elsif recurse =~ /^inf/ # infinite recursion + else # anything else is infinite recursion + recurse = true + end + end + + # are we at the end of the recursion? + if recurse == 0 + return + end + + # okay, we're not going to recurse ourselves here; instead, we're + # going to rely on the fact that we've already got all of that + # working in pfile + + args = { + :name => self.name, + :linkmaker => true, + :recurse => recurse, + :source => @target + } + + dir = Puppet::Type::PFile.new(args) + dir.parent = self + Puppet.debug "Got dir %s" % dir.name + self.push dir + #Dir.foreach(@target) { |file| + # next if file =~ /^\.\.?$/ # skip . and .. + # newtarget = File.join(@target,file) + # #stat = File.stat(File.join(@target,file)) + # self.newchild(file, :target => newtarget) + #} + end end # Puppet::Type::Symlink end # Puppet::Type - end diff --git a/test/puppettest.rb b/test/puppettest.rb index 90367dedc..23ff7fe97 100644 --- a/test/puppettest.rb +++ b/test/puppettest.rb @@ -13,18 +13,6 @@ unless defined? PuppetTestSuite } end - def self.conffile - File.join($puppetbase,"examples/root/etc/configfile") - end - - def self.tempfile - File.join(self.tmpdir(), "puppetestfile") - end - - def self.tmpdir - "/tmp" - end - def initialize(name) unless FileTest.directory?(name) puts "TestSuites are directories containing test cases" @@ -51,18 +39,6 @@ unless defined? PuppetTestSuite textdir = File.join($puppetbase,"examples","code") # only parse this one file now yield File.join(textdir,"head") -# files = Dir.entries(textdir).reject { |file| -# file =~ %r{\.swp} -# }.reject { |file| -# file =~ %r{\.disabled} -# }.collect { |file| -# File.join(textdir,file) -# }.find_all { |file| -# FileTest.file?(file) -# }.sort.each { |file| -# puts "Processing %s" % file -# yield file -# } end def failers @@ -81,4 +57,240 @@ unless defined? PuppetTestSuite yield file } end + + module FileTesting + def newcomp(name,*ary) + comp = Puppet::Component.new( + :name => name + ) + ary.each { |item| comp.push item } + + return comp + end + + def cycle(comp) + trans = nil + assert_nothing_raised { + trans = comp.evaluate + } + assert_nothing_raised { + trans.evaluate + } + end + + def randlist(list) + num = rand(4) + if num == 0 + num = 1 + end + set = [] + + ret = [] + num.times { |index| + item = list[rand(list.length)] + if set.include?(item) + redo + end + + ret.push item + } + return ret + end + + def mkranddirsandfiles(dirs = nil,files = nil,depth = 3) + if depth < 0 + return + end + + unless dirs + dirs = %w{This Is A Set Of Directories} + end + + unless files + files = %w{and this is a set of files} + end + + tfiles = randlist(files) + tdirs = randlist(dirs) + + tfiles.each { |file| + File.open(file, "w") { |of| + 4.times { + of.puts rand(100) + } + } + } + + tdirs.each { |dir| + # it shouldn't already exist, but... + unless FileTest.exists?(dir) + Dir.mkdir(dir) + FileUtils.cd(dir) { + mkranddirsandfiles(dirs,files,depth - 1) + } + end + } + end + + def file_list(dir) + list = nil + FileUtils.cd(dir) { + list = %x{find . 2>/dev/null}.chomp.split(/\n/) + } + return list + end + + def assert_trees_equal(fromdir,todir) + assert(FileTest.directory?(fromdir)) + assert(FileTest.directory?(todir)) + + # verify the file list is the same + fromlist = nil + FileUtils.cd(fromdir) { + fromlist = %x{find . 2>/dev/null}.chomp.split(/\n/).reject { |file| + ! FileTest.readable?(file) + } + } + tolist = file_list(todir) + + assert_equal(fromlist,tolist) + + # and then do some verification that the files are actually set up + # the same + checked = 0 + fromlist.each_with_index { |file,i| + fromfile = File.join(fromdir,file) + tofile = File.join(todir,file) + fromstat = File.stat(fromfile) + tostat = File.stat(tofile) + [:ftype,:gid,:mode,:uid].each { |method| + assert_equal( + fromstat.send(method), + tostat.send(method) + ) + + next if fromstat.ftype == "directory" + if checked < 10 and i % 3 == 0 + from = File.open(fromfile) { |f| f.read } + to = File.open(tofile) { |f| f.read } + + assert_equal(from,to) + checked += 1 + end + } + } + end + + def random_files(dir) + checked = 0 + list = file_list(dir) + list.reverse.each_with_index { |file,i| + path = File.join(dir,file) + stat = File.stat(dir) + if checked < 10 and (i % 3) == 2 + unless yield path + next + end + checked += 1 + end + } + end + + def delete_random_files(dir) + random_files(dir) { |file| + stat = File.stat(file) + begin + if stat.ftype == "directory" + false + else + File.unlink(file) + true + end + rescue => detail + # we probably won't be able to open our own secured files + puts detail + false + end + } + end + + def add_random_files(dir) + added = [] + random_files(dir) { |file| + stat = File.stat(file) + begin + if stat.ftype == "directory" + name = File.join(file,"file" + rand(100).to_s) + File.open(name, "w") { |f| + f.puts rand(10) + } + added << name + else + false + end + rescue => detail + # we probably won't be able to open our own secured files + puts detail + false + end + } + return added + end + + def modify_random_files(dir) + modded = [] + random_files(dir) { |file| + stat = File.stat(file) + begin + if stat.ftype == "directory" + false + else + File.open(file, "w") { |f| + f.puts rand(10) + } + modded << name + true + end + rescue => detail + # we probably won't be able to open our own secured files + puts detail + false + end + } + return modded + end + + def readonly_random_files(dir) + modded = [] + random_files(dir) { |file| + stat = File.stat(file) + begin + if stat.ftype == "directory" + File.new(file).chmod(0111) + else + File.new(file).chmod(0000) + end + modded << file + rescue => detail + # we probably won't be able to open our own secured files + puts detail + false + end + } + return modded + end + def conffile + File.join($puppetbase,"examples/root/etc/configfile") + end + + def tempfile + File.join(self.tmpdir(), "puppetestfile") + end + + def tmpdir + "/tmp" + end + + end + end diff --git a/test/types/tc_file.rb b/test/types/tc_file.rb index a0a683240..c646e6272 100644 --- a/test/types/tc_file.rb +++ b/test/types/tc_file.rb @@ -12,6 +12,7 @@ require 'puppettest' # $Id$ class TestFile < Test::Unit::TestCase + include FileTesting # hmmm # this is complicated, because we store references to the created # objects in a central store @@ -26,30 +27,12 @@ class TestFile < Test::Unit::TestCase def testfile # because luke's home directory is on nfs, it can't be used for testing # as root - tmpfile = PuppetTestSuite.tempfile() + tmpfile = tempfile() File.open(tmpfile, "w") { |f| f.puts rand(100) } @@tmpfiles.push tmpfile mkfile(:name => tmpfile) end - def comp(ary) - comp = Puppet::Component.new( - :name => "component" - ) - ary.each { |item| comp.push item } - - return comp - end - - def cycle(comp) - assert_nothing_raised { - trans = comp.evaluate - } - assert_nothing_raised { - trans.evaluate - } - end - def setup @@tmpfiles = [] Puppet[:loglevel] = :debug if __FILE__ == $0 @@ -262,41 +245,6 @@ class TestFile < Test::Unit::TestCase } end - # just test normal links - def test_normal_links - link = "/tmp/puppetlink" - @@tmpfiles.push link - file = testfile() - assert_nothing_raised() { - file[:link] = link - } - # assert we got a fully qualified link - assert(file.state(:link).should =~ /^\//) - - # assert we aren't linking to ourselves - assert(File.expand_path(file.state(:link).link) != - File.expand_path(file.name)) - - # assert the should value does point to us - assert_equal(File.expand_path(file.state(:link).should), - File.expand_path(file.name)) - - assert_nothing_raised() { - file.evaluate - } - assert_nothing_raised() { - file.sync - } - assert_nothing_raised() { - file.evaluate - } - assert(file.insync?()) - assert_nothing_raised() { - file.delete(:link) - } - @@tmpfiles.push link - end - def test_checksums types = %w{md5 md5lite timestamp ctime} exists = "/tmp/sumtest-exists" @@ -493,208 +441,6 @@ class TestFile < Test::Unit::TestCase @@tmpfiles.push path end - def randlist(list) - num = rand(4) - if num == 0 - num = 1 - end - set = [] - - ret = [] - num.times { |index| - item = list[rand(list.length)] - if set.include?(item) - redo - end - - ret.push item - } - return ret - end - - def mkranddirsandfiles(dirs = nil,files = nil,depth = 3) - if depth < 0 - return - end - - unless dirs - dirs = %w{This Is A Set Of Directories} - end - - unless files - files = %w{and this is a set of files} - end - - tfiles = randlist(files) - tdirs = randlist(dirs) - - tfiles.each { |file| - File.open(file, "w") { |of| - 4.times { - of.puts rand(100) - } - } - } - - tdirs.each { |dir| - # it shouldn't already exist, but... - unless FileTest.exists?(dir) - Dir.mkdir(dir) - FileUtils.cd(dir) { - mkranddirsandfiles(dirs,files,depth - 1) - } - end - } - end - - def file_list(dir) - list = nil - FileUtils.cd(dir) { - list = %x{find . 2>/dev/null}.chomp.split(/\n/) - } - return list - end - - def assert_trees_equal(fromdir,todir) - assert(FileTest.directory?(fromdir)) - assert(FileTest.directory?(todir)) - - # verify the file list is the same - fromlist = nil - FileUtils.cd(fromdir) { - fromlist = %x{find . 2>/dev/null}.chomp.split(/\n/).reject { |file| - ! FileTest.readable?(file) - } - } - tolist = file_list(todir) - - assert_equal(fromlist,tolist) - - # and then do some verification that the files are actually set up - # the same - checked = 0 - fromlist.each_with_index { |file,i| - fromfile = File.join(fromdir,file) - tofile = File.join(todir,file) - fromstat = File.stat(fromfile) - tostat = File.stat(tofile) - [:ftype,:gid,:mode,:uid].each { |method| - assert_equal( - fromstat.send(method), - tostat.send(method) - ) - - next if fromstat.ftype == "directory" - if checked < 10 and i % 3 == 0 - from = File.open(fromfile) { |f| f.read } - to = File.open(tofile) { |f| f.read } - - assert_equal(from,to) - checked += 1 - end - } - } - end - - def random_files(dir) - checked = 0 - list = file_list(dir) - list.reverse.each_with_index { |file,i| - path = File.join(dir,file) - stat = File.stat(dir) - if checked < 10 and (i % 3) == 2 - unless yield path - next - end - checked += 1 - end - } - end - - def delete_random_files(dir) - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - false - else - File.unlink(file) - true - end - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - end - - def add_random_files(dir) - added = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - name = File.join(file,"file" + rand(100).to_s) - File.open(name, "w") { |f| - f.puts rand(10) - } - added << name - else - false - end - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - return added - end - - def modify_random_files(dir) - modded = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - false - else - File.open(file, "w") { |f| - f.puts rand(10) - } - modded << name - true - end - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - return modded - end - - def readonly_random_files(dir) - modded = [] - random_files(dir) { |file| - stat = File.stat(file) - begin - if stat.ftype == "directory" - File.new(file).chmod(0111) - else - File.new(file).chmod(0000) - end - modded << file - rescue => detail - # we probably won't be able to open our own secured files - puts detail - false - end - } - return modded - end - def recursive_source_test(fromdir, todir) initstorage tofile = nil diff --git a/test/types/tc_symlink.rb b/test/types/tc_symlink.rb index f322c1167..43ee8e073 100755 --- a/test/types/tc_symlink.rb +++ b/test/types/tc_symlink.rb @@ -5,63 +5,110 @@ if __FILE__ == $0 end require 'puppet' +require 'puppettest' require 'test/unit' # $Id$ class TestSymlink < Test::Unit::TestCase + include FileTesting # hmmm # this is complicated, because we store references to the created # objects in a central store def setup @symlink = nil - @path = File.join($puppetbase,"examples/root/etc/symlink") - - Kernel.system("rm -f %s" % @path) + @@tmpfiles = [] Puppet[:loglevel] = :debug if __FILE__ == $0 - assert_nothing_raised() { - unless Puppet::Type::Symlink.has_key?(@path) - Puppet::Type::Symlink.new( - :path => @path - ) + end + + def teardown + @@tmpfiles.each { |file| + if FileTest.exists?(file) + Kernel.system("rm -rf %s" % file) + end + if FileTest.symlink?(file) + Kernel.system("rm -rf %s" % file) end - @symlink = Puppet::Type::Symlink[@path] } + Puppet::Type.allclear + end + + def mktmpfile + # because luke's home directory is on nfs, it can't be used for testing + # as root + tmpfile = tempfile() + File.open(tmpfile, "w") { |f| f.puts rand(100) } + @@tmpfiles.push tmpfile + return tmpfile + end + + def mktmpdir + dir = File.join(tmpdir(), "puppetlinkdir") + unless FileTest.exists?(dir) + Dir.mkdir(dir) + end + @@tmpfiles.push dir + return dir + end + + def tmplink + link = File.join(tmpdir(), "puppetlinktest") + @@tmpfiles.push link + return link + end + + def newlink(hash = {}) + hash[:name] = tmplink() + unless hash.include?(:target) + hash[:target] = mktmpfile() + end + link = Puppet::Type::Symlink.new(hash) + return link end def test_target + link = nil + file = mktmpfile() assert_nothing_raised() { - @symlink[:target] = "configfile" + link = newlink() } assert_nothing_raised() { - @symlink.retrieve + link.retrieve } # we might already be in sync - assert(!@symlink.insync?()) - assert_nothing_raised() { - @symlink.sync - } + assert(!link.insync?()) assert_nothing_raised() { - @symlink.retrieve + link.sync } - assert(@symlink.insync?()) assert_nothing_raised() { - @symlink[:target] = nil + link.retrieve } - assert_nothing_raised() { - @symlink.retrieve - } - assert(!@symlink.insync?()) - assert_nothing_raised() { - @symlink.sync + assert(link.insync?()) + end + + def test_recursion + source = mktmpdir() + FileUtils.cd(source) { + mkranddirsandfiles() } - assert_nothing_raised() { - @symlink.retrieve + + link = nil + assert_nothing_raised { + link = newlink(:target => source, :recurse => true) } - assert(@symlink.insync?()) - end + comp = newcomp("linktest",link) + cycle(comp) - def teardown - Kernel.system("rm -f %s" % @path) + path = link.name + list = file_list(path) + FileUtils.cd(path) { + list.each { |file| + unless FileTest.directory?(file) + assert(FileTest.symlink?(file)) + target = File.readlink(file) + assert_equal(target,File.join(source,file.sub(/^\.\//,''))) + end + } + } end end |