Browse Source

[4204] Extended expression parser tests to reference option by name.

Marcin Siodelski 9 years ago
parent
commit
749b1261ca
1 changed files with 105 additions and 51 deletions
  1. 105 51
      src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc

+ 105 - 51
src/lib/dhcpsrv/tests/client_class_def_parser_unittest.cc

@@ -15,6 +15,8 @@
 #include <config.h>
 
 #include <cc/data.h>
+#include <dhcp/libdhcp++.h>
+#include <dhcp/option.h>
 #include <dhcp/option_string.h>
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/parsers/client_class_def_parser.h>
@@ -32,6 +34,61 @@ using namespace isc::dhcp;
 
 namespace {
 
+/// @brief Test fixture class for @c ExpressionParser.
+class ExpressionParserTest : public ::testing::Test {
+protected:
+
+    /// @brief Test that validate expression can be evaluated against v4 or
+    /// v6 packet.
+    ///
+    /// Verifies that given a valid expression, the ExpressionParser
+    /// produces an Expression which can be evaluated against a v4 or v6
+    /// packet.
+    ///
+    /// @param universe V4 or V6.
+    /// @param expression Textual representation of the expression to be
+    /// evaluated.
+    /// @param option_string String data to be placed in the hostname
+    /// option, being placed in the packet used for evaluation.
+    /// @tparam Type of the packet: @c Pkt4 or @c Pkt6.
+    template<typename PktType>
+    void testValidExpression(const Option::Universe& universe,
+                             const std::string& expression,
+                             const std::string& option_string) {
+        ParserContextPtr context(new ParserContext(universe));
+        ExpressionParserPtr parser;
+        ExpressionPtr parsed_expr;
+
+        // Turn config into elements.  This may emit exceptions.
+        ElementPtr config_element = Element::fromJSON(expression);
+
+        // Create the parser.
+        ASSERT_NO_THROW(parser.reset(new ExpressionParser("", parsed_expr,
+                                                      context)));
+        // Expression should parse and commit.
+        ASSERT_NO_THROW(parser->build(config_element));
+        ASSERT_NO_THROW(parser->commit());
+
+        // Parsed expression should exist.
+        ASSERT_TRUE(parsed_expr);
+
+        // Build a packet that will fail evaluation.
+        boost::shared_ptr<PktType> pkt(new PktType(universe == Option::V4 ?
+                                                   DHCPDISCOVER : DHCPV6_SOLICIT,
+                                                   123));
+        EXPECT_FALSE(evaluate(*parsed_expr, *pkt));
+
+        // Now add the option so it will pass. Use a standard option carrying a
+        // single string value, i.e. hostname for DHCPv4 and bootfile url for
+        // DHCPv6.
+        OptionPtr opt(new OptionString(universe, universe == Option::V4 ?
+                                       DHO_HOST_NAME : D6O_BOOTFILE_URL,
+                                       option_string));
+        pkt->addOption(opt);
+        EXPECT_TRUE(evaluate(*parsed_expr, *pkt));
+    }
+};
+
 /// @brief Test fixture class for @c ClientClassDefParser.
 class ClientClassDefParserTest : public ::testing::Test {
 protected:
@@ -113,69 +170,66 @@ protected:
 
 // Verifies that given a valid expression, the ExpressionParser
 // produces an Expression which can be evaluated against a v4 packet.
-TEST(ExpressionParserTest, validExpression4) {
-    ParserContextPtr context(new ParserContext(Option::V4));
-    ExpressionParserPtr parser;
-    ExpressionPtr parsed_expr;
-
-    // Turn config into elements.  This may emit exceptions.
-    std::string cfg_txt = "\"option[100].text == 'hundred4'\"";
-    ElementPtr config_element = Element::fromJSON(cfg_txt);
-
-    // Create the parser.
-    ASSERT_NO_THROW(parser.reset(new ExpressionParser("", parsed_expr,
-                                                      context)));
-    // Expression should parse and commit.
-    ASSERT_NO_THROW(parser->build(config_element));
-    ASSERT_NO_THROW(parser->commit());
+TEST_F(ExpressionParserTest, validExpression4) {
+    testValidExpression<Pkt4>(Option::V4, "\"option[12].text == 'hundred4'\"",
+                              "hundred4");
+}
 
-    // Parsed expression should exist.
-    ASSERT_TRUE(parsed_expr);
+// Verifies that the option name can be used in the evaluated expression.
+TEST_F(ExpressionParserTest, validExpressionWithOptionName4) {
+    testValidExpression<Pkt4>(Option::V4,
+                              "\"option['host-name'].text == 'hundred4'\"",
+                              "hundred4");
+}
 
-    // Build a packet that will fail evaluation.
-    Pkt4Ptr pkt4(new Pkt4(DHCPDISCOVER, 123));
-    EXPECT_FALSE(evaluate(*parsed_expr, *pkt4));
+// Verifies that given a valid expression using .hex operator for option, the
+// ExpressionParser produces an Expression which can be evaluated against
+// a v4 packet.
+TEST_F(ExpressionParserTest, validExpressionWithHex4) {
+    testValidExpression<Pkt4>(Option::V4, "\"option[12].hex == 0x68756E6472656434\"",
+                              "hundred4");
+}
 
-    // Now add the option so it will pass.
-    OptionPtr opt(new OptionString(Option::V4, 100, "hundred4"));
-    pkt4->addOption(opt);
-    EXPECT_TRUE(evaluate(*parsed_expr, *pkt4));
+// Verifies that the option name can be used together with .hex operator in
+// the evaluated expression.
+TEST_F(ExpressionParserTest, validExpressionWithOptionNameAndHex4) {
+    testValidExpression<Pkt6>(Option::V4,
+                              "\"option['host-name'].text == 0x68756E6472656434\"",
+                              "hundred4");
 }
 
 // Verifies that given a valid expression, the ExpressionParser
 // produces an Expression which can be evaluated against a v6 packet.
-TEST(ExpressionParserTest, validExpression6) {
-    ParserContextPtr context(new ParserContext(Option::V6));
-    ExpressionParserPtr parser;
-    ExpressionPtr parsed_expr;
-
-    // Turn config into elements.  This may emit exceptions.
-    std::string cfg_txt = "\"option[100].text == 'hundred6'\"";
-    ElementPtr config_element = Element::fromJSON(cfg_txt);
-
-    // Create the parser.
-    ASSERT_NO_THROW(parser.reset(new ExpressionParser("", parsed_expr,
-                                                      context)));
-    // Expression should parse and commit.
-    ASSERT_NO_THROW(parser->build(config_element));
-    ASSERT_NO_THROW(parser->commit());
-
-    // Parsed expression should exist.
-    ASSERT_TRUE(parsed_expr);
+TEST_F(ExpressionParserTest, validExpression6) {
+    testValidExpression<Pkt6>(Option::V6, "\"option[59].text == 'hundred6'\"",
+                              "hundred6");
+}
 
-    // Build a packet that will fail evaluation.
-    Pkt6Ptr pkt6(new Pkt6(DHCPDISCOVER, 123));
-    EXPECT_FALSE(evaluate(*parsed_expr, *pkt6));
+// Verifies that the option name can be used in the evaluated expression.
+TEST_F(ExpressionParserTest, validExpressionWithOptionName6) {
+    testValidExpression<Pkt6>(Option::V6,
+                              "\"option['bootfile-url'].text == 'hundred6'\"",
+                              "hundred6");
+}
 
-    // Now add the option so it will pass.
-    OptionPtr opt(new OptionString(Option::V6, 100, "hundred6"));
-    pkt6->addOption(opt);
-    EXPECT_TRUE(evaluate(*parsed_expr, *pkt6));
+// Verifies that given a valid expression using .hex operator for option, the
+// ExpressionParser produces an Expression which can be evaluated against
+// a v6 packet.
+TEST_F(ExpressionParserTest, validExpressionWithHex6) {
+    testValidExpression<Pkt6>(Option::V6, "\"option[59].hex == 0x68756E6472656436\"",
+                              "hundred6");
 }
 
+// Verifies that the option name can be used together with .hex operator in
+// the evaluated expression.
+TEST_F(ExpressionParserTest, validExpressionWithOptionNameAndHex6) {
+    testValidExpression<Pkt6>(Option::V6,
+                              "\"option['bootfile-url'].text == 0x68756E6472656436\"",
+                              "hundred6");
+}
 
 // Verifies that an the ExpressionParser only accepts StringElements.
-TEST(ExpressionParserTest, invalidExpressionElement) {
+TEST_F(ExpressionParserTest, invalidExpressionElement) {
     ParserContextPtr context(new ParserContext(Option::V4));
     ExpressionParserPtr parser;
     ExpressionPtr parsed_expr;
@@ -196,7 +250,7 @@ TEST(ExpressionParserTest, invalidExpressionElement) {
 // is not intended to be an exhaustive test or expression syntax.
 // It is simply to ensure that if the parser fails, it does so
 // Properly.
-TEST(ExpressionParserTest, expressionSyntaxError) {
+TEST_F(ExpressionParserTest, expressionSyntaxError) {
     ParserContextPtr context(new ParserContext(Option::V4));
     ExpressionParserPtr parser;
     ExpressionPtr parsed_expr;