mcollective-client 1.3.3

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.

Files changed (103) hide show
  1. data/bin/mc-call-agent +54 -0
  2. data/bin/mco +27 -0
  3. data/lib/mcollective.rb +70 -0
  4. data/lib/mcollective/agents.rb +160 -0
  5. data/lib/mcollective/application.rb +354 -0
  6. data/lib/mcollective/applications.rb +145 -0
  7. data/lib/mcollective/client.rb +292 -0
  8. data/lib/mcollective/config.rb +202 -0
  9. data/lib/mcollective/connector.rb +18 -0
  10. data/lib/mcollective/connector/base.rb +24 -0
  11. data/lib/mcollective/facts.rb +39 -0
  12. data/lib/mcollective/facts/base.rb +86 -0
  13. data/lib/mcollective/log.rb +103 -0
  14. data/lib/mcollective/logger.rb +5 -0
  15. data/lib/mcollective/logger/base.rb +73 -0
  16. data/lib/mcollective/logger/console_logger.rb +61 -0
  17. data/lib/mcollective/logger/file_logger.rb +46 -0
  18. data/lib/mcollective/logger/syslog_logger.rb +53 -0
  19. data/lib/mcollective/matcher.rb +16 -0
  20. data/lib/mcollective/matcher/parser.rb +93 -0
  21. data/lib/mcollective/matcher/scanner.rb +123 -0
  22. data/lib/mcollective/message.rb +201 -0
  23. data/lib/mcollective/monkey_patches.rb +104 -0
  24. data/lib/mcollective/optionparser.rb +164 -0
  25. data/lib/mcollective/pluginmanager.rb +180 -0
  26. data/lib/mcollective/pluginpackager.rb +26 -0
  27. data/lib/mcollective/pluginpackager/agent_definition.rb +79 -0
  28. data/lib/mcollective/pluginpackager/standard_definition.rb +59 -0
  29. data/lib/mcollective/registration.rb +16 -0
  30. data/lib/mcollective/registration/base.rb +75 -0
  31. data/lib/mcollective/rpc.rb +188 -0
  32. data/lib/mcollective/rpc/actionrunner.rb +142 -0
  33. data/lib/mcollective/rpc/agent.rb +441 -0
  34. data/lib/mcollective/rpc/audit.rb +38 -0
  35. data/lib/mcollective/rpc/client.rb +793 -0
  36. data/lib/mcollective/rpc/ddl.rb +258 -0
  37. data/lib/mcollective/rpc/helpers.rb +339 -0
  38. data/lib/mcollective/rpc/progress.rb +63 -0
  39. data/lib/mcollective/rpc/reply.rb +61 -0
  40. data/lib/mcollective/rpc/request.rb +51 -0
  41. data/lib/mcollective/rpc/result.rb +41 -0
  42. data/lib/mcollective/rpc/stats.rb +185 -0
  43. data/lib/mcollective/runnerstats.rb +90 -0
  44. data/lib/mcollective/security.rb +26 -0
  45. data/lib/mcollective/security/base.rb +237 -0
  46. data/lib/mcollective/shell.rb +87 -0
  47. data/lib/mcollective/ssl.rb +246 -0
  48. data/lib/mcollective/unix_daemon.rb +37 -0
  49. data/lib/mcollective/util.rb +274 -0
  50. data/lib/mcollective/vendor.rb +41 -0
  51. data/lib/mcollective/vendor/require_vendored.rb +2 -0
  52. data/lib/mcollective/windows_daemon.rb +25 -0
  53. data/spec/Rakefile +16 -0
  54. data/spec/fixtures/application/test.rb +7 -0
  55. data/spec/fixtures/test-cert.pem +15 -0
  56. data/spec/fixtures/test-private.pem +15 -0
  57. data/spec/fixtures/test-public.pem +6 -0
  58. data/spec/monkey_patches/instance_variable_defined.rb +7 -0
  59. data/spec/spec.opts +1 -0
  60. data/spec/spec_helper.rb +25 -0
  61. data/spec/unit/agents_spec.rb +280 -0
  62. data/spec/unit/application_spec.rb +636 -0
  63. data/spec/unit/applications_spec.rb +155 -0
  64. data/spec/unit/array.rb +30 -0
  65. data/spec/unit/config_spec.rb +148 -0
  66. data/spec/unit/facts/base_spec.rb +118 -0
  67. data/spec/unit/facts_spec.rb +39 -0
  68. data/spec/unit/log_spec.rb +71 -0
  69. data/spec/unit/logger/base_spec.rb +110 -0
  70. data/spec/unit/logger/syslog_logger_spec.rb +86 -0
  71. data/spec/unit/matcher/parser_spec.rb +106 -0
  72. data/spec/unit/matcher/scanner_spec.rb +71 -0
  73. data/spec/unit/message_spec.rb +401 -0
  74. data/spec/unit/optionparser_spec.rb +113 -0
  75. data/spec/unit/pluginmanager_spec.rb +173 -0
  76. data/spec/unit/pluginpackager/agent_definition_spec.rb +130 -0
  77. data/spec/unit/pluginpackager/standard_definition_spec.rb +75 -0
  78. data/spec/unit/plugins/mcollective/connector/activemq_spec.rb +533 -0
  79. data/spec/unit/plugins/mcollective/connector/stomp/eventlogger_spec.rb +34 -0
  80. data/spec/unit/plugins/mcollective/connector/stomp_spec.rb +417 -0
  81. data/spec/unit/plugins/mcollective/packagers/ospackage_spec.rb +229 -0
  82. data/spec/unit/plugins/mcollective/security/psk_spec.rb +156 -0
  83. data/spec/unit/registration/base_spec.rb +77 -0
  84. data/spec/unit/rpc/actionrunner_spec.rb +213 -0
  85. data/spec/unit/rpc/agent_spec.rb +155 -0
  86. data/spec/unit/rpc/client_spec.rb +523 -0
  87. data/spec/unit/rpc/ddl_spec.rb +388 -0
  88. data/spec/unit/rpc/helpers_spec.rb +55 -0
  89. data/spec/unit/rpc/reply_spec.rb +143 -0
  90. data/spec/unit/rpc/request_spec.rb +115 -0
  91. data/spec/unit/rpc/result_spec.rb +66 -0
  92. data/spec/unit/rpc/stats_spec.rb +288 -0
  93. data/spec/unit/runnerstats_spec.rb +40 -0
  94. data/spec/unit/security/base_spec.rb +279 -0
  95. data/spec/unit/shell_spec.rb +144 -0
  96. data/spec/unit/ssl_spec.rb +244 -0
  97. data/spec/unit/symbol.rb +11 -0
  98. data/spec/unit/unix_daemon.rb +41 -0
  99. data/spec/unit/util_spec.rb +342 -0
  100. data/spec/unit/vendor_spec.rb +34 -0
  101. data/spec/unit/windows_daemon.rb +43 -0
  102. data/spec/windows_spec.opts +1 -0
  103. metadata +242 -0
@@ -0,0 +1,401 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ module MCollective
6
+ describe Message do
7
+ before do
8
+ Config.instance.set_config_defaults("")
9
+ end
10
+
11
+ describe "#initialize" do
12
+ it "should set defaults" do
13
+ m = Message.new("payload", "message")
14
+ m.payload.should == "payload"
15
+ m.message.should == "message"
16
+ m.request.should == nil
17
+ m.headers.should == {}
18
+ m.agent.should == nil
19
+ m.collective.should == nil
20
+ m.type.should == :message
21
+ m.filter.should == Util.empty_filter
22
+ m.requestid.should == nil
23
+ m.base64?.should == false
24
+ m.options.should == {}
25
+ m.discovered_hosts.should == nil
26
+ m.ttl.should == 60
27
+ m.validated.should == false
28
+ m.msgtime.should == 0
29
+ m.expected_msgid == nil
30
+ end
31
+
32
+ it "should set all supplied options" do
33
+ Message.any_instance.expects(:base64_decode!)
34
+
35
+ m = Message.new("payload", "message", :base64 => true,
36
+ :agent => "rspecagent",
37
+ :headers => {:rspec => "test"},
38
+ :type => :rspec,
39
+ :filter => "filter",
40
+ :options => {:ttl => 30},
41
+ :collective => "collective")
42
+ m.payload.should == "payload"
43
+ m.message.should == "message"
44
+ m.request.should == nil
45
+ m.headers.should == {:rspec => "test"}
46
+ m.agent.should == "rspecagent"
47
+ m.collective.should == "collective"
48
+ m.type.should == :rspec
49
+ m.filter.should == "filter"
50
+ m.base64?.should == true
51
+ m.options.should == {:ttl => 30}
52
+ m.ttl.should == 30
53
+ end
54
+
55
+ it "if given a request it should set options based on the request" do
56
+ request = mock
57
+ request.expects(:agent).returns("request")
58
+ request.expects(:collective).returns("collective")
59
+
60
+ m = Message.new("payload", "message", :request => request)
61
+ m.agent.should == "request"
62
+ m.collective.should == "collective"
63
+ m.type.should == :reply
64
+ m.request.should == request
65
+ end
66
+ end
67
+
68
+ describe "#reply_to=" do
69
+ it "should only set the reply-to header for requests" do
70
+ Config.instance.instance_variable_set("@direct_addressing", true)
71
+ m = Message.new("payload", "message", :type => :reply)
72
+ m.discovered_hosts = ["foo"]
73
+ expect { m.reply_to = "foo" }.to raise_error(/reply targets/)
74
+
75
+ [:request, :direct_request].each do |t|
76
+ m.type = t
77
+ m.reply_to = "foo"
78
+ m.reply_to.should == "foo"
79
+ end
80
+ end
81
+ end
82
+
83
+ describe "#expected_msgid=" do
84
+ it "should correctly set the property" do
85
+ m = Message.new("payload", "message", :type => :reply)
86
+ m.expected_msgid = "rspec test"
87
+ m.expected_msgid.should == "rspec test"
88
+ end
89
+
90
+ it "should only be set for reply messages" do
91
+ m = Message.new("payload", "message", :type => :request)
92
+
93
+ expect {
94
+ m.expected_msgid = "rspec test"
95
+ }.to raise_error("Can only store the expected msgid for reply messages")
96
+ end
97
+ end
98
+
99
+ describe "#base64_decode!" do
100
+ it "should not decode if not encoded" do
101
+ SSL.expects(:base64_decode).never
102
+ m = Message.new("payload", "message")
103
+ end
104
+
105
+ it "should decode encoded messages" do
106
+ SSL.expects(:base64_decode)
107
+ m = Message.new("payload", "message", :base64 => true)
108
+ end
109
+
110
+ it "should set base64 to false after decoding" do
111
+ SSL.expects(:base64_decode).with("payload")
112
+ m = Message.new("payload", "message", :base64 => true)
113
+ m.base64?.should == false
114
+ end
115
+ end
116
+
117
+ describe "#base64_encode" do
118
+ it "should not encode already encoded messages" do
119
+ SSL.expects(:base64_encode).never
120
+ Message.any_instance.stubs(:base64_decode!)
121
+ m = Message.new("payload", "message", :base64 => true)
122
+ m.base64_encode!
123
+ end
124
+
125
+ it "should encode plain messages" do
126
+ SSL.expects(:base64_encode).with("payload")
127
+ m = Message.new("payload", "message")
128
+ m.base64_encode!
129
+ end
130
+
131
+ it "should set base64 to false after encoding" do
132
+ SSL.expects(:base64_encode)
133
+ m = Message.new("payload", "message")
134
+ m.base64_encode!
135
+ m.base64?.should == true
136
+ end
137
+ end
138
+
139
+ describe "#base64?" do
140
+ it "should correctly report base64 state" do
141
+ m = Message.new("payload", "message")
142
+ m.base64?.should == m.instance_variable_get("@base64")
143
+ end
144
+ end
145
+
146
+ describe "#type=" do
147
+ it "should only allow types to be set when discovered hosts were given" do
148
+ m = Message.new("payload", "message")
149
+ Config.instance.instance_variable_set("@direct_addressing", true)
150
+
151
+ expect {
152
+ m.type = :direct_request
153
+ }.to raise_error("Can only set type to :direct_request if discovered_hosts have been set")
154
+ end
155
+
156
+ it "should not allow direct_request to be set if direct addressing isnt enabled" do
157
+ m = Message.new("payload", "message")
158
+ Config.instance.instance_variable_set("@direct_addressing", false)
159
+
160
+ expect {
161
+ m.type = :direct_request
162
+ }.to raise_error("Direct requests is not enabled using the direct_addressing config option")
163
+ end
164
+
165
+ it "should only accept valid types" do
166
+ m = Message.new("payload", "message")
167
+ Config.instance.instance_variable_set("@direct_addressing", true)
168
+
169
+ expect {
170
+ m.type = :foo
171
+ }.to raise_error("Unknown message type foo")
172
+ end
173
+
174
+ it "should set the type" do
175
+ m = Message.new("payload", "message")
176
+ m.type = :request
177
+ m.type.should == :request
178
+ end
179
+ end
180
+
181
+ describe "#encode!" do
182
+ it "should encode replies using the security plugin #encodereply" do
183
+ request = mock
184
+ request.stubs(:agent).returns("rspec_agent")
185
+ request.stubs(:collective).returns("collective")
186
+ request.stubs(:payload).returns({:requestid => "123", :callerid => "id=callerid"})
187
+
188
+ security = mock
189
+ security.expects(:encodereply).with('rspec_agent', 'payload', '123', 'id=callerid')
190
+ security.expects(:valid_callerid?).with("id=callerid").returns(true)
191
+
192
+ PluginManager.expects("[]").with("security_plugin").returns(security).twice
193
+
194
+ m = Message.new("payload", "message", :request => request, :type => :reply)
195
+
196
+ m.encode!
197
+ end
198
+
199
+ it "should encode requests using the security plugin #encoderequest" do
200
+ security = mock
201
+ security.expects(:encoderequest).with("identity", 'payload', '123', Util.empty_filter, 'rspec_agent', 'mcollective', 60).twice
202
+ PluginManager.expects("[]").with("security_plugin").returns(security).twice
203
+
204
+ Config.any_instance.expects(:identity).returns("identity").times(4)
205
+
206
+ Message.any_instance.expects(:requestid).returns("123").twice
207
+
208
+ m = Message.new("payload", "message", :type => :request, :agent => "rspec_agent", :collective => "mcollective")
209
+ m.encode!
210
+
211
+ m = Message.new("payload", "message", :type => :direct_request, :agent => "rspec_agent", :collective => "mcollective")
212
+ m.encode!
213
+ end
214
+
215
+ it "should not allow bad callerids when replying" do
216
+ request = mock
217
+ request.stubs(:agent).returns("rspec_agent")
218
+ request.stubs(:collective).returns("collective")
219
+ request.stubs(:payload).returns({:requestid => "123", :callerid => "caller/id"})
220
+
221
+ security = mock
222
+ security.expects(:valid_callerid?).with("caller/id").returns(false)
223
+ PluginManager.expects("[]").with("security_plugin").returns(security)
224
+
225
+ m = Message.new("payload", "message", :request => request, :type => :reply)
226
+
227
+ expect {
228
+ m.encode!
229
+ }.to raise_error('callerid in original request is not valid, surpressing reply to potentially forged request')
230
+ end
231
+ end
232
+
233
+ describe "#decode!" do
234
+ it "should check for valid types" do
235
+ expect {
236
+ m = Message.new("payload", "message", :type => :foo)
237
+ m.decode!
238
+ }.to raise_error("Cannot decode message type foo")
239
+ end
240
+
241
+ it "should set state based on decoded message" do
242
+ msg = mock
243
+ msg.stubs(:include?).returns(true)
244
+ msg.stubs("[]").with(:collective).returns("collective")
245
+ msg.stubs("[]").with(:agent).returns("rspecagent")
246
+ msg.stubs("[]").with(:filter).returns("filter")
247
+ msg.stubs("[]").with(:requestid).returns("1234")
248
+ msg.stubs("[]").with(:ttl).returns(30)
249
+ msg.stubs("[]").with(:msgtime).returns(1314628987)
250
+
251
+ security = mock
252
+ security.expects(:decodemsg).returns(msg)
253
+ PluginManager.expects("[]").with("security_plugin").returns(security)
254
+
255
+ m = Message.new(msg, "message", :type => :reply)
256
+ m.decode!
257
+
258
+ m.collective.should == "collective"
259
+ m.agent.should == "rspecagent"
260
+ m.filter.should == "filter"
261
+ m.requestid.should == "1234"
262
+ m.ttl.should == 30
263
+ end
264
+
265
+ it "should not allow bad callerids from the security plugin on requests" do
266
+ security = mock
267
+ security.expects(:decodemsg).returns({:callerid => "foo/bar"})
268
+ security.expects(:valid_callerid?).with("foo/bar").returns(false)
269
+
270
+ PluginManager.expects("[]").with("security_plugin").returns(security).twice
271
+
272
+ m = Message.new("payload", "message", :type => :request)
273
+
274
+ expect {
275
+ m.decode!
276
+ }.to raise_error('callerid in request is not valid, surpressing reply to potentially forged request')
277
+ end
278
+ end
279
+
280
+ describe "#validate" do
281
+ it "should only validate requests" do
282
+ m = Message.new("msg", "message", :type => :reply)
283
+ expect {
284
+ m.validate
285
+ }.to raise_error("Can only validate request messages")
286
+ end
287
+
288
+ it "should raise an exception for incorrect messages" do
289
+ sec = mock
290
+ sec.expects("validate_filter?").returns(false)
291
+ PluginManager.expects("[]").with("security_plugin").returns(sec)
292
+
293
+ payload = mock
294
+ payload.expects("[]").with(:filter).returns({})
295
+
296
+ m = Message.new(payload, "message", :type => :request)
297
+ m.instance_variable_set("@msgtime", Time.now.to_i)
298
+
299
+ expect {
300
+ m.validate
301
+ }.to raise_error(NotTargettedAtUs)
302
+ end
303
+
304
+ it "should pass for good messages" do
305
+ sec = mock
306
+ sec.expects(:validate_filter?).returns(true)
307
+ PluginManager.expects("[]").returns(sec)
308
+
309
+ payload = mock
310
+ payload.expects("[]").with(:filter).returns({})
311
+ m = Message.new(payload, "message", :type => :request)
312
+ m.instance_variable_set("@msgtime", Time.now.to_i)
313
+ m.validate
314
+ end
315
+
316
+ it "should set the @validated property" do
317
+ sec = mock
318
+ sec.expects(:validate_filter?).returns(true)
319
+ PluginManager.expects("[]").returns(sec)
320
+
321
+ payload = mock
322
+ payload.expects("[]").with(:filter).returns({})
323
+ m = Message.new(payload, "message", :type => :request)
324
+ m.instance_variable_set("@msgtime", Time.now.to_i)
325
+
326
+ m.validated.should == false
327
+ m.validate
328
+ m.validated.should == true
329
+ end
330
+
331
+ it "should not validate for messages older than TTL" do
332
+ stats = mock
333
+ stats.expects(:ttlexpired).once
334
+
335
+ MCollective::PluginManager << {:type => "global_stats", :class => stats}
336
+
337
+ m = Message.new({:callerid => "caller", :senderid => "sender"}, "message", :type => :request)
338
+ m.instance_variable_set("@msgtime", (Time.now.to_i - 120))
339
+
340
+ expect {
341
+ m.validate
342
+ }.to raise_error(MsgTTLExpired)
343
+ end
344
+ end
345
+
346
+ describe "#publish" do
347
+ it "should publish itself to the connector" do
348
+ m = Message.new("msg", "message", :type => :request)
349
+
350
+ connector = mock
351
+ connector.expects(:publish).with(m)
352
+ PluginManager.expects("[]").returns(connector)
353
+
354
+ m.publish
355
+ end
356
+
357
+ it "should support direct addressing" do
358
+ m = Message.new("msg", "message", :type => :request)
359
+ m.discovered_hosts = ["one", "two", "three"]
360
+
361
+ Config.any_instance.expects(:direct_addressing).returns(true)
362
+ Config.any_instance.expects(:direct_addressing_threshold).returns(10)
363
+
364
+ connector = mock
365
+ connector.expects(:publish).with(m)
366
+ PluginManager.expects("[]").returns(connector)
367
+
368
+ m.publish
369
+ m.type.should == :direct_request
370
+ end
371
+
372
+ it "should only direct publish below the configured threshold" do
373
+ m = Message.new("msg", "message", :type => :request)
374
+ m.discovered_hosts = ["one", "two", "three"]
375
+
376
+ Config.any_instance.expects(:direct_addressing).returns(true)
377
+ Config.any_instance.expects(:direct_addressing_threshold).returns(1)
378
+
379
+ connector = mock
380
+ connector.expects(:publish).with(m)
381
+ PluginManager.expects("[]").returns(connector)
382
+
383
+ m.publish
384
+ m.type.should == :request
385
+ end
386
+ end
387
+
388
+ describe "#create_reqid" do
389
+ it "should create a valid request id" do
390
+ m = Message.new("msg", "message", :agent => "rspec", :collective => "mc")
391
+
392
+ Config.any_instance.expects(:identity).returns("rspec")
393
+ Time.expects(:now).returns(1.1)
394
+
395
+ Digest::MD5.expects(:hexdigest).with("rspec-1.1-rspec-mc").returns("reqid")
396
+
397
+ m.create_reqid.should == "reqid"
398
+ end
399
+ end
400
+ end
401
+ end
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ module MCollective
6
+ describe Optionparser do
7
+ describe "#initialize" do
8
+ it "should store the included list as an array" do
9
+ parser = Optionparser.new({}, "included")
10
+ parser.instance_variable_get("@include").should == ["included"]
11
+
12
+ parser = Optionparser.new({}, ["included"])
13
+ parser.instance_variable_get("@include").should == ["included"]
14
+ end
15
+
16
+ it "should store the excluded list as an array" do
17
+ parser = Optionparser.new({}, "", "excluded")
18
+ parser.instance_variable_get("@exclude").should == ["excluded"]
19
+
20
+ parser = Optionparser.new({}, "", ["excluded"])
21
+ parser.instance_variable_get("@exclude").should == ["excluded"]
22
+ end
23
+
24
+ it "should gather default options" do
25
+ Util.expects(:default_options).returns({})
26
+ Optionparser.new({})
27
+ end
28
+
29
+ it "should merge supplied options with defaults" do
30
+ defaults = {}
31
+ supplied = {}
32
+
33
+ Util.expects(:default_options).returns(defaults)
34
+ defaults.expects(:merge!).with(supplied)
35
+
36
+ Optionparser.new(supplied)
37
+ end
38
+ end
39
+
40
+ describe "#parse" do
41
+ it "should yield to the caller" do
42
+ parser = Optionparser.new(defaults={:default => 1})
43
+
44
+ block_ran = false
45
+
46
+ parser.parse do |p, o|
47
+ p.class.should == OptionParser
48
+ o.should == Util.default_options.merge(defaults)
49
+ block_ran = true
50
+ end
51
+
52
+ block_ran.should == true
53
+ end
54
+
55
+ it "should add required options" do
56
+ parser = Optionparser.new(defaults={:default => 1})
57
+ parser.expects(:add_required_options)
58
+ parser.parse
59
+ end
60
+
61
+ it "should optionally add common options" do
62
+ parser = Optionparser.new(defaults={:default => 1})
63
+ parser.stubs(:add_required_options)
64
+ parser.expects(:add_common_options)
65
+ parser.parse
66
+
67
+ parser = Optionparser.new(defaults={:default => 1}, "", "common")
68
+ parser.stubs(:add_required_options)
69
+ parser.expects(:add_common_options).never
70
+ parser.parse
71
+ end
72
+
73
+ it "should support adding arbitrary named sections of options" do
74
+ parser = Optionparser.new(defaults={:default => 1}, "filter")
75
+ parser.stubs(:add_required_options)
76
+ parser.stubs(:add_common_options)
77
+ parser.expects(:add_filter_options)
78
+ parser.parse
79
+ end
80
+
81
+ it "should support excluding sections that was specifically included" do
82
+ parser = Optionparser.new(defaults={:default => 1}, "filter", "filter")
83
+ parser.stubs(:add_required_options)
84
+ parser.stubs(:add_common_options)
85
+ parser.expects(:add_filter_options).never
86
+ parser.parse
87
+ end
88
+
89
+ it "should parse MCOLLECTIVE_EXTRA_OPTS" do
90
+ ENV["MCOLLECTIVE_EXTRA_OPTS"] = "--dt 999"
91
+ @parser = Optionparser.new
92
+ @parser.parse[:disctimeout].should == 999
93
+ ENV.delete("MCOLLECTIVE_EXTRA_OPTS")
94
+ end
95
+
96
+ it "should not set the active collective from the config class if given on the cli" do
97
+ parser = Optionparser.new(defaults={:collective => "rspec"})
98
+ parser.stubs(:add_required_options)
99
+ parser.stubs(:add_common_options)
100
+ Config.any_instance.expects(:main_collective).never
101
+ parser.parse
102
+ end
103
+
104
+ it "should set the active collective from the config class if not given on the cli" do
105
+ parser = Optionparser.new(defaults={})
106
+ parser.stubs(:add_required_options)
107
+ parser.stubs(:add_common_options)
108
+ Config.any_instance.expects(:main_collective).returns(:rspec).once
109
+ parser.parse[:collective].should == :rspec
110
+ end
111
+ end
112
+ end
113
+ end