Updated mcollective.init according to OSCI-658
[packages/precise/mcollective.git] / spec / unit / aggregate_spec.rb
diff --git a/spec/unit/aggregate_spec.rb b/spec/unit/aggregate_spec.rb
new file mode 100644 (file)
index 0000000..633b8ad
--- /dev/null
@@ -0,0 +1,170 @@
+#!/usr/bin/env rspec
+
+require 'spec_helper'
+
+module MCollective
+  describe Aggregate do
+    let(:ddl) do
+      {
+        :aggregate => [{:function => :func, :args=>[:foo, {:format => "%s"}]}],
+        :action => "test_action",
+        :output => {:foo => nil, :bar => nil}
+      }
+    end
+
+    describe '#create_functions' do
+      let(:function){mock}
+
+      it "should load all the functions with a format if defined" do
+        function.expects(:new).with(:foo, {}, "%s", 'test_action')
+        Aggregate.any_instance.expects(:contains_output?).returns(true)
+        Aggregate.any_instance.expects(:load_function).once.returns(function)
+        Aggregate.new(ddl)
+      end
+
+      it "should load all the functions without a format if it isn't defined" do
+        function.expects(:new).with(:foo, {}, nil, 'test_action')
+        Aggregate.any_instance.expects(:load_function).once.returns(function)
+        ddl[:aggregate].first[:args][1][:format] = nil
+        Aggregate.new(ddl)
+      end
+
+      it "should not summarize functions where the output is not specified in the ddl" do
+        invalid_ddl = { :aggregate => [{:function => :func, :args=>[:foo], :format => "%s"}, {:function => :func, :args=>[:fail], :format => "%s"}],
+                        :action => "test_action",
+                        :output => {:foo => nil, :bar => nil}}
+
+        function.stubs(:new).returns("function")
+        Aggregate.any_instance.stubs(:load_function).returns(function)
+
+        Log.expects(:error)
+        aggregate = Aggregate.new(invalid_ddl)
+        aggregate.functions.should == ["function"]
+        aggregate.failed.should == [{:type=>:create, :name=>:fail}]
+      end
+
+      it "should pass additional arguments if specified in the ddl" do
+        function.expects(:new).with(:foo, {:extra => "extra"}, "%s", 'test_action')
+        Aggregate.any_instance.expects(:load_function).once.returns(function)
+        ddl[:aggregate].first[:args][1][:extra] = "extra"
+        Aggregate.new(ddl)
+      end
+
+      it "should not summarize functions if the startup hook raises an exception" do
+        function.stubs(:new).raises("rspec")
+        Aggregate.any_instance.expects(:load_function).returns(function)
+
+        Log.expects(:error)
+        aggregate = Aggregate.new(ddl)
+        aggregate.failed.should == [{:type=>:startup, :name =>:foo }]
+      end
+    end
+
+    describe '#contains_ouput?' do
+      before :all do
+        Aggregate.any_instance.stubs(:create_functions)
+        @aggregate = Aggregate.new(ddl)
+      end
+
+      it "should return false if the ddl output does not include the function's input" do
+        result = @aggregate.contains_output?(:baz)
+        result.should == false
+      end
+
+      it "should return true if the ddl output includes the function's input" do
+        result = @aggregate.contains_output?(:foo)
+        result.should == true
+      end
+    end
+
+    describe '#call_functions' do
+      let(:aggregate){ Aggregate.new(ddl)}
+      let(:result){ RPC::Result.new("rspec", "rspec", :sender => "rspec", :statuscode => 0, :statusmsg => "rspec", :data => {:test => :result})}
+      let(:function) {mock}
+
+      before :each do
+        Aggregate.any_instance.stubs(:create_functions)
+      end
+
+      it "should call all of the functions" do
+        function.expects(:process_result).with(:result, result).once
+        function.expects(:output_name).returns(:test)
+        aggregate.functions = [function]
+
+        aggregate.call_functions(result)
+      end
+
+      it "should not fail if 'process_result' method raises an exception" do
+        aggregate.functions = [function]
+        function.stubs(:output_name).returns(:test)
+        function.stubs(:process_result).raises("Failed")
+
+        Log.expects(:error)
+        aggregate.call_functions(result)
+        aggregate.failed.should == [:name => :test, :type => :process_result]
+      end
+
+      it "should not fail if 'summarize' method raises en exception" do
+        function.stubs(:summarize).raises("Failed")
+        function.stubs(:output_name).returns("rspec")
+        aggregate.functions = [function]
+
+        Log.expects(:error)
+        result = aggregate.summarize
+      end
+    end
+
+    describe '#summarize' do
+      it "should return the ordered function results" do
+        Aggregate.any_instance.stubs(:create_functions)
+        aggregate = Aggregate.new(ddl)
+
+        func1 = mock
+        func1.expects(:summarize).returns(func1)
+        func1.stubs(:result).returns(:output => 5)
+
+        func2 = mock
+        func2.expects(:summarize).returns(func2)
+        func2.stubs(:result).returns(:output => 2)
+
+        aggregate.functions = [func1, func2]
+
+        result = aggregate.summarize
+        result.should == [func2, func1]
+      end
+
+      it "should not summarise data that raises an exception" do
+        Aggregate.any_instance.stubs(:create_functions)
+        aggregate = Aggregate.new(ddl)
+        func = mock
+        func.stubs(:summarize).raises("rspec")
+        func.stubs(:output_name).returns("rspec")
+        aggregate.functions = [func]
+        Log.expects(:error)
+
+        aggregate.summarize
+        aggregate.failed.should == [{:name => "rspec", :type => :summarize}]
+      end
+    end
+
+    describe '#load_function' do
+      before :all do
+        Aggregate.any_instance.stubs(:create_functions)
+        @aggregate = Aggregate.new(ddl)
+      end
+
+      it "should return a class object if it can be loaded" do
+        PluginManager.expects(:loadclass).with("MCollective::Aggregate::Test")
+        Aggregate.expects(:const_get).with("Test")
+        function = @aggregate.load_function("test")
+      end
+
+      it "should raise an exception if the class object cannot be loaded" do
+        PluginManager.expects(:loadclass).with("MCollective::Aggregate::Test")
+        expect {
+          function = @aggregate.load_function("test")
+        }.to raise_error("Aggregate function file 'test.rb' cannot be loaded")
+      end
+    end
+  end
+end