Browse Source

[5039] SimpleParser is now split into cc/SimpleParser and SimpleParser{4,6}

Tomek Mrugalski 8 years ago
parent
commit
475b253194

+ 2 - 2
src/bin/dhcp4/Makefile.am

@@ -3,7 +3,7 @@ SUBDIRS = . tests
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
 AM_CPPFLAGS += -I$(top_srcdir)/src -I$(top_builddir)/src
-AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(BOOST_INCLUDES) -std=c++11
 if HAVE_MYSQL
 AM_CPPFLAGS += $(MYSQL_CPPFLAGS)
 endif
@@ -62,8 +62,8 @@ libdhcp4_la_SOURCES += json_config_parser.cc json_config_parser.h
 libdhcp4_la_SOURCES += dhcp4_log.cc dhcp4_log.h
 libdhcp4_la_SOURCES += dhcp4_srv.cc dhcp4_srv.h
 libdhcp4_la_SOURCES += dhcp4to6_ipc.cc dhcp4to6_ipc.h
-
 libdhcp4_la_SOURCES += kea_controller.cc
+libdhcp4_la_SOURCES += simple_parser4.cc simple_parser4.h
 
 nodist_libdhcp4_la_SOURCES = dhcp4_messages.h dhcp4_messages.cc
 EXTRA_DIST += dhcp4_messages.mes

+ 2 - 2
src/bin/dhcp4/json_config_parser.cc

@@ -8,6 +8,7 @@
 
 #include <cc/command_interpreter.h>
 #include <dhcp4/dhcp4_log.h>
+#include <dhcp4/simple_parser4.h>
 #include <dhcp/libdhcp++.h>
 #include <dhcp/option_definition.h>
 #include <dhcpsrv/cfg_option.h>
@@ -20,7 +21,6 @@
 #include <dhcpsrv/parsers/host_reservation_parser.h>
 #include <dhcpsrv/parsers/host_reservations_list_parser.h>
 #include <dhcpsrv/parsers/ifaces_config_parser.h>
-#include <dhcpsrv/parsers/simple_parser.h>
 #include <dhcpsrv/timer_mgr.h>
 #include <config/command_mgr.h>
 #include <util/encode/hex.h>
@@ -573,7 +573,7 @@ configureDhcp4Server(Dhcpv4Srv&, isc::data::ConstElementPtr config_set) {
         mutable_cfg->setValue(values);
 
         // Set all default values if not specified by the user.
-        SimpleParser::setAllDefaults(mutable_cfg, false);
+        SimpleParser4::setAllDefaults(mutable_cfg);
 
         // We need definitions first
         ConstElementPtr option_defs = mutable_cfg->get("option-def");

+ 73 - 0
src/bin/dhcp4/simple_parser4.cc

@@ -0,0 +1,73 @@
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <dhcp4/simple_parser4.h>
+#include <cc/data.h>
+#include <boost/foreach.hpp>
+
+using namespace std;
+using namespace isc::data;
+
+namespace isc {
+namespace dhcp {
+
+/// This table defines default values for option definitions in DHCPv4
+const SimpleDefaults SimpleParser4::OPTION4_DEF_DEFAULTS = {
+    { "record-types", Element::string,  ""},
+    { "space",        Element::string,  "dhcp4"},
+    { "array",        Element::boolean, "false"},
+    { "encapsulate",  Element::string,  "" }
+};
+
+/// This table defines default values for options in DHCPv4
+const SimpleDefaults SimpleParser4::OPTION4_DEFAULTS = {
+    { "space",        Element::string,  "dhcp4"},
+    { "csv-format",   Element::boolean, "true"},
+    { "encapsulate",  Element::string,  "" }
+};
+
+/// This table defines default values for DHCPv4
+const SimpleDefaults SimpleParser4::GLOBAL4_DEFAULTS = {
+    { "renew-timer",        Element::integer, "900" },
+    { "rebind-timer",       Element::integer, "1800" },
+    { "valid-lifetime",     Element::integer, "7200" }
+};
+
+/// This list defines parameters that can be inherited from the global
+/// scope to subnet6 scope.
+const ParamsList SimpleParser4::INHERIT_GLOBAL_TO_SUBNET4 = {
+    "renew-timer",
+    "rebind-timer",
+    "valid-lifetime"
+};
+
+size_t SimpleParser4::setAllDefaults(isc::data::ElementPtr global) {
+    size_t cnt = 0;
+
+    // Set global defaults first.
+    cnt = setDefaults(global, GLOBAL4_DEFAULTS);
+
+    // Now set option defintion defaults for each specified option definition
+    ConstElementPtr option_defs = global->get("option-def");
+    if (option_defs) {
+        BOOST_FOREACH(ElementPtr option_def, option_defs->listValue()) {
+            cnt += SimpleParser::setDefaults(option_def, OPTION4_DEF_DEFAULTS);
+        }
+    }
+
+    // Finally, set the defaults for option data
+    ConstElementPtr options = global->get("option-data");
+    if (options) {
+        BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
+            cnt += SimpleParser::setDefaults(single_option, OPTION4_DEFAULTS);
+        }
+    }
+
+    return (cnt);
+}
+
+};
+};

+ 33 - 0
src/bin/dhcp4/simple_parser4.h

@@ -0,0 +1,33 @@
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef SIMPLE_PARSER4_H
+#define SIMPLE_PARSER4_H
+
+#include <cc/simple_parser.h>
+
+namespace isc {
+namespace dhcp {
+
+class SimpleParser4 : public isc::data::SimpleParser {
+public:
+    /// @brief Sets all defaults for DHCPv4 configuration
+    ///
+    /// This method sets global, option data and option definitions defaults.
+    ///
+    /// @param global scope to be filled in with defaults.
+    /// @return number of default values added
+    static size_t setAllDefaults(isc::data::ElementPtr global);
+
+    static const isc::data::SimpleDefaults OPTION4_DEF_DEFAULTS;
+    static const isc::data::SimpleDefaults OPTION4_DEFAULTS;
+    static const isc::data::SimpleDefaults GLOBAL4_DEFAULTS;
+    static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET4;
+};
+
+};
+};
+#endif

+ 1 - 0
src/bin/dhcp4/tests/Makefile.am

@@ -92,6 +92,7 @@ dhcp4_unittests_SOURCES += out_of_range_unittest.cc
 dhcp4_unittests_SOURCES += decline_unittest.cc
 dhcp4_unittests_SOURCES += kea_controller_unittest.cc
 dhcp4_unittests_SOURCES += dhcp4to6_ipc_unittest.cc
+dhcp4_unittests_SOURCES += simple_parser4_unittest.cc
 
 nodist_dhcp4_unittests_SOURCES = marker_file.h test_libraries.h
 

+ 91 - 0
src/bin/dhcp4/tests/simple_parser4_unittest.cc

@@ -0,0 +1,91 @@
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+#include <gtest/gtest.h>
+#include <dhcp4/simple_parser4.h>
+#include <cc/data.h>
+
+using namespace isc::data;
+
+namespace isc {
+namespace dhcp {
+namespace test {
+
+/// @brief DHCP Parser test fixture class
+class SimpleParser4Test : public ::testing::Test {
+public:
+    /// @brief Checks if specified map has an integer parameter with expected value
+    ///
+    /// @param map map to be checked
+    /// @param param_name name of the parameter to be checked
+    /// @param exp_value expected value of the parameter.
+    void checkIntegerValue(const ConstElementPtr& map, const std::string& param_name,
+                           int64_t exp_value) {
+
+        // First check if the passed element is a map.
+        ASSERT_EQ(Element::map, map->getType());
+
+        // Now try to get the element being checked
+        ConstElementPtr elem = map->get(param_name);
+        ASSERT_TRUE(elem);
+
+        // Now check if it's indeed integer
+        ASSERT_EQ(Element::integer, elem->getType());
+
+        // Finally, check if its value meets expectation.
+        EXPECT_EQ(exp_value, elem->intValue());
+    }
+};
+
+// This test checks if global defaults are properly set for DHCPv4.
+TEST_F(SimpleParser4Test, globalDefaults4) {
+
+    ElementPtr empty = Element::fromJSON("{ }");
+    size_t num = 0;
+
+    EXPECT_NO_THROW(num = SimpleParser4::setAllDefaults(empty));
+
+
+    // We expect at least 3 parameters to be inserted.
+    EXPECT_TRUE(num >= 3);
+
+    checkIntegerValue(empty, "valid-lifetime", 7200);
+    checkIntegerValue(empty, "rebind-timer", 1800);
+    checkIntegerValue(empty, "renew-timer", 900);
+
+    // Make sure that preferred-lifetime is not set for v4 (it's v6 only
+    // parameter)
+    EXPECT_FALSE(empty->get("preferred-lifetime"));
+}
+
+// This test checks if the parameters can be inherited from the global
+// scope to the subnet scope.
+TEST_F(SimpleParser4Test, inheritGlobalToSubnet4) {
+    ElementPtr global = Element::fromJSON("{ \"renew-timer\": 1,"
+                                          "  \"rebind-timer\": 2,"
+                                          "  \"preferred-lifetime\": 3,"
+                                          "  \"valid-lifetime\": 4"
+                                          "}");
+    ElementPtr subnet = Element::fromJSON("{ \"renew-timer\": 100 }");
+
+    // we should inherit 3 parameters. Renew-timer should remain intact,
+    // as it was already defined in the subnet scope.
+    size_t num;
+    EXPECT_NO_THROW(num = SimpleParser4::deriveParams(global, subnet,
+                          SimpleParser4::INHERIT_GLOBAL_TO_SUBNET4));
+    EXPECT_EQ(2, num);
+
+    // Check the values. 2 of them are interited, while the third one
+    // was already defined in the subnet, so should not be inherited.
+    checkIntegerValue(subnet, "renew-timer", 100);
+    checkIntegerValue(subnet, "rebind-timer", 2);
+    checkIntegerValue(subnet, "valid-lifetime", 4);
+}
+
+};
+};
+};

+ 4 - 4
src/bin/dhcp6/Makefile.am

@@ -3,7 +3,7 @@ SUBDIRS = . tests
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
 AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin
 AM_CPPFLAGS += -I$(top_srcdir)/src -I$(top_builddir)/src
-AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(BOOST_INCLUDES) -std=c++11
 if HAVE_MYSQL
 AM_CPPFLAGS += $(MYSQL_CPPFLAGS)
 endif
@@ -31,8 +31,8 @@ if GENERATE_DOCS
 
 kea-dhcp6.8: kea-dhcp6.xml
 	@XSLTPROC@ --novalid --xinclude --nonet -o $@ \
-        http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \
-        $(srcdir)/kea-dhcp6.xml
+	http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \
+	$(srcdir)/kea-dhcp6.xml
 
 else
 
@@ -63,8 +63,8 @@ libdhcp6_la_SOURCES += dhcp6_srv.cc dhcp6_srv.h
 libdhcp6_la_SOURCES += ctrl_dhcp6_srv.cc ctrl_dhcp6_srv.h
 libdhcp6_la_SOURCES += json_config_parser.cc json_config_parser.h
 libdhcp6_la_SOURCES += dhcp6to4_ipc.cc dhcp6to4_ipc.h
-
 libdhcp6_la_SOURCES += kea_controller.cc
+libdhcp6_la_SOURCES += simple_parser6.cc simple_parser6.h
 
 nodist_libdhcp6_la_SOURCES = dhcp6_messages.h dhcp6_messages.cc
 EXTRA_DIST += dhcp6_messages.mes

+ 2 - 2
src/bin/dhcp6/json_config_parser.cc

@@ -13,6 +13,7 @@
 #include <dhcp/libdhcp++.h>
 #include <dhcp6/json_config_parser.h>
 #include <dhcp6/dhcp6_log.h>
+#include <dhcp6/simple_parser6.h>
 #include <dhcp/iface_mgr.h>
 #include <dhcpsrv/cfg_option.h>
 #include <dhcpsrv/cfgmgr.h>
@@ -29,7 +30,6 @@
 #include <dhcpsrv/parsers/host_reservation_parser.h>
 #include <dhcpsrv/parsers/host_reservations_list_parser.h>
 #include <dhcpsrv/parsers/ifaces_config_parser.h>
-#include <dhcpsrv/parsers/simple_parser.h>
 #include <log/logger_support.h>
 #include <util/encode/hex.h>
 #include <util/strutil.h>
@@ -845,7 +845,7 @@ configureDhcp6Server(Dhcpv6Srv&, isc::data::ConstElementPtr config_set) {
         ElementPtr mutable_cfg(new MapElement());
         mutable_cfg->setValue(values);
 
-        SimpleParser::setAllDefaults(mutable_cfg, true);
+        SimpleParser6::setAllDefaults(mutable_cfg);
 
         // Make parsers grouping.
         const std::map<std::string, ConstElementPtr>& values_map =

+ 76 - 0
src/bin/dhcp6/simple_parser6.cc

@@ -0,0 +1,76 @@
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <dhcp6/simple_parser6.h>
+#include <cc/data.h>
+#include <boost/foreach.hpp>
+
+using namespace std;
+using namespace isc::data;
+
+namespace isc {
+namespace dhcp {
+
+/// This table defines default values for option definitions in DHCPv6
+const SimpleDefaults SimpleParser6::OPTION6_DEF_DEFAULTS = {
+    { "record-types", Element::string,  ""},
+    { "space",        Element::string,  "dhcp6"},
+    { "array",        Element::boolean, "false"},
+    { "encapsulate",  Element::string,  "" }
+};
+
+/// This table defines default values for options in DHCPv6
+const SimpleDefaults SimpleParser6::OPTION6_DEFAULTS = {
+    { "space",        Element::string,  "dhcp6"},
+    { "csv-format",   Element::boolean, "true"},
+    { "encapsulate",  Element::string,  "" }
+};
+
+/// This table defines default values for both DHCPv4 and DHCPv6
+const SimpleDefaults SimpleParser6::GLOBAL6_DEFAULTS = {
+    { "renew-timer",        Element::integer, "900" },
+    { "rebind-timer",       Element::integer, "1800" },
+    { "preferred-lifetime", Element::integer, "3600" },
+    { "valid-lifetime",     Element::integer, "7200" }
+};
+
+/// This list defines parameters that can be inherited from the global
+/// scope to subnet6 scope.
+const ParamsList SimpleParser6::INHERIT_GLOBAL_TO_SUBNET6 = {
+    "renew-timer",
+    "rebind-timer",
+    "preferred-lifetime",
+    "valid-lifetime"
+};
+
+
+size_t SimpleParser6::setAllDefaults(isc::data::ElementPtr global) {
+    size_t cnt = 0;
+
+    // Set global defaults first.
+    cnt = setDefaults(global, GLOBAL6_DEFAULTS);
+
+    // Now set the defaults for each specified option definition
+    ConstElementPtr option_defs = global->get("option-def");
+    if (option_defs) {
+        BOOST_FOREACH(ElementPtr option_def, option_defs->listValue()) {
+            cnt += SimpleParser::setDefaults(option_def, OPTION6_DEF_DEFAULTS);
+        }
+    }
+
+    // Finally, set the defaults for option data
+    ConstElementPtr options = global->get("option-data");
+    if (options) {
+        BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
+            cnt += SimpleParser::setDefaults(single_option, OPTION6_DEFAULTS);
+        }
+    }
+
+    return (cnt);
+}
+
+};
+};

+ 35 - 0
src/bin/dhcp6/simple_parser6.h

@@ -0,0 +1,35 @@
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifndef SIMPLE_PARSER6_H
+#define SIMPLE_PARSER6_H
+
+#include <cc/simple_parser.h>
+
+namespace isc {
+namespace dhcp {
+
+class SimpleParser6 : public isc::data::SimpleParser {
+public:
+
+    /// @brief Sets all defaults for DHCPv6 configuration
+    ///
+    /// This method sets global, option data and option definitions defaults.
+    ///
+    /// @param global scope to be filled in with defaults.
+    /// @return number of default values added
+    static size_t setAllDefaults(isc::data::ElementPtr global);
+
+    static const isc::data::SimpleDefaults OPTION6_DEF_DEFAULTS;
+    static const isc::data::SimpleDefaults OPTION6_DEFAULTS;
+    static const isc::data::SimpleDefaults GLOBAL6_DEFAULTS;
+    static const isc::data::ParamsList INHERIT_GLOBAL_TO_SUBNET6;
+};
+
+};
+};
+
+#endif

+ 1 - 0
src/bin/dhcp6/tests/Makefile.am

@@ -93,6 +93,7 @@ dhcp6_unittests_SOURCES += dhcp6_message_test.cc dhcp6_message_test.h
 dhcp6_unittests_SOURCES += kea_controller_unittest.cc
 dhcp6_unittests_SOURCES += dhcp6to4_ipc_unittest.cc
 dhcp6_unittests_SOURCES += classify_unittests.cc
+dhcp6_unittests_SOURCES += simple_parser6_unittest.cc
 
 nodist_dhcp6_unittests_SOURCES  = marker_file.h test_libraries.h
 

+ 87 - 0
src/bin/dhcp6/tests/simple_parser6_unittest.cc

@@ -0,0 +1,87 @@
+// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC")
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#include <config.h>
+#include <cc/data.h>
+#include <dhcp6/simple_parser6.h>
+#include <gtest/gtest.h>
+
+using namespace isc;
+using namespace isc::data;
+using namespace isc::dhcp;
+
+namespace {
+
+/// @brief DHCP Parser test fixture class
+class SimpleParser6Test : public ::testing::Test {
+public:
+    /// @brief Checks if specified map has an integer parameter with expected value
+    ///
+    /// @param map map to be checked
+    /// @param param_name name of the parameter to be checked
+    /// @param exp_value expected value of the parameter.
+    void checkIntegerValue(const ConstElementPtr& map, const std::string& param_name,
+                           int64_t exp_value) {
+
+        // First check if the passed element is a map.
+        ASSERT_EQ(Element::map, map->getType());
+
+        // Now try to get the element being checked
+        ConstElementPtr elem = map->get(param_name);
+        ASSERT_TRUE(elem);
+
+        // Now check if it's indeed integer
+        ASSERT_EQ(Element::integer, elem->getType());
+
+        // Finally, check if its value meets expectation.
+        EXPECT_EQ(exp_value, elem->intValue());
+    }
+};
+
+// This test checks if global defaults are properly set for DHCPv6.
+TEST_F(SimpleParser6Test, globalDefaults6) {
+
+    ElementPtr empty = Element::fromJSON("{ }");
+    size_t num = 0;
+
+    EXPECT_NO_THROW(num = SimpleParser6::setAllDefaults(empty));
+
+    // We expect at least 4 parameters to be inserted.
+    EXPECT_TRUE(num >= 4);
+
+    checkIntegerValue(empty, "valid-lifetime", 7200);
+    checkIntegerValue(empty, "preferred-lifetime", 3600);
+    checkIntegerValue(empty, "rebind-timer", 1800);
+    checkIntegerValue(empty, "renew-timer", 900);
+}
+
+// This test checks if the parameters can be inherited from the global
+// scope to the subnet scope.
+TEST_F(SimpleParser6Test, inheritGlobalToSubnet6) {
+    ElementPtr global = Element::fromJSON("{ \"renew-timer\": 1,"
+                                          "  \"rebind-timer\": 2,"
+                                          "  \"preferred-lifetime\": 3,"
+                                          "  \"valid-lifetime\": 4"
+                                          "}");
+    ElementPtr subnet = Element::fromJSON("{ \"renew-timer\": 100 }");
+
+    // we should inherit 3 parameters. Renew-timer should remain intact,
+    // as it was already defined in the subnet scope.
+    size_t num;
+    EXPECT_NO_THROW(num = SimpleParser::deriveParams(global, subnet,
+                                                     SimpleParser6::INHERIT_GLOBAL_TO_SUBNET6));
+    EXPECT_EQ(3, num);
+
+    // Check the values. 3 of them are interited, while the fourth one
+    // was already defined in the subnet, so should not be inherited.
+    checkIntegerValue(subnet, "renew-timer", 100);
+    checkIntegerValue(subnet, "rebind-timer", 2);
+    checkIntegerValue(subnet, "preferred-lifetime", 3);
+    checkIntegerValue(subnet, "valid-lifetime", 4);
+}
+
+};
+

+ 5 - 5
src/lib/dhcpsrv/parsers/dhcp_parsers.h

@@ -17,7 +17,7 @@
 #include <dhcpsrv/subnet.h>
 #include <dhcpsrv/cfg_option_def.h>
 #include <dhcpsrv/parsers/dhcp_config_parser.h>
-#include <dhcpsrv/parsers/simple_parser.h>
+#include <cc/simple_parser.h>
 #include <hooks/libinfo.h>
 #include <exceptions/exceptions.h>
 #include <util/optional_value.h>
@@ -536,7 +536,7 @@ private:
 /// an option the configuration will not be accepted. If parsing
 /// is successful then an instance of an option is created and
 /// added to the storage provided by the calling class.
-class OptionDataParser : public SimpleParser {
+class OptionDataParser : public isc::data::SimpleParser {
 public:
     /// @brief Constructor.
     ///
@@ -652,7 +652,7 @@ typedef OptionDataParser *OptionDataParserFactory(const std::string&,
 /// data for a particular subnet and creates a collection of options.
 /// If parsing is successful, all these options are added to the Subnet
 /// object.
-class OptionDataListParser : public SimpleParser {
+class OptionDataListParser : public isc::data::SimpleParser {
 public:
     /// @brief Constructor.
     ///
@@ -679,7 +679,7 @@ typedef std::pair<isc::dhcp::OptionDefinitionPtr, std::string> OptionDefinitionT
 /// @brief Parser for a single option definition.
 ///
 /// This parser creates an instance of a single option definition.
-class OptionDefParser : public SimpleParser {
+class OptionDefParser : public isc::data::SimpleParser {
 public:
     /// @brief Constructor.
     ///
@@ -706,7 +706,7 @@ private:
 /// option definitions and creates instances of these definitions.
 /// If the parsing is successful, the collection of created definitions
 /// is put into the provided storage.
-class OptionDefListParser : public SimpleParser {
+class OptionDefListParser : public isc::data::SimpleParser {
 public:
     /// @brief Constructor.
     ///

+ 1 - 1
src/lib/dhcpsrv/tests/Makefile.am

@@ -8,7 +8,7 @@ AM_CPPFLAGS += -DKEA_LFC_BUILD_DIR=\"$(abs_top_builddir)/src/bin/lfc\"
 AM_CPPFLAGS += -DLOGGING_SPEC_FILE=\"$(abs_top_srcdir)/src/lib/dhcpsrv/logging.spec\"
 AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
 
-AM_CXXFLAGS = $(KEA_CXXFLAGS)
+AM_CXXFLAGS = $(KEA_CXXFLAGS) -std=c++11
 
 if USE_STATIC_LINK
 AM_LDFLAGS = -static

+ 97 - 85
src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc

@@ -7,6 +7,7 @@
 #include <config.h>
 #include <cc/command_interpreter.h>
 #include <cc/data.h>
+#include <cc/simple_parser.h>
 #include <dhcp/option.h>
 #include <dhcp/option_custom.h>
 #include <dhcp/option_int.h>
@@ -16,7 +17,6 @@
 #include <dhcpsrv/subnet.h>
 #include <dhcpsrv/cfg_mac_source.h>
 #include <dhcpsrv/parsers/dhcp_parsers.h>
-#include <dhcpsrv/parsers/simple_parser.h>
 #include <dhcpsrv/tests/test_libraries.h>
 #include <dhcpsrv/testutils/config_result_check.h>
 #include <exceptions/exceptions.h>
@@ -412,6 +412,101 @@ public:
         return (parser);
     }
 
+    /// @brief DHCP-specific method that sets global, and option specific defaults
+    ///
+    /// This method sets the defaults in the global scope, in option definitions,
+    /// and in option data.
+    ///
+    /// @param global pointer to the Element tree that holds configuration
+    /// @param global_defaults array with global default values
+    /// @param option_defaults array with option-data default values
+    /// @param option_def_defaults array with default values for option definitions
+    /// @return number of default values inserted.
+    size_t setAllDefaults(isc::data::ElementPtr global,
+                          const SimpleDefaults& global_defaults,
+                          const SimpleDefaults& option_defaults,
+                          const SimpleDefaults& option_def_defaults) {
+        size_t cnt = 0;
+        // Set global defaults first.
+        /// @todo: Uncomment as part of the ticket 5019 work.
+        cnt = SimpleParser::setDefaults(global, global_defaults);
+
+        // Now set option defintion defaults for each specified option definition
+        ConstElementPtr option_defs = global->get("option-def");
+        if (option_defs) {
+            BOOST_FOREACH(ElementPtr single_def, option_defs->listValue()) {
+                cnt += SimpleParser::setDefaults(single_def, option_def_defaults);
+            }
+        }
+
+        ConstElementPtr options = global->get("option-data");
+        if (options) {
+            BOOST_FOREACH(ElementPtr single_option, options->listValue()) {
+                cnt += SimpleParser::setDefaults(single_option, option_defaults);
+            }
+        }
+
+        return (cnt);
+    }
+
+    /// @brief sets all default values for DHCPv4 and DHCPv6
+    ///
+    /// This function largely duplicates what SimpleParser4 and SimpleParser6 classes
+    /// provide. However, since there are tons of unit-tests in dhcpsrv that need
+    /// this functionality and there are good reasons to keep those classes in
+    /// src/bin/dhcp{4,6}, the most straightforward way is to simply copy the
+    /// minimum code here. Hence this method.
+    ///
+    /// @param config configuration structure to be filled with default values
+    /// @param v6 true = DHCPv6, false = DHCPv4
+    void setAllDefaults(ElementPtr config, bool v6) {
+        /// This table defines default values for option definitions in DHCPv6
+        const SimpleDefaults OPTION6_DEF_DEFAULTS = {
+            { "record-types", Element::string,  ""},
+            { "space",        Element::string,  "dhcp6"},
+            { "array",        Element::boolean, "false"},
+            { "encapsulate",  Element::string,  "" }
+        };
+
+        /// This table defines default values for option definitions in DHCPv4
+        const SimpleDefaults OPTION4_DEF_DEFAULTS = {
+            { "record-types", Element::string,  ""},
+            { "space",        Element::string,  "dhcp4"},
+            { "array",        Element::boolean, "false"},
+            { "encapsulate",  Element::string,  "" }
+        };
+
+        /// This table defines default values for options in DHCPv6
+        const SimpleDefaults OPTION6_DEFAULTS = {
+            { "space",        Element::string,  "dhcp6"},
+            { "csv-format",   Element::boolean, "true"},
+            { "encapsulate",  Element::string,  "" }
+        };
+
+        /// This table defines default values for options in DHCPv4
+        const SimpleDefaults OPTION4_DEFAULTS = {
+            { "space",        Element::string,  "dhcp4"},
+            { "csv-format",   Element::boolean, "true"},
+            { "encapsulate",  Element::string,  "" }
+        };
+
+        /// This table defines default values for both DHCPv4 and DHCPv6
+        const SimpleDefaults GLOBAL6_DEFAULTS = {
+            { "renew-timer",        Element::integer, "900" },
+            { "rebind-timer",       Element::integer, "1800" },
+            { "preferred-lifetime", Element::integer, "3600" },
+            { "valid-lifetime",     Element::integer, "7200" }
+        };
+
+        if (v6) {
+            setAllDefaults(config, GLOBAL6_DEFAULTS, OPTION6_DEFAULTS,
+                           OPTION6_DEF_DEFAULTS);
+        } else {
+            setAllDefaults(config, GLOBAL6_DEFAULTS, OPTION4_DEFAULTS,
+                           OPTION4_DEF_DEFAULTS);
+        }
+    }
+
     /// @brief Convenience method for parsing a configuration
     ///
     /// Given a configuration string, convert it into Elements
@@ -427,7 +522,7 @@ public:
         ElementPtr json = Element::fromJSON(config);
         EXPECT_TRUE(json);
         if (json) {
-            SimpleParser::setAllDefaults(json, v6);
+            setAllDefaults(json, v6);
 
             ConstElementPtr status = parseElementSet(json);
             ConstElementPtr comment = parseAnswer(rcode_, status);
@@ -487,28 +582,6 @@ public:
         CfgMgr::instance().setD2ClientConfig(tmp);
     }
 
-    /// @brief Checks if specified map has an integer parameter with expected value
-    ///
-    /// @param map map to be checked
-    /// @param param_name name of the parameter to be checked
-    /// @param exp_value expected value of the parameter.
-    void checkIntegerValue(const ConstElementPtr& map, const std::string& param_name,
-                           int64_t exp_value) {
-
-        // First check if the passed element is a map.
-        ASSERT_EQ(Element::map, map->getType());
-
-        // Now try to get the element being checked
-        ConstElementPtr elem = map->get(param_name);
-        ASSERT_TRUE(elem);
-
-        // Now check if it's indeed integer
-        ASSERT_EQ(Element::integer, elem->getType());
-
-        // Finally, check if its value meets expectation.
-        EXPECT_EQ(exp_value, elem->intValue());
-    }
-
     /// @brief Parsers used in the parsing of the configuration
     ///
     /// Allows the tests to interrogate the state of the parsers (if required).
@@ -2425,65 +2498,4 @@ TEST_F(ParseConfigTest, validRelayInfo6) {
 // (see CtrlDhcpv4SrvTest.commandSocketBasic in
 // src/bin/dhcp4/tests/ctrl_dhcp4_srv_unittest.cc).
 
-// This test checks if global defaults are properly set for DHCPv6.
-TEST_F(ParseConfigTest, globalDefaults6) {
-
-    ElementPtr empty = Element::fromJSON("{ }");
-    size_t num;
-
-    EXPECT_NO_THROW(num = SimpleParser::setGlobalDefaults(empty, true));
-
-    // We expect at least 4 parameters to be inserted.
-    EXPECT_TRUE(num >= 4);
-
-    checkIntegerValue(empty, "valid-lifetime", 7200);
-    checkIntegerValue(empty, "preferred-lifetime", 3600);
-    checkIntegerValue(empty, "rebind-timer", 1800);
-    checkIntegerValue(empty, "renew-timer", 900);
-}
-
-// This test checks if global defaults are properly set for DHCPv4.
-TEST_F(ParseConfigTest, DISABLED_globalDefaults4) {
-
-    ElementPtr empty = Element::fromJSON("{ }");
-    size_t num;
-
-    EXPECT_NO_THROW(num = SimpleParser::setGlobalDefaults(empty, false));
-
-    // We expect at least 3 parameters to be inserted.
-    EXPECT_TRUE(num >= 3);
-
-    checkIntegerValue(empty, "valid-lifetime", 7200);
-    checkIntegerValue(empty, "rebind-timer", 1800);
-    checkIntegerValue(empty, "renew-timer", 900);
-
-    // Make sure that preferred-lifetime is not set for v4 (it's v6 only
-    // parameter)
-    EXPECT_FALSE(empty->get("preferred-lifetime"));
-}
-
-// This test checks if the parameters can be inherited from the global
-// scope to the subnet scope.
-TEST_F(ParseConfigTest, inheritGlobalToSubnet) {
-    ElementPtr global = Element::fromJSON("{ \"renew-timer\": 1,"
-                                          "  \"rebind-timer\": 2,"
-                                          "  \"preferred-lifetime\": 3,"
-                                          "  \"valid-lifetime\": 4"
-                                          "}");
-    ElementPtr subnet = Element::fromJSON("{ \"renew-timer\": 100 }");
-
-    // we should inherit 3 parameters. Renew-timer should remain intact,
-    // as it was already defined in the subnet scope.
-    size_t num;
-    EXPECT_NO_THROW(num = SimpleParser::inheritGlobalToSubnet(global, subnet));
-    EXPECT_EQ(3, num);
-
-    // Check the values. 3 of them are interited, while the fourth one
-    // was already defined in the subnet, so should not be inherited.
-    checkIntegerValue(subnet, "renew-timer", 100);
-    checkIntegerValue(subnet, "rebind-timer", 2);
-    checkIntegerValue(subnet, "preferred-lifetime", 3);
-    checkIntegerValue(subnet, "valid-lifetime", 4);
-}
-
 };  // Anonymous namespace