mcollective-client 2.2.4 → 2.4.0

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.

Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/lib/mcollective/application.rb +25 -34
  3. data/lib/mcollective/client.rb +91 -33
  4. data/lib/mcollective/config.rb +42 -43
  5. data/lib/mcollective/data/base.rb +1 -1
  6. data/lib/mcollective/data/result.rb +6 -2
  7. data/lib/mcollective/ddl/agentddl.rb +28 -1
  8. data/lib/mcollective/ddl/base.rb +8 -6
  9. data/lib/mcollective/log.rb +11 -3
  10. data/lib/mcollective/logger/file_logger.rb +4 -4
  11. data/lib/mcollective/matcher.rb +9 -1
  12. data/lib/mcollective/message.rb +14 -23
  13. data/lib/mcollective/optionparser.rb +9 -1
  14. data/lib/mcollective/pluginpackager.rb +24 -3
  15. data/lib/mcollective/pluginpackager/agent_definition.rb +12 -12
  16. data/lib/mcollective/pluginpackager/standard_definition.rb +12 -12
  17. data/lib/mcollective/rpc/agent.rb +15 -12
  18. data/lib/mcollective/rpc/client.rb +67 -31
  19. data/lib/mcollective/rpc/helpers.rb +7 -1
  20. data/lib/mcollective/rpc/reply.rb +3 -1
  21. data/lib/mcollective/shell.rb +45 -8
  22. data/lib/mcollective/util.rb +37 -1
  23. data/lib/mcollective/windows_daemon.rb +14 -3
  24. data/spec/spec_helper.rb +2 -0
  25. data/spec/unit/application_spec.rb +45 -26
  26. data/spec/unit/cache_spec.rb +3 -3
  27. data/spec/unit/client_spec.rb +269 -24
  28. data/spec/unit/config_spec.rb +89 -26
  29. data/spec/unit/data/base_spec.rb +1 -0
  30. data/spec/unit/data/result_spec.rb +19 -1
  31. data/spec/unit/data_spec.rb +3 -0
  32. data/spec/unit/ddl/agentddl_spec.rb +32 -0
  33. data/spec/unit/ddl/base_spec.rb +4 -0
  34. data/spec/unit/ddl/dataddl_spec.rb +1 -1
  35. data/spec/unit/log_spec.rb +44 -27
  36. data/spec/unit/logger/base_spec.rb +1 -1
  37. data/spec/unit/matcher_spec.rb +14 -0
  38. data/spec/unit/message_spec.rb +24 -0
  39. data/spec/unit/optionparser_spec.rb +99 -0
  40. data/spec/unit/pluginpackager/agent_definition_spec.rb +48 -17
  41. data/spec/unit/pluginpackager/standard_definition_spec.rb +44 -20
  42. data/spec/unit/pluginpackager_spec.rb +31 -7
  43. data/spec/unit/plugins/mcollective/agent/rpcutil_spec.rb +176 -0
  44. data/spec/unit/plugins/mcollective/application/plugin_spec.rb +81 -0
  45. data/spec/unit/plugins/mcollective/audit/logfile_spec.rb +44 -0
  46. data/spec/unit/plugins/mcollective/connector/activemq_spec.rb +118 -27
  47. data/spec/unit/plugins/mcollective/connector/rabbitmq_spec.rb +168 -34
  48. data/spec/unit/plugins/mcollective/data/agent_data_spec.rb +1 -0
  49. data/spec/unit/plugins/mcollective/data/fstat_data_spec.rb +1 -0
  50. data/spec/unit/plugins/mcollective/discovery/flatfile_spec.rb +10 -0
  51. data/spec/unit/plugins/mcollective/discovery/stdin_spec.rb +65 -0
  52. data/spec/unit/plugins/mcollective/facts/yaml_facts_spec.rb +65 -0
  53. data/spec/unit/plugins/mcollective/packagers/debpackage_packager_spec.rb +240 -219
  54. data/spec/unit/plugins/mcollective/packagers/modulepackage_packager_spec.rb +209 -0
  55. data/spec/unit/plugins/mcollective/packagers/rpmpackage_packager_spec.rb +223 -109
  56. data/spec/unit/rpc/actionrunner_spec.rb +2 -1
  57. data/spec/unit/rpc/agent_spec.rb +130 -1
  58. data/spec/unit/rpc/client_spec.rb +169 -3
  59. data/spec/unit/security/base_spec.rb +0 -1
  60. data/spec/unit/shell_spec.rb +76 -3
  61. data/spec/unit/util_spec.rb +69 -1
  62. data/spec/unit/windows_daemon_spec.rb +30 -9
  63. metadata +104 -90
  64. data/spec/unit/plugins/mcollective/connector/stomp/eventlogger_spec.rb +0 -34
  65. data/spec/unit/plugins/mcollective/connector/stomp_spec.rb +0 -424
  66. data/spec/unit/plugins/mcollective/validator/any_validator_spec.rb +0 -15
@@ -27,6 +27,7 @@ module MCollective
27
27
  @config.stubs(:configured).returns(true)
28
28
  @config.stubs(:identity).returns("rspec")
29
29
  @config.stubs(:collectives).returns(["mcollective"])
30
+ @config.stubs(:pluginconf).returns({})
30
31
 
31
32
  logger = mock
32
33
  logger.stubs(:log)
@@ -96,6 +97,8 @@ module MCollective
96
97
  "rabbitmq.backup" => "true",
97
98
  "rabbitmq.timeout" => "1",
98
99
  "rabbitmq.vhost" => "mcollective",
100
+ "rabbitmq.max_hbrlck_fails" => 3,
101
+ "rabbitmq.max_hbread_fails" => 3,
99
102
  "rabbitmq.connect_timeout" => "5"}
100
103
 
101
104
 
@@ -115,10 +118,12 @@ module MCollective
115
118
  :use_exponential_back_off => false,
116
119
  :max_reconnect_attempts => 5,
117
120
  :initial_reconnect_delay => 0.02,
121
+ :max_hbread_fails => 3,
122
+ :max_hbrlck_fails => 3,
118
123
  :randomize => true,
119
124
  :reliable => true,
120
125
  :logger => "logger",
121
- :connect_headers => {'accept-version' => '1.0', 'host' => 'mcollective'},
126
+ :connect_headers => {},
122
127
  :hosts => [{:passcode => 'password1',
123
128
  :host => 'host1',
124
129
  :port => 6163,
@@ -132,12 +137,56 @@ module MCollective
132
137
  ])
133
138
 
134
139
  @c.expects(:ssl_parameters).with(2, true).returns(true)
140
+ @c.expects(:connection_headers).returns({})
135
141
 
136
142
  @c.instance_variable_set("@connection", nil)
137
143
  @c.connect(connector)
138
144
  end
139
145
  end
140
146
 
147
+ describe "#connection_headers" do
148
+ before do
149
+ @c.stubs(:stomp_version).returns("1.2.10")
150
+ end
151
+
152
+ it "should default to stomp 1.0 only" do
153
+ @config.expects(:pluginconf).returns({}).at_least_once
154
+ @c.connection_headers[:"accept-version"] == "1.0"
155
+ end
156
+
157
+ it "should support setting the vhost" do
158
+ @config.expects(:pluginconf).returns("rabbitmq.vhost" => "rspec").at_least_once
159
+ @c.connection_headers.should == {:host => "rspec", :"accept-version" => "1.0"}
160
+ end
161
+
162
+ it "should log a warning about not using Stomp 1.1" do
163
+ @config.expects(:pluginconf).returns("rabbitmq.heartbeat_interval" => "0").at_least_once
164
+ Log.expects(:warn).with(regexp_matches(/without STOMP 1.1 heartbeats/))
165
+ @c.connection_headers
166
+ end
167
+
168
+ it "should not support stomp 1.1 with older versions of the stomp gem" do
169
+ @config.expects(:pluginconf).returns("rabbitmq.heartbeat_interval" => "30").at_least_once
170
+ @c.expects(:stomp_version).returns("1.0.0").once
171
+ 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")
172
+ end
173
+
174
+ it "should force the heartbeat to min 30 seconds" do
175
+ @config.expects(:pluginconf).returns("rabbitmq.heartbeat_interval" => "10").at_least_once
176
+ @c.connection_headers[:"heart-beat"].should == "30500,29500"
177
+ end
178
+
179
+ it "should default to 1.0 and 1.1 support" do
180
+ @config.expects(:pluginconf).returns("rabbitmq.heartbeat_interval" => "30").at_least_once
181
+ @c.connection_headers[:"accept-version"].should == "1.1,1.0"
182
+ end
183
+
184
+ it "should support stomp 1.1 only operation" do
185
+ @config.expects(:pluginconf).returns("rabbitmq.heartbeat_interval" => "30", "rabbitmq.stomp_1_0_fallback" => 0).at_least_once
186
+ @c.connection_headers[:"accept-version"].should == "1.1"
187
+ end
188
+ end
189
+
141
190
  describe "#ssl_paramaters" do
142
191
  it "should ensure all settings are provided" do
143
192
  pluginconf = {"rabbitmq.pool.1.host" => "host1",
@@ -163,6 +212,8 @@ module MCollective
163
212
  "rabbitmq.pool.1.ssl.ca" => "rspec1.ca,rspec2.ca"}
164
213
 
165
214
  @config.expects(:pluginconf).returns(pluginconf).at_least_once
215
+ @c.expects(:get_key_file).returns("rspec.key").at_least_once
216
+ @c.expects(:get_cert_file).returns("rspec.cert").at_least_once
166
217
 
167
218
  File.expects(:exist?).with("rspec.cert").twice.returns(true)
168
219
  File.expects(:exist?).with("rspec.key").twice.returns(true)
@@ -199,6 +250,32 @@ module MCollective
199
250
  end
200
251
  end
201
252
 
253
+ describe "#get_key_file" do
254
+ it "should return the filename from the environment variable" do
255
+ ENV["MCOLLECTIVE_RABBITMQ_POOL2_SSL_KEY"] = "/path/to/rspec/env"
256
+ @c.get_key_file(2).should == "/path/to/rspec/env"
257
+ end
258
+
259
+ it "should return the filename define in the config file if the environment variable doesn't exist" do
260
+ ENV.delete("MCOLLECTIVE_RABBITMQ_POOL2_SSL_KEY")
261
+ @c.expects(:get_option).with("rabbitmq.pool.2.ssl.key", false).returns("/path/to/rspec/conf")
262
+ @c.get_key_file(2).should == "/path/to/rspec/conf"
263
+ end
264
+ end
265
+
266
+ describe "#get_cert_file" do
267
+ it "shold return the filename from the environment variable" do
268
+ ENV["MCOLLECTIVE_RABBITMQ_POOL2_SSL_CERT"] = "/path/to/rspec/env"
269
+ @c.get_cert_file(2).should == "/path/to/rspec/env"
270
+ end
271
+
272
+ it "should return the filename defined in the config file if the environment variable doesn't exist" do
273
+ ENV.delete("MCOLLECTIVE_RABBITMQ_POOL2_SSL_CERT")
274
+ @c.expects(:get_option).with("rabbitmq.pool.2.ssl.cert", false).returns("/path/to/rspec/conf")
275
+ @c.get_cert_file(2).should == "/path/to/rspec/conf"
276
+ end
277
+ end
278
+
202
279
  describe "#receive" do
203
280
  it "should receive from the middleware" do
204
281
  payload = mock
@@ -265,10 +342,11 @@ module MCollective
265
342
  msg.stubs(:collective).returns("mcollective")
266
343
  msg.stubs(:type).returns(:direct_request)
267
344
  msg.stubs(:reply_to).returns("/topic/mcollective")
345
+ msg.stubs(:ttl).returns(60)
268
346
  msg.expects(:discovered_hosts).returns(["one", "two"])
269
347
 
270
- @connection.expects(:publish).with('/exchange/mcollective_directed/one', 'msg', {'reply-to' => '/temp-queue/mcollective_reply_agent'})
271
- @connection.expects(:publish).with('/exchange/mcollective_directed/two', 'msg', {'reply-to' => '/temp-queue/mcollective_reply_agent'})
348
+ @connection.expects(:publish).with('/exchange/mcollective_directed/one', 'msg', {'reply-to' => '/temp-queue/mcollective_reply_agent', 'expiration' => '70000'})
349
+ @connection.expects(:publish).with('/exchange/mcollective_directed/two', 'msg', {'reply-to' => '/temp-queue/mcollective_reply_agent', 'expiration' => '70000'})
272
350
 
273
351
  @c.publish(msg)
274
352
  end
@@ -332,13 +410,14 @@ module MCollective
332
410
  it "should create reply targets based on reply-to headers in requests" do
333
411
  message = mock
334
412
  message.expects(:type).returns(:reply)
413
+ message.expects(:ttl).returns(60)
335
414
 
336
415
  request = mock
337
416
  request.expects(:headers).returns({"reply-to" => "foo"})
338
417
 
339
418
  message.expects(:request).returns(request)
340
419
 
341
- @c.target_for(message).should == {:name => "foo", :headers => {}, :id => ""}
420
+ @c.target_for(message).should == {:name => "foo", :headers => {"expiration" => "70000"}, :id => ""}
342
421
  end
343
422
 
344
423
  it "should create new request targets" do
@@ -347,8 +426,9 @@ module MCollective
347
426
  message.expects(:agent).returns("rspecagent")
348
427
  message.expects(:collective).returns("mcollective")
349
428
  message.expects(:reply_to).returns("/topic/rspec")
429
+ message.expects(:ttl).returns(60)
350
430
 
351
- @c.expects(:make_target).with("rspecagent", :request, "mcollective", "/topic/rspec", nil)
431
+ @c.expects(:make_target).with("rspecagent", :request, "mcollective", "/topic/rspec", nil).returns({:name => "", :headers => {}, :id => nil})
352
432
  @c.target_for(message)
353
433
  end
354
434
 
@@ -358,8 +438,9 @@ module MCollective
358
438
  message.expects(:agent).returns("rspecagent")
359
439
  message.expects(:collective).returns("mcollective")
360
440
  message.expects(:reply_to).returns("/topic/rspec")
441
+ message.expects(:ttl).returns(60)
361
442
 
362
- @c.expects(:make_target).with("rspecagent", :direct_request, "mcollective", "/topic/rspec", nil)
443
+ @c.expects(:make_target).with("rspecagent", :direct_request, "mcollective", "/topic/rspec", nil).returns({:name => "", :headers => {}, :id => nil})
363
444
  @c.target_for(message)
364
445
  end
365
446
 
@@ -377,17 +458,87 @@ module MCollective
377
458
  it "should disconnect from the stomp connection" do
378
459
  @connection.expects(:disconnect)
379
460
  @c.disconnect
461
+ @c.connection.should == nil
380
462
  end
381
463
  end
382
464
 
383
465
  describe "#make_target" do
384
- it "should create correct targets" do
385
- @c.make_target("test", :reply, "mcollective").should == {:name => "/temp-queue/mcollective_reply_test", :headers => {}, :id => "mcollective_test_replies"}
386
- @c.make_target("test", :broadcast, "mcollective").should == {:name => "/exchange/mcollective_broadcast/test", :headers => {"reply-to"=>"/temp-queue/mcollective_reply_test"}, :id => "mcollective_broadcast_test"}
387
- @c.make_target("test", :request, "mcollective").should == {:name => "/exchange/mcollective_broadcast/test", :headers => {"reply-to"=>"/temp-queue/mcollective_reply_test"}, :id => "mcollective_broadcast_test"}
388
- @c.make_target("test", :direct_request, "mcollective", nil, "rspec").should == {:headers=>{"reply-to"=>"/temp-queue/mcollective_reply_test"}, :name=>"/exchange/mcollective_directed/rspec", :id => nil}
389
- @c.make_target("test", :directed, "mcollective").should == {:name => "/exchange/mcollective_directed/rspec", :headers=>{}, :id => "rspec_directed_to_identity"}
390
- @c.make_target("test", :request, "mcollective", "/topic/rspec", "rspec").should == {:headers=>{"reply-to"=>"/topic/rspec"}, :name=>"/exchange/mcollective_broadcast/test", :id => "mcollective_broadcast_test"}
466
+ context 'rabbitmq.use_reply_exchange' do
467
+ context 'default (false)' do
468
+ it "should create correct targets" do
469
+ @c.make_target("test", :reply, "mcollective").should eq({
470
+ :name => "/temp-queue/mcollective_reply_test",
471
+ :headers => {},
472
+ :id => "mcollective_test_replies",
473
+ })
474
+ @c.make_target("test", :broadcast, "mcollective").should eq({
475
+ :name => "/exchange/mcollective_broadcast/test",
476
+ :headers => { "reply-to" => "/temp-queue/mcollective_reply_test" },
477
+ :id => "mcollective_broadcast_test"
478
+ })
479
+ @c.make_target("test", :request, "mcollective").should eq({
480
+ :name => "/exchange/mcollective_broadcast/test",
481
+ :headers => { "reply-to" => "/temp-queue/mcollective_reply_test" },
482
+ :id => "mcollective_broadcast_test",
483
+ })
484
+ @c.make_target("test", :direct_request, "mcollective", nil, "rspec").should eq({
485
+ :headers => { "reply-to" => "/temp-queue/mcollective_reply_test" },
486
+ :name => "/exchange/mcollective_directed/rspec",
487
+ :id => nil
488
+ })
489
+ @c.make_target("test", :directed, "mcollective").should eq({
490
+ :name => "/exchange/mcollective_directed/rspec",
491
+ :headers => {},
492
+ :id => "mcollective_rspec_directed_to_identity",
493
+ })
494
+ @c.make_target("test", :request, "mcollective", "/topic/rspec", "rspec").should eq({
495
+ :headers => { "reply-to" => "/topic/rspec" },
496
+ :name => "/exchange/mcollective_broadcast/test",
497
+ :id => "mcollective_broadcast_test",
498
+ })
499
+ end
500
+ end
501
+
502
+ context 'true' do
503
+ before :each do
504
+ @config.stubs(:pluginconf).returns({
505
+ 'rabbitmq.use_reply_exchange' => '1',
506
+ })
507
+ end
508
+
509
+ it "should create correct targets" do
510
+ @c.make_target("test", :reply, "mcollective").should eq({
511
+ :name => "/exchange/mcollective_reply/rspec_#{$$}",
512
+ :headers => {},
513
+ :id => "mcollective_test_replies",
514
+ })
515
+ @c.make_target("test", :broadcast, "mcollective").should eq({
516
+ :name => "/exchange/mcollective_broadcast/test",
517
+ :headers => { "reply-to" => "/exchange/mcollective_reply/rspec_#{$$}" },
518
+ :id => "mcollective_broadcast_test"
519
+ })
520
+ @c.make_target("test", :request, "mcollective").should eq({
521
+ :name => "/exchange/mcollective_broadcast/test",
522
+ :headers => { "reply-to" => "/exchange/mcollective_reply/rspec_#{$$}" },
523
+ :id => "mcollective_broadcast_test",
524
+ })
525
+ @c.make_target("test", :direct_request, "mcollective", nil, "rspec").should eq({
526
+ :headers => { "reply-to" => "/exchange/mcollective_reply/rspec_#{$$}" },
527
+ :name => "/exchange/mcollective_directed/rspec",
528
+ :id => nil
529
+ })
530
+ @c.make_target("test", :directed, "mcollective").should eq({
531
+ :name => "/exchange/mcollective_directed/rspec",
532
+ :headers => {},
533
+ :id => "mcollective_rspec_directed_to_identity",
534
+ })
535
+ @c.make_target("test", :request, "mcollective", "/topic/rspec", "rspec").should eq({
536
+ :headers => { "reply-to" => "/topic/rspec" },
537
+ :name => "/exchange/mcollective_broadcast/test",
538
+ :id => "mcollective_broadcast_test",
539
+ })
540
+ end
541
+ end
391
542
  end
392
543
 
393
544
  it "should raise an error for unknown collectives" do
@@ -453,28 +604,11 @@ module MCollective
453
604
  end
454
605
 
455
606
  describe "#get_bool_option" do
456
- it "should return the default if option isnt set" do
457
- @config.expects(:pluginconf).returns({}).once
458
- @c.get_bool_option("test", "default").should == "default"
459
- end
460
-
461
- ["1", "yes", "true"].each do |boolean|
462
- it "should map options to true correctly" do
463
- @config.expects(:pluginconf).returns({"test" => boolean}).twice
464
- @c.get_bool_option("test", "default").should == true
465
- end
466
- end
467
-
468
- ["0", "no", "false"].each do |boolean|
469
- it "should map options to false correctly" do
470
- @config.expects(:pluginconf).returns({"test" => boolean}).twice
471
- @c.get_bool_option("test", "default").should == false
472
- end
473
- end
607
+ it "should use Util::str_to_bool to translate a boolean value found in the config" do
608
+ @config.expects(:pluginconf).returns({"rspec" => "true"})
609
+ Util.expects(:str_to_bool).with("true").returns(true)
474
610
 
475
- it "should return default for non boolean options" do
476
- @config.expects(:pluginconf).returns({"test" => "foo"}).twice
477
- @c.get_bool_option("test", "default").should == "default"
611
+ @c.get_bool_option("rspec", "true").should be_true
478
612
  end
479
613
  end
480
614
  end
@@ -10,6 +10,7 @@ module MCollective
10
10
  describe "#query_data" do
11
11
  before do
12
12
  @ddl = mock
13
+ @ddl.stubs(:dataquery_interface).returns({:output => {}})
13
14
  @ddl.stubs(:meta).returns({:timeout => 1})
14
15
  DDL.stubs(:new).returns(@ddl)
15
16
  @plugin = Agent_data.new
@@ -11,6 +11,7 @@ module MCollective
11
11
  before do
12
12
  @ddl = mock
13
13
  @ddl.stubs(:meta).returns({:timeout => 1})
14
+ @ddl.stubs(:dataquery_interface).returns({:output => {}})
14
15
  DDL.stubs(:new).returns(@ddl)
15
16
  @plugin = Fstat_data.new
16
17
 
@@ -42,6 +42,16 @@ module MCollective
42
42
  it "should filter against non regex nodes" do
43
43
  Flatfile.discover(Util.empty_filter.merge("identity" => ["one"]), 0, 0, @client).should == ["one"]
44
44
  end
45
+
46
+ it "should fail for invalid identities" do
47
+ [" one", "two ", " three ", "four four"].each do |host|
48
+ File.expects(:readlines).with("/nonexisting").returns([host])
49
+
50
+ expect {
51
+ Flatfile.discover(Util.empty_filter, 0, 0, @client).should == ["one", "two", "three", "four"]
52
+ }.to raise_error('Identities can only match /\w\.\-/')
53
+ end
54
+ end
45
55
  end
46
56
  end
47
57
  end
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+
5
+ require File.dirname(__FILE__) + '/../../../../../plugins/mcollective/discovery/stdin.rb'
6
+
7
+ module MCollective
8
+ class Discovery
9
+ describe Stdin do
10
+ describe "#discover" do
11
+ before do
12
+ @client = mock
13
+ @client.stubs(:options).returns({})
14
+ @client.stubs(:options).returns({:discovery_options => []})
15
+ STDIN.stubs(:read).with().returns("one\ntwo\n")
16
+ end
17
+
18
+ it "should use a simple string list" do
19
+ Stdin.discover(Util.empty_filter, 0, 0, @client).should == ["one", "two"]
20
+ end
21
+
22
+ ['auto', 'json', 'text', nil].each do |type|
23
+ it "should fail if no data is given (type %{type})" do
24
+ unless type.nil?
25
+ @client.stubs(:options).returns({:discovery_options => [type]})
26
+ end
27
+ STDIN.stubs(:read).with().returns(" ")
28
+ expect { Stdin.discover(Util.empty_filter, 0, 0, @client) }.to raise_error("data piped on STDIN contained only whitespace - could not discover hosts from it.")
29
+ end
30
+ end
31
+
32
+ it "should work for JSON data" do
33
+ STDIN.stubs(:read).with().returns('[{"sender":"example.com"},{"sender":"another.com"}]')
34
+ Stdin.discover(Util.empty_filter, 0, 0, @client).should == ["example.com", "another.com"]
35
+ end
36
+
37
+ it "should regex filters" do
38
+ Stdin.discover(Util.empty_filter.merge("identity" => [/one/]), 0, 0, @client).should == ["one"]
39
+ end
40
+
41
+ it "should filter against non regex nodes" do
42
+ Stdin.discover(Util.empty_filter.merge("identity" => ["one"]), 0, 0, @client).should == ["one"]
43
+ end
44
+
45
+ it "should fail for invalid identities" do
46
+ [" one", "two ", " three ", "four four"].each do |host|
47
+ STDIN.stubs(:read).with().returns("#{host}\n")
48
+
49
+ expect {
50
+ Stdin.discover(Util.empty_filter, 0, 0, @client)
51
+ }.to raise_error('Identities can only match /\w\.\-/')
52
+ end
53
+ end
54
+
55
+ it "should raise on incorrect options" do
56
+ @client.stubs(:options).returns({:discovery_options => ['foo']})
57
+ expect {
58
+ Stdin.discover(Util.empty_filter, 0, 0, @client)
59
+ }.to raise_error('stdin discovery plugin only knows the types auto/text/json, not "foo"')
60
+ end
61
+
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env rspec
2
+
3
+ require 'spec_helper'
4
+ require File.join(File.dirname(__FILE__), '../../../../../', 'plugins', 'mcollective', 'facts', 'yaml_facts.rb')
5
+
6
+ module MCollective
7
+ module Facts
8
+ describe Yaml_facts do
9
+ before :each do
10
+ config = mock
11
+ config.stubs(:pluginconf).returns({'yaml' => 'facts.yaml'})
12
+ Config.stubs(:instance).returns(config)
13
+ @stat = mock
14
+ File.stubs(:stat).returns(@stat)
15
+ @facts = Yaml_facts.new
16
+ end
17
+
18
+ describe '#initialize' do
19
+ it 'should initialize a mtimes instance variable' do
20
+ facts = Yaml_facts.new
21
+ facts.instance_variable_get(:@yaml_file_mtimes).should == {}
22
+ end
23
+ end
24
+
25
+ describe '#load_facts_from_source' do
26
+ it 'should fail and return empty facts if the source file does not exist' do
27
+ File.stubs(:exist?).with('facts.yaml').returns(false)
28
+ Log.expects(:error)
29
+ @facts.load_facts_from_source.should == {}
30
+ end
31
+
32
+ it 'should fail and return empty facts in the yaml cannot be parsed' do
33
+ yaml = "---"
34
+ YAML.stubs(:load).raises("error")
35
+ File.stubs(:exist?).with('facts.yaml').returns(true)
36
+ File.stubs(:read).with('facts.yaml').returns(yaml)
37
+ Log.expects(:error)
38
+ @facts.load_facts_from_source.should == {}
39
+ end
40
+
41
+ it 'should return the facts if the file exists and can be parsed' do
42
+ yaml = "---\n osfamily : Magic"
43
+ File.stubs(:exist?).with('facts.yaml').returns(true)
44
+ File.stubs(:read).with('facts.yaml').returns(yaml)
45
+ Log.expects(:error).never
46
+ @facts.load_facts_from_source.should == {"osfamily" => "Magic"}
47
+ end
48
+ end
49
+
50
+ describe '#force_reload?' do
51
+ it 'should return true if the mtime has changed' do
52
+ @facts.instance_variable_get(:@yaml_file_mtimes)['facts.yaml'] = 1234
53
+ @stat.stubs(:mtime).returns(1235)
54
+ @facts.force_reload?.should be_true
55
+ end
56
+
57
+ it 'should return false if the mtime is the same' do
58
+ @facts.instance_variable_get(:@yaml_file_mtimes)['facts.yaml'] = 1234
59
+ @stat.stubs(:mtime).returns(1234)
60
+ @facts.force_reload?.should be_false
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end