mcollective-client 2.4.1 → 2.5.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mcollective-client might be problematic. Click here for more details.
- data/lib/mcollective.rb +1 -14
- data/lib/mcollective/config.rb +4 -1
- data/lib/mcollective/exceptions.rb +27 -0
- data/lib/mcollective/unix_daemon.rb +4 -1
- data/lib/mcollective/windows_daemon.rb +18 -9
- data/spec/unit/plugins/mcollective/connector/activemq_spec.rb +331 -228
- data/spec/unit/plugins/mcollective/connector/rabbitmq_spec.rb +332 -239
- data/spec/unit/runner_spec.rb +253 -0
- data/spec/unit/unix_daemon_spec.rb +2 -2
- data/spec/unit/windows_daemon_spec.rb +1 -7
- metadata +8 -23
- data/spec/unit/security/runner_spec.rb +0 -67
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"
|
data/lib/mcollective/config.rb
CHANGED
@@ -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
|
@@ -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
|
-
|
21
|
-
|
22
|
-
|
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
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
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
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
55
|
-
|
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
|
-
|
62
|
-
|
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
|
-
|
67
|
-
|
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
|
-
|
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
|
-
|
111
|
-
|
112
|
-
:back_off_multiplier =>
|
113
|
-
:max_reconnect_delay =>
|
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 =>
|
150
|
+
:use_exponential_back_off => true,
|
117
151
|
:max_reconnect_attempts => 5,
|
118
|
-
:initial_reconnect_delay => 0.
|
119
|
-
:max_hbread_fails =>
|
120
|
-
:max_hbrlck_fails =>
|
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
|
-
|
138
|
-
|
171
|
+
connector.expects(:ssl_parameters).with(2, true).returns(true)
|
172
|
+
connector.expects(:connection_headers).returns({})
|
139
173
|
|
140
|
-
|
141
|
-
|
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
|
-
|
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
|
-
|
152
|
-
|
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
|
-
|
157
|
-
|
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
|
161
|
-
|
162
|
-
|
163
|
-
|
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
|
-
|
168
|
-
|
169
|
-
expect {
|
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
|
-
|
174
|
-
|
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
|
-
|
179
|
-
|
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
|
-
|
184
|
-
|
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
|
-
|
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 {
|
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
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
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 {
|
275
|
+
expect { connector.ssl_parameters(1, false) }.to raise_error("Cannot find CA file rspec2.ca")
|
222
276
|
|
223
|
-
|
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
|
-
|
228
|
-
|
229
|
-
|
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
|
-
|
285
|
+
connector.ssl_parameters(1, true).should == true
|
236
286
|
end
|
237
287
|
|
238
288
|
it "should fail if fallback isnt enabled" do
|
239
|
-
|
240
|
-
|
241
|
-
|
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 {
|
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
|
-
|
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
|
-
|
260
|
-
|
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
|
-
|
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
|
-
|
274
|
-
|
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
|
-
|
352
|
+
connection.expects(:receive).returns(payload)
|
285
353
|
|
286
354
|
Message.expects(:new).with("msg", payload, :base64 => true, :headers => "headers").returns("message")
|
287
|
-
|
355
|
+
connector.instance_variable_set("@base64", true)
|
288
356
|
|
289
|
-
received =
|
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
|
-
|
300
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
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
|
-
|
409
|
+
connector.publish(msg)
|
319
410
|
end
|
320
411
|
|
321
412
|
it "should not base64 encode if not configured to do so" do
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
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
|
-
|
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
|
-
|
333
|
-
|
334
|
-
|
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
|
-
|
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
|
-
|
349
|
-
|
350
|
-
|
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
|
-
|
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
|
-
|
449
|
+
connection.expects(:subscribe).raises(::Stomp::Error::DuplicateSubscription)
|
359
450
|
Log.expects(:error).with(regexp_matches(/already had a matching subscription, ignoring/))
|
360
|
-
|
451
|
+
connector.subscribe("test", :broadcast, "mcollective")
|
361
452
|
end
|
362
453
|
|
363
454
|
it "should use the make_target correctly" do
|
364
|
-
|
365
|
-
|
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
|
-
|
370
|
-
|
371
|
-
|
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
|
-
|
464
|
+
connector.subscribe("test", :broadcast, "mcollective")
|
374
465
|
end
|
375
466
|
|
376
467
|
it "should subscribe to the middleware" do
|
377
|
-
|
378
|
-
|
379
|
-
|
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
|
-
|
384
|
-
|
385
|
-
|
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
|
-
|
392
|
-
|
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
|
-
|
397
|
-
|
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
|
-
|
490
|
+
connector.unsubscribe("test", :broadcast, "mcollective")
|
400
491
|
end
|
401
492
|
|
402
493
|
it "should delete the source from subscriptions" do
|
403
|
-
|
404
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
430
|
-
|
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
|
-
|
440
|
-
|
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
|
-
|
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
|
-
|
456
|
-
|
457
|
-
|
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
|
-
|
470
|
-
|
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
|
-
|
481
|
-
|
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
|
-
|
495
|
-
|
585
|
+
connector.instance_variable_set("@msgpriority", 0)
|
586
|
+
connector.expects(:make_target).with("rspecagent", :reply, "mcollective").returns({:name => "test"})
|
496
587
|
|
497
|
-
headers =
|
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
|
-
|
513
|
-
|
514
|
-
|
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
|
-
|
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 =
|
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
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
577
|
-
|
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
|
-
|
582
|
-
|
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
|
-
|
677
|
+
config.expects(:pluginconf).returns({}).once
|
587
678
|
|
588
679
|
expect {
|
589
|
-
|
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
|
-
|
597
|
-
|
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
|
-
|
602
|
-
|
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
|
-
|
703
|
+
config.expects(:pluginconf).returns({}).once
|
607
704
|
|
608
705
|
expect {
|
609
|
-
|
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
|
-
|
719
|
+
config.expects(:pluginconf).returns({"rspec" => "true"})
|
617
720
|
Util.expects(:str_to_bool).with("true").returns(true)
|
618
721
|
|
619
|
-
|
722
|
+
connector.get_bool_option("rspec", "true").should be_true
|
620
723
|
end
|
621
724
|
end
|
622
725
|
end
|