Update mcollective.init according to OSCI-855
[packages/precise/mcollective.git] / spec / unit / matcher_spec.rb
1 #!/usr/bin/env rspec
2
3 require 'spec_helper'
4
5 module MCollective
6   describe Matcher do
7     describe "#create_function_hash" do
8       it "should create a correct hash for a 'normal' function call using single quotes" do
9         result = Matcher.create_function_hash("foo('bar').res=1")
10         result["value"].should == "res"
11         result["params"].should == "bar"
12         result["r_compare"].should == "1"
13         result["operator"].should == "=="
14         result["name"].should == "foo"
15       end
16
17       it "should create a correct hash for a 'normal' function call using double quotes" do
18         result = Matcher.create_function_hash('foo("bar").res=1')
19         result["value"].should == "res"
20         result["params"].should == "bar"
21         result["r_compare"].should == "1"
22         result["operator"].should == "=="
23         result["name"].should == "foo"
24        end
25
26       it "should create a correct hash when a paramater contains a dot value" do
27         result = Matcher.create_function_hash("foo('bar.1').res=1")
28         result["value"].should == "res"
29         result["params"].should == "bar.1"
30         result["r_compare"].should == "1"
31         result["operator"].should == "=="
32         result["name"].should == "foo"
33       end
34
35       it "should create a correct hash when right compare value is a regex" do
36         result = Matcher.create_function_hash("foo('bar').res=/reg/")
37         result["value"].should == "res"
38         result["params"].should == "bar"
39         result["r_compare"].should == /reg/
40         result["operator"].should == "=~"
41         result["name"].should == "foo"
42       end
43
44       it "should create a correct hash when the operator is >= or <=" do
45         result = Matcher.create_function_hash("foo('bar').res<=1")
46         result["value"].should == "res"
47         result["params"].should == "bar"
48         result["r_compare"].should == "1"
49         result["operator"].should == "<="
50         result["name"].should == "foo"
51
52         result = Matcher.create_function_hash("foo('bar').res>=1")
53         result["value"].should == "res"
54         result["params"].should == "bar"
55         result["r_compare"].should == "1"
56         result["operator"].should == ">="
57         result["name"].should == "foo"
58       end
59
60       it "should create a correct hash when no dot value is present" do
61         result = Matcher.create_function_hash("foo('bar')<=1")
62         result["value"].should == nil
63         result["params"].should == "bar"
64         result["r_compare"].should == "1"
65         result["operator"].should == "<="
66         result["name"].should == "foo"
67       end
68
69       it "should create a correct hash when a dot is present in a parameter but no dot value is present" do
70         result = Matcher.create_function_hash("foo('bar.one')<=1")
71         result["value"].should == nil
72         result["params"].should == "bar.one"
73         result["r_compare"].should == "1"
74         result["operator"].should == "<="
75         result["name"].should == "foo"
76       end
77
78       it "should create a correct hash when multiple dots are present in parameters but no dot value is present" do
79         result = Matcher.create_function_hash("foo('bar.one.two, bar.three.four')<=1")
80         result["value"].should == nil
81         result["params"].should == "bar.one.two, bar.three.four"
82         result["r_compare"].should == "1"
83         result["operator"].should == "<="
84         result["name"].should == "foo"
85       end
86
87       it "should create a correct hash when no parameters are given" do
88         result = Matcher.create_function_hash("foo()<=1")
89         result["value"].should == nil
90         result["params"].should == nil
91         result["r_compare"].should == "1"
92         result["operator"].should == "<="
93         result["name"].should == "foo"
94      end
95
96       it "should create a correct hash parameters are empty strings" do
97         result = Matcher.create_function_hash("foo('')=1")
98         result["value"].should == nil
99         result["params"].should == ""
100         result["r_compare"].should == "1"
101         result["operator"].should == "=="
102         result["name"].should == "foo"
103       end
104     end
105
106     describe "#execute_function" do
107       it "should return the result of an evaluated function with a dot value" do
108         data = mock
109         data.expects(:send).with("value").returns("success")
110         MCollective::Data.expects(:send).with("foo", "bar").returns(data)
111         result = Matcher.execute_function({"name" => "foo", "params" => "bar", "value" => "value"})
112         result.should == "success"
113       end
114
115       it "should return the result of an evaluated function without a dot value" do
116         MCollective::Data.expects(:send).with("foo", "bar").returns("success")
117         result = Matcher.execute_function({"name" => "foo", "params" => "bar"})
118         result.should == "success"
119       end
120     end
121
122     describe "#eval_compound_statement" do
123       it "should return correctly on a regex class statement" do
124         Util.expects(:has_cf_class?).with("/foo/").returns(true)
125         Matcher.eval_compound_statement({"statement" => "/foo/"}).should == true
126         Util.expects(:has_cf_class?).with("/foo/").returns(false)
127         Matcher.eval_compound_statement({"statement" => "/foo/"}).should == false
128       end
129
130       it "should return correcly for string and regex facts" do
131         Util.expects(:has_fact?).with("foo", "bar", "==").returns(true)
132         Matcher.eval_compound_statement({"statement" => "foo=bar"}).should == "true"
133         Util.expects(:has_fact?).with("foo", "/bar/", "=~").returns(false)
134         Matcher.eval_compound_statement({"statement" => "foo=/bar/"}).should == "false"
135       end
136
137       it "should return correctly on a string class statement" do
138         Util.expects(:has_cf_class?).with("foo").returns(true)
139         Matcher.eval_compound_statement({"statement" => "foo"}).should == true
140         Util.expects(:has_cf_class?).with("foo").returns(false)
141         Matcher.eval_compound_statement({"statement" => "foo"}).should == false
142       end
143     end
144
145     describe "#eval_compound_fstatement" do
146       describe "it should return false if a string, true or false are compared with > or <" do
147         let(:function_hash) do
148           {"name" => "foo",
149            "params" => "bar",
150            "value" => "value",
151            "operator" => "<",
152            "r_compare" => "teststring"}
153         end
154
155
156         it "should return false if a string is compare with a < or >" do
157           Matcher.expects(:execute_function).returns("teststring")
158           result = Matcher.eval_compound_fstatement(function_hash)
159           result.should == false
160         end
161
162         it "should return false if a TrueClass is compared with a < or > " do
163           Matcher.expects(:execute_function).returns(true)
164           result = Matcher.eval_compound_fstatement(function_hash)
165           result.should == false
166         end
167
168         it "should return false if a FalseClass is compared with a < or >" do
169           Matcher.expects(:execute_function).returns(false)
170           result = Matcher.eval_compound_fstatement(function_hash)
171           result.should == false
172         end
173       end
174
175       describe "it should return false if backticks are present in parameters and if non strings are compared with regex's" do
176         before :each do
177           @function_hash = {"name" => "foo",
178                            "params" => "bar",
179                            "value" => "value",
180                            "operator" => "=",
181                            "r_compare" => "1"}
182         end
183
184         it "should return false if a backtick is present in a parameter" do
185           @function_hash["params"] = "`bar`"
186           Matcher.expects(:execute_function).returns("teststring")
187           MCollective::Log.expects(:debug).with("Cannot use backticks in function parameters")
188           result = Matcher.eval_compound_fstatement(@function_hash)
189           result.should == false
190         end
191
192         it "should return false if left compare object isn't a string and right compare is a regex" do
193           Matcher.expects(:execute_function).returns(1)
194           @function_hash["r_compare"] = "/foo/"
195           @function_hash["operator"] = "=~"
196           MCollective::Log.expects(:debug).with("Cannot do a regex check on a non string value.")
197           result = Matcher.eval_compound_fstatement(@function_hash)
198           result.should == false
199         end
200       end
201
202       describe "it should return the expected result for valid function hashes" do
203         before :each do
204           @function_hash = {"name" => "foo",
205                             "params" => "bar",
206                             "value" => "value",
207                             "operator" => "=",
208                             "r_compare" => ""}
209         end
210
211         it "should return true if right value is a regex and matches the left value" do
212           Matcher.expects(:execute_function).returns("teststring")
213           @function_hash["r_compare"] = /teststring/
214           @function_hash["operator"] = "=~"
215           result = Matcher.eval_compound_fstatement(@function_hash)
216           result.should == true
217         end
218
219         it "should return false if right value is a regex, operator is != and regex equals left value" do
220           Matcher.expects(:execute_function).returns("teststring")
221           @function_hash["r_compare"] = /teststring/
222           @function_hash["operator"] = "!=~"
223           result = Matcher.eval_compound_fstatement(@function_hash)
224           result.should == false
225         end
226
227         it "should return false if right value is a regex and does not match left value" do
228           Matcher.expects(:execute_function).returns("testsnotstring")
229           @function_hash["r_compare"] = /teststring/
230           @function_hash["operator"] = "=~"
231           result = Matcher.eval_compound_fstatement(@function_hash)
232           result.should == false
233         end
234
235         it "should return true if left value logically compares to the right value" do
236           Matcher.expects(:execute_function).returns(1)
237           @function_hash["r_compare"] = 1
238           @function_hash["operator"] = ">="
239           result = Matcher.eval_compound_fstatement(@function_hash)
240           result.should == true
241        end
242
243         it "should return false if left value does not logically compare to right value" do
244           Matcher.expects(:execute_function).returns("1")
245           @function_hash["r_compare"] = "1"
246           @function_hash["operator"] = ">"
247           result = Matcher.eval_compound_fstatement(@function_hash)
248           result.should == false
249         end
250       end
251     end
252
253     describe "#create_compound_callstack" do
254       it "should create a callstack from a valid call_string" do
255         result = Matcher.create_compound_callstack("foo('bar')=1 and bar=/bar/")
256         result.should == [{"fstatement" => {"params"=>"bar", "name"=>"foo", "operator"=>"==", "r_compare"=>"1"}}, {"and" => "and"}, {"statement" => "bar=/bar/"}]
257       end
258     end
259   end
260 end