diff --git a/spec/unit/configurer_spec.rb b/spec/unit/configurer_spec.rb index 0c9d06362..2f8e615ff 100755 --- a/spec/unit/configurer_spec.rb +++ b/spec/unit/configurer_spec.rb @@ -1,494 +1,491 @@ #!/usr/bin/env ruby # # Created by Luke Kanies on 2007-11-12. # Copyright (c) 2007. All rights reserved. require File.dirname(__FILE__) + '/../spec_helper' require 'puppet/configurer' describe Puppet::Configurer do before do Puppet.settings.stubs(:use).returns(true) @agent = Puppet::Configurer.new end it "should include the Plugin Handler module" do Puppet::Configurer.ancestors.should be_include(Puppet::Configurer::PluginHandler) end it "should include the Fact Handler module" do Puppet::Configurer.ancestors.should be_include(Puppet::Configurer::FactHandler) end it "should use the puppetdlockfile as its lockfile path" do Puppet.settings.expects(:value).with(:puppetdlockfile).returns("/my/lock") Puppet::Configurer.lockfile_path.should == "/my/lock" end describe "when executing a pre-run hook" do it "should do nothing if the hook is set to an empty string" do Puppet.settings[:prerun_command] = "" Puppet::Util.expects(:exec).never @agent.execute_prerun_command end it "should execute any pre-run command provided via the 'prerun_command' setting" do Puppet.settings[:prerun_command] = "/my/command" Puppet::Util.expects(:execute).with { |args| args[0] == "/my/command" } @agent.execute_prerun_command end it "should fail if the command fails" do Puppet.settings[:prerun_command] = "/my/command" Puppet::Util.expects(:execute).raises Puppet::ExecutionFailure lambda { @agent.execute_prerun_command }.should raise_error(Puppet::Configurer::CommandHookError) end end describe "when executing a post-run hook" do it "should do nothing if the hook is set to an empty string" do Puppet.settings[:postrun_command] = "" Puppet::Util.expects(:exec).never @agent.execute_postrun_command end it "should execute any post-run command provided via the 'postrun_command' setting" do Puppet.settings[:postrun_command] = "/my/command" Puppet::Util.expects(:execute).with { |args| args[0] == "/my/command" } @agent.execute_postrun_command end it "should fail if the command fails" do Puppet.settings[:postrun_command] = "/my/command" Puppet::Util.expects(:execute).raises Puppet::ExecutionFailure lambda { @agent.execute_postrun_command }.should raise_error(Puppet::Configurer::CommandHookError) end end end describe Puppet::Configurer, "when initializing a report" do it "should return an instance of a transaction report" do Puppet.settings.stubs(:use).returns(true) @agent = Puppet::Configurer.new @agent.initialize_report.should be_instance_of(Puppet::Transaction::Report) end end describe Puppet::Configurer, "when executing a catalog run" do before do Puppet.settings.stubs(:use).returns(true) @agent = Puppet::Configurer.new @agent.stubs(:prepare) @agent.stubs(:facts_for_uploading).returns({}) @catalog = Puppet::Resource::Catalog.new @catalog.stubs(:apply) @agent.stubs(:retrieve_catalog).returns @catalog - - Puppet::Util::Log.stubs(:newdestination) - Puppet::Util::Log.stubs(:close) end it "should prepare for the run" do @agent.expects(:prepare) @agent.run end it "should initialize a transaction report if one is not provided" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report @agent.run end it "should pass the new report to the catalog" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.stubs(:initialize_report).returns report @catalog.expects(:apply).with{|options| options[:report] == report} @agent.run end it "should use the provided report if it was passed one" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).never @catalog.expects(:apply).with{|options| options[:report] == report} @agent.run(:report => report) end it "should set the report as a log destination" do report = stub 'report' @agent.expects(:initialize_report).returns report Puppet::Util::Log.expects(:newdestination).with(report) @agent.run end it "should retrieve the catalog" do @agent.expects(:retrieve_catalog) @agent.run end it "should log a failure and do nothing if no catalog can be retrieved" do @agent.expects(:retrieve_catalog).returns nil Puppet.expects(:err).with "Could not retrieve catalog; skipping run" @agent.run end it "should apply the catalog with all options to :run" do @agent.expects(:retrieve_catalog).returns @catalog @catalog.expects(:apply).with { |args| args[:one] == true } @agent.run :one => true end it "should accept a catalog and use it instead of retrieving a different one" do @agent.expects(:retrieve_catalog).never @catalog.expects(:apply) @agent.run :one => true, :catalog => @catalog end it "should benchmark how long it takes to apply the catalog" do @agent.expects(:benchmark).with(:notice, "Finished catalog run") @agent.expects(:retrieve_catalog).returns @catalog @catalog.expects(:apply).never # because we're not yielding @agent.run end it "should execute post-run hooks after the run" do @agent.expects(:execute_postrun_command) @agent.run end it "should send the report" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report @agent.expects(:send_report).with { |r, trans| r == report } @agent.run end it "should send the transaction report with a reference to the transaction if a run was actually made" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report trans = stub 'transaction' @catalog.expects(:apply).returns trans @agent.expects(:send_report).with { |r, t| t == trans } @agent.run :catalog => @catalog end it "should send the transaction report even if the catalog could not be retrieved" do @agent.expects(:retrieve_catalog).returns nil - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report @agent.expects(:send_report) @agent.run end it "should send the transaction report even if there is a failure" do @agent.expects(:retrieve_catalog).raises "whatever" - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report @agent.expects(:send_report) lambda { @agent.run }.should raise_error end it "should remove the report as a log destination when the run is finished" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report - - Puppet::Util::Log.expects(:close).with(report) + report.expects(:<<).at_least_once @agent.run + Puppet::Util::Log.destinations.should_not include(report) end it "should return the report as the result of the run" do - report = stub 'report' + report = Puppet::Transaction::Report.new @agent.expects(:initialize_report).returns report @agent.run.should equal(report) end end describe Puppet::Configurer, "when sending a report" do before do Puppet.settings.stubs(:use).returns(true) @configurer = Puppet::Configurer.new @report = stub 'report' @trans = stub 'transaction' end it "should require a report" do lambda { @configurer.send_report }.should raise_error(ArgumentError) end it "should allow specification of a transaction" do lambda { @configurer.send_report(@report, @trans) }.should_not raise_error(ArgumentError) end it "should use any provided transaction to add metrics to the report" do @trans.expects(:generate_report) @configurer.send_report(@report, @trans) end it "should print a report summary if configured to do so" do Puppet.settings[:summarize] = true @report.expects(:summary).returns "stuff" @configurer.expects(:puts).with("stuff") @configurer.send_report(@report) end it "should not print a report summary if not configured to do so" do Puppet.settings[:summarize] = false @configurer.expects(:puts).never @configurer.send_report(@report) end it "should save the report if reporting is enabled" do Puppet.settings[:report] = true @report.expects(:save) @configurer.send_report(@report) end it "should not save the report if reporting is disabled" do Puppet.settings[:report] = false @report.expects(:save).never @configurer.send_report(@report) end it "should log but not fail if saving the report fails" do Puppet.settings[:report] = true @report.expects(:save).raises "whatever" Puppet.expects(:err) lambda { @configurer.send_report(@report) }.should_not raise_error end end describe Puppet::Configurer, "when retrieving a catalog" do before do Puppet.settings.stubs(:use).returns(true) @agent = Puppet::Configurer.new @agent.stubs(:facts_for_uploading).returns({}) @catalog = Puppet::Resource::Catalog.new # this is the default when using a Configurer instance Puppet::Resource::Catalog.indirection.stubs(:terminus_class).returns :rest @agent.stubs(:convert_catalog).returns @catalog end describe "and configured to only retrieve a catalog from the cache" do before do Puppet.settings[:use_cached_catalog] = true end it "should first look in the cache for a catalog" do Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.never @agent.retrieve_catalog.should == @catalog end it "should compile a new catalog if none is found in the cache" do Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog @agent.retrieve_catalog.should == @catalog end end describe "when not using a REST terminus for catalogs" do it "should not pass any facts when retrieving the catalog" do @agent.expects(:facts_for_uploading).never Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:facts].nil? }.returns @catalog @agent.retrieve_catalog end end describe "when using a REST terminus for catalogs" do it "should pass the prepared facts and the facts format as arguments when retrieving the catalog" do @agent.expects(:facts_for_uploading).returns(:facts => "myfacts", :facts_format => :foo) Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:facts] == "myfacts" and options[:facts_format] == :foo }.returns @catalog @agent.retrieve_catalog end end it "should use the Catalog class to get its catalog" do Puppet::Resource::Catalog.expects(:find).returns @catalog @agent.retrieve_catalog end it "should use its certname to retrieve the catalog" do Facter.stubs(:value).returns "eh" Puppet.settings[:certname] = "myhost.domain.com" Puppet::Resource::Catalog.expects(:find).with { |name, options| name == "myhost.domain.com" }.returns @catalog @agent.retrieve_catalog end it "should default to returning a catalog retrieved directly from the server, skipping the cache" do Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog @agent.retrieve_catalog.should == @catalog end it "should log and return the cached catalog when no catalog can be retrieved from the server" do Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog Puppet.expects(:notice) @agent.retrieve_catalog.should == @catalog end it "should not look in the cache for a catalog if one is returned from the server" do Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns @catalog Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.never @agent.retrieve_catalog.should == @catalog end it "should return the cached catalog when retrieving the remote catalog throws an exception" do Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.raises "eh" Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns @catalog @agent.retrieve_catalog.should == @catalog end it "should log and return nil if no catalog can be retrieved from the server and :usecacheonfailure is disabled" do Puppet.stubs(:[]) Puppet.expects(:[]).with(:usecacheonfailure).returns false Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil Puppet.expects(:warning) @agent.retrieve_catalog.should be_nil end it "should return nil if no cached catalog is available and no catalog can be retrieved from the server" do Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_cache] == true }.returns nil Puppet::Resource::Catalog.expects(:find).with { |name, options| options[:ignore_terminus] == true }.returns nil @agent.retrieve_catalog.should be_nil end it "should convert the catalog before returning" do Puppet::Resource::Catalog.stubs(:find).returns @catalog @agent.expects(:convert_catalog).with { |cat, dur| cat == @catalog }.returns "converted catalog" @agent.retrieve_catalog.should == "converted catalog" end it "should return nil if there is an error while retrieving the catalog" do Puppet::Resource::Catalog.expects(:find).raises "eh" @agent.retrieve_catalog.should be_nil end end describe Puppet::Configurer, "when converting the catalog" do before do Puppet.settings.stubs(:use).returns(true) @agent = Puppet::Configurer.new @catalog = Puppet::Resource::Catalog.new @oldcatalog = stub 'old_catalog', :to_ral => @catalog end it "should convert the catalog to a RAL-formed catalog" do @oldcatalog.expects(:to_ral).returns @catalog @agent.convert_catalog(@oldcatalog, 10).should equal(@catalog) end it "should finalize the catalog" do @catalog.expects(:finalize) @agent.convert_catalog(@oldcatalog, 10) end it "should record the passed retrieval time with the RAL catalog" do @catalog.expects(:retrieval_duration=).with 10 @agent.convert_catalog(@oldcatalog, 10) end it "should write the RAL catalog's class file" do @catalog.expects(:write_class_file) @agent.convert_catalog(@oldcatalog, 10) end end describe Puppet::Configurer, "when preparing for a run" do before do Puppet.settings.stubs(:use).returns(true) @agent = Puppet::Configurer.new @agent.stubs(:dostorage) @agent.stubs(:download_fact_plugins) @agent.stubs(:download_plugins) @agent.stubs(:execute_prerun_command) @facts = {"one" => "two", "three" => "four"} end it "should initialize the metadata store" do @agent.class.stubs(:facts).returns(@facts) @agent.expects(:dostorage) @agent.prepare end it "should download fact plugins" do @agent.expects(:download_fact_plugins) @agent.prepare end it "should download plugins" do @agent.expects(:download_plugins) @agent.prepare end it "should perform the pre-run commands" do @agent.expects(:execute_prerun_command) @agent.prepare end end diff --git a/spec/unit/util/log_spec.rb b/spec/unit/util/log_spec.rb index 7d96fe190..4cec7105d 100755 --- a/spec/unit/util/log_spec.rb +++ b/spec/unit/util/log_spec.rb @@ -1,215 +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 arraydest = [] Puppet::Util::Log.newdestination(arraydest) Puppet::Util::Log.new(:level => :notice, :message => "foo") message = arraydest.last.message message.should == "foo" 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 #{attr} attribute" 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([]) + Puppet::Util::Log.newdestination(:console) 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