Updated mcollective.init according to OSCI-658
[packages/precise/mcollective.git] / spec / unit / pluginmanager_spec.rb
diff --git a/spec/unit/pluginmanager_spec.rb b/spec/unit/pluginmanager_spec.rb
new file mode 100755 (executable)
index 0000000..be531c8
--- /dev/null
@@ -0,0 +1,173 @@
+#!/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