From: Tomek Mrugalski Date: Thu, 22 Dec 2016 15:20:34 +0000 (+0100) Subject: [5039] SimpleParser is now split into cc/SimpleParser and SimpleParser{4,6} X-Git-Tag: trac5021_base~3^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=475b2531947004a6d96cb99125da2e48d96a2b5f;p=thirdparty%2Fkea.git [5039] SimpleParser is now split into cc/SimpleParser and SimpleParser{4,6} --- diff --git a/src/bin/dhcp4/Makefile.am b/src/bin/dhcp4/Makefile.am index 8360677861..d395f458a4 100644 --- a/src/bin/dhcp4/Makefile.am +++ b/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 diff --git a/src/bin/dhcp4/json_config_parser.cc b/src/bin/dhcp4/json_config_parser.cc index e4edf89027..6a4c352342 100644 --- a/src/bin/dhcp4/json_config_parser.cc +++ b/src/bin/dhcp4/json_config_parser.cc @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -20,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -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"); diff --git a/src/bin/dhcp4/simple_parser4.cc b/src/bin/dhcp4/simple_parser4.cc new file mode 100644 index 0000000000..f927429fdc --- /dev/null +++ b/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 +#include +#include + +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); +} + +}; +}; diff --git a/src/bin/dhcp4/simple_parser4.h b/src/bin/dhcp4/simple_parser4.h new file mode 100644 index 0000000000..5b2fc32743 --- /dev/null +++ b/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 + +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 diff --git a/src/bin/dhcp4/tests/Makefile.am b/src/bin/dhcp4/tests/Makefile.am index f0b5babb3d..cfe9c143d1 100644 --- a/src/bin/dhcp4/tests/Makefile.am +++ b/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 diff --git a/src/bin/dhcp4/tests/simple_parser4_unittest.cc b/src/bin/dhcp4/tests/simple_parser4_unittest.cc new file mode 100644 index 0000000000..9d02c049fd --- /dev/null +++ b/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 +#include +#include +#include + +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); +} + +}; +}; +}; diff --git a/src/bin/dhcp6/Makefile.am b/src/bin/dhcp6/Makefile.am index 47155aecf5..b1f6899e32 100644 --- a/src/bin/dhcp6/Makefile.am +++ b/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 diff --git a/src/bin/dhcp6/json_config_parser.cc b/src/bin/dhcp6/json_config_parser.cc index aaa0e2a03b..ee9ea6a98e 100644 --- a/src/bin/dhcp6/json_config_parser.cc +++ b/src/bin/dhcp6/json_config_parser.cc @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -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& values_map = diff --git a/src/bin/dhcp6/simple_parser6.cc b/src/bin/dhcp6/simple_parser6.cc new file mode 100644 index 0000000000..1190481439 --- /dev/null +++ b/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 +#include +#include + +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); +} + +}; +}; diff --git a/src/bin/dhcp6/simple_parser6.h b/src/bin/dhcp6/simple_parser6.h new file mode 100644 index 0000000000..28521180cc --- /dev/null +++ b/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 + +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 diff --git a/src/bin/dhcp6/tests/Makefile.am b/src/bin/dhcp6/tests/Makefile.am index 87c619761e..a2dd2358bb 100644 --- a/src/bin/dhcp6/tests/Makefile.am +++ b/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 diff --git a/src/bin/dhcp6/tests/simple_parser6_unittest.cc b/src/bin/dhcp6/tests/simple_parser6_unittest.cc new file mode 100644 index 0000000000..e5aca51151 --- /dev/null +++ b/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 +#include +#include +#include + +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); +} + +}; + diff --git a/src/lib/dhcpsrv/parsers/dhcp_parsers.h b/src/lib/dhcpsrv/parsers/dhcp_parsers.h index df829dc1db..365481b47e 100644 --- a/src/lib/dhcpsrv/parsers/dhcp_parsers.h +++ b/src/lib/dhcpsrv/parsers/dhcp_parsers.h @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -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 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. /// diff --git a/src/lib/dhcpsrv/tests/Makefile.am b/src/lib/dhcpsrv/tests/Makefile.am index 8729de987d..430049c7d4 100644 --- a/src/lib/dhcpsrv/tests/Makefile.am +++ b/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 diff --git a/src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc b/src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc index b9d5a76322..52e63bf782 100644 --- a/src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc +++ b/src/lib/dhcpsrv/tests/dhcp_parsers_unittest.cc @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -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