mcollective-client 2.4.1 → 2.5.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of mcollective-client might be problematic. Click here for more details.

data/lib/mcollective.rb CHANGED
@@ -13,6 +13,7 @@ require 'tempfile'
13
13
  require 'tmpdir'
14
14
  require 'mcollective/monkey_patches'
15
15
  require 'mcollective/cache'
16
+ require 'mcollective/exceptions'
16
17
 
17
18
  # == The Marionette Collective
18
19
  #
@@ -24,20 +25,6 @@ require 'mcollective/cache'
24
25
  # For an overview of the idea behind this and what it enables please see:
25
26
  # http://www.devco.net/archives/2009/10/18/middleware_for_systems_administration.php
26
27
  module MCollective
27
- # Exceptions for the RPC system
28
- class DDLValidationError<RuntimeError;end
29
- class ValidatorError<RuntimeError; end
30
- class MsgDoesNotMatchRequestID < RuntimeError; end
31
- class MsgTTLExpired<RuntimeError;end
32
- class NotTargettedAtUs<RuntimeError;end
33
- class RPCError<StandardError;end
34
- class SecurityValidationFailed<RuntimeError;end
35
-
36
- class InvalidRPCData<RPCError;end
37
- class MissingRPCData<RPCError;end
38
- class RPCAborted<RPCError;end
39
- class UnknownRPCAction<RPCError;end
40
- class UnknownRPCError<RPCError;end
41
28
 
42
29
  autoload :Agent, "mcollective/agent"
43
30
  autoload :Agents, "mcollective/agents"
@@ -15,7 +15,7 @@ module MCollective
15
15
  attr_reader :main_collective, :ssl_cipher, :registration_collective
16
16
  attr_reader :direct_addressing, :direct_addressing_threshold, :ttl
17
17
  attr_reader :default_discovery_method, :default_discovery_options
18
- attr_reader :publish_timeout, :threaded
18
+ attr_reader :publish_timeout, :threaded, :soft_shutdown
19
19
 
20
20
  def initialize
21
21
  @configured = false
@@ -113,6 +113,8 @@ module MCollective
113
113
  @default_discovery_options << val
114
114
  when "default_discovery_method"
115
115
  @default_discovery_method = val
116
+ when "soft_shutdown"
117
+ @soft_shutdown = Util.str_to_bool(val)
116
118
  when "topicprefix", "topicsep", "queueprefix", "rpchelptemplate", "helptemplatedir"
117
119
  Log.warn("Use of deprecated '#{key}' option. This option is ignored and should be removed from '#{configfile}'")
118
120
  else
@@ -190,6 +192,7 @@ module MCollective
190
192
  @mode = :client
191
193
  @publish_timeout = 2
192
194
  @threaded = false
195
+ @soft_shutdown = false
193
196
  end
194
197
 
195
198
  def read_plugin_config_dir(dir)
@@ -0,0 +1,27 @@
1
+ module MCollective
2
+ # Exceptions for the RPC system
3
+ class DDLValidationError<RuntimeError;end
4
+ class ValidatorError<RuntimeError; end
5
+ class MsgDoesNotMatchRequestID < RuntimeError; end
6
+ class MsgTTLExpired<RuntimeError;end
7
+ class NotTargettedAtUs<RuntimeError;end
8
+ class RPCError<StandardError;end
9
+ class SecurityValidationFailed<RuntimeError;end
10
+
11
+ class BackoffSuggestion<StandardError
12
+ attr_reader :backoff
13
+
14
+ def initialize(backoff = nil)
15
+ @backoff = backoff
16
+ end
17
+ end
18
+
19
+ class MessageNotReceived<BackoffSuggestion; end
20
+ class UnexpectedMessageType<BackoffSuggestion; end
21
+
22
+ class InvalidRPCData<RPCError;end
23
+ class MissingRPCData<RPCError;end
24
+ class RPCAborted<RPCError;end
25
+ class UnknownRPCAction<RPCError;end
26
+ class UnknownRPCError<RPCError;end
27
+ end
@@ -27,7 +27,10 @@ module MCollective
27
27
 
28
28
  begin
29
29
  runner = Runner.new(nil)
30
- runner.run
30
+ runner.main_loop
31
+ rescue => e
32
+ Log.warn(e.backtrace)
33
+ Log.warn(e)
31
34
  ensure
32
35
  File.unlink(pid) if pid && File.exist?(pid)
33
36
  end
@@ -2,6 +2,7 @@ require 'win32/daemon'
2
2
 
3
3
  module MCollective
4
4
  class WindowsDaemon < Win32::Daemon
5
+
5
6
  def self.daemonize_runner(pid=nil)
6
7
  raise "Writing pid files are not supported on the Windows Platform" if pid
7
8
  raise "The Windows Daemonizer should only be used on the Windows Platform" unless Util.windows?
@@ -11,15 +12,14 @@ module MCollective
11
12
 
12
13
  def service_main
13
14
  Log.debug("Starting Windows Service Daemon")
14
- while running?
15
- return if state != RUNNING
16
- @runner = Runner.new(nil)
17
- @runner.run
18
- end
19
15
 
20
- # Right now we don't have a way to let the connection and windows sleeper threads
21
- # run to conclusion. Until that is possible we iterate the list of living threads
22
- # and kill everything that isn't the main thread. This lets us exit cleanly.
16
+ @runner = Runner.new(nil)
17
+ @runner.main_loop
18
+
19
+ # On shut down there may be threads outside of the runner's context that are
20
+ # in a sleeping state, causing the stop action to wait for them to cleanly exit.
21
+ # We get around this by iterating the list of threads and killing everything that
22
+ # isn't the main thread, letting us shut down cleanly.
23
23
  Thread.list.each do |t|
24
24
  if t != Thread.current
25
25
  t.kill
@@ -30,7 +30,16 @@ module MCollective
30
30
  def service_stop
31
31
  Log.info("Windows service stopping")
32
32
  @runner.stop
33
- PluginManager["connector_plugin"].disconnect
33
+ end
34
+
35
+ def service_pause
36
+ Log.info("Pausing MCollective Windows server")
37
+ @runner.pause
38
+ end
39
+
40
+ def service_resume
41
+ Log.info("Resuming MCollective Windows server")
42
+ @runner.resume
34
43
  end
35
44
  end
36
45
  end
@@ -18,106 +18,140 @@ end
18
18
  module MCollective
19
19
  module Connector
20
20
  describe Activemq do
21
- before do
22
- unless ::Stomp::Error.constants.map{|c| c.to_s}.include?("NoCurrentConnection")
23
- class ::Stomp::Error::NoCurrentConnection < RuntimeError ; end
24
- end
25
21
 
26
- @config = mock
27
- @config.stubs(:configured).returns(true)
28
- @config.stubs(:identity).returns("rspec")
29
- @config.stubs(:collectives).returns(["mcollective"])
22
+ let(:config) do
23
+ conf = mock
24
+ conf.stubs(:configured).returns(true)
25
+ conf.stubs(:identity).returns("rspec")
26
+ conf.stubs(:collectives).returns(["mcollective"])
27
+ conf
28
+ end
30
29
 
31
- logger = mock
32
- logger.stubs(:log)
33
- logger.stubs(:start)
34
- Log.configure(logger)
30
+ let(:logger) do
31
+ log = mock
32
+ log.stubs(:log)
33
+ log.stubs(:start)
34
+ Log.configure(log)
35
+ log
36
+ end
35
37
 
36
- Config.stubs(:instance).returns(@config)
38
+ let(:msg) do
39
+ m = mock
40
+ m.stubs(:base64_encode!)
41
+ m.stubs(:payload).returns("msg")
42
+ m.stubs(:agent).returns("agent")
43
+ m.stubs(:type).returns(:reply)
44
+ m.stubs(:collective).returns("mcollective")
45
+ m
46
+ end
37
47
 
38
- @msg = mock
39
- @msg.stubs(:base64_encode!)
40
- @msg.stubs(:payload).returns("msg")
41
- @msg.stubs(:agent).returns("agent")
42
- @msg.stubs(:type).returns(:reply)
43
- @msg.stubs(:collective).returns("mcollective")
48
+ let(:subscription) do
49
+ sub = mock
50
+ sub.stubs("<<").returns(true)
51
+ sub.stubs("include?").returns(false)
52
+ sub.stubs("delete").returns(false)
53
+ sub
54
+ end
44
55
 
45
- @subscription = mock
46
- @subscription.stubs("<<").returns(true)
47
- @subscription.stubs("include?").returns(false)
48
- @subscription.stubs("delete").returns(false)
56
+ let(:connection) do
57
+ con = mock
58
+ con.stubs(:subscribe).returns(true)
59
+ con.stubs(:unsubscribe).returns(true)
60
+ con
61
+ end
62
+
63
+ let(:connector) do
64
+ Activemq.any_instance.stubs(:get_bool_option).with("activemq.use_exponential_back_off", "true").returns(true)
65
+ Activemq.any_instance.stubs(:get_option).with("activemq.initial_reconnect_delay", 0.01).returns(0.01)
66
+ Activemq.any_instance.stubs(:get_option).with("activemq.back_off_multiplier", 2).returns(2)
67
+ Activemq.any_instance.stubs(:get_option).with("activemq.max_reconnect_delay", 30.0).returns(30.0)
68
+ c = Activemq.new
69
+ c.instance_variable_set("@subscriptions", subscription)
70
+ c.instance_variable_set("@connection", connection)
71
+ c
72
+ end
49
73
 
50
- @connection = mock
51
- @connection.stubs(:subscribe).returns(true)
52
- @connection.stubs(:unsubscribe).returns(true)
74
+ before do
75
+ unless ::Stomp::Error.constants.map{|c| c.to_s}.include?("NoCurrentConnection")
76
+ class ::Stomp::Error::NoCurrentConnection < RuntimeError ; end
77
+ end
53
78
 
54
- @c = Activemq.new
55
- @c.instance_variable_set("@subscriptions", @subscription)
56
- @c.instance_variable_set("@connection", @connection)
79
+ logger
80
+ Config.stubs(:instance).returns(config)
57
81
  end
58
82
 
59
83
  describe "#initialize" do
84
+ before :each do
85
+ Activemq.any_instance.stubs(:get_bool_option).with("activemq.use_exponential_back_off", "true").returns(true)
86
+ Activemq.any_instance.stubs(:get_option).with("activemq.initial_reconnect_delay", 0.01).returns(0.01)
87
+ Activemq.any_instance.stubs(:get_option).with("activemq.back_off_multiplier", 2).returns(2)
88
+ Activemq.any_instance.stubs(:get_option).with("activemq.max_reconnect_delay", 30.0).returns(30.0)
89
+ end
90
+
60
91
  it "should set the @config variable" do
61
- c = Activemq.new
62
- c.instance_variable_get("@config").should == @config
92
+ connector_obj = Activemq.new
93
+ connector_obj.instance_variable_get("@config").should == config
63
94
  end
64
95
 
65
96
  it "should set @subscriptions to an empty list" do
66
- c = Activemq.new
67
- c.instance_variable_get("@subscriptions").should == []
97
+ connector_obj = Activemq.new
98
+ connector_obj.instance_variable_get("@subscriptions").should == []
68
99
  end
69
100
  end
70
101
 
71
102
  describe "#connect" do
103
+ before :each do
104
+ Activemq.any_instance.stubs(:get_option).with("activemq.heartbeat_interval", 0).returns(30)
105
+ Activemq.any_instance.stubs(:get_bool_option).with('activemq.stomp_1_0_fallback', true).returns(true)
106
+ Activemq.any_instance.stubs(:get_bool_option).with('activemq.base64', 'false').returns(false)
107
+ Activemq.any_instance.stubs(:get_option).with('activemq.vhost', 'mcollective').returns('rspec')
108
+ Activemq.any_instance.stubs(:get_option).with("activemq.max_reconnect_attempts", 0).returns(5)
109
+ Activemq.any_instance.stubs(:get_bool_option).with("activemq.randomize", "false").returns(true)
110
+ Activemq.any_instance.stubs(:get_bool_option).with("activemq.backup", "false").returns(true)
111
+ Activemq.any_instance.stubs(:get_option).with("activemq.timeout", -1).returns(1)
112
+ Activemq.any_instance.stubs(:get_option).with("activemq.connect_timeout", 30).returns(5)
113
+ Activemq.any_instance.stubs(:get_option).with("activemq.max_hbrlck_fails", 2).returns(2)
114
+ Activemq.any_instance.stubs(:get_option).with("activemq.max_hbread_fails", 2).returns(2)
115
+ Activemq.any_instance.stubs(:get_bool_option).with("activemq.base64", 'false').returns(false)
116
+ Activemq.any_instance.stubs(:get_option).with("activemq.priority", 0).returns(0)
117
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.size").returns(2)
118
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.host").returns("host1")
119
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.port", 61613).returns(6163)
120
+ Activemq.any_instance.stubs(:get_bool_option).with("activemq.pool.1.ssl", "false").returns(false)
121
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.2.host").returns("host2")
122
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.2.port", 61613).returns(6164)
123
+ Activemq.any_instance.stubs(:get_bool_option).with("activemq.pool.2.ssl", "false").returns(true)
124
+ Activemq.any_instance.stubs(:get_bool_option).with("activemq.pool.2.ssl.fallback", "false").returns(true)
125
+ Activemq.any_instance.stubs(:get_env_or_option).with("STOMP_USER", "activemq.pool.1.user").returns("user1")
126
+ Activemq.any_instance.stubs(:get_env_or_option).with("STOMP_USER", "activemq.pool.2.user").returns("user2")
127
+ Activemq.any_instance.stubs(:get_env_or_option).with("STOMP_PASSWORD", "activemq.pool.1.password").returns("password1")
128
+ Activemq.any_instance.stubs(:get_env_or_option).with("STOMP_PASSWORD", "activemq.pool.2.password").returns("password2")
129
+ Activemq.any_instance.instance_variable_set("@subscriptions", subscription)
130
+ Activemq.any_instance.instance_variable_set("@connection", connection)
131
+ end
132
+
72
133
  it "should not try to reconnect if already connected" do
73
134
  Log.expects(:debug).with("Already connection, not re-initializing connection").once
74
- @c.connect
135
+ connector.connect
75
136
  end
76
137
 
77
138
  it "should support new style config" do
78
- pluginconf = {"activemq.pool.size" => "2",
79
- "activemq.pool.1.host" => "host1",
80
- "activemq.pool.1.port" => "6163",
81
- "activemq.pool.1.user" => "user1",
82
- "activemq.pool.1.password" => "password1",
83
- "activemq.pool.1.ssl" => "false",
84
- "activemq.pool.2.host" => "host2",
85
- "activemq.pool.2.port" => "6164",
86
- "activemq.pool.2.user" => "user2",
87
- "activemq.pool.2.password" => "password2",
88
- "activemq.pool.2.ssl" => "true",
89
- "activemq.pool.2.ssl.fallback" => "true",
90
- "activemq.initial_reconnect_delay" => "0.02",
91
- "activemq.max_reconnect_delay" => "40",
92
- "activemq.use_exponential_back_off" => "false",
93
- "activemq.back_off_multiplier" => "3",
94
- "activemq.max_reconnect_attempts" => "5",
95
- "activemq.randomize" => "true",
96
- "activemq.backup" => "true",
97
- "activemq.timeout" => "1",
98
- "activemq.max_hbrlck_fails" => 3,
99
- "activemq.max_hbread_fails" => 3,
100
- "activemq.connect_timeout" => "5"}
101
-
102
-
103
139
  ENV.delete("STOMP_USER")
104
140
  ENV.delete("STOMP_PASSWORD")
105
141
 
106
- @config.expects(:pluginconf).returns(pluginconf).at_least_once
107
-
108
142
  Activemq::EventLogger.expects(:new).returns("logger")
109
143
 
110
- connector = mock
111
- connector.expects(:new).with(:backup => true,
112
- :back_off_multiplier => 3,
113
- :max_reconnect_delay => 40.0,
144
+ connector_obj = mock
145
+ connector_obj.expects(:new).with(:backup => true,
146
+ :back_off_multiplier => 2,
147
+ :max_reconnect_delay => 30.0,
114
148
  :timeout => 1,
115
149
  :connect_timeout => 5,
116
- :use_exponential_back_off => false,
150
+ :use_exponential_back_off => true,
117
151
  :max_reconnect_attempts => 5,
118
- :initial_reconnect_delay => 0.02,
119
- :max_hbread_fails => 3,
120
- :max_hbrlck_fails => 3,
152
+ :initial_reconnect_delay => 0.01,
153
+ :max_hbread_fails => 2,
154
+ :max_hbrlck_fails => 2,
121
155
  :randomize => true,
122
156
  :reliable => true,
123
157
  :logger => "logger",
@@ -134,130 +168,142 @@ module MCollective
134
168
  :login => 'user2'}
135
169
  ])
136
170
 
137
- @c.expects(:ssl_parameters).with(2, true).returns(true)
138
- @c.expects(:connection_headers).returns({})
171
+ connector.expects(:ssl_parameters).with(2, true).returns(true)
172
+ connector.expects(:connection_headers).returns({})
139
173
 
140
- @c.instance_variable_set("@connection", nil)
141
- @c.connect(connector)
174
+ connector.instance_variable_set("@connection", nil)
175
+ connector.connect(connector_obj)
176
+ end
177
+ end
178
+
179
+ describe "#stomp_version_supports_heartbeat?" do
180
+ it "should not be supported with stomp 1.2.9" do
181
+ connector.stubs(:stomp_version).returns("1.2.9")
182
+ connector.stomp_version_supports_heartbeat? == false
183
+ end
184
+
185
+ it "should be supported with stomp 1.2.10" do
186
+ connector.stubs(:stomp_version).returns("1.2.10")
187
+ connector.stomp_version_supports_heartbeat? == true
142
188
  end
143
189
  end
144
190
 
145
191
  describe "#connection_headers" do
146
192
  before do
147
- @c.stubs(:stomp_version).returns("1.2.10")
193
+ connector.stubs(:stomp_version).returns("1.2.10")
194
+ Activemq.any_instance.stubs(:get_option).with("activemq.heartbeat_interval", 0).returns(1)
195
+ Activemq.any_instance.stubs(:get_bool_option).with('activemq.stomp_1_0_fallback', true).returns(true)
196
+ Activemq.any_instance.stubs(:get_option).with('activemq.vhost', 'mcollective').returns('rspec')
148
197
  end
149
198
 
150
199
  it "should default to stomp 1.0 only" do
151
- @config.expects(:pluginconf).returns({}).at_least_once
152
- @c.connection_headers[:"accept-version"] == "1.0"
200
+ Activemq.any_instance.stubs(:get_option).with("activemq.heartbeat_interval", 0).returns(0)
201
+ connector.connection_headers[:"accept-version"] == "1.0"
153
202
  end
154
203
 
155
204
  it "should support setting the vhost" do
156
- @config.expects(:pluginconf).returns("activemq.vhost" => "rspec").at_least_once
157
- @c.connection_headers.should == {:host => "rspec", :"accept-version" => "1.0"}
205
+ connector.connection_headers[:host].should == "rspec"
206
+ end
207
+
208
+ it "should log an informational message about not using Stomp 1.1" do
209
+ Activemq.any_instance.stubs(:get_option).with("activemq.heartbeat_interval", 0).returns(0)
210
+ Log.expects(:info).with(regexp_matches(/without STOMP 1.1 heartbeats/))
211
+ connector.connection_headers
158
212
  end
159
213
 
160
- it "should log a warning about not using Stomp 1.1" do
161
- @config.expects(:pluginconf).returns("activemq.heartbeat_interval" => "0").at_least_once
162
- Log.expects(:warn).with(regexp_matches(/without STOMP 1.1 heartbeats/))
163
- @c.connection_headers
214
+ it "should not log an informational message about not using Stomp 1.1 if the gem won't support it" do
215
+ Activemq.any_instance.stubs(:get_option).with("activemq.heartbeat_interval", 0).returns(0)
216
+ connector.stubs(:stomp_version).returns("1.0.0")
217
+ Log.expects(:info).with(regexp_matches(/without STOMP 1.1 heartbeats/)).never
218
+ connector.connection_headers
164
219
  end
165
220
 
166
221
  it "should not support stomp 1.1 with older versions of the stomp gem" do
167
- @config.expects(:pluginconf).returns("activemq.heartbeat_interval" => "30").at_least_once
168
- @c.expects(:stomp_version).returns("1.0.0").once
169
- expect { @c.connection_headers }.to raise_error("Setting STOMP 1.1 properties like heartbeat intervals require at least version 1.2.10 of the STOMP gem")
222
+ Activemq.any_instance.stubs(:get_option).with("activemq.heartbeat_interval", 0).returns(1)
223
+ connector.expects(:stomp_version).returns("1.0.0").once
224
+ expect { connector.connection_headers }.to raise_error("Setting STOMP 1.1 properties like heartbeat intervals require at least version 1.2.10 of the STOMP gem")
170
225
  end
171
226
 
172
227
  it "should force the heartbeat to min 30 seconds" do
173
- @config.expects(:pluginconf).returns("activemq.heartbeat_interval" => "10").at_least_once
174
- @c.connection_headers[:"heart-beat"].should == "30500,29500"
228
+ Activemq.any_instance.stubs(:get_option).with("activemq.heartbeat_interval", 0).returns(1)
229
+ connector.connection_headers[:"heart-beat"].should == "30500,29500"
175
230
  end
176
231
 
177
232
  it "should default to 1.0 and 1.1 support" do
178
- @config.expects(:pluginconf).returns("activemq.heartbeat_interval" => "30").at_least_once
179
- @c.connection_headers[:"accept-version"].should == "1.1,1.0"
233
+ Activemq.any_instance.stubs(:get_option).with("activemq.heartbeat_interval", 0).returns(1)
234
+ connector.connection_headers[:"accept-version"].should == "1.1,1.0"
180
235
  end
181
236
 
182
237
  it "should support stomp 1.1 only operation" do
183
- @config.expects(:pluginconf).returns("activemq.heartbeat_interval" => "30", "activemq.stomp_1_0_fallback" => 0).at_least_once
184
- @c.connection_headers[:"accept-version"].should == "1.1"
238
+ Activemq.any_instance.stubs(:get_option).with("activemq.heartbeat_interval", 0).returns(1)
239
+ Activemq.any_instance.stubs(:get_bool_option).with("activemq.stomp_1_0_fallback", true).returns(false)
240
+ connector.connection_headers[:"accept-version"].should == "1.1"
185
241
  end
186
242
  end
187
243
 
188
244
  describe "#ssl_paramaters" do
189
- it "should ensure all settings are provided" do
190
- pluginconf = {"activemq.pool.1.host" => "host1",
191
- "activemq.pool.1.port" => "6164",
192
- "activemq.pool.1.user" => "user1",
193
- "activemq.pool.1.password" => "password1",
194
- "activemq.pool.1.ssl" => "true",
195
- "activemq.pool.1.ssl.cert" => "rspec"}
196
245
 
197
- @config.expects(:pluginconf).returns(pluginconf).at_least_once
246
+ before :each do
247
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.host").returns("host1")
248
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.port").returns("6164")
249
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.user").returns("user1")
250
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.password").returns("password1")
251
+ Activemq.any_instance.stubs(:get_bool_option).with("activemq.pool.1.ssl", false).returns(true)
252
+ end
253
+
254
+ it "should ensure all settings are provided" do
255
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.cert", false).returns("rspec")
256
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.key", false).returns(nil)
257
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.ca", false).returns(nil)
198
258
 
199
- expect { @c.ssl_parameters(1, false) }.to raise_error("cert, key and ca has to be supplied for verified SSL mode")
259
+ expect { connector.ssl_parameters(1, false) }.to raise_error("cert, key and ca has to be supplied for verified SSL mode")
200
260
  end
201
261
 
202
262
  it "should verify the ssl files exist" do
203
- pluginconf = {"activemq.pool.1.host" => "host1",
204
- "activemq.pool.1.port" => "6164",
205
- "activemq.pool.1.user" => "user1",
206
- "activemq.pool.1.password" => "password1",
207
- "activemq.pool.1.ssl" => "true",
208
- "activemq.pool.1.ssl.cert" => "rspec.cert",
209
- "activemq.pool.1.ssl.key" => "rspec.key",
210
- "activemq.pool.1.ssl.ca" => "rspec1.ca,rspec2.ca"}
211
-
212
- @config.expects(:pluginconf).returns(pluginconf).at_least_once
213
- @c.expects(:get_key_file).returns("rspec.key").at_least_once
214
- @c.expects(:get_cert_file).returns("rspec.cert").at_least_once
263
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.cert", false).returns("rspec")
264
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.key", false).returns('rspec.key')
265
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.ca", false).returns('rspec1.ca,rspec2.ca')
266
+
267
+ connector.expects(:get_key_file).returns("rspec.key").at_least_once
268
+ connector.expects(:get_cert_file).returns("rspec.cert").at_least_once
215
269
 
216
270
  File.expects(:exist?).with("rspec.cert").twice.returns(true)
217
271
  File.expects(:exist?).with("rspec.key").twice.returns(true)
218
272
  File.expects(:exist?).with("rspec1.ca").twice.returns(true)
219
273
  File.expects(:exist?).with("rspec2.ca").twice.returns(false)
220
274
 
221
- expect { @c.ssl_parameters(1, false) }.to raise_error("Cannot find CA file rspec2.ca")
275
+ expect { connector.ssl_parameters(1, false) }.to raise_error("Cannot find CA file rspec2.ca")
222
276
 
223
- @c.ssl_parameters(1, true).should == true
277
+ connector.ssl_parameters(1, true).should == true
224
278
  end
225
279
 
226
280
  it "should support fallback mode when there are errors" do
227
- pluginconf = {"activemq.pool.1.host" => "host1",
228
- "activemq.pool.1.port" => "6164",
229
- "activemq.pool.1.user" => "user1",
230
- "activemq.pool.1.password" => "password1",
231
- "activemq.pool.1.ssl" => "true"}
232
-
233
- @config.expects(:pluginconf).returns(pluginconf).at_least_once
281
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.cert", false).returns("rspec")
282
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.key", false).returns('rspec.key')
283
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.ca", false).returns('rspec1.ca,rspec2.ca')
234
284
 
235
- @c.ssl_parameters(1, true).should == true
285
+ connector.ssl_parameters(1, true).should == true
236
286
  end
237
287
 
238
288
  it "should fail if fallback isnt enabled" do
239
- pluginconf = {"activemq.pool.1.host" => "host1",
240
- "activemq.pool.1.port" => "6164",
241
- "activemq.pool.1.user" => "user1",
242
- "activemq.pool.1.password" => "password1",
243
- "activemq.pool.1.ssl" => "true"}
244
-
245
- @config.expects(:pluginconf).returns(pluginconf).at_least_once
289
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.cert", false).returns("rspec")
290
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.key", false).returns('rspec.key')
291
+ Activemq.any_instance.stubs(:get_option).with("activemq.pool.1.ssl.ca", false).returns('rspec1.ca,rspec2.ca')
246
292
 
247
- expect { @c.ssl_parameters(1, false) }.to raise_error
293
+ expect { connector.ssl_parameters(1, false) }.to raise_error
248
294
  end
249
295
  end
250
296
 
251
297
  describe "#get_key_file" do
252
298
  it "should return the filename from the environment variable" do
253
299
  ENV["MCOLLECTIVE_ACTIVEMQ_POOL2_SSL_KEY"] = "/path/to/rspec/env"
254
- @c.get_key_file(2).should == "/path/to/rspec/env"
300
+ connector.get_key_file(2).should == "/path/to/rspec/env"
255
301
  end
256
302
 
257
303
  it "should return the filename defined in the config file if the environment varialbe doesn't exist" do
258
304
  ENV.delete("MCOLLECTIVE_ACTIVEMQ_POOL2_SSL_KEY")
259
- @c.expects(:get_option).with("activemq.pool.2.ssl.key", false).returns("/path/to/rspec/conf")
260
- @c.get_key_file(2).should == "/path/to/rspec/conf"
305
+ connector.expects(:get_option).with("activemq.pool.2.ssl.key", false).returns("/path/to/rspec/conf")
306
+ connector.get_key_file(2).should == "/path/to/rspec/conf"
261
307
  end
262
308
 
263
309
  end
@@ -265,75 +311,120 @@ module MCollective
265
311
  describe "#get_cert_file" do
266
312
  it "should return the filename from the environment variable" do
267
313
  ENV["MCOLLECTIVE_ACTIVEMQ_POOL2_SSL_CERT"] = "/path/to/rspec/env"
268
- @c.get_cert_file(2).should == "/path/to/rspec/env"
314
+ connector.get_cert_file(2).should == "/path/to/rspec/env"
269
315
  end
270
316
 
271
317
  it "should return the filename defined in the config file if the environment varialbe doesn't exist" do
272
318
  ENV.delete("MCOLLECTIVE_ACTIVEMQ_POOL2_SSL_CERT")
273
- @c.expects(:get_option).with("activemq.pool.2.ssl.cert", false).returns("/path/to/rspec/conf")
274
- @c.get_cert_file(2).should == "/path/to/rspec/conf"
319
+ connector.expects(:get_option).with("activemq.pool.2.ssl.cert", false).returns("/path/to/rspec/conf")
320
+ connector.get_cert_file(2).should == "/path/to/rspec/conf"
321
+ end
322
+ end
323
+
324
+ describe '#exponential_back_off' do
325
+ it "should not do anything when use_exponential_back_off is off" do
326
+ connector.instance_variable_set(:@use_exponential_back_off, false)
327
+ connector.exponential_back_off.should == nil
328
+ end
329
+
330
+ it 'should return values of the expected sequence on subsequent calls' do
331
+ connector.instance_variable_set(:@use_exponential_back_off, true)
332
+ connector.instance_variable_set(:@initial_reconnect_delay, 5.0)
333
+ connector.instance_variable_set(:@back_off_multiplier, 2)
334
+ connector.instance_variable_set(:@max_reconnect_delay, 30.0)
335
+ connector.instance_variable_set(:@reconnect_delay, 5.0)
336
+
337
+ connector.exponential_back_off.should == 5
338
+ connector.exponential_back_off.should == 10
339
+ connector.exponential_back_off.should == 20
340
+ connector.exponential_back_off.should == 30
341
+ connector.exponential_back_off.should == 30
275
342
  end
276
343
  end
277
344
 
278
345
  describe "#receive" do
279
346
  it "should receive from the middleware" do
280
347
  payload = mock
348
+ payload.stubs(:command).returns("MESSAGE")
281
349
  payload.stubs(:body).returns("msg")
282
350
  payload.stubs(:headers).returns("headers")
283
351
 
284
- @connection.expects(:receive).returns(payload)
352
+ connection.expects(:receive).returns(payload)
285
353
 
286
354
  Message.expects(:new).with("msg", payload, :base64 => true, :headers => "headers").returns("message")
287
- @c.instance_variable_set("@base64", true)
355
+ connector.instance_variable_set("@base64", true)
288
356
 
289
- received = @c.receive
357
+ received = connector.receive
290
358
  received.should == "message"
291
359
  end
292
360
 
293
361
  it "should sleep and retry if recieving while disconnected" do
294
362
  payload = mock
363
+ payload.stubs(:command).returns("MESSAGE")
295
364
  payload.stubs(:body).returns("msg")
296
365
  payload.stubs(:headers).returns("headers")
297
366
 
298
367
  Message.stubs(:new).returns("rspec")
299
- @connection.expects(:receive).raises(::Stomp::Error::NoCurrentConnection).returns(payload).twice
300
- @c.expects(:sleep).with(1)
368
+ connection.expects(:receive).raises(::Stomp::Error::NoCurrentConnection).returns(payload).twice
369
+ connector.expects(:sleep).with(1)
370
+
371
+ connector.receive.should == "rspec"
372
+ end
373
+
374
+ it "should raise an error on failure to receive a frame" do
375
+ connection.expects(:receive).returns(nil)
376
+
377
+ expect { connector.receive }.to raise_error(MessageNotReceived, /No message received from ActiveMQ./)
378
+ end
379
+
380
+ it "should log and raise UnexpectedMessageType on non-MESSAGE frames" do
381
+ payload = mock
382
+ payload.stubs(:command).returns("ERROR")
383
+ payload.stubs(:body).returns("Out of cheese exception")
384
+ payload.stubs(:headers).returns("headers")
301
385
 
302
- @c.receive.should == "rspec"
386
+ connection.expects(:receive).returns(payload)
387
+
388
+ Message.stubs(:new)
389
+
390
+ Log.stubs(:debug)
391
+ Log.expects(:debug).with('Unexpected \'ERROR\' frame. Headers: "headers" Body: "Out of cheese exception"')
392
+
393
+ expect { connector.receive }.to raise_error(UnexpectedMessageType, /Received frame of type 'ERROR' expected 'MESSAGE'/)
303
394
  end
304
395
  end
305
396
 
306
397
  describe "#publish" do
307
398
  before do
308
- @connection.stubs(:publish).with("test", "msg", {}).returns(true)
399
+ connection.stubs(:publish).with("test", "msg", {}).returns(true)
309
400
  end
310
401
 
311
402
  it "should base64 encode a message if configured to do so" do
312
- @c.instance_variable_set("@base64", true)
313
- @c.expects(:headers_for).returns({})
314
- @c.expects(:target_for).returns({:name => "test", :headers => {}})
315
- @connection.expects(:publish).with("test", "msg", {})
316
- @msg.expects(:base64_encode!)
403
+ connector.instance_variable_set("@base64", true)
404
+ connector.expects(:headers_for).returns({})
405
+ connector.expects(:target_for).returns({:name => "test", :headers => {}})
406
+ connection.expects(:publish).with("test", "msg", {})
407
+ msg.expects(:base64_encode!)
317
408
 
318
- @c.publish(@msg)
409
+ connector.publish(msg)
319
410
  end
320
411
 
321
412
  it "should not base64 encode if not configured to do so" do
322
- @c.instance_variable_set("@base64", false)
323
- @c.expects(:headers_for).returns({})
324
- @c.expects(:target_for).returns({:name => "test", :headers => {}})
325
- @connection.expects(:publish).with("test", "msg", {})
326
- @msg.expects(:base64_encode!).never
413
+ connector.instance_variable_set("@base64", false)
414
+ connector.expects(:headers_for).returns({})
415
+ connector.expects(:target_for).returns({:name => "test", :headers => {}})
416
+ connection.expects(:publish).with("test", "msg", {})
417
+ msg.expects(:base64_encode!).never
327
418
 
328
- @c.publish(@msg)
419
+ connector.publish(msg)
329
420
  end
330
421
 
331
422
  it "should publish the correct message to the correct target with msgheaders" do
332
- @connection.expects(:publish).with("test", "msg", {"test" => "test"}).once
333
- @c.expects(:headers_for).returns({"test" => "test"})
334
- @c.expects(:target_for).returns({:name => "test", :headers => {}})
423
+ connection.expects(:publish).with("test", "msg", {"test" => "test"}).once
424
+ connector.expects(:headers_for).returns({"test" => "test"})
425
+ connector.expects(:target_for).returns({:name => "test", :headers => {}})
335
426
 
336
- @c.publish(@msg)
427
+ connector.publish(msg)
337
428
  end
338
429
 
339
430
  it "should publish direct messages based on discovered_hosts" do
@@ -345,65 +436,65 @@ module MCollective
345
436
  msg.stubs(:type).returns(:direct_request)
346
437
  msg.expects(:discovered_hosts).returns(["one", "two"])
347
438
 
348
- @c.expects(:headers_for).with(msg, "one")
349
- @c.expects(:headers_for).with(msg, "two")
350
- @connection.expects(:publish).with('/queue/mcollective.nodes', 'msg', nil).twice
439
+ connector.expects(:headers_for).with(msg, "one")
440
+ connector.expects(:headers_for).with(msg, "two")
441
+ connection.expects(:publish).with('/queue/mcollective.nodes', 'msg', nil).twice
351
442
 
352
- @c.publish(msg)
443
+ connector.publish(msg)
353
444
  end
354
445
  end
355
446
 
356
447
  describe "#subscribe" do
357
448
  it "should handle duplicate subscription errors" do
358
- @connection.expects(:subscribe).raises(::Stomp::Error::DuplicateSubscription)
449
+ connection.expects(:subscribe).raises(::Stomp::Error::DuplicateSubscription)
359
450
  Log.expects(:error).with(regexp_matches(/already had a matching subscription, ignoring/))
360
- @c.subscribe("test", :broadcast, "mcollective")
451
+ connector.subscribe("test", :broadcast, "mcollective")
361
452
  end
362
453
 
363
454
  it "should use the make_target correctly" do
364
- @c.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}})
365
- @c.subscribe("test", :broadcast, "mcollective")
455
+ connector.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}})
456
+ connector.subscribe("test", :broadcast, "mcollective")
366
457
  end
367
458
 
368
459
  it "should check for existing subscriptions" do
369
- @c.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}, :id => "rspec"})
370
- @subscription.expects("include?").with("rspec").returns(false)
371
- @connection.expects(:subscribe).never
460
+ connector.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}, :id => "rspec"})
461
+ subscription.expects("include?").with("rspec").returns(false)
462
+ connection.expects(:subscribe).never
372
463
 
373
- @c.subscribe("test", :broadcast, "mcollective")
464
+ connector.subscribe("test", :broadcast, "mcollective")
374
465
  end
375
466
 
376
467
  it "should subscribe to the middleware" do
377
- @c.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}, :id => "rspec"})
378
- @connection.expects(:subscribe).with("test", {}, "rspec")
379
- @c.subscribe("test", :broadcast, "mcollective")
468
+ connector.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}, :id => "rspec"})
469
+ connection.expects(:subscribe).with("test", {}, "rspec")
470
+ connector.subscribe("test", :broadcast, "mcollective")
380
471
  end
381
472
 
382
473
  it "should add to the list of subscriptions" do
383
- @c.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}, :id => "rspec"})
384
- @subscription.expects("<<").with("rspec")
385
- @c.subscribe("test", :broadcast, "mcollective")
474
+ connector.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}, :id => "rspec"})
475
+ subscription.expects("<<").with("rspec")
476
+ connector.subscribe("test", :broadcast, "mcollective")
386
477
  end
387
478
  end
388
479
 
389
480
  describe "#unsubscribe" do
390
481
  it "should use make_target correctly" do
391
- @c.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}})
392
- @c.unsubscribe("test", :broadcast, "mcollective")
482
+ connector.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}})
483
+ connector.unsubscribe("test", :broadcast, "mcollective")
393
484
  end
394
485
 
395
486
  it "should unsubscribe from the target" do
396
- @c.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}, :id => "rspec"})
397
- @connection.expects(:unsubscribe).with("test", {}, "rspec").once
487
+ connector.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}, :id => "rspec"})
488
+ connection.expects(:unsubscribe).with("test", {}, "rspec").once
398
489
 
399
- @c.unsubscribe("test", :broadcast, "mcollective")
490
+ connector.unsubscribe("test", :broadcast, "mcollective")
400
491
  end
401
492
 
402
493
  it "should delete the source from subscriptions" do
403
- @c.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}, :id => "rspec"})
404
- @subscription.expects(:delete).with("rspec").once
494
+ connector.expects("make_target").with("test", :broadcast, "mcollective").returns({:name => "test", :headers => {}, :id => "rspec"})
495
+ subscription.expects(:delete).with("rspec").once
405
496
 
406
- @c.unsubscribe("test", :broadcast, "mcollective")
497
+ connector.unsubscribe("test", :broadcast, "mcollective")
407
498
  end
408
499
  end
409
500
 
@@ -417,7 +508,7 @@ module MCollective
417
508
 
418
509
  message.expects(:request).returns(request)
419
510
 
420
- @c.target_for(message).should == {:name => "foo", :headers => {}}
511
+ connector.target_for(message).should == {:name => "foo", :headers => {}}
421
512
  end
422
513
 
423
514
  it "should create new request targets" do
@@ -426,8 +517,8 @@ module MCollective
426
517
  message.expects(:agent).returns("rspecagent")
427
518
  message.expects(:collective).returns("mcollective")
428
519
 
429
- @c.expects(:make_target).with("rspecagent", :request, "mcollective")
430
- @c.target_for(message)
520
+ connector.expects(:make_target).with("rspecagent", :request, "mcollective")
521
+ connector.target_for(message)
431
522
  end
432
523
 
433
524
  it "should support direct requests" do
@@ -436,8 +527,8 @@ module MCollective
436
527
  message.expects(:agent).returns("rspecagent")
437
528
  message.expects(:collective).returns("mcollective")
438
529
 
439
- @c.expects(:make_target).with("rspecagent", :direct_request, "mcollective")
440
- @c.target_for(message)
530
+ connector.expects(:make_target).with("rspecagent", :direct_request, "mcollective")
531
+ connector.target_for(message)
441
532
  end
442
533
 
443
534
  it "should fail for unknown message types" do
@@ -445,16 +536,16 @@ module MCollective
445
536
  message.stubs(:type).returns(:fail)
446
537
 
447
538
  expect {
448
- @c.target_for(message)
539
+ connector.target_for(message)
449
540
  }.to raise_error("Don't now how to create a target for message type fail")
450
541
  end
451
542
  end
452
543
 
453
544
  describe "#disconnect" do
454
545
  it "should disconnect from the stomp connection" do
455
- @connection.expects(:disconnect)
456
- @c.disconnect
457
- @c.connection.should == nil
546
+ connection.expects(:disconnect)
547
+ connector.disconnect
548
+ connector.connection.should == nil
458
549
  end
459
550
  end
460
551
 
@@ -466,8 +557,8 @@ module MCollective
466
557
 
467
558
  Time.expects(:now).twice.returns(Time.at(1368557431))
468
559
 
469
- @c.instance_variable_set("@msgpriority", 0)
470
- @c.headers_for(message).should_not includes("priority")
560
+ connector.instance_variable_set("@msgpriority", 0)
561
+ connector.headers_for(message).should_not includes("priority")
471
562
  end
472
563
 
473
564
  it "should return a priority if priority is non 0" do
@@ -477,8 +568,8 @@ module MCollective
477
568
 
478
569
  Time.expects(:now).twice.returns(Time.at(1368557431))
479
570
 
480
- @c.instance_variable_set("@msgpriority", 1)
481
- @c.headers_for(message)["priority"].should == 1
571
+ connector.instance_variable_set("@msgpriority", 1)
572
+ connector.headers_for(message)["priority"].should == 1
482
573
  end
483
574
 
484
575
  it "should set mc_identity for direct requests" do
@@ -491,10 +582,10 @@ module MCollective
491
582
 
492
583
  Time.expects(:now).twice.returns(Time.at(1368557431))
493
584
 
494
- @c.instance_variable_set("@msgpriority", 0)
495
- @c.expects(:make_target).with("rspecagent", :reply, "mcollective").returns({:name => "test"})
585
+ connector.instance_variable_set("@msgpriority", 0)
586
+ connector.expects(:make_target).with("rspecagent", :reply, "mcollective").returns({:name => "test"})
496
587
 
497
- headers = @c.headers_for(message, "some.node")
588
+ headers = connector.headers_for(message, "some.node")
498
589
  headers["mc_identity"].should == "some.node"
499
590
  headers["reply-to"].should == "test"
500
591
  end
@@ -509,9 +600,9 @@ module MCollective
509
600
 
510
601
  Time.expects(:now).twice.returns(Time.at(1368557431))
511
602
 
512
- @c.instance_variable_set("@msgpriority", 0)
513
- @c.expects(:make_target).with("rspecagent", :reply, "mcollective").returns({:name => "test"})
514
- @c.headers_for(message)["reply-to"].should == "test"
603
+ connector.instance_variable_set("@msgpriority", 0)
604
+ connector.expects(:make_target).with("rspecagent", :reply, "mcollective").returns({:name => "test"})
605
+ connector.headers_for(message)["reply-to"].should == "test"
515
606
  end
516
607
 
517
608
  it "should set reply-to correctly if the message defines it" do
@@ -524,7 +615,7 @@ module MCollective
524
615
 
525
616
  Time.expects(:now).twice.returns(Time.at(1368557431))
526
617
 
527
- @c.headers_for(message)["reply-to"].should == "rspec"
618
+ connector.headers_for(message)["reply-to"].should == "rspec"
528
619
  end
529
620
 
530
621
  it "should set the timestamp and ttl based on the message object" do
@@ -534,7 +625,7 @@ module MCollective
534
625
 
535
626
  Time.expects(:now).twice.returns(Time.at(1368557431))
536
627
 
537
- headers = @c.headers_for(message)
628
+ headers = connector.headers_for(message)
538
629
  headers["timestamp"].should == "1368557431000"
539
630
  headers["expires"].should == "1368557541000"
540
631
  end
@@ -542,22 +633,22 @@ module MCollective
542
633
 
543
634
  describe "#make_target" do
544
635
  it "should create correct targets" do
545
- @c.make_target("test", :reply, "mcollective").should == {:name => "/queue/mcollective.reply.rspec_#{$$}", :headers => {}, :id => "/queue/mcollective.reply.rspec_#{$$}"}
546
- @c.make_target("test", :broadcast, "mcollective").should == {:name => "/topic/mcollective.test.agent", :headers => {}, :id => "/topic/mcollective.test.agent"}
547
- @c.make_target("test", :request, "mcollective").should == {:name => "/topic/mcollective.test.agent", :headers => {}, :id => "/topic/mcollective.test.agent"}
548
- @c.make_target("test", :direct_request, "mcollective").should == {:headers=>{}, :name=>"/queue/mcollective.nodes", :id => "/queue/mcollective.nodes"}
549
- @c.make_target("test", :directed, "mcollective").should == {:name => "/queue/mcollective.nodes", :headers=>{"selector"=>"mc_identity = 'rspec'"}, :id => "mcollective_directed_to_identity"}
636
+ connector.make_target("test", :reply, "mcollective").should == {:name => "/queue/mcollective.reply.rspec_#{$$}", :headers => {}, :id => "/queue/mcollective.reply.rspec_#{$$}"}
637
+ connector.make_target("test", :broadcast, "mcollective").should == {:name => "/topic/mcollective.test.agent", :headers => {}, :id => "/topic/mcollective.test.agent"}
638
+ connector.make_target("test", :request, "mcollective").should == {:name => "/topic/mcollective.test.agent", :headers => {}, :id => "/topic/mcollective.test.agent"}
639
+ connector.make_target("test", :direct_request, "mcollective").should == {:headers=>{}, :name=>"/queue/mcollective.nodes", :id => "/queue/mcollective.nodes"}
640
+ connector.make_target("test", :directed, "mcollective").should == {:name => "/queue/mcollective.nodes", :headers=>{"selector"=>"mc_identity = 'rspec'"}, :id => "mcollective_directed_to_identity"}
550
641
  end
551
642
 
552
643
  it "should raise an error for unknown collectives" do
553
644
  expect {
554
- @c.make_target("test", :broadcast, "foo")
645
+ connector.make_target("test", :broadcast, "foo")
555
646
  }.to raise_error("Unknown collective 'foo' known collectives are 'mcollective'")
556
647
  end
557
648
 
558
649
  it "should raise an error for unknown types" do
559
650
  expect {
560
- @c.make_target("test", :test, "mcollective")
651
+ connector.make_target("test", :test, "mcollective")
561
652
  }.to raise_error("Unknown target type test")
562
653
  end
563
654
  end
@@ -567,56 +658,68 @@ module MCollective
567
658
  it "should return the environment variable if set" do
568
659
  ENV["test"] = "rspec_env_test"
569
660
 
570
- @c.get_env_or_option("test", nil, nil).should == "rspec_env_test"
661
+ connector.get_env_or_option("test", nil, nil).should == "rspec_env_test"
571
662
 
572
663
  ENV.delete("test")
573
664
  end
574
665
 
575
666
  it "should return the config option if set" do
576
- @config.expects(:pluginconf).returns({"test" => "rspec_test"}).twice
577
- @c.get_env_or_option("test", "test", "test").should == "rspec_test"
667
+ config.expects(:pluginconf).returns({"test" => "rspec_test"}).twice
668
+ connector.get_env_or_option("test", "test", "test").should == "rspec_test"
578
669
  end
579
670
 
580
671
  it "should return default if nothing else matched" do
581
- @config.expects(:pluginconf).returns({}).once
582
- @c.get_env_or_option("test", "test", "test").should == "test"
672
+ config.expects(:pluginconf).returns({}).once
673
+ connector.get_env_or_option("test", "test", "test").should == "test"
583
674
  end
584
675
 
585
676
  it "should raise an error if no default is supplied" do
586
- @config.expects(:pluginconf).returns({}).once
677
+ config.expects(:pluginconf).returns({}).once
587
678
 
588
679
  expect {
589
- @c.get_env_or_option("test", "test")
680
+ connector.get_env_or_option("test", "test")
590
681
  }.to raise_error("No test environment or plugin.test configuration option given")
591
682
  end
592
683
  end
593
684
 
594
685
  describe "#get_option" do
686
+ before :each do
687
+ # realize the connector let so that we can unstub it
688
+ connector
689
+ Activemq.any_instance.unstub(:get_option)
690
+ end
691
+
595
692
  it "should return the config option if set" do
596
- @config.expects(:pluginconf).returns({"test" => "rspec_test"}).twice
597
- @c.get_option("test").should == "rspec_test"
693
+ config.expects(:pluginconf).returns({"test" => "rspec_test"}).twice
694
+ connector.get_option("test").should == "rspec_test"
598
695
  end
599
696
 
600
697
  it "should return default option was not found" do
601
- @config.expects(:pluginconf).returns({}).once
602
- @c.get_option("test", "test").should == "test"
698
+ config.expects(:pluginconf).returns({}).once
699
+ connector.get_option("test", "test").should == "test"
603
700
  end
604
701
 
605
702
  it "should raise an error if no default is supplied" do
606
- @config.expects(:pluginconf).returns({}).once
703
+ config.expects(:pluginconf).returns({}).once
607
704
 
608
705
  expect {
609
- @c.get_option("test")
706
+ connector.get_option("test")
610
707
  }.to raise_error("No plugin.test configuration option given")
611
708
  end
612
709
  end
613
710
 
614
711
  describe "#get_bool_option" do
712
+ before :each do
713
+ # realize the connector let so that we can unstub it
714
+ connector
715
+ Activemq.any_instance.unstub(:get_bool_option)
716
+ end
717
+
615
718
  it "should use Util::str_to_bool to translate a boolean value found in the config" do
616
- @config.expects(:pluginconf).returns({"rspec" => "true"})
719
+ config.expects(:pluginconf).returns({"rspec" => "true"})
617
720
  Util.expects(:str_to_bool).with("true").returns(true)
618
721
 
619
- @c.get_bool_option("rspec", "true").should be_true
722
+ connector.get_bool_option("rspec", "true").should be_true
620
723
  end
621
724
  end
622
725
  end