From: Tomek Mrugalski Date: Thu, 22 Dec 2016 10:57:32 +0000 (+0100) Subject: [5039] Unit-tests for SimpleParser added. X-Git-Tag: trac5021_base~3^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d352a45e2ba969c1be20c37e95c640f081bf25a4;p=thirdparty%2Fkea.git [5039] Unit-tests for SimpleParser added. --- diff --git a/src/lib/cc/Makefile.am b/src/lib/cc/Makefile.am index 8a734761f8..1b057bd8a5 100644 --- a/src/lib/cc/Makefile.am +++ b/src/lib/cc/Makefile.am @@ -7,6 +7,7 @@ AM_CXXFLAGS = $(KEA_CXXFLAGS) lib_LTLIBRARIES = libkea-cc.la libkea_cc_la_SOURCES = data.cc data.h libkea_cc_la_SOURCES += command_interpreter.cc command_interpreter.h +libkea_cc_la_SOURCES += simple_parser.cc simple_parser.h libkea_cc_la_LIBADD = $(top_builddir)/src/lib/exceptions/libkea-exceptions.la libkea_cc_la_LIBADD += $(BOOST_LIBS) diff --git a/src/lib/cc/simple_parser.cc b/src/lib/cc/simple_parser.cc index e40ba28f45..aeaeb469bb 100644 --- a/src/lib/cc/simple_parser.cc +++ b/src/lib/cc/simple_parser.cc @@ -1,68 +1,19 @@ -#include +// 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 #include using namespace std; -using namespace isc::data; namespace isc { -namespace dhcp { - -/// 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 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 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 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 DHCPv4 -const SimpleDefaults GLOBAL4_DEFAULTS = { - { "renew-timer", Element::integer, "900" }, - { "rebind-timer", Element::integer, "1800" }, - { "valid-lifetime", Element::integer, "7200" } -}; - -/// 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" } -}; - -/// This list defines parameters that can be inherited from the global -/// scope to subnet scope. -const ParamsList INHERIT_GLOBAL_TO_SUBNET = { - "renew-timer", - "rebind-timer", - "preferred-lifetime", - "valid-lifetime" -}; +namespace data { std::string SimpleParser::getString(isc::data::ConstElementPtr scope, const std::string& name) { @@ -104,7 +55,7 @@ SimpleParser::getBoolean(isc::data::ConstElementPtr scope, const std::string& na } const data::Element::Position& -SimpleParser::getPosition(const std::string& name, const data::ConstElementPtr parent) const { +SimpleParser::getPosition(const std::string& name, const data::ConstElementPtr parent) { if (!parent) { return (data::Element::ZERO_POSITION()); } @@ -178,59 +129,13 @@ size_t SimpleParser::setDefaults(isc::data::ElementPtr scope, return (cnt); } -size_t SimpleParser::setGlobalDefaults(isc::data::ElementPtr global, bool v6) { - return (setDefaults(global, v6 ? GLOBAL6_DEFAULTS : GLOBAL4_DEFAULTS)); -} - -size_t SimpleParser::setOptionDefaults(isc::data::ElementPtr option, bool v6) { - return (setDefaults(option, v6?OPTION6_DEFAULTS : OPTION4_DEFAULTS)); -} - -size_t SimpleParser::setOptionListDefaults(isc::data::ElementPtr option_list, bool v6) { - size_t cnt = 0; - BOOST_FOREACH(ElementPtr single_option, option_list->listValue()) { - cnt += setOptionDefaults(single_option, v6); - } - return (cnt); -} - -size_t SimpleParser::setOptionDefDefaults(isc::data::ElementPtr option_def, bool v6) { - return (setDefaults(option_def, v6? OPTION6_DEF_DEFAULTS : OPTION4_DEF_DEFAULTS)); -} - -size_t SimpleParser::setOptionDefListDefaults(isc::data::ElementPtr option_def_list, - bool v6) { - size_t cnt = 0; - BOOST_FOREACH(ElementPtr single_def, option_def_list->listValue()) { - cnt += setOptionDefDefaults(single_def, v6); - } - return (cnt); -} - - -size_t SimpleParser::setAllDefaults(isc::data::ElementPtr global, bool v6) { +size_t +SimpleParser::setListDefaults(isc::data::ElementPtr list, + const SimpleDefaults& default_values) { size_t cnt = 0; - - // Set global defaults first. - /// @todo: Uncomment as part of the ticket 5019 work. - //cnt = setGlobalDefaults(global, v6); - - // 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 += setOptionDefDefaults(single_def, v6); - } - } - - ConstElementPtr options = global->get("option-data"); - if (options) { - BOOST_FOREACH(ElementPtr single_option, options->listValue()) { - cnt += setOptionDefaults(single_option, v6); - } - //setOptionListDefaults(options); + BOOST_FOREACH(ElementPtr entry, list->listValue()) { + cnt += setDefaults(entry, default_values); } - return (cnt); } @@ -266,11 +171,5 @@ SimpleParser::deriveParams(isc::data::ConstElementPtr parent, return (cnt); } -size_t -SimpleParser::inheritGlobalToSubnet(isc::data::ConstElementPtr global, - isc::data::ElementPtr subnet) { - return deriveParams(global, subnet, INHERIT_GLOBAL_TO_SUBNET); -} - }; // end of isc::dhcp namespace }; // end of isc namespace diff --git a/src/lib/cc/simple_parser.h b/src/lib/cc/simple_parser.h index 16fe5c6e3e..af4dd63aa9 100644 --- a/src/lib/cc/simple_parser.h +++ b/src/lib/cc/simple_parser.h @@ -1,3 +1,9 @@ +// 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_PARSER_H #define SIMPLE_PARSER_H @@ -6,7 +12,7 @@ #include namespace isc { -namespace dhcp { +namespace data { /// This array defines a single entry of default values struct SimpleDefault { @@ -62,17 +68,6 @@ class SimpleParser { static size_t deriveParams(isc::data::ConstElementPtr parent, isc::data::ElementPtr child, const ParamsList& params); - /// @brief Derives (inherits) parameters from global to subnet scope - /// - /// This method derives global parameters into subnet scope if they're - /// not defined there yet. - /// - /// @param global parameters will be inherited from here - /// @param subnet parameters will be inserted here - /// @return number of parameters copied - static size_t - inheritGlobalToSubnet(isc::data::ConstElementPtr global, - isc::data::ElementPtr subnet); /// @brief Sets the default values /// @@ -88,64 +83,8 @@ class SimpleParser { static size_t setDefaults(isc::data::ElementPtr scope, const SimpleDefaults& default_values); - /// @brief Sets global defaults - /// - /// This method sets global defaults. Note it does not set the - /// defaults for any scopes lower than global. See @ref setAllDefaults - /// for that. - /// - /// @param global scope to be filled in with defaults. - /// @param v6 is it v6 (true) or v4 (false) option? - /// @return number of default values added - static size_t setGlobalDefaults(isc::data::ElementPtr global, bool v6); - - /// @brief Sets option defaults for a single option - /// - /// This method sets default values for a single option. - /// - /// @param option an option data to be filled in with defaults. - /// @param v6 is it v6 (true) or v4 (false) option? - /// @return number of default values added - static size_t setOptionDefaults(isc::data::ElementPtr option, bool v6); - - /// @brief Sets option defaults for the whole options list - /// - /// This method sets default values for a list of options. - /// - /// @param option_list an option data to be filled in with defaults. - /// @param v6 is it v6 (true) or v4 (false) option? - /// @return number of default values added - static size_t setOptionListDefaults(isc::data::ElementPtr option_list, bool v6); - - /// @brief Sets option defaults for a single option definition - /// - /// This method sets default values for a single option definition. - /// - /// @param option_def an option defintion to be filled in with defaults. - /// @param v6 is it v6 (true) or v4 (false) option defintion? - /// @return number of default values added - static size_t setOptionDefDefaults(isc::data::ElementPtr option_def, bool v6); - - /// @brief Sets option defaults for the whole option definitions list - /// - /// This method sets default values for a list of option definitions. - /// - /// @param option_def_list a list of option defintions to be filled in with defaults. - /// @param v6 is it v6 (true) or v4 (false) option? - /// @return number of default values added - static size_t setOptionDefListDefaults(isc::data::ElementPtr option_def_list, - bool v6); - - /// @brief Sets defaults for the whole configuration - /// - /// This method sets global, options and option definition defaults. Note - /// it does set the defaults for scopes lower than global. If you want to - /// set the global defaults only, see @ref setGlobalDefaults for that. - /// - /// @param global scope to be filled in with defaults. - /// @param v6 true = v6, false = v4 - /// @return number of default values added - static size_t setAllDefaults(isc::data::ElementPtr global, bool v6); + static size_t setListDefaults(isc::data::ElementPtr list, + const SimpleDefaults& default_values); /// @brief Utility method that returns position of an element /// @@ -154,14 +93,9 @@ class SimpleParser { /// @param name position of that element will be returned /// @param parent parent element (optional) /// @return position of the element specified. - const data::Element::Position& + static const data::Element::Position& getPosition(const std::string& name, const data::ConstElementPtr parent = - data::ConstElementPtr()) const; - - /// Destructor - /// - /// It's really simple, isn't it? - virtual ~SimpleParser() {} + data::ConstElementPtr()); protected: @@ -173,7 +107,8 @@ class SimpleParser { /// @param scope specified parameter will be extracted from this scope /// @param name name of the parameter /// @return a string value of the parameter - static std::string getString(isc::data::ConstElementPtr scope, const std::string& name); + static std::string getString(isc::data::ConstElementPtr scope, + const std::string& name); /// @brief Returns an integer parameter from a scope /// @@ -183,7 +118,8 @@ class SimpleParser { /// @param scope specified parameter will be extracted from this scope /// @param name name of the parameter /// @return an integer value of the parameter - static int64_t getInteger(isc::data::ConstElementPtr scope, const std::string& name); + static int64_t getInteger(isc::data::ConstElementPtr scope, + const std::string& name); /// @brief Returns a boolean parameter from a scope /// @@ -193,7 +129,8 @@ class SimpleParser { /// @param scope specified parameter will be extracted from this scope /// @param name name of the parameter /// @return a boolean value of the parameter - static bool getBoolean(isc::data::ConstElementPtr scope, const std::string& name); + static bool getBoolean(isc::data::ConstElementPtr scope, + const std::string& name); }; }; diff --git a/src/lib/cc/tests/Makefile.am b/src/lib/cc/tests/Makefile.am index 67d85bab26..81358f6a92 100644 --- a/src/lib/cc/tests/Makefile.am +++ b/src/lib/cc/tests/Makefile.am @@ -1,6 +1,6 @@ AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib AM_CPPFLAGS += $(BOOST_INCLUDES) -AM_CXXFLAGS = $(KEA_CXXFLAGS) +AM_CXXFLAGS = $(KEA_CXXFLAGS) -std=c++11 if USE_STATIC_LINK AM_LDFLAGS = -static @@ -16,6 +16,7 @@ if HAVE_GTEST TESTS += run_unittests run_unittests_SOURCES = command_interpreter_unittests.cc data_unittests.cc run_unittests_SOURCES += data_file_unittests.cc run_unittests.cc +run_unittests_SOURCES += simple_parser_unittest.cc run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) run_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) diff --git a/src/lib/cc/tests/simple_parser_unittest.cc b/src/lib/cc/tests/simple_parser_unittest.cc new file mode 100644 index 0000000000..1726306321 --- /dev/null +++ b/src/lib/cc/tests/simple_parser_unittest.cc @@ -0,0 +1,132 @@ +// 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 + +using namespace isc::data; + +/// This table defines sample default values. Although these are DHCPv6 +/// specific, the mechanism is generic and can be used by any other component. +const SimpleDefaults SAMPLE_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 one scope +/// to another. Although these are DHCPv6 specific, the mechanism is generic and +/// can be used by any other component. +const ParamsList SAMPLE_INHERITS = { + "renew-timer", + "rebind-timer", + "preferred-lifetime", + "valid-lifetime" +}; + +/// @brief Simple Parser test fixture class +class SimpleParserTest : 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 the parameters can be inherited from the global +// scope to the subnet scope. +TEST_F(SimpleParserTest, deriveParams) { + 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, + SAMPLE_INHERITS)); + 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); +} + +// This test checks if global defaults are properly set for DHCPv6. +TEST_F(SimpleParserTest, setDefaults) { + + ElementPtr empty = Element::fromJSON("{ }"); + size_t num = 0; + + EXPECT_NO_THROW(num = SimpleParser::setDefaults(empty, SAMPLE_DEFAULTS)); + + // We expect at least 4 parameters to be inserted. + EXPECT_GE(num, 3); + + 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 DHCPv6. +TEST_F(SimpleParserTest, setListDefaults) { + + ElementPtr empty = Element::fromJSON("[{}, {}, {}]"); + size_t num; + + EXPECT_NO_THROW(num = SimpleParser::setListDefaults(empty, SAMPLE_DEFAULTS)); + + // We expect at least 12 parameters to be inserted (3 entries, with + // 4 parameters inserted in each) + EXPECT_EQ(12, num); + + ASSERT_EQ(Element::list, empty->getType()); + ASSERT_EQ(3, empty->size()); + + ConstElementPtr first = empty->get(0); + ConstElementPtr second = empty->get(1); + ConstElementPtr third = empty->get(2); + + checkIntegerValue(first, "valid-lifetime", 7200); + checkIntegerValue(first, "preferred-lifetime", 3600); + checkIntegerValue(first, "rebind-timer", 1800); + checkIntegerValue(first, "renew-timer", 900); + + checkIntegerValue(second, "valid-lifetime", 7200); + checkIntegerValue(second, "preferred-lifetime", 3600); + checkIntegerValue(second, "rebind-timer", 1800); + checkIntegerValue(second, "renew-timer", 900); + + checkIntegerValue(third, "valid-lifetime", 7200); + checkIntegerValue(third, "preferred-lifetime", 3600); + checkIntegerValue(third, "rebind-timer", 1800); + checkIntegerValue(third, "renew-timer", 900); +} diff --git a/src/lib/dhcpsrv/Makefile.am b/src/lib/dhcpsrv/Makefile.am index 289b9e5f71..fbd269bec6 100644 --- a/src/lib/dhcpsrv/Makefile.am +++ b/src/lib/dhcpsrv/Makefile.am @@ -33,8 +33,6 @@ EXTRA_DIST = EXTRA_DIST += parsers/client_class_def_parser.cc EXTRA_DIST += parsers/client_class_def_parser.h EXTRA_DIST += parsers/dhcp_config_parser.h -EXTRA_DIST += parsers/simple_parser.cc -EXTRA_DIST += parsers/simple_parser.h EXTRA_DIST += parsers/dbaccess_parser.cc EXTRA_DIST += parsers/dbaccess_parser.h EXTRA_DIST += parsers/dhcp_parsers.cc @@ -164,8 +162,6 @@ libkea_dhcpsrv_la_SOURCES += parsers/dbaccess_parser.cc libkea_dhcpsrv_la_SOURCES += parsers/dbaccess_parser.h libkea_dhcpsrv_la_SOURCES += parsers/dhcp_parsers.cc libkea_dhcpsrv_la_SOURCES += parsers/dhcp_parsers.h -libkea_dhcpsrv_la_SOURCES += parsers/simple_parser.cc -libkea_dhcpsrv_la_SOURCES += parsers/simple_parser.h libkea_dhcpsrv_la_SOURCES += parsers/duid_config_parser.cc libkea_dhcpsrv_la_SOURCES += parsers/duid_config_parser.h libkea_dhcpsrv_la_SOURCES += parsers/expiration_config_parser.cc