diff --git a/lib/puppet/configurer/plugin_handler.rb b/lib/puppet/configurer/plugin_handler.rb index 47a38c788..d2a12e233 100644 --- a/lib/puppet/configurer/plugin_handler.rb +++ b/lib/puppet/configurer/plugin_handler.rb @@ -1,21 +1,37 @@ # Break out the code related to plugins. This module is # just included into the agent, but having it here makes it # easier to test. module Puppet::Configurer::PluginHandler def download_plugins? Puppet[:pluginsync] end # Retrieve facts from the central server. def download_plugins return nil unless download_plugins? plugin_downloader = Puppet::Configurer::Downloader.new( "plugin", Puppet[:plugindest], Puppet[:pluginsource], Puppet[:pluginsignore] ) - plugin_downloader.evaluate.each { |file| Puppet.info "Downloaded #{file} from master" unless FileTest.directory?(file) } + plugin_downloader.evaluate.each { |file| load_plugin(file) } + end + + def load_plugin(file) + return unless FileTest.exist?(file) + return if FileTest.directory?(file) + + begin + if file =~ /.rb$/ + Puppet.info "Loading downloaded plugin #{file}" + load file + else + Puppet.debug "Skipping downloaded plugin #{file}" + end + rescue Exception => detail + Puppet.err "Could not load downloaded file #{file}: #{detail}" + end end end diff --git a/spec/unit/configurer/plugin_handler_spec.rb b/spec/unit/configurer/plugin_handler_spec.rb index 1a19d02e3..0fb718334 100755 --- a/spec/unit/configurer/plugin_handler_spec.rb +++ b/spec/unit/configurer/plugin_handler_spec.rb @@ -1,53 +1,122 @@ #!/usr/bin/env rspec require 'spec_helper' require 'puppet/configurer' require 'puppet/configurer/plugin_handler' class PluginHandlerTester include Puppet::Configurer::PluginHandler end describe Puppet::Configurer::PluginHandler do before do @pluginhandler = PluginHandlerTester.new + + # PluginHandler#load_plugin has an extra-strong rescue clause + # this mock is to make sure that we don't silently ignore errors + Puppet.expects(:err).never end it "should have a method for downloading plugins" do @pluginhandler.should respond_to(:download_plugins) end it "should have a boolean method for determining whether plugins should be downloaded" do @pluginhandler.should respond_to(:download_plugins?) end it "should download plugins when :pluginsync is true" do Puppet.settings.expects(:value).with(:pluginsync).returns true @pluginhandler.should be_download_plugins end it "should not download plugins when :pluginsync is false" do Puppet.settings.expects(:value).with(:pluginsync).returns false @pluginhandler.should_not be_download_plugins end it "should not download plugins when downloading is disabled" do Puppet::Configurer::Downloader.expects(:new).never @pluginhandler.expects(:download_plugins?).returns false @pluginhandler.download_plugins end it "should use an Agent Downloader, with the name, source, destination, and ignore set correctly, to download plugins when downloading is enabled" do downloader = mock 'downloader' Puppet.settings.expects(:value).with(:pluginsource).returns "psource" Puppet.settings.expects(:value).with(:plugindest).returns "pdest" Puppet.settings.expects(:value).with(:pluginsignore).returns "pignore" Puppet::Configurer::Downloader.expects(:new).with("plugin", "pdest", "psource", "pignore").returns downloader downloader.expects(:evaluate).returns [] @pluginhandler.expects(:download_plugins?).returns true @pluginhandler.download_plugins end + + it "should be able to load plugins" do + @pluginhandler.should respond_to(:load_plugin) + end + + it "should load each downloaded file" do + FileTest.stubs(:exist?).returns true + downloader = mock 'downloader' + + Puppet::Configurer::Downloader.expects(:new).returns downloader + + downloader.expects(:evaluate).returns %w{one two} + + @pluginhandler.expects(:download_plugins?).returns true + + @pluginhandler.expects(:load_plugin).with("one") + @pluginhandler.expects(:load_plugin).with("two") + + @pluginhandler.download_plugins + end + + it "should load ruby plugins when asked to do so" do + FileTest.stubs(:exist?).returns true + @pluginhandler.expects(:load).with("foo.rb") + + @pluginhandler.load_plugin("foo.rb") + end + + it "should skip non-ruby plugins when asked to do so" do + FileTest.stubs(:exist?).returns true + @pluginhandler.expects(:load).never + + @pluginhandler.load_plugin("foo") + end + + it "should not try to load files that don't exist" do + FileTest.expects(:exist?).with("foo.rb").returns false + @pluginhandler.expects(:load).never + + @pluginhandler.load_plugin("foo.rb") + end + + it "should not try to load directories" do + FileTest.stubs(:exist?).returns true + FileTest.expects(:directory?).with("foo").returns true + @pluginhandler.expects(:load).never + + @pluginhandler.load_plugin("foo") + end + + it "should warn but not fail if loading a file raises an exception" do + FileTest.stubs(:exist?).returns true + @pluginhandler.expects(:load).with("foo.rb").raises "eh" + + Puppet.expects(:err) + @pluginhandler.load_plugin("foo.rb") + end + + it "should warn but not fail if loading a file raises a LoadError" do + FileTest.stubs(:exist?).returns true + @pluginhandler.expects(:load).with("foo.rb").raises LoadError.new("eh") + + Puppet.expects(:err) + @pluginhandler.load_plugin("foo.rb") + end end