+++ /dev/null
-#!/usr/bin/env rspec
-
-require 'spec_helper'
-
-module MCollective
- describe Message do
- before do
- Config.instance.set_config_defaults("")
- end
-
- describe "#initialize" do
- it "should set defaults" do
- m = Message.new("payload", "message")
- m.payload.should == "payload"
- m.message.should == "message"
- m.request.should == nil
- m.headers.should == {}
- m.agent.should == nil
- m.collective.should == nil
- m.type.should == :message
- m.filter.should == Util.empty_filter
- m.requestid.should == nil
- m.base64?.should == false
- m.options.should == {}
- m.discovered_hosts.should == nil
- m.ttl.should == 60
- m.validated.should == false
- m.msgtime.should == 0
- m.expected_msgid == nil
- end
-
- it "should set all supplied options" do
- Message.any_instance.expects(:base64_decode!)
-
- m = Message.new("payload", "message", :base64 => true,
- :agent => "rspecagent",
- :headers => {:rspec => "test"},
- :type => :rspec,
- :filter => "filter",
- :options => {:ttl => 30},
- :collective => "collective")
- m.payload.should == "payload"
- m.message.should == "message"
- m.request.should == nil
- m.headers.should == {:rspec => "test"}
- m.agent.should == "rspecagent"
- m.collective.should == "collective"
- m.type.should == :rspec
- m.filter.should == "filter"
- m.base64?.should == true
- m.options.should == {:ttl => 30}
- m.ttl.should == 30
- end
-
- it "if given a request it should set options based on the request" do
- request = mock
- request.expects(:agent).returns("request")
- request.expects(:collective).returns("collective")
-
- m = Message.new("payload", "message", :request => request)
- m.agent.should == "request"
- m.collective.should == "collective"
- m.type.should == :reply
- m.request.should == request
- end
- end
-
- describe "#reply_to=" do
- it "should only set the reply-to header for requests" do
- Config.instance.expects(:direct_addressing).returns(true)
- m = Message.new("payload", "message", :type => :reply)
- m.discovered_hosts = ["foo"]
- expect { m.reply_to = "foo" }.to raise_error(/reply targets/)
-
- [:request, :direct_request].each do |t|
- m.type = t
- m.reply_to = "foo"
- m.reply_to.should == "foo"
- end
- end
- end
-
- describe "#expected_msgid=" do
- it "should correctly set the property" do
- m = Message.new("payload", "message", :type => :reply)
- m.expected_msgid = "rspec test"
- m.expected_msgid.should == "rspec test"
- end
-
- it "should only be set for reply messages" do
- m = Message.new("payload", "message", :type => :request)
-
- expect {
- m.expected_msgid = "rspec test"
- }.to raise_error("Can only store the expected msgid for reply messages")
- end
- end
-
- describe "#base64_decode!" do
- it "should not decode if not encoded" do
- SSL.expects(:base64_decode).never
- m = Message.new("payload", "message")
- end
-
- it "should decode encoded messages" do
- SSL.expects(:base64_decode)
- m = Message.new("payload", "message", :base64 => true)
- end
-
- it "should set base64 to false after decoding" do
- SSL.expects(:base64_decode).with("payload")
- m = Message.new("payload", "message", :base64 => true)
- m.base64?.should == false
- end
- end
-
- describe "#base64_encode" do
- it "should not encode already encoded messages" do
- SSL.expects(:base64_encode).never
- Message.any_instance.stubs(:base64_decode!)
- m = Message.new("payload", "message", :base64 => true)
- m.base64_encode!
- end
-
- it "should encode plain messages" do
- SSL.expects(:base64_encode).with("payload")
- m = Message.new("payload", "message")
- m.base64_encode!
- end
-
- it "should set base64 to false after encoding" do
- SSL.expects(:base64_encode)
- m = Message.new("payload", "message")
- m.base64_encode!
- m.base64?.should == true
- end
- end
-
- describe "#base64?" do
- it "should correctly report base64 state" do
- m = Message.new("payload", "message")
- m.base64?.should == m.instance_variable_get("@base64")
- end
- end
-
- describe "#type=" do
- it "should only allow types to be set when discovered hosts were given" do
- m = Message.new("payload", "message")
- Config.instance.stubs(:direct_addressing).returns(true)
-
- expect {
- m.type = :direct_request
- }.to raise_error("Can only set type to :direct_request if discovered_hosts have been set")
- end
-
- it "should not allow direct_request to be set if direct addressing isnt enabled" do
- m = Message.new("payload", "message")
- Config.instance.stubs(:direct_addressing).returns(false)
-
- expect {
- m.type = :direct_request
- }.to raise_error("Direct requests is not enabled using the direct_addressing config option")
- end
-
- it "should only accept valid types" do
- m = Message.new("payload", "message")
- Config.instance.stubs(:direct_addressing).returns(true)
-
- expect {
- m.type = :foo
- }.to raise_error("Unknown message type foo")
- end
-
- it "should clear the filter in direct_request mode and add just an agent filter" do
- m = Message.new("payload", "message")
- m.discovered_hosts = ["rspec"]
- Config.instance.stubs(:direct_addressing).returns(true)
-
- m.filter = Util.empty_filter.merge({"cf_class" => ["test"]})
- m.agent = "rspec"
- m.type = :direct_request
- m.filter.should == Util.empty_filter.merge({"agent" => ["rspec"]})
- end
-
- it "should set the type" do
- m = Message.new("payload", "message")
- m.type = :request
- m.type.should == :request
- end
- end
-
- describe "#encode!" do
- it "should encode replies using the security plugin #encodereply" do
- request = mock
- request.stubs(:agent).returns("rspec_agent")
- request.stubs(:collective).returns("collective")
- request.stubs(:payload).returns({:requestid => "123", :callerid => "id=callerid"})
-
- security = mock
- security.expects(:encodereply).with('rspec_agent', 'payload', '123', 'id=callerid')
- security.expects(:valid_callerid?).with("id=callerid").returns(true)
-
- PluginManager.expects("[]").with("security_plugin").returns(security).twice
-
- m = Message.new("payload", "message", :request => request, :type => :reply)
-
- m.encode!
- end
-
- it "should encode requests using the security plugin #encoderequest" do
- security = mock
- security.expects(:encoderequest).with("identity", 'payload', '123', Util.empty_filter, 'rspec_agent', 'mcollective', 60).twice
- PluginManager.expects("[]").with("security_plugin").returns(security).twice
-
- Config.instance.expects(:identity).returns("identity").twice
-
- Message.any_instance.expects(:requestid).returns("123").twice
-
- m = Message.new("payload", "message", :type => :request, :agent => "rspec_agent", :collective => "mcollective")
- m.encode!
-
- m = Message.new("payload", "message", :type => :direct_request, :agent => "rspec_agent", :collective => "mcollective")
- m.encode!
- end
-
- it "should retain the requestid if it was specifically set" do
- security = mock
- security.expects(:encoderequest).with("identity", 'payload', '123', Util.empty_filter, 'rspec_agent', 'mcollective', 60)
- PluginManager.expects("[]").with("security_plugin").returns(security)
-
- Config.instance.expects(:identity).returns("identity")
-
- m = Message.new("payload", "message", :type => :request, :agent => "rspec_agent", :collective => "mcollective")
- m.expects(:create_reqid).never
- m.requestid = "123"
- m.encode!
- m.requestid.should == "123"
- end
-
- it "should not allow bad callerids when replying" do
- request = mock
- request.stubs(:agent).returns("rspec_agent")
- request.stubs(:collective).returns("collective")
- request.stubs(:payload).returns({:requestid => "123", :callerid => "caller/id"})
-
- security = mock
- security.expects(:valid_callerid?).with("caller/id").returns(false)
- PluginManager.expects("[]").with("security_plugin").returns(security)
-
- m = Message.new("payload", "message", :request => request, :type => :reply)
-
- expect {
- m.encode!
- }.to raise_error('callerid in original request is not valid, surpressing reply to potentially forged request')
- end
- end
-
- describe "#decode!" do
- it "should check for valid types" do
- expect {
- m = Message.new("payload", "message", :type => :foo)
- m.decode!
- }.to raise_error("Cannot decode message type foo")
- end
-
- it "should set state based on decoded message" do
- msg = mock
- msg.stubs(:include?).returns(true)
- msg.stubs("[]").with(:collective).returns("collective")
- msg.stubs("[]").with(:agent).returns("rspecagent")
- msg.stubs("[]").with(:filter).returns("filter")
- msg.stubs("[]").with(:requestid).returns("1234")
- msg.stubs("[]").with(:ttl).returns(30)
- msg.stubs("[]").with(:msgtime).returns(1314628987)
-
- security = mock
- security.expects(:decodemsg).returns(msg)
- PluginManager.expects("[]").with("security_plugin").returns(security)
-
- m = Message.new(msg, "message", :type => :reply)
- m.decode!
-
- m.collective.should == "collective"
- m.agent.should == "rspecagent"
- m.filter.should == "filter"
- m.requestid.should == "1234"
- m.ttl.should == 30
- end
-
- it "should not allow bad callerids from the security plugin on requests" do
- security = mock
- security.expects(:decodemsg).returns({:callerid => "foo/bar"})
- security.expects(:valid_callerid?).with("foo/bar").returns(false)
-
- PluginManager.expects("[]").with("security_plugin").returns(security).twice
-
- m = Message.new("payload", "message", :type => :request)
-
- expect {
- m.decode!
- }.to raise_error('callerid in request is not valid, surpressing reply to potentially forged request')
- end
- end
-
- describe "#validate" do
- it "should only validate requests" do
- m = Message.new("msg", "message", :type => :reply)
- expect {
- m.validate
- }.to raise_error("Can only validate request messages")
- end
-
- it "should raise an exception for incorrect messages" do
- sec = mock
- sec.expects("validate_filter?").returns(false)
- PluginManager.expects("[]").with("security_plugin").returns(sec)
-
- payload = mock
- payload.expects("[]").with(:filter).returns({})
-
- m = Message.new(payload, "message", :type => :request)
- m.instance_variable_set("@msgtime", Time.now.to_i)
-
- expect {
- m.validate
- }.to raise_error(NotTargettedAtUs)
- end
-
- it "should pass for good messages" do
- sec = mock
- sec.expects(:validate_filter?).returns(true)
- PluginManager.expects("[]").returns(sec)
-
- payload = mock
- payload.expects("[]").with(:filter).returns({})
- m = Message.new(payload, "message", :type => :request)
- m.instance_variable_set("@msgtime", Time.now.to_i)
- m.validate
- end
-
- it "should set the @validated property" do
- sec = mock
- sec.expects(:validate_filter?).returns(true)
- PluginManager.expects("[]").returns(sec)
-
- payload = mock
- payload.expects("[]").with(:filter).returns({})
- m = Message.new(payload, "message", :type => :request)
- m.instance_variable_set("@msgtime", Time.now.to_i)
-
- m.validated.should == false
- m.validate
- m.validated.should == true
- end
-
- it "should not validate for messages older than TTL" do
- stats = mock
- stats.expects(:ttlexpired).once
-
- MCollective::PluginManager << {:type => "global_stats", :class => stats}
-
- m = Message.new({:callerid => "caller", :senderid => "sender"}, "message", :type => :request)
- m.instance_variable_set("@msgtime", (Time.now.to_i - 120))
-
- expect {
- m.validate
- }.to raise_error(MsgTTLExpired)
- end
- end
-
- describe "#publish" do
- it "should publish itself to the connector" do
- m = Message.new("msg", "message", :type => :request)
-
- connector = mock
- connector.expects(:publish).with(m)
- PluginManager.expects("[]").returns(connector)
-
- m.publish
- end
-
- it "should support direct addressing" do
- m = Message.new("msg", "message", :type => :request)
- m.discovered_hosts = ["one", "two", "three"]
-
- Config.instance.stubs(:direct_addressing).returns(true)
- Config.instance.stubs(:direct_addressing_threshold).returns(10)
-
- connector = mock
- connector.expects(:publish).with(m)
- PluginManager.expects("[]").returns(connector)
-
- m.publish
- m.type.should == :direct_request
- end
-
- it "should only direct publish below the configured threshold" do
- m = Message.new("msg", "message", :type => :request)
- m.discovered_hosts = ["one", "two", "three"]
-
- Config.instance.expects(:direct_addressing).returns(true)
- Config.instance.expects(:direct_addressing_threshold).returns(1)
-
- connector = mock
- connector.expects(:publish).with(m)
- PluginManager.expects("[]").returns(connector)
-
- m.publish
- m.type.should == :request
- end
- end
-
- describe "#create_reqid" do
- it "should create a valid request id" do
- m = Message.new("msg", "message", :agent => "rspec", :collective => "mc")
-
- SSL.expects(:uuid).returns("reqid")
-
- m.create_reqid.should == "reqid"
- end
- end
- end
-end