summaryrefslogtreecommitdiffstats
path: root/src/lib/eval/tests
diff options
context:
space:
mode:
authorRazvan Becheriu <razvan.becheriu@qualitance.com>2017-12-12 13:28:29 +0100
committerRazvan Becheriu <razvan.becheriu@qualitance.com>2017-12-12 13:28:29 +0100
commitf14a42d0baba9b074b4b72d961ddeaf1214098b1 (patch)
treeca4d827596963b298f862c4db110f04ebb753e60 /src/lib/eval/tests
parentMerge branch 'isc-master' into config-h (diff)
parent[master] Added ChangeLog entry for #5403. (diff)
downloadkea-f14a42d0baba9b074b4b72d961ddeaf1214098b1.tar.xz
kea-f14a42d0baba9b074b4b72d961ddeaf1214098b1.zip
Merge remote-tracking branch 'isc-kea/master' into HEAD
Diffstat (limited to 'src/lib/eval/tests')
-rw-r--r--src/lib/eval/tests/context_unittest.cc40
-rw-r--r--src/lib/eval/tests/evaluate_unittest.cc14
-rw-r--r--src/lib/eval/tests/token_unittest.cc39
3 files changed, 93 insertions, 0 deletions
diff --git a/src/lib/eval/tests/context_unittest.cc b/src/lib/eval/tests/context_unittest.cc
index 40252f8afb..fffc27f979 100644
--- a/src/lib/eval/tests/context_unittest.cc
+++ b/src/lib/eval/tests/context_unittest.cc
@@ -406,6 +406,14 @@ public:
EXPECT_TRUE(conc);
}
+ /// @brief checks if the given token is an ifelse operator
+ void checkTokenIfElse(const TokenPtr& token) {
+ ASSERT_TRUE(token);
+ boost::shared_ptr<TokenIfElse> alt =
+ boost::dynamic_pointer_cast<TokenIfElse>(token);
+ EXPECT_TRUE(alt);
+ }
+
/// @brief checks if the given expression raises the expected message
/// when it is parsed.
void checkError(const string& expr, const string& msg) {
@@ -1209,6 +1217,26 @@ TEST_F(EvalContextTest, concat) {
checkTokenConcat(tmp3);
}
+// Test the parsing of an ifelse expression
+TEST_F(EvalContextTest, ifElse) {
+ EvalContext eval(Option::V4);
+
+ EXPECT_NO_THROW(parsed_ =
+ eval.parseString("ifelse('foo' == 'bar', 'us', 'them') == 'you'"));
+
+ ASSERT_EQ(8, eval.expression.size());
+
+ TokenPtr tmp1 = eval.expression.at(2);
+ TokenPtr tmp2 = eval.expression.at(3);
+ TokenPtr tmp3 = eval.expression.at(4);
+ TokenPtr tmp4 = eval.expression.at(5);
+
+ checkTokenEq(tmp1);
+ checkTokenString(tmp2, "us");
+ checkTokenString(tmp3, "them");
+ checkTokenIfElse(tmp4);
+}
+
//
// Test some scanner error cases
TEST_F(EvalContextTest, scanErrors) {
@@ -1358,6 +1386,10 @@ TEST_F(EvalContextTest, parseErrors) {
"<string>:1.16: syntax error, unexpected ), expecting \",\"");
checkError("concat('foo','bar','') == 'foobar'",
"<string>:1.19: syntax error, unexpected \",\", expecting )");
+ checkError("ifelse('foo'=='bar','foo')",
+ "<string>:1.26: syntax error, unexpected ), expecting \",\"");
+ checkError("ifelse('foo'=='bar','foo','bar','')",
+ "<string>:1.32: syntax error, unexpected \",\", expecting )");
}
// Tests some type error cases
@@ -1388,6 +1420,14 @@ TEST_F(EvalContextTest, typeErrors) {
"<string>:1.8-10: syntax error, unexpected and, expecting ==");
checkError("'true' or 'false'",
"<string>:1.8-9: syntax error, unexpected or, expecting ==");
+ // Ifelse requires a boolean condition and string branches.
+ checkError("ifelse('foobar','foo','bar')",
+ "<string>:1.16: syntax error, unexpected \",\", expecting ==");
+ checkError("ifelse('foo'=='bar','foo'=='foo','bar')",
+ "<string>:1.26-27: syntax error, unexpected ==, "
+ "expecting \",\"");
+ checkError("ifelse('foo'=='bar','foo','bar'=='bar')",
+ "<string>:1.32-33: syntax error, unexpected ==, expecting )");
}
diff --git a/src/lib/eval/tests/evaluate_unittest.cc b/src/lib/eval/tests/evaluate_unittest.cc
index 6799770eb4..5afb635c91 100644
--- a/src/lib/eval/tests/evaluate_unittest.cc
+++ b/src/lib/eval/tests/evaluate_unittest.cc
@@ -490,6 +490,20 @@ TEST_F(ExpressionsTest, evaluateString) {
EvalContext::PARSER_STRING);
testExpressionNegative<EvalParseError>("pkt6.msgtype == 1", Option::V6,
EvalContext::PARSER_STRING);
+
+ // Check that ifelse works as expecting (it was added explicitely for
+ // the string evaluation).
+ testExpressionString(Option::V4,
+ "ifelse(option[100].exists,'foo','bar')", "foo");
+ testExpressionString(Option::V4,
+ "ifelse(option[200].exists,'foo','bar')", "bar");
+
+ // Check that ifelse can be chained.
+ testExpressionString(Option::V4,
+ "ifelse(option[200].exists,option[200].hex,"
+ "ifelse(option[100].exists,"
+ "option[100].hex,'none?'))",
+ "hundred4");
}
};
diff --git a/src/lib/eval/tests/token_unittest.cc b/src/lib/eval/tests/token_unittest.cc
index d1e99798b1..f9fee2ccff 100644
--- a/src/lib/eval/tests/token_unittest.cc
+++ b/src/lib/eval/tests/token_unittest.cc
@@ -1954,6 +1954,45 @@ TEST_F(TokenTest, concat) {
EXPECT_TRUE(checkFile());
}
+// This test checks if a token representing an ifelse is able
+// to select the branch following the condition.
+TEST_F(TokenTest, ifElse) {
+ ASSERT_NO_THROW(t_.reset(new TokenIfElse()));
+
+ // Ifelse requires three values on the stack, try
+ // with 0, 1 and 2 all should throw an exception
+ EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalBadStack);
+
+ values_.push("bar");
+ EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalBadStack);
+
+ values_.push("foo");
+ EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalBadStack);
+
+ // The condition must be a boolean
+ values_.push("bar");
+ EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalTypeError);
+
+ // Check if what it returns
+ clearStack();
+ ASSERT_NO_THROW(t_.reset(new TokenIfElse()));
+ values_.push("true");
+ values_.push("foo");
+ values_.push("bar");
+ EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
+ ASSERT_EQ(1, values_.size());
+ EXPECT_EQ("foo", values_.top());
+
+ clearStack();
+ ASSERT_NO_THROW(t_.reset(new TokenIfElse()));
+ values_.push("false");
+ values_.push("foo");
+ values_.push("bar");
+ EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
+ ASSERT_EQ(1, values_.size());
+ EXPECT_EQ("bar", values_.top());
+}
+
// This test checks if a token representing a not is able to
// negate a boolean value (with incorrectly built stack).
TEST_F(TokenTest, operatorNotInvalid) {