#!/usr/bin/env rspec require 'spec_helper' module MCollective describe PluginManager do before do class MCollective::Foo; end PluginManager.pluginlist.each {|p| PluginManager.delete p} end describe "#<<" do it "should store a plugin by name" do PluginManager << {:type => "foo", :class => "MCollective::Foo"} PluginManager.instance_variable_get("@plugins").include?("foo").should == true end it "should store a plugin instance" do f = MCollective::Foo.new PluginManager << {:type => "foo", :class => f} PluginManager.instance_variable_get("@plugins")["foo"][:instance].object_id.should == f.object_id end it "should detect duplicate plugins" do PluginManager << {:type => "foo", :class => "MCollective::Foo"} expect { PluginManager << {:type => "foo", :class => "MCollective::Foo"} }.to raise_error("Plugin foo already loaded") end it "should store single instance preference correctly" do PluginManager << {:type => "foo", :class => "MCollective::Foo", :single_instance => false} PluginManager.instance_variable_get("@plugins")["foo"][:single].should == false end it "should always set single to true when supplied an instance" do PluginManager << {:type => "foo", :class => MCollective::Foo.new, :single_instance => false} PluginManager.instance_variable_get("@plugins")["foo"][:single].should == true end end describe "#delete" do it "should remove plugins" do PluginManager << {:type => "foo", :class => MCollective::Foo.new} PluginManager.instance_variable_get("@plugins").include?("foo").should == true PluginManager.delete("foo") PluginManager.instance_variable_get("@plugins").include?("foo").should == false end end describe "#include?" do it "should correctly check if plugins were added" do PluginManager << {:type => "foo", :class => MCollective::Foo.new} PluginManager.include?("foo").should == true PluginManager.include?("bar").should == false end end describe "#pluginlist" do it "should return the correct list of plugins" do PluginManager << {:type => "foo", :class => MCollective::Foo.new} PluginManager << {:type => "bar", :class => MCollective::Foo.new} PluginManager.pluginlist.sort.should == ["bar", "foo"] end end describe "#[]" do it "should detect if the requested plugin does not exist" do expect { PluginManager["foo"] }.to raise_error("No plugin foo defined") end it "should create new instances on demand" do PluginManager << {:type => "foo", :class => "MCollective::Foo"} PluginManager["foo"].class.should == MCollective::Foo end it "should return the cached instance" do f = MCollective::Foo.new PluginManager << {:type => "foo", :class => f} PluginManager["foo"].object_id.should == f.object_id end it "should create new instances on every request if requested" do PluginManager << {:type => "foo", :class => "MCollective::Foo", :single_instance => false} PluginManager["foo"].object_id.should_not == PluginManager["foo"].object_id end end describe "#find" do before do @config.stubs(:libdir).returns(["/libdir/"]) Config.stubs(:instance).returns(@config) end it "should find all plugins in configured libdirs" do File.expects(:join).with(["/libdir/", "mcollective", "test"]).returns("/plugindir/") File.expects(:directory?).with("/plugindir/").returns(true) Dir.expects(:new).with("/plugindir/").returns(["plugin.rb"]) PluginManager.find("test").should == ["plugin"] end it "should find all plugins with a given file extension" do File.expects(:join).with(["/libdir/", "mcollective", "test"]).returns("/plugindir/") File.expects(:directory?).with("/plugindir/").returns(true) Dir.expects(:new).with("/plugindir/").returns(["plugin.ddl"]) PluginManager.find("test", "ddl").should == ["plugin"] end it "should skip libdirs that do not have the plugin type directories" do @config.stubs(:libdir).returns(["/plugindir/", "/tmp/"]) File.expects(:join).with(["/plugindir/", "mcollective", "test"]).returns("/plugindir/") File.expects(:join).with(["/tmp/", "mcollective", "test"]).returns("/tmpdir/") File.expects(:directory?).with("/plugindir/").returns(true) File.expects(:directory?).with("/tmpdir/").returns(false) Dir.expects(:new).with("/plugindir/").returns(["plugin.ddl"]) PluginManager.find("test", "ddl").should == ["plugin"] end end describe "#find_and_load" do before do @config.stubs(:libdir).returns(["/libdir/"]) Config.stubs(:instance).returns(@config) PluginManager.expects(:loadclass).with("MCollective::Test::Testplugin", true) end it "should find and load all plugins from all libdirs that match the type" do PluginManager.expects(:find).with("test", ".rb").returns(["testplugin"]) PluginManager.find_and_load("test") end it "should exclude plugins who do not match criteria if block is given" do PluginManager.expects(:find).with("test", ".rb").returns(["testplugin", "failplugin"]) PluginManager.find_and_load("test") {|plugin| plugin.match(/^test/)} end end describe "#loadclass" do it "should load the correct filename given a ruby class name" do PluginManager.stubs(:load).with("mcollective/foo.rb").once PluginManager.loadclass("MCollective::Foo") end it "should raise errors for load errors" do PluginManager.stubs(:load).raises("load failure") Log.expects(:error) expect { PluginManager.loadclass("foo") }.to raise_error(/load failure/) end it "should support squashing load errors" do PluginManager.stubs(:load).raises("load failure") Log.expects(:error) PluginManager.loadclass("foo", true) end end describe "#grep" do it "should return matching plugins from the list" do PluginManager << {:type => "foo", :class => MCollective::Foo.new} PluginManager << {:type => "bar", :class => MCollective::Foo.new} PluginManager.grep(/oo/).should == ["foo"] end end end end