1 /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
2 
3 #include "config/configcompiler.hpp"
4 #include "base/exception.hpp"
5 #include <BoostTestTargetConfig.h>
6 
7 using namespace icinga;
8 
9 BOOST_AUTO_TEST_SUITE(config_ops)
10 
BOOST_AUTO_TEST_CASE(simple)11 BOOST_AUTO_TEST_CASE(simple)
12 {
13 	ScriptFrame frame(true);
14 	std::unique_ptr<Expression> expr;
15 	Dictionary::Ptr dict;
16 
17 	expr = ConfigCompiler::CompileText("<test>", "");
18 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == Empty);
19 
20 	expr = ConfigCompiler::CompileText("<test>", "\n3");
21 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
22 
23 	expr = ConfigCompiler::CompileText("<test>", "{ 3\n\n5 }");
24 	BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
25 
26 	expr = ConfigCompiler::CompileText("<test>", "1 + 3");
27 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 4);
28 
29 	expr = ConfigCompiler::CompileText("<test>", "3 - 1");
30 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 2);
31 
32 	expr = ConfigCompiler::CompileText("<test>", "5m * 10");
33 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3000);
34 
35 	expr = ConfigCompiler::CompileText("<test>", "5m / 5");
36 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 60);
37 
38 	expr = ConfigCompiler::CompileText("<test>", "7 & 3");
39 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
40 
41 	expr = ConfigCompiler::CompileText("<test>", "2 | 3");
42 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
43 
44 	expr = ConfigCompiler::CompileText("<test>", "true && false");
45 	BOOST_CHECK(!expr->Evaluate(frame).GetValue());
46 
47 	expr = ConfigCompiler::CompileText("<test>", "true || false");
48 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
49 
50 	expr = ConfigCompiler::CompileText("<test>", "3 < 5");
51 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
52 
53 	expr = ConfigCompiler::CompileText("<test>", "3 > 5");
54 	BOOST_CHECK(!expr->Evaluate(frame).GetValue());
55 
56 	expr = ConfigCompiler::CompileText("<test>", "3 <= 3");
57 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
58 
59 	expr = ConfigCompiler::CompileText("<test>", "3 >= 3");
60 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
61 
62 	expr = ConfigCompiler::CompileText("<test>", "2 + 3 * 4");
63 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 14);
64 
65 	expr = ConfigCompiler::CompileText("<test>", "(2 + 3) * 4");
66 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 20);
67 
68 	expr = ConfigCompiler::CompileText("<test>", "2 * - 3");
69 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == -6);
70 
71 	expr = ConfigCompiler::CompileText("<test>", "-(2 + 3)");
72 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == -5);
73 
74 	expr = ConfigCompiler::CompileText("<test>", "- 2 * 2 - 2 * 3 - 4 * - 5");
75 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 10);
76 
77 	expr = ConfigCompiler::CompileText("<test>", "!0 == true");
78 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
79 
80 	expr = ConfigCompiler::CompileText("<test>", "~0");
81 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == (double)~(long)0);
82 
83 	expr = ConfigCompiler::CompileText("<test>", "4 << 8");
84 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 1024);
85 
86 	expr = ConfigCompiler::CompileText("<test>", "1024 >> 4");
87 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 64);
88 
89 	expr = ConfigCompiler::CompileText("<test>", "2 << 3 << 4");
90 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 256);
91 
92 	expr = ConfigCompiler::CompileText("<test>", "256 >> 4 >> 3");
93 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 2);
94 
95 	expr = ConfigCompiler::CompileText("<test>", R"("hello" == "hello")");
96 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
97 
98 	expr = ConfigCompiler::CompileText("<test>", R"("hello" != "hello")");
99 	BOOST_CHECK(!expr->Evaluate(frame).GetValue());
100 
101 	expr = ConfigCompiler::CompileText("<test>", R"("foo" in [ "foo", "bar" ])");
102 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
103 
104 	expr = ConfigCompiler::CompileText("<test>", R"("foo" in [ "bar", "baz" ])");
105 	BOOST_CHECK(!expr->Evaluate(frame).GetValue());
106 
107 	expr = ConfigCompiler::CompileText("<test>", "\"foo\" in null");
108 	BOOST_CHECK(!expr->Evaluate(frame).GetValue());
109 
110 	expr = ConfigCompiler::CompileText("<test>", R"("foo" in "bar")");
111 	BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
112 
113 	expr = ConfigCompiler::CompileText("<test>", R"("foo" !in [ "bar", "baz" ])");
114 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
115 
116 	expr = ConfigCompiler::CompileText("<test>", R"("foo" !in [ "foo", "bar" ])");
117 	BOOST_CHECK(!expr->Evaluate(frame).GetValue());
118 
119 	expr = ConfigCompiler::CompileText("<test>", "\"foo\" !in null");
120 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
121 
122 	expr = ConfigCompiler::CompileText("<test>", R"("foo" !in "bar")");
123 	BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
124 
125 	expr = ConfigCompiler::CompileText("<test>", "{ a += 3 }");
126 	dict = expr->Evaluate(frame).GetValue();
127 	BOOST_CHECK(dict->GetLength() == 1);
128 	BOOST_CHECK(dict->Get("a") == 3);
129 
130 	expr = ConfigCompiler::CompileText("<test>", "test");
131 	BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
132 
133 	expr = ConfigCompiler::CompileText("<test>", "null + 3");
134 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
135 
136 	expr = ConfigCompiler::CompileText("<test>", "3 + null");
137 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
138 
139 	expr = ConfigCompiler::CompileText("<test>", "\"test\" + 3");
140 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == "test3");
141 
142 	expr = ConfigCompiler::CompileText("<test>", R"("\"te\\st")");
143 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == "\"te\\st");
144 
145 	expr = ConfigCompiler::CompileText("<test>", R"("\'test")");
146 	BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
147 
148 	expr = ConfigCompiler::CompileText("<test>", "({ a = 3\nb = 3 })");
149 	BOOST_CHECK(expr->Evaluate(frame).GetValue().IsObjectType<Dictionary>());
150 }
151 
152 BOOST_AUTO_TEST_CASE(advanced)
153 {
154 	ScriptFrame frame(true);
155 	std::unique_ptr<Expression> expr;
156 	Function::Ptr func;
157 
158 	expr = ConfigCompiler::CompileText("<test>", R"(regex("^Hello", "Hello World"))");
159 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
160 
161 	expr = ConfigCompiler::CompileText("<test>", "__boost_test()");
162 	BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
163 
164 	Object::Ptr self = new Object();
165 	ScriptFrame frame2(true, self);
166 	expr = ConfigCompiler::CompileText("<test>", "this");
167 	BOOST_CHECK(expr->Evaluate(frame2).GetValue() == Value(self));
168 
169 	expr = ConfigCompiler::CompileText("<test>", "var v = 7; v");
170 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
171 
172 	expr = ConfigCompiler::CompileText("<test>", "{ a = 3 }.a");
173 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
174 
175 	expr = ConfigCompiler::CompileText("<test>", "[ 2, 3 ][1]");
176 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
177 
178 	expr = ConfigCompiler::CompileText("<test>", "var v = { a = 3}; v.a");
179 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
180 
181 	expr = ConfigCompiler::CompileText("<test>", "a = 3 b = 3");
182 	BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
183 
184 	expr = ConfigCompiler::CompileText("<test>", "function() { 3 }()");
185 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
186 
187 	expr = ConfigCompiler::CompileText("<test>", "function() { return 3, 5 }()");
188 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
189 
190 	expr = ConfigCompiler::CompileText("<test>", "typeof([]) == Array");
191 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
192 
193 	expr = ConfigCompiler::CompileText("<test>", "typeof({}) == Dictionary");
194 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
195 
196 	expr = ConfigCompiler::CompileText("<test>", "typeof(3) == Number");
197 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
198 
199 	expr = ConfigCompiler::CompileText("<test>", "typeof(\"test\") == String");
200 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
201 
202 	expr = ConfigCompiler::CompileText("<test>", "(7 | 8) == 15");
203 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
204 
205 	expr = ConfigCompiler::CompileText("<test>", "(7 ^ 8) == 15");
206 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
207 
208 	expr = ConfigCompiler::CompileText("<test>", "(7 & 15) == 7");
209 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
210 
211 	expr = ConfigCompiler::CompileText("<test>", "7 in [7] == true");
212 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
213 
214 	expr = ConfigCompiler::CompileText("<test>", "7 !in [7] == false");
215 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
216 
217 	expr = ConfigCompiler::CompileText("<test>", "(7 | 8) > 14");
218 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
219 
220 	expr = ConfigCompiler::CompileText("<test>", "(7 ^ 8) > 14");
221 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
222 
223 	expr = ConfigCompiler::CompileText("<test>", "(7 & 15) > 6");
224 	BOOST_CHECK(expr->Evaluate(frame).GetValue());
225 
226 	expr = ConfigCompiler::CompileText("<test>", "\"a\" = 3");
227 	BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
228 
229 	expr = ConfigCompiler::CompileText("<test>", "3 = 3");
230 	BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
231 
232 	expr = ConfigCompiler::CompileText("<test>", "var e; e");
233 	BOOST_CHECK(expr->Evaluate(frame).GetValue().IsEmpty());
234 
235 	expr = ConfigCompiler::CompileText("<test>", "var e = 3; e");
236 	BOOST_CHECK(expr->Evaluate(frame).GetValue() == 3);
237 
238 	expr = ConfigCompiler::CompileText("<test>", "Array.x");
239 	BOOST_CHECK_THROW(expr->Evaluate(frame).GetValue(), ScriptError);
240 
241 	expr = ConfigCompiler::CompileText("<test>", "{{ 3 }}");
242 	func = expr->Evaluate(frame).GetValue();
243 	BOOST_CHECK(func->Invoke() == 3);
244 }
245 
246 BOOST_AUTO_TEST_SUITE_END()
247