require 'spec/spec_helper' class ErrorPlugin < Scout::Plugin def build_report raise 'FOO' end end class FooPlugin < Scout::Plugin OPTIONS=<<-EOS username: name: Username notes: The MySQL username to use default: other EOS end class FooPlugin::NestedPlugin < Scout::Plugin end class OptionsPlugin < Scout::Plugin OPTIONS=<<-EOS host: name: Host notes: The slave host to monitor default: 127.0.0.1 username: name: Username notes: The MySQL username to use default: root EOS end describe Deputy do before do srand(Time.now.to_f * 100000) # fixes rand in klass() not being random Socket.stub!(:gethostname).and_return 'my_host' end it "has a VERSION" do Deputy::VERSION.should =~ /^\d+\.\d+\.\d+$/ end def klass(name, options={}) <<-CODE module TEMP_#{options[:rand]||rand(11111)} def self.interval #{options[:interval] || 60} end class #{name} < Scout::Plugin #{options[:class_eval]} def build_report #{options[:code]} end end end CODE end describe Scout do describe :plugins do it "finds plugins" do Scout.plugins(klass('A', :rand => 1111)).inspect.should == '[[60, TEMP_1111::A]]' end it "reports non-plugins" do Deputy.should_receive(:send_report) Scout.plugins("module TEMP_XXX;def self.interval;60;end;class Foo;def self.interval;11;end;end;end").inspect.should == '[]' end end describe :option do it "get default" do OptionsPlugin.new.send(:option, :username).should == 'root' end it "get nil when no default is there" do OptionsPlugin.new.send(:option, :foo).should == nil end it "get nil when no OPTIONS are there" do ErrorPlugin.new.send(:option, :foo).should == nil end it "does not overwrite others" do FooPlugin.new.send(:option, :username).should == 'other' end end describe :report do it "sends a report" do Deputy.should_receive(:send_report).with("NestedPlugin.x", 1) FooPlugin::NestedPlugin.new.send(:report, :x => 1) end it "sends multiple reports" do Deputy.should_receive(:send_report).with("NestedPlugin.x", 1) Deputy.should_receive(:send_report).with("NestedPlugin.y", 2) FooPlugin::NestedPlugin.new.send(:report, :x => 1, 'y' => 2) end it "sends alerts" do Deputy.should_receive(:send_report).with("NestedPlugin.alert", '1, "2"') FooPlugin::NestedPlugin.new.send(:alert, 1, "2") end it "sends errors" do Deputy.should_receive(:send_report).with("NestedPlugin.error", '1, "2"') FooPlugin::NestedPlugin.new.send(:error, 1, "2") end end describe :memory do before do `rm -f #{FooPlugin::NestedPlugin.new.send(:memory_file)}` `rm -f #{FooPlugin.new.send(:memory_file)}` end it "remembers" do FooPlugin::NestedPlugin.new.send(:remember, 'foo' => 1) FooPlugin::NestedPlugin.new.send(:memory, 'foo').should == 1 end it "remembers different stuff" do FooPlugin::NestedPlugin.new.send(:remember, :foo => 1) FooPlugin::NestedPlugin.new.send(:remember, :bar => 1) FooPlugin::NestedPlugin.new.send(:memory, :foo).should == 1 FooPlugin::NestedPlugin.new.send(:memory, :bar).should == 1 end it "is nil for unremembered" do FooPlugin::NestedPlugin.new.send(:memory, :asdsa).should == nil FooPlugin.new.send(:memory, :asdsa).should == nil end it "remembers key and value" do FooPlugin::NestedPlugin.new.send(:remember, :foo, 1) FooPlugin::NestedPlugin.new.send(:memory, :foo).should == 1 end end describe :needs do it "can create plugins with needs" do Scout.plugins(klass('D', :class_eval => "needs 'fastercsv'", :rand => 1112)).inspect.should == '[[60, TEMP_1112::D]]' defined?(FasterCSV).should == "constant" end end describe :clean_class_name do it "is simple name for simple e.g. from irb" do FooPlugin.clean_class_name.should == 'FooPlugin' end it "is last parts for namespaced" do FooPlugin::NestedPlugin.clean_class_name.should == 'NestedPlugin' end end end describe :run_plugins do before do Deputy.stub!(:config).and_return "sheriff_url" => 'http://sheri.ff' end it "executes all plugins" do $notify = 0 FakeWeb.register_uri(:get, "http://sheri.ff/plugins.rb?hostname=my_host", :body => klass('C', :code => '$notify=1')) FakeWeb.register_uri(:get, "http://sheri.ff/notify?group=Deputies.finished&value=OK&hostname=my_host", :body => 'OK') Deputy.run_plugins $notify.should == 1 end it "does not execute not-running plugins" do $notify = 0 FakeWeb.register_uri(:get, "http://sheri.ff/plugins.rb?hostname=my_host", :body => klass('C', :code => '$notify=1', :interval => 9999999)) FakeWeb.register_uri(:get, "http://sheri.ff/notify?group=Deputies.finished&value=OK&hostname=my_host", :body => 'OK') Deputy.run_plugins $notify.should == 0 end it "sleeps a random interval if given in config" do Socket.stub!(:gethostname).and_return 'foo' Deputy.stub!(:config).and_return('max_random_start_delay' => 30) Deputy.stub!(:send_report) Deputy.should_receive(:sleep).with(25).and_raise("OK") lambda{ Deputy.run_plugins }.should raise_error("OK") end it "does not sleeps no_wait given" do FakeWeb.register_uri(:get, "http://sheri.ff/plugins.rb?hostname=my_host", :body => '') FakeWeb.register_uri(:get, "http://sheri.ff/notify?group=Deputies.finished&value=OK&hostname=my_host", :body => 'OK') Deputy.stub!(:send_report) Deputy.should_not_receive(:sleep) Deputy.run_plugins end it "fails with nice backtrace" do FakeWeb.register_uri(:get, "http://sheri.ff/plugins.rb?hostname=my_host", :body => klass('FooBar', :code => 'raise')) FakeWeb.register_uri(:get, "http://sheri.ff/notify?group=Deputies.finished&value=Error&hostname=my_host", :body => 'OK') FakeWeb.register_uri(:get, "http://sheri.ff/notify?group=Deputies.Error&value=FooBar&hostname=my_host", :body => 'OK') lambda{ Deputy.run_plugins }.should raise_error('FooBar') end it "continues to run plugins when one fails" do $notify = 0 FakeWeb.register_uri(:get, "http://sheri.ff/plugins.rb?hostname=my_host", :body => klass('FooBar', :code => 'raise') + klass('C', :code => '$notify = 1')) FakeWeb.register_uri(:get, "http://sheri.ff/notify?group=Deputies.finished&value=Error&hostname=my_host", :body => 'OK') FakeWeb.register_uri(:get, "http://sheri.ff/notify?group=Deputies.Error&value=&hostname=my_host", :body => 'OK') lambda{ Deputy.run_plugins }.should raise_error $notify.should == 1 end end describe :send_report do before do Deputy.stub!(:config).and_return "sheriff_url" => 'http://sheri.ff' end it "sends a report" do FakeWeb.register_uri(:get, "http://sheri.ff/notify?group=Xxx.yyy&value=123&hostname=my_host", :body => 'OK') Deputy.send_report('Xxx.yyy', '123').should == 'OK' end it "escapes metric names" do FakeWeb.register_uri(:get, "http://sheri.ff/notify?group=Xxx.yy%3Fy&value=123&hostname=my_host", :body => 'OK') Deputy.send_report('Xxx.yy?y', '123').should == 'OK' end it "overrides host, if specified in options" do FakeWeb.register_uri(:get, "http://sheri.ff/notify?group=Xxx.yy%3Fy&value=123&hostname=general&forced_host=true", :body => 'OK') Deputy.send_report('Xxx.yy?y', '123', {:host => 'general'}).should == 'OK' end it "does nothing, if disabled" do Deputy.stub!(:config).and_return "disabled" => true Deputy.send_report('Xxx.yy?y', '123', {:host => 'general'}).should == nil end end describe :extract_auth_from_url! do it "finds auth" do Deputy.extract_auth_from_url!('http://x:y@foo').should == ['x','y'] end it "removes auth from url" do url = 'http://x:y@foo' Deputy.extract_auth_from_url!(url) url.should == 'http://foo' end it "returns nil when auth was not found" do Deputy.extract_auth_from_url!('http://foo').should == nil end it "does not alter url when auth was not found" do url = 'http://foo' Deputy.extract_auth_from_url!(url) url.should == 'http://foo' end end end