diff --git a/lib/puppet/util/log/destinations.rb b/lib/puppet/util/log/destinations.rb index 403733d35..e748e5108 100644 --- a/lib/puppet/util/log/destinations.rb +++ b/lib/puppet/util/log/destinations.rb @@ -1,234 +1,229 @@ Puppet::Util::Log.newdesttype :syslog do def close Syslog.close end def initialize if Syslog.opened? Syslog.close end name = Puppet[:name] name = "puppet-#{name}" unless name =~ /puppet/ options = Syslog::LOG_PID | Syslog::LOG_NDELAY # XXX This should really be configurable. str = Puppet[:syslogfacility] begin facility = Syslog.const_get("LOG_#{str.upcase}") rescue NameError raise Puppet::Error, "Invalid syslog facility %s" % str end @syslog = Syslog.open(name, options, facility) end def handle(msg) # XXX Syslog currently has a bug that makes it so you # cannot log a message with a '%' in it. So, we get rid # of them. if msg.source == "Puppet" @syslog.send(msg.level, msg.to_s.gsub("%", '%%')) else @syslog.send(msg.level, "(%s) %s" % [msg.source.to_s.gsub("%", ""), msg.to_s.gsub("%", '%%') ] ) end end end Puppet::Util::Log.newdesttype :file do match(/^\//) def close if defined? @file @file.close @file = nil end end def flush if defined? @file @file.flush end end def initialize(path) @name = path # first make sure the directory exists # We can't just use 'Config.use' here, because they've # specified a "special" destination. unless FileTest.exist?(File.dirname(path)) Puppet.recmkdir(File.dirname(path)) Puppet.info "Creating log directory %s" % File.dirname(path) end # create the log file, if it doesn't already exist file = File.open(path, File::WRONLY|File::CREAT|File::APPEND) @file = file @autoflush = Puppet[:autoflush] end def handle(msg) @file.puts("%s %s (%s): %s" % [msg.time, msg.source, msg.level, msg.to_s]) @file.flush if @autoflush end end Puppet::Util::Log.newdesttype :console do RED = {:console => "", :html => "FFA0A0"} GREEN = {:console => "", :html => "00CD00"} YELLOW = {:console => "", :html => "FFFF60"} BLUE = {:console => "", :html => "80A0FF"} PURPLE = {:console => "", :html => "FFA500"} CYAN = {:console => "", :html => "40FFFF"} WHITE = {:console => "", :html => "FFFFFF"} HRED = {:console => "", :html => "FFA0A0"} HGREEN = {:console => "", :html => "00CD00"} HYELLOW = {:console => "", :html => "FFFF60"} HBLUE = {:console => "", :html => "80A0FF"} HPURPLE = {:console => "", :html => "FFA500"} HCYAN = {:console => "", :html => "40FFFF"} HWHITE = {:console => "", :html => "FFFFFF"} RESET = {:console => "", :html => "" } @@colormap = { :debug => WHITE, :info => GREEN, :notice => CYAN, :warning => YELLOW, :err => HPURPLE, :alert => RED, :emerg => HRED, :crit => HRED } def colorize(level, str) case Puppet[:color] when true, :ansi, "ansi", "yes"; console_color(level, str) when :html, "html"; html_color(level, str) else str end end def console_color(level, str) @@colormap[level][:console] + str + RESET[:console] end def html_color(level, str) %{%s} % [@@colormap[level][:html], str] end def initialize # Flush output immediately. $stdout.sync = true end def handle(msg) if msg.source == "Puppet" puts colorize(msg.level, "%s: %s" % [msg.level, msg.to_s]) else puts colorize(msg.level, "%s: %s: %s" % [msg.level, msg.source, msg.to_s]) end end end Puppet::Util::Log.newdesttype :host do def initialize(host) Puppet.info "Treating %s as a hostname" % host args = {} if host =~ /:(\d+)/ args[:Port] = $1 args[:Server] = host.sub(/:\d+/, '') else args[:Server] = host end @name = host @driver = Puppet::Network::Client::LogClient.new(args) end def handle(msg) unless msg.is_a?(String) or msg.remote unless defined? @hostname @hostname = Facter["hostname"].value end unless defined? @domain @domain = Facter["domain"].value if @domain @hostname += "." + @domain end end if msg.source =~ /^\// msg.source = @hostname + ":" + msg.source elsif msg.source == "Puppet" msg.source = @hostname + " " + msg.source else msg.source = @hostname + " " + msg.source end begin #puts "would have sent %s" % msg #puts "would have sent %s" % # CGI.escape(YAML.dump(msg)) begin tmp = CGI.escape(YAML.dump(msg)) rescue => detail puts "Could not dump: %s" % detail.to_s return end # Add the hostname to the source @driver.addlog(tmp) rescue => detail if Puppet[:trace] puts detail.backtrace end Puppet.err detail Puppet::Util::Log.close(self) end end end end # Log to a transaction report. Puppet::Util::Log.newdesttype :report do attr_reader :report match "Puppet::Transaction::Report" def initialize(report) @report = report end def handle(msg) @report << msg end end # Log to an array, just for testing. Puppet::Util::Log.newdesttype :array do match "Array" - attr_accessor :messages - def initialize - @messages = [] + def initialize(messages) + @messages = messages end def handle(msg) @messages << msg end - - def close - @messages.clear - end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index bd5b9a1b3..e7dd55482 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,91 +1,96 @@ unless defined? SPEC_HELPER_IS_LOADED SPEC_HELPER_IS_LOADED = 1 dir = File.expand_path(File.dirname(__FILE__)) $LOAD_PATH.unshift("#{dir}/") $LOAD_PATH.unshift("#{dir}/lib") # a spec-specific test lib dir $LOAD_PATH.unshift("#{dir}/../lib") $LOAD_PATH.unshift("#{dir}/../test/lib") # Add the old test dir, so that we can still find our local mocha and spec # include any gems in vendor/gems Dir["#{dir}/../vendor/gems/**"].each do |path| libpath = File.join(path, "lib") if File.directory?(libpath) $LOAD_PATH.unshift(libpath) else $LOAD_PATH.unshift(path) end end require 'puppettest' require 'puppettest/runnable_test' require 'mocha' gem 'rspec', '>=1.2.9' require 'spec/autorun' # So everyone else doesn't have to include this base constant. module PuppetSpec FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR) end # load any monkey-patches Dir["#{dir}/monkey_patches/*.rb"].map { |file| require file } Spec::Runner.configure do |config| config.mock_with :mocha # config.prepend_before :all do # setup_mocks_for_rspec # setup() if respond_to? :setup # end # config.prepend_after :each do Puppet.settings.clear Puppet::Node::Environment.clear Puppet::Util::Storage.clear if defined?($tmpfiles) $tmpfiles.each do |file| file = File.expand_path(file) if Puppet.features.posix? and file !~ /^\/tmp/ and file !~ /^\/var\/folders/ puts "Not deleting tmpfile #{file} outside of /tmp or /var/folders" next elsif Puppet.features.win32? tempdir = File.expand_path(File.join(Dir::LOCAL_APPDATA, "Temp")) if file !~ /^#{tempdir}/ puts "Not deleting tmpfile #{file} outside of #{tempdir}" next end end if FileTest.exist?(file) system("chmod -R 755 '#{file}'") system("rm -rf '#{file}'") end end $tmpfiles.clear end + + Puppet::Util::Log.close_all end config.prepend_before :each do # these globals are set by Application $puppet_application_mode = nil $puppet_application_name = nil # Set the confdir and vardir to gibberish so that tests # have to be correctly mocked. Puppet[:confdir] = "/dev/null" Puppet[:vardir] = "/dev/null" # Avoid opening ports to the outside world Puppet.settings[:bindaddress] = "127.0.0.1" + + @logs = [] + Puppet::Util::Log.newdestination(@logs) end end # We need this because the RAL uses 'should' as a method. This # allows us the same behaviour but with a different method name. class Object alias :must :should end end diff --git a/spec/unit/util/log_spec.rb b/spec/unit/util/log_spec.rb index df3c36ff2..e188a2366 100755 --- a/spec/unit/util/log_spec.rb +++ b/spec/unit/util/log_spec.rb @@ -1,226 +1,215 @@ #!/usr/bin/env ruby Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } require 'puppet/util/log' describe Puppet::Util::Log do it "should write a given message to the specified destination" do - Puppet::Util::Log.newdestination(:array) + arraydest = [] + Puppet::Util::Log.newdestination(arraydest) Puppet::Util::Log.new(:level => :notice, :message => "foo") - message = Puppet::Util::Log.destinations[:array].messages.shift.message + message = arraydest.last.message message.should == "foo" - - Puppet::Util::Log.close_all - end - - it "should be able to close all log destinations" do - destinations = stub_everything('destinations') - destinations.stubs(:keys).returns %w{foo bar} - Puppet::Util::Log.expects(:destinations).returns(destinations) - Puppet::Util::Log.expects(:close).with("foo") - Puppet::Util::Log.expects(:close).with("bar") - - Puppet::Util::Log.close_all end describe Puppet::Util::Log::DestConsole do before do @console = Puppet::Util::Log::DestConsole.new end it "should colorize if Puppet[:color] is :ansi" do Puppet[:color] = :ansi @console.colorize(:alert, "abc").should == "\e[0;31mabc\e[0m" end it "should colorize if Puppet[:color] is 'yes'" do Puppet[:color] = "yes" @console.colorize(:alert, "abc").should == "\e[0;31mabc\e[0m" end it "should htmlize if Puppet[:color] is :html" do Puppet[:color] = :html @console.colorize(:alert, "abc").should == "abc" end it "should do nothing if Puppet[:color] is false" do Puppet[:color] = false @console.colorize(:alert, "abc").should == "abc" end it "should do nothing if Puppet[:color] is invalid" do Puppet[:color] = "invalid option" @console.colorize(:alert, "abc").should == "abc" end end describe "instances" do before do Puppet::Util::Log.stubs(:newmessage) end [:level, :message, :time, :remote].each do |attr| it "should have a %s attribute" % attr do log = Puppet::Util::Log.new :level => :notice, :message => "A test message" log.should respond_to(attr) log.should respond_to(attr.to_s + "=") end end it "should fail if created without a level" do lambda { Puppet::Util::Log.new(:message => "A test message") }.should raise_error(ArgumentError) end it "should fail if created without a message" do lambda { Puppet::Util::Log.new(:level => :notice) }.should raise_error(ArgumentError) end it "should make available the level passed in at initialization" do Puppet::Util::Log.new(:level => :notice, :message => "A test message").level.should == :notice end it "should make available the message passed in at initialization" do Puppet::Util::Log.new(:level => :notice, :message => "A test message").message.should == "A test message" end # LAK:NOTE I don't know why this behavior is here, I'm just testing what's in the code, # at least at first. it "should always convert messages to strings" do Puppet::Util::Log.new(:level => :notice, :message => :foo).message.should == "foo" end it "should flush the log queue when the first destination is specified" do + Puppet::Util::Log.close_all Puppet::Util::Log.expects(:flushqueue) Puppet::Util::Log.newdestination(:array) - Puppet::Util::Log.close_all end it "should convert the level to a symbol if it's passed in as a string" do Puppet::Util::Log.new(:level => "notice", :message => :foo).level.should == :notice end it "should fail if the level is not a symbol or string" do lambda { Puppet::Util::Log.new(:level => 50, :message => :foo) }.should raise_error(ArgumentError) end it "should fail if the provided level is not valid" do Puppet::Util::Log.expects(:validlevel?).with(:notice).returns false lambda { Puppet::Util::Log.new(:level => :notice, :message => :foo) }.should raise_error(ArgumentError) end it "should set its time to the initialization time" do time = mock 'time' Time.expects(:now).returns time Puppet::Util::Log.new(:level => "notice", :message => :foo).time.should equal(time) end it "should make available any passed-in tags" do log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :tags => %w{foo bar}) log.tags.should be_include("foo") log.tags.should be_include("bar") end it "should use an passed-in source" do Puppet::Util::Log.any_instance.expects(:source=).with "foo" Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => "foo") end [:file, :line, :version].each do |attr| it "should use #{attr} if provided" do Puppet::Util::Log.any_instance.expects(attr.to_s + "=").with "foo" Puppet::Util::Log.new(:level => "notice", :message => :foo, attr => "foo") end end it "should default to 'Puppet' as its source" do Puppet::Util::Log.new(:level => "notice", :message => :foo).source.should == "Puppet" end it "should register itself with Log" do Puppet::Util::Log.expects(:newmessage) Puppet::Util::Log.new(:level => "notice", :message => :foo) end it "should have a method for determining if a tag is present" do Puppet::Util::Log.new(:level => "notice", :message => :foo).should respond_to(:tagged?) end it "should match a tag if any of the tags are equivalent to the passed tag as a string" do Puppet::Util::Log.new(:level => "notice", :message => :foo, :tags => %w{one two}).should be_tagged(:one) end it "should tag itself with its log level" do Puppet::Util::Log.new(:level => "notice", :message => :foo).should be_tagged(:notice) end it "should return its message when converted to a string" do Puppet::Util::Log.new(:level => "notice", :message => :foo).to_s.should == "foo" end it "should include its time, source, level, and message when prepared for reporting" do log = Puppet::Util::Log.new(:level => "notice", :message => :foo) report = log.to_report report.should be_include("notice") report.should be_include("foo") report.should be_include(log.source) report.should be_include(log.time.to_s) end describe "when setting the source as a RAL object" do it "should tag itself with any tags the source has" do source = Puppet::Type.type(:file).new :path => "/foo/bar" log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source) source.tags.each do |tag| log.tags.should be_include(tag) end end it "should use the source_descriptors" do source = stub "source" source.stubs(:source_descriptors).returns(:tags => ["tag","tag2"], :path => "path", :version => 100) log = Puppet::Util::Log.new(:level => "notice", :message => :foo) log.expects(:tag).with("tag") log.expects(:tag).with("tag2") log.expects(:version=).with(100) log.source = source log.source.should == "path" end it "should copy over any version information" do catalog = Puppet::Resource::Catalog.new catalog.version = 25 source = Puppet::Type.type(:file).new :path => "/foo/bar" catalog.add_resource source log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source) log.version.should == 25 end it "should copy over any file and line information" do source = Puppet::Type.type(:file).new :path => "/foo/bar" source.file = "/my/file" source.line = 50 log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source) log.file.should == "/my/file" log.line.should == 50 end end describe "when setting the source as a non-RAL object" do it "should not try to copy over file, version, line, or tag information" do source = Puppet::Module.new("foo") source.expects(:file).never log = Puppet::Util::Log.new(:level => "notice", :message => :foo, :source => source) end end end end diff --git a/spec/unit/util/logging_spec.rb b/spec/unit/util/logging_spec.rb index 41b07d433..62a66fc92 100755 --- a/spec/unit/util/logging_spec.rb +++ b/spec/unit/util/logging_spec.rb @@ -1,94 +1,95 @@ #!/usr/bin/env ruby Dir.chdir(File.dirname(__FILE__)) { (s = lambda { |f| File.exist?(f) ? require(f) : Dir.chdir("..") { s.call(f) } }).call("spec/spec_helper.rb") } require 'puppet/util/logging' class LoggingTester include Puppet::Util::Logging end describe Puppet::Util::Logging do before do @logger = LoggingTester.new end Puppet::Util::Log.eachlevel do |level| it "should have a method for sending '#{level}' logs" do @logger.should respond_to(level) end end it "should have a method for sending a log with a specified log level" do @logger.expects(:to_s).returns "I'm a string!" Puppet::Util::Log.expects(:create).with { |args| args[:source] == "I'm a string!" and args[:level] == "loglevel" and args[:message] == "mymessage" } @logger.send_log "loglevel", "mymessage" end describe "when sending a log" do it "should use the Log's 'create' entrance method" do Puppet::Util::Log.expects(:create) @logger.notice "foo" end it "should send itself converted to a string as the log source" do @logger.expects(:to_s).returns "I'm a string!" Puppet::Util::Log.expects(:create).with { |args| args[:source] == "I'm a string!" } @logger.notice "foo" end it "should queue logs sent without a specified destination" do + Puppet::Util::Log.close_all Puppet::Util::Log.expects(:queuemessage) @logger.notice "foo" end it "should use the path of any provided resource type" do resource = Puppet::Type.type(:mount).new :name => "foo" resource.expects(:path).returns "/path/to/mount".to_sym Puppet::Util::Log.expects(:create).with { |args| args[:source] == "/path/to/mount" } resource.notice "foo" end it "should use the path of any provided resource parameter" do resource = Puppet::Type.type(:mount).new :name => "foo" param = resource.parameter(:name) param.expects(:path).returns "/path/to/param".to_sym Puppet::Util::Log.expects(:create).with { |args| args[:source] == "/path/to/param" } param.notice "foo" end it "should send the provided argument as the log message" do Puppet::Util::Log.expects(:create).with { |args| args[:message] == "foo" } @logger.notice "foo" end it "should join any provided arguments into a single string for the message" do Puppet::Util::Log.expects(:create).with { |args| args[:message] == "foo bar baz" } @logger.notice ["foo", "bar", "baz"] end [:file, :line, :version, :tags].each do |attr| it "should include #{attr} if available" do @logger.singleton_class.send(:attr_accessor, attr) @logger.send(attr.to_s + "=", "myval") Puppet::Util::Log.expects(:create).with { |args| args[attr] == "myval" } @logger.notice "foo" end end end end diff --git a/test/lib/puppettest.rb b/test/lib/puppettest.rb index 32f57f394..f94fb4cec 100755 --- a/test/lib/puppettest.rb +++ b/test/lib/puppettest.rb @@ -1,350 +1,350 @@ # Add .../test/lib testlib = File.expand_path(File.dirname(__FILE__)) $LOAD_PATH.unshift(testlib) unless $LOAD_PATH.include?(testlib) # Add .../lib mainlib = File.expand_path(File.join(File.dirname(__FILE__), '../../lib')) $LOAD_PATH.unshift(mainlib) unless $LOAD_PATH.include?(mainlib) require 'puppet' # include any gems in vendor/gems Dir["#{mainlib}/../vendor/gems/**"].each do |path| libpath = File.join(path, "lib") if File.directory?(libpath) $LOAD_PATH.unshift(libpath) else $LOAD_PATH.unshift(path) end end require 'mocha' # Only load the test/unit class if we're not in the spec directory. # Else we get the bogus 'no tests, no failures' message. unless Dir.getwd =~ /spec/ require 'test/unit' end # Yay; hackish but it works if ARGV.include?("-d") ARGV.delete("-d") $console = true end # Some monkey-patching to allow us to test private methods. class Class def publicize_methods(*methods) saved_private_instance_methods = methods.empty? ? self.private_instance_methods : methods self.class_eval { public(*saved_private_instance_methods) } yield self.class_eval { private(*saved_private_instance_methods) } end end module PuppetTest # These need to be here for when rspec tests use these # support methods. @@tmpfiles = [] # Munge cli arguments, so we can enable debugging if we want # and so we can run just specific methods. def self.munge_argv require 'getoptlong' result = GetoptLong.new( [ "--debug", "-d", GetoptLong::NO_ARGUMENT ], [ "--resolve", "-r", GetoptLong::REQUIRED_ARGUMENT ], [ "-n", GetoptLong::REQUIRED_ARGUMENT ], [ "--help", "-h", GetoptLong::NO_ARGUMENT ] ) usage = "USAGE: TESTOPTS='[-n -n ...] [-d]' rake [target] [target] ..." opts = [] dir = method = nil result.each { |opt,arg| case opt when "--resolve" dir, method = arg.split(",") when "--debug" $puppet_debug = true Puppet::Util::Log.level = :debug Puppet::Util::Log.newdestination(:console) when "--help" puts usage exit else opts << opt << arg end } suites = nil args = ARGV.dup # Reset the options, so the test suite can deal with them (this is # what makes things like '-n' work). opts.each { |o| ARGV << o } return args end # Find the root of the Puppet tree; this is not the test directory, but # the parent of that dir. def basedir(*list) unless defined? @@basedir Dir.chdir(File.dirname(__FILE__)) do @@basedir = File.dirname(File.dirname(Dir.getwd)) end end if list.empty? @@basedir else File.join(@@basedir, *list) end end def datadir(*list) File.join(basedir, "test", "data", *list) end def exampledir(*args) unless defined? @@exampledir @@exampledir = File.join(basedir, "examples") end if args.empty? return @@exampledir else return File.join(@@exampledir, *args) end end module_function :basedir, :datadir, :exampledir def cleanup(&block) @@cleaners << block end # Rails clobbers RUBYLIB, thanks def libsetup curlibs = ENV["RUBYLIB"].split(":") $:.reject do |dir| dir =~ /^\/usr/ end.each do |dir| unless curlibs.include?(dir) curlibs << dir end end ENV["RUBYLIB"] = curlibs.join(":") end def logcollector collector = [] Puppet::Util::Log.newdestination(collector) cleanup do Puppet::Util::Log.close(collector) end collector end def rake? $0 =~ /test_loader/ end # Redirect stdout and stderr def redirect @stderr = tempfile @stdout = tempfile $stderr = File.open(@stderr, "w") $stdout = File.open(@stdout, "w") cleanup do $stderr = STDERR $stdout = STDOUT end end def setup unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin") ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" end @memoryatstart = Puppet::Util.memory if defined? @@testcount @@testcount += 1 else @@testcount = 0 end @configpath = File.join(tmpdir, "configdir" + @@testcount.to_s + "/" ) unless defined? $user and $group $user = nonrootuser().uid.to_s $group = nonrootgroup().gid.to_s end Puppet.settings.clear Puppet[:user] = $user Puppet[:group] = $group Puppet[:confdir] = @configpath Puppet[:vardir] = @configpath unless File.exists?(@configpath) Dir.mkdir(@configpath) end @@tmpfiles << @configpath << tmpdir() @@tmppids = [] @@cleaners = [] @logs = [] # If we're running under rake, then disable debugging and such. #if rake? or ! Puppet[:debug] #if defined?($puppet_debug) or ! rake? if textmate? Puppet[:color] = false end Puppet::Util::Log.newdestination(@logs) if defined? $console Puppet.info @method_name Puppet::Util::Log.newdestination(:console) Puppet[:trace] = true end Puppet::Util::Log.level = :debug #$VERBOSE = 1 #else # Puppet::Util::Log.close # Puppet::Util::Log.newdestination(@logs) # Puppet[:httplog] = tempfile() #end Puppet[:ignoreschedules] = true #@start = Time.now #Facter.stubs(:value).returns "stubbed_value" #Facter.stubs(:to_hash).returns({}) end def tempfile if defined? @@tmpfilenum @@tmpfilenum += 1 else @@tmpfilenum = 1 end f = File.join(self.tmpdir(), "tempfile_" + @@tmpfilenum.to_s) @@tmpfiles ||= [] @@tmpfiles << f return f end def textmate? if ENV["TM_FILENAME"] return true else return false end end def tstdir dir = tempfile() Dir.mkdir(dir) return dir end def tmpdir unless defined? @tmpdir and @tmpdir @tmpdir = case Facter["operatingsystem"].value when "Darwin"; "/private/tmp" when "SunOS"; "/var/tmp" else "/tmp" end @tmpdir = File.join(@tmpdir, "puppettesting" + Process.pid.to_s) unless File.exists?(@tmpdir) FileUtils.mkdir_p(@tmpdir) File.chmod(01777, @tmpdir) end end @tmpdir end def remove_tmp_files @@tmpfiles.each { |file| unless file =~ /tmp/ puts "Not deleting tmpfile %s" % file next end if FileTest.exists?(file) system("chmod -R 755 %s" % file) system("rm -rf %s" % file) end } @@tmpfiles.clear end def teardown #@stop = Time.now #File.open("/tmp/test_times.log", ::File::WRONLY|::File::CREAT|::File::APPEND) { |f| f.puts "%0.4f %s %s" % [@stop - @start, @method_name, self.class] } @@cleaners.each { |cleaner| cleaner.call() } remove_tmp_files @@tmppids.each { |pid| %x{kill -INT #{pid} 2>/dev/null} } @@tmppids.clear Puppet::Util::Storage.clear Puppet.clear Puppet.settings.clear Puppet::Util::Cacher.expire @memoryatend = Puppet::Util.memory diff = @memoryatend - @memoryatstart if diff > 1000 Puppet.info "%s#%s memory growth (%s to %s): %s" % [self.class, @method_name, @memoryatstart, @memoryatend, diff] end # reset all of the logs - Puppet::Util::Log.close + Puppet::Util::Log.close_all @logs.clear # Just in case there are processes waiting to die... require 'timeout' begin Timeout::timeout(5) do Process.waitall end rescue Timeout::Error # just move on end end def logstore @logs = [] Puppet::Util::Log.newdestination(@logs) end end require 'puppettest/support' require 'puppettest/filetesting' require 'puppettest/fakes' require 'puppettest/exetest' require 'puppettest/parsertesting' require 'puppettest/servertest' require 'puppettest/testcase' diff --git a/test/util/log.rb b/test/util/log.rb index 00db10e61..b28d601e9 100755 --- a/test/util/log.rb +++ b/test/util/log.rb @@ -1,215 +1,214 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../lib/puppettest' require 'puppet' require 'puppet/util/log' require 'puppettest' class TestLog < Test::Unit::TestCase include PuppetTest def setup super @oldloglevel = Puppet::Util::Log.level - Puppet::Util::Log.close + Puppet::Util::Log.close_all end def teardown super - Puppet::Util::Log.close + Puppet::Util::Log.close_all Puppet::Util::Log.level = @oldloglevel - Puppet::Util::Log.newdestination(:console) end def getlevels levels = nil assert_nothing_raised() { levels = [] Puppet::Util::Log.eachlevel { |level| levels << level } } # Don't test the top levels; too annoying return levels.reject { |level| level == :emerg or level == :crit } end def mkmsgs(levels) levels.collect { |level| next if level == :alert assert_nothing_raised() { Puppet::Util::Log.new( :level => level, :source => "Test", :message => "Unit test for %s" % level ) } } end def test_logfile fact = nil levels = nil Puppet::Util::Log.level = :debug levels = getlevels logfile = tempfile() fact = nil assert_nothing_raised() { Puppet::Util::Log.newdestination(logfile) } msgs = mkmsgs(levels) assert(msgs.length == levels.length) - Puppet::Util::Log.close + Puppet::Util::Log.close_all count = 0 assert(FileTest.exists?(logfile), "Did not create logfile") assert_nothing_raised() { File.open(logfile) { |of| count = of.readlines.length } } assert(count == levels.length - 1) # skip alert end def test_syslog levels = nil assert_nothing_raised() { levels = getlevels.reject { |level| level == :emerg || level == :crit } } assert_nothing_raised() { Puppet::Util::Log.newdestination("syslog") } # there's really no way to verify that we got syslog messages... msgs = mkmsgs(levels) assert(msgs.length == levels.length) end def test_levelmethods assert_nothing_raised() { Puppet::Util::Log.newdestination("/dev/null") } getlevels.each { |level| assert_nothing_raised() { Puppet.send(level,"Testing for %s" % level) } } end def test_output Puppet::Util::Log.level = :notice assert(Puppet.err("This is an error").is_a?(Puppet::Util::Log)) assert(Puppet.debug("This is debugging").nil?) Puppet::Util::Log.level = :debug assert(Puppet.err("This is an error").is_a?(Puppet::Util::Log)) assert(Puppet.debug("This is debugging").is_a?(Puppet::Util::Log)) end def test_creatingdirs dir = tempfile() file = File.join(dir, "logfile") Puppet::Util::Log.newdestination file Puppet.info "testing logs" assert(FileTest.directory?(dir)) assert(FileTest.file?(file)) end # Verify that we can pass strings that match printf args def test_percentlogs Puppet::Util::Log.newdestination :syslog assert_nothing_raised { Puppet::Util::Log.new( :level => :info, :message => "A message with %s in it" ) } end # Verify that the error and source are always strings def test_argsAreStrings msg = nil file = Puppet::Type.type(:file).new( :path => tempfile(), :check => %w{owner group} ) assert_nothing_raised { msg = Puppet::Util::Log.new(:level => :info, :message => "This is a message") } assert_nothing_raised { msg.source = file } assert_instance_of(String, msg.to_s) assert_instance_of(String, msg.source) end def test_destination_matching dest = nil assert_nothing_raised { dest = Puppet::Util::Log.newdesttype("Destine") do def handle(msg) puts msg end end } [:destine, "Destine", "destine"].each do |name| assert(dest.match?(name), "Did not match %s" % name.inspect) end assert_nothing_raised { dest.match(:yayness) } assert(dest.match("Yayness"), "Did not match yayness") Puppet::Util::Log.close(dest) end def test_autoflush file = tempfile Puppet::Util::Log.close(:console) Puppet::Util::Log.newdestination(file) Puppet.warning "A test" assert(File.read(file) !~ /A test/, "File defualted to autoflush") Puppet::Util::Log.flush assert(File.read(file) =~ /A test/, "File did not flush") Puppet::Util::Log.close(file) # Now try one with autoflush enabled Puppet[:autoflush] = true file = tempfile Puppet::Util::Log.newdestination(file) Puppet.warning "A test" assert(File.read(file) =~ /A test/, "File did not autoflush") Puppet::Util::Log.close(file) end def test_reopen Puppet[:autoflush] = true file = tempfile Puppet::Util::Log.close(:console) Puppet::Util::Log.newdestination(file) Puppet.warning "A test" assert(File.read(file) =~ /A test/, "File did not flush") # Rename the file newfile = file + ".old" File.rename(file, newfile) # Send another log Puppet.warning "Another test" assert(File.read(newfile) =~ /Another test/, "File did not rename") # Now reopen the log Puppet::Util::Log.reopen Puppet.warning "Reopen test" assert(File.read(file) =~ /Reopen test/, "File did not reopen") Puppet::Util::Log.close(file) end end