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
@@ -5,6 +5,34 @@ require 'spec_helper'
5
5
  module MCollective
6
6
  describe Config do
7
7
  describe "#loadconfig" do
8
+ it "should fail when no libdir is set" do
9
+ File.expects(:exists?).with("/nonexisting").returns(true)
10
+ File.expects(:readlines).with("/nonexisting").returns([])
11
+ Config.instance.stubs(:set_config_defaults)
12
+ expect { Config.instance.loadconfig("/nonexisting") }.to raise_error("The /nonexisting config file does not specify a libdir setting, cannot continue")
13
+ end
14
+
15
+ it "should only test that libdirs are absolute paths" do
16
+ Util.expects(:absolute_path?).with("/one").returns(true)
17
+ Util.expects(:absolute_path?).with("/two").returns(true)
18
+ Util.expects(:absolute_path?).with("/three").returns(true)
19
+ Util.expects(:absolute_path?).with("four").returns(false)
20
+
21
+ File.stubs(:exists?).with("/nonexisting").returns(true)
22
+
23
+ ["/one#{File::PATH_SEPARATOR}/two", "/three"].each do |path|
24
+ File.expects(:readlines).with("/nonexisting").returns(["libdir = #{path}"])
25
+
26
+ Config.instance.loadconfig("/nonexisting")
27
+
28
+ PluginManager.clear
29
+ end
30
+
31
+ File.expects(:readlines).with("/nonexisting").returns(["libdir = four"])
32
+
33
+ expect { Config.instance.loadconfig("/nonexisting") }.to raise_error(/should be absolute paths/)
34
+ end
35
+
8
36
  it "should not allow any path like construct for identities" do
9
37
  # Taken from puppet test cases
10
38
  ['../foo', '..\\foo', './../foo', '.\\..\\foo',
@@ -16,9 +44,8 @@ module MCollective
16
44
  "\\\\?\\c:\\foo", "//?/UNC/bar", "//foo/bar",
17
45
  "//?/c:/foo"
18
46
  ].each do |input|
19
- File.expects(:open).with("/nonexisting", "r").returns(StringIO.new("identity = #{input}"))
47
+ File.expects(:readlines).with("/nonexisting").returns(["identity = #{input}", "libdir=/nonexistinglib"])
20
48
  File.expects(:exists?).with("/nonexisting").returns(true)
21
- File.expects(:exists?).with(File.join(File.dirname("/nonexisting"), "rpc-help.erb")).returns(true)
22
49
 
23
50
  expect {
24
51
  Config.instance.loadconfig("/nonexisting")
@@ -26,11 +53,19 @@ module MCollective
26
53
  end
27
54
  end
28
55
 
56
+ it "should strip whitespaces from config keys" do
57
+ File.expects(:exists?).with("/nonexisting").returns(true)
58
+ File.expects(:readlines).with("/nonexisting").returns([" identity= your.example.com ", "libdir=/nonexisting"])
59
+
60
+ config = Config.instance
61
+ config.loadconfig("/nonexisting")
62
+ config.identity.should == "your.example.com"
63
+ end
64
+
29
65
  it "should allow valid identities" do
30
66
  ["foo", "foo_bar", "foo-bar", "foo-bar-123", "foo.bar", "foo_bar_123"].each do |input|
31
- File.expects(:open).with("/nonexisting", "r").returns(StringIO.new("identity = #{input}"))
67
+ File.expects(:readlines).with("/nonexisting").returns(["identity = #{input}", "libdir=/nonexistinglib"])
32
68
  File.expects(:exists?).with("/nonexisting").returns(true)
33
- File.expects(:exists?).with(File.join(File.dirname("/nonexisting"), "rpc-help.erb")).returns(true)
34
69
  PluginManager.stubs(:loadclass)
35
70
  PluginManager.stubs("<<")
36
71
 
@@ -38,54 +73,74 @@ module MCollective
38
73
  end
39
74
  end
40
75
 
41
- it "should not allow the syslog logger type on windows" do
42
- Util.expects("windows?").returns(true).twice
43
- File.expects(:open).with("/nonexisting", "r").returns(StringIO.new("logger_type = syslog"))
76
+ it "should set direct_addressing to true by default" do
77
+ File.expects(:readlines).with("/nonexisting").returns(["libdir=/nonexistinglib"])
44
78
  File.expects(:exists?).with("/nonexisting").returns(true)
45
- File.expects(:exists?).with(File.join(File.dirname("/nonexisting"), "rpc-help.erb")).returns(true)
46
79
  PluginManager.stubs(:loadclass)
47
80
  PluginManager.stubs("<<")
48
81
 
49
- expect { Config.instance.loadconfig("/nonexisting") }.to raise_error("The sylog logger is not usable on the Windows platform")
82
+ Config.instance.loadconfig("/nonexisting")
83
+ Config.instance.direct_addressing.should == true
50
84
  end
51
85
 
52
- it "should default to finding the help template in the same dir as the config file" do
53
- path = File.join(File.dirname("/nonexisting"), "rpc-help.erb")
54
-
55
- File.expects(:open).with("/nonexisting", "r").returns(StringIO.new(""))
86
+ it "should allow direct_addressing to be disabled in the config file" do
87
+ File.expects(:readlines).with("/nonexisting").returns(["libdir=/nonexistinglib", "direct_addressing=n"])
56
88
  File.expects(:exists?).with("/nonexisting").returns(true)
57
89
  PluginManager.stubs(:loadclass)
58
90
  PluginManager.stubs("<<")
59
91
 
60
- File.expects(:exists?).with(path).returns(true)
61
-
62
92
  Config.instance.loadconfig("/nonexisting")
63
- Config.instance.rpchelptemplate.should == path
93
+ Config.instance.direct_addressing.should == false
64
94
  end
65
95
 
66
- it "should fall back to old behavior if the help template file does not exist in the config dir" do
67
- path = File.join(File.dirname("/nonexisting"), "rpc-help.erb")
68
-
69
- File.expects(:open).with("/nonexisting", "r").returns(StringIO.new(""))
96
+ it "should not allow the syslog logger type on windows" do
97
+ Util.expects("windows?").returns(true).twice
98
+ File.expects(:readlines).with("/nonexisting").returns(["libdir=/nonexistinglib", "logger_type=syslog"])
70
99
  File.expects(:exists?).with("/nonexisting").returns(true)
71
- File.expects(:exists?).with(path).returns(false)
72
100
  PluginManager.stubs(:loadclass)
73
101
  PluginManager.stubs("<<")
74
102
 
75
- Config.instance.loadconfig("/nonexisting")
76
- Config.instance.rpchelptemplate.should == "/etc/mcollective/rpc-help.erb"
103
+ expect { Config.instance.loadconfig("/nonexisting") }.to raise_error("The sylog logger is not usable on the Windows platform")
77
104
  end
78
105
 
79
106
  it "should support multiple default_discovery_options" do
80
- File.expects(:open).with("/nonexisting", "r").returns(StringIO.new("default_discovery_options = 1\ndefault_discovery_options = 2"))
107
+ File.expects(:readlines).with("/nonexisting").returns(["default_discovery_options = 1", "default_discovery_options = 2", "libdir=/nonexistinglib"])
81
108
  File.expects(:exists?).with("/nonexisting").returns(true)
82
- File.expects(:exists?).with(File.join(File.dirname("/nonexisting"), "rpc-help.erb")).returns(true)
83
109
  PluginManager.stubs(:loadclass)
84
110
  PluginManager.stubs("<<")
85
111
 
86
112
  Config.instance.loadconfig("/nonexisting")
87
113
  Config.instance.default_discovery_options.should == ["1", "2"]
88
114
  end
115
+
116
+ it "should not allow non integer values when expecting an integer value" do
117
+ PluginManager.stubs(:loadclass)
118
+ PluginManager.stubs("<<")
119
+
120
+ ["registerinterval", "max_log_size", "direct_addressing_threshold", "publish_timeout",
121
+ "fact_cache_time", "ttl"].each do |key|
122
+ File.expects(:readlines).with("/nonexisting").returns(["#{key} = nan"])
123
+ File.expects(:exists?).with("/nonexisting").returns(true)
124
+
125
+ expect{
126
+ Config.instance.loadconfig("/nonexisting")
127
+ }.to raise_error "Could not parse value for configuration option '#{key}' with value 'nan'"
128
+ end
129
+ end
130
+
131
+ it 'should log a warning when using a deprecated option' do
132
+ PluginManager.stubs(:loadclass)
133
+ PluginManager.stubs("<<")
134
+
135
+ ["topicprefix", "topicsep", "queueprefix", "rpchelptemplate", "helptemplatedir"].each do |key|
136
+ File.expects(:exists?).with("/nonexisting").returns(true)
137
+ File.expects(:readlines).with("/nonexisting").returns(["#{key} = nan", "libdir = /nonexistinglib"])
138
+
139
+ Log.stubs(:warn)
140
+ Log.expects(:warn).with("Use of deprecated '#{key}' option. This option is ignored and should be removed from '/nonexisting'")
141
+ Config.instance.loadconfig("/nonexisting")
142
+ end
143
+ end
89
144
  end
90
145
 
91
146
  describe "#read_plugin_config_dir" do
@@ -124,6 +179,13 @@ module MCollective
124
179
  Config.instance.pluginconf.should == {"foo.rspec" => "test"}
125
180
  end
126
181
 
182
+ it "should strip whitespaces from config keys" do
183
+ Dir.expects(:new).with(@plugindir).returns(["foo.cfg"])
184
+ File.expects(:open).with(File.join(@plugindir, "foo.cfg"), "r").returns([" rspec = test"])
185
+ Config.instance.read_plugin_config_dir(@plugindir)
186
+ Config.instance.pluginconf.should == {"foo.rspec" => "test"}
187
+ end
188
+
127
189
  it "should override main config file" do
128
190
  configfile = File.join(@plugindir, "foo.cfg")
129
191
  servercfg = File.join(File.dirname(@plugindir), "server.cfg")
@@ -133,7 +195,8 @@ module MCollective
133
195
  File.stubs(:exists?).returns(true)
134
196
  File.stubs(:directory?).with(@plugindir).returns(true)
135
197
  File.stubs(:exists?).with(servercfg).returns(true)
136
- File.expects(:open).with(servercfg, "r").returns(["plugin.rspec.key = default"])
198
+ File.expects(:readlines).with(servercfg).returns(["plugin.rspec.key = default", "libdir=/nonexisting"])
199
+ File.stubs(:directory?).with("/nonexisting").returns(true)
137
200
 
138
201
  Dir.expects(:new).with(@plugindir).returns(["rspec.cfg"])
139
202
  File.expects(:open).with(File.join(@plugindir, "rspec.cfg"), "r").returns(["key = overridden"])
@@ -7,6 +7,7 @@ module MCollective
7
7
  describe Base do
8
8
  before do
9
9
  @ddl = mock
10
+ @ddl.stubs(:dataquery_interface).returns({:output => {'rspec' => {}}})
10
11
  @ddl.stubs(:meta).returns({:timeout => 1})
11
12
  end
12
13
 
@@ -6,7 +6,21 @@ module MCollective
6
6
  module Data
7
7
  describe Result do
8
8
  before(:each) do
9
- @result = Result.new
9
+ @result = Result.new({})
10
+ end
11
+
12
+ describe "#initialize" do
13
+ it "should initialize empty values for all output fields" do
14
+ result = Result.new({:rspec1 => {}, :rspec2 => {}})
15
+ result[:rspec1].should == nil
16
+ result[:rspec2].should == nil
17
+ end
18
+
19
+ it "should set default values for all output fields" do
20
+ result = Result.new({:rspec1 => {:default => 1}, :rspec2 => {}})
21
+ result[:rspec1].should == 1
22
+ result[:rspec2].should == nil
23
+ end
10
24
  end
11
25
 
12
26
  describe "#[]=" do
@@ -58,6 +72,10 @@ module MCollective
58
72
  end
59
73
 
60
74
  describe "#method_missing" do
75
+ it "should raise the correct exception for unknown keys" do
76
+ expect { @result.nosuchdata }.to raise_error(NoMethodError)
77
+ end
78
+
61
79
  it "should retrieve the correct data" do
62
80
  @result["rspec"] = "rspec value"
63
81
  @result.rspec.should == "rspec value"
@@ -17,6 +17,8 @@ module MCollective
17
17
 
18
18
  ddl = mock
19
19
  ddl.stubs(:meta).returns({:timeout => 1})
20
+ ddl.stubs(:dataquery_interface).returns({:rspec => nil})
21
+ ddl.stubs(:dataquery_interface).returns({:output => {}})
20
22
  DDL.stubs(:new).returns(ddl)
21
23
  Data::Base.expects(:activate?).returns(false)
22
24
  PluginManager.expects("[]").with("rspec_data").returns(Data::Base.new)
@@ -30,6 +32,7 @@ module MCollective
30
32
 
31
33
  ddl = mock
32
34
  ddl.stubs(:meta).returns({:timeout => 1})
35
+ ddl.stubs(:dataquery_interface).returns({:output => {}})
33
36
  DDL.stubs(:new).returns(ddl)
34
37
  Data::Base.expects(:activate?).raises("rspec failure")
35
38
  Log.expects(:debug).once.with("Disabling data plugin rspec_data due to exception RuntimeError: rspec failure")
@@ -17,6 +17,36 @@ module MCollective
17
17
  end
18
18
  end
19
19
 
20
+ describe "#set_default_input_arguments" do
21
+ before do
22
+ @ddl.action(:test, :description => "rspec")
23
+ @ddl.instance_variable_set("@current_entity", :test)
24
+
25
+ @ddl.input(:optional, :prompt => "prompt", :description => "descr",
26
+ :type => :string, :optional => true, :validation => "",
27
+ :maxlength => 1, :default => "default")
28
+ @ddl.input(:required, :prompt => "prompt", :description => "descr",
29
+ :type => :string, :optional => false, :validation => "",
30
+ :maxlength => 1, :default => "default")
31
+ end
32
+
33
+ it "should correctly add default arguments to required inputs" do
34
+ args = {}
35
+
36
+ @ddl.set_default_input_arguments(:test, args)
37
+
38
+ args.should == {:required => "default"}
39
+ end
40
+
41
+ it "should not override any existing arguments" do
42
+ args = {:required => "specified"}
43
+
44
+ @ddl.set_default_input_arguments(:test, args)
45
+
46
+ args.should == {:required => "specified"}
47
+ end
48
+ end
49
+
20
50
  describe "#validate_rpc_request" do
21
51
  it "should ensure the action is known" do
22
52
  @ddl.action(:test, :description => "rspec")
@@ -38,6 +68,8 @@ module MCollective
38
68
  :type => :string, :optional => false, :validation => "",
39
69
  :maxlength => 1)
40
70
 
71
+ @ddl.stubs(:validate_input_argument).returns(true)
72
+
41
73
  expect {
42
74
  @ddl.validate_rpc_request(:test, {})
43
75
  }.to raise_error("Action test needs a required argument")
@@ -18,6 +18,8 @@ module MCollective
18
18
 
19
19
  it "should return correct new path for other ddls" do
20
20
  @ddl.instance_variable_set("@plugintype", :data)
21
+ @ddl.stubs(:helptemplatedir).returns("/etc/mcollective")
22
+ Util.stubs(:templatepath).with("data-help.erb").returns("/etc/mcollective/data-help.erb")
21
23
  File.expects(:exists?).with("/etc/mcollective/data-help.erb").returns(true)
22
24
  @ddl.template_for_plugintype.should == "data-help.erb"
23
25
  end
@@ -31,6 +33,8 @@ module MCollective
31
33
  end
32
34
 
33
35
  it "should use template from help template path when provided template name is not an absolute file path" do
36
+ Util.stubs(:absolute_path?).returns(false)
37
+ Util.stubs(:templatepath).returns("/etc/mcollective/foo", "/etc/mcollective/metadata-help.erb")
34
38
  File.expects(:read).with("/etc/mcollective/foo").returns("rspec")
35
39
  File.expects(:read).with("/etc/mcollective/metadata-help.erb").returns("rspec")
36
40
  @ddl.help("foo").should == "rspec"
@@ -34,7 +34,7 @@ module MCollective
34
34
  end
35
35
 
36
36
  @ddl.dataquery_interface.should == {:description => "rspec",
37
- :input => {:query => input.merge(:optional => nil)},
37
+ :input => {:query => input.merge(:optional => nil, :default => nil)},
38
38
  :output => {:rspec => output}}
39
39
  end
40
40
  end
@@ -10,9 +10,17 @@ module MCollective
10
10
  @logger.stubs(:start)
11
11
  @logger.stubs(:set_logging_level)
12
12
  @logger.stubs(:valid_levels)
13
+ @logger.stubs(:new).returns(@logger)
14
+
15
+ # we stub it out at the top of the test suite
16
+ Log.unstub(:log)
17
+ Log.unstub(:logexception)
18
+ Log.unstub(:logmsg)
19
+
20
+ Log.set_logger(@logger)
13
21
  end
14
22
 
15
- describe "#cofigure" do
23
+ describe "#configure" do
16
24
  it "should default to console logging if called prior to configuration" do
17
25
  Config.instance.instance_variable_set("@configured", false)
18
26
  Log.configure
@@ -28,43 +36,52 @@ module MCollective
28
36
  end
29
37
 
30
38
  describe "#log" do
31
- it "should log at debug level" do
32
- @logger.expects(:log).with(:debug, anything, regexp_matches(/debug test/))
33
- Log.configure(@logger)
34
- Log.debug("debug test")
39
+ it "should log at the right levels" do
40
+ [:debug, :info, :fatal, :error, :warn].each do |level|
41
+ @logger.expects(:log).with(level, anything, regexp_matches(/#{level} test/))
42
+ Log.send(level, "#{level} test")
43
+ end
35
44
  end
45
+ end
36
46
 
37
- it "should log at info level" do
38
- @logger.expects(:log).with(:info, anything, regexp_matches(/info test/))
39
- Log.configure(@logger)
40
- Log.info("info test")
41
- end
47
+ describe "#cycle_level" do
48
+ it "should cycle logger class levels" do
49
+ @logger.expects(:cycle_level)
42
50
 
43
- it "should log at fatal level" do
44
- @logger.expects(:log).with(:fatal, anything, regexp_matches(/fatal test/))
45
51
  Log.configure(@logger)
46
- Log.fatal("fatal test")
52
+ Log.cycle_level
47
53
  end
54
+ end
48
55
 
49
- it "should log at error level" do
50
- @logger.expects(:log).with(:error, anything, regexp_matches(/error test/))
51
- Log.configure(@logger)
52
- Log.error("error test")
56
+ describe "#from" do
57
+ let(:execution_stack) do
58
+ if Util.windows?
59
+ ['C:\rspec\test1:52:in `rspec block1\'',
60
+ 'C:\rspec\test2:52:in `rspec block2\'',
61
+ 'C:\rspec\test3:52:in `rspec block3\'',
62
+ 'C:\rspec\test4:52:in `rspec block4\'']
63
+ else
64
+ ["/rspec/test1:52:in `rspec block1'",
65
+ "/rspec/test2:52:in `rspec block2'",
66
+ "/rspec/test3:52:in `rspec block3'",
67
+ "/rspec/test4:52:in `rspec block4'"]
68
+ end
53
69
  end
54
70
 
55
- it "should log at warning level" do
56
- @logger.expects(:log).with(:warn, anything, regexp_matches(/warn test/))
57
- Log.configure(@logger)
58
- Log.warn("warn test")
71
+ it "should return the correct from string when given file, line, block" do
72
+ Log.stubs(:execution_stack).returns(execution_stack)
73
+ Log.from.should == "test4:52:in `rspec block4'"
59
74
  end
60
- end
61
75
 
62
- describe "#cycle_level" do
63
- it "should cycle logger class levels" do
64
- @logger.expects(:cycle_level)
76
+ it "should return the correct from string shen given file and line" do
77
+ if Util.windows?
78
+ execution_stack[3] = 'C:\rspec\test4:52'
79
+ else
80
+ execution_stack[3] = '/rspec/test4:52'
81
+ end
65
82
 
66
- Log.configure(@logger)
67
- Log.cycle_level
83
+ Log.stubs(:execution_stack).returns(execution_stack)
84
+ Log.from.should == "test4:52"
68
85
  end
69
86
  end
70
87
  end
@@ -23,7 +23,7 @@ module MCollective::Logger
23
23
  end
24
24
 
25
25
  it "should accept correct levels" do
26
- Base.new
26
+ expect { Base.new }.to_not raise_error
27
27
  end
28
28
  end
29
29
 
@@ -117,6 +117,14 @@ module MCollective
117
117
  result = Matcher.execute_function({"name" => "foo", "params" => "bar"})
118
118
  result.should == "success"
119
119
  end
120
+
121
+ it "should return nil if the result cannot be evaluated" do
122
+ data = mock
123
+ data.expects(:send).with("value").raises("error")
124
+ Data.expects(:send).with("foo", "bar").returns(data)
125
+ result = Matcher.execute_function({"name" => "foo", "params" => "bar", "value" => "value"})
126
+ result.should == nil
127
+ end
120
128
  end
121
129
 
122
130
  describe "#eval_compound_statement" do
@@ -170,6 +178,12 @@ module MCollective
170
178
  result = Matcher.eval_compound_fstatement(function_hash)
171
179
  result.should == false
172
180
  end
181
+
182
+ it "should return false immediately if the function execution returns nil" do
183
+ Matcher.expects(:execute_function).returns(nil)
184
+ result = Matcher.eval_compound_fstatement(function_hash)
185
+ result.should == false
186
+ end
173
187
  end
174
188
 
175
189
  describe "it should return false if backticks are present in parameters and if non strings are compared with regex's" do