mcollective-client 2.2.4 → 2.4.0

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 (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