diff options
Diffstat (limited to 'src/lib/dhcpsrv/tests/expiration_config_parser_unittest.cc')
-rw-r--r-- | src/lib/dhcpsrv/tests/expiration_config_parser_unittest.cc | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/src/lib/dhcpsrv/tests/expiration_config_parser_unittest.cc b/src/lib/dhcpsrv/tests/expiration_config_parser_unittest.cc new file mode 100644 index 0000000..fd76507 --- /dev/null +++ b/src/lib/dhcpsrv/tests/expiration_config_parser_unittest.cc @@ -0,0 +1,252 @@ +// Copyright (C) 2015,2017 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 <dhcpsrv/cfgmgr.h> +#include <dhcpsrv/cfg_expiration.h> +#include <dhcpsrv/parsers/expiration_config_parser.h> +#include <dhcpsrv/parsers/dhcp_parsers.h> +#include <gtest/gtest.h> +#include <sstream> +#include <stdint.h> +#include <string> + +using namespace isc::data; +using namespace isc::dhcp; + +namespace { + +/// @brief Test fixture class for @c ExpirationConfigParser. +class ExpirationConfigParserTest : public ::testing::Test { +protected: + + /// @brief Setup for each test. + /// + /// Clears the configuration in the @c CfgMgr. + virtual void SetUp(); + + /// @brief Cleans up after each test. + /// + /// Clears the configuration in the @c CfgMgr. + virtual void TearDown(); + + /// @brief Include a specified parameter in the configuration. + /// + /// If the specified parameter already exists, its value is replaced. + /// + /// @param param_name Parameter name. + /// @param value Parameter value. + void addParam(const std::string& param_name, const int64_t value); + + /// @brief Creates configuration and parses it with the parser under test. + /// + /// This method creates the JSON configuration form the parameters + /// specified using the @c ExpirationConfigParserTest::addParam method. + /// It then uses the parser to parse this configuration. Any exceptions + /// emitted by the parser are propagated to the caller (they aren't + /// caught by this method). + /// + /// @return Pointer to the parsed configuration. + CfgExpirationPtr renderConfig() const; + + /// @brief Tests that the out of range parameter value is not accepted. + /// + /// This test checks that the negative value and the value which is + /// greater than the maximum for the given parameter is not accepted. + /// + /// @param param Parameter name. + /// @param max_value Maximum value allowed for the parameter. + void testOutOfRange(const std::string& param, const uint64_t max_value); + +private: + + /// @brief Holds configuration parameters specified for a test. + std::map<std::string, int64_t> config_params_; + +}; + +void +ExpirationConfigParserTest::SetUp() { + CfgMgr::instance().clear(); +} + +void +ExpirationConfigParserTest::TearDown() { + CfgMgr::instance().clear(); +} + +void +ExpirationConfigParserTest::addParam(const std::string& param_name, + const int64_t value) { + config_params_[param_name] = value; +} + +CfgExpirationPtr +ExpirationConfigParserTest::renderConfig() const { + std::ostringstream s; + // Create JSON configuration from the parameters in the map. + s << "{"; + for (std::map<std::string, int64_t>::const_iterator param = + config_params_.begin(); param != config_params_.end(); + ++param) { + // Include comma sign if we're at the subsequent parameter. + if (std::distance(config_params_.begin(), param) > 0) { + s << ","; + } + s << "\"" << param->first << "\": " << param->second; + } + s << "}"; + + ElementPtr config_element = Element::fromJSON(s.str()); + + // Parse the configuration. This may emit exceptions. + ExpirationConfigParser parser; + parser.parse(config_element); + + // No exception so return configuration. + return (CfgMgr::instance().getStagingCfg()->getCfgExpiration()); +} + +void +ExpirationConfigParserTest::testOutOfRange(const std::string& param, + const uint64_t max_value) { + // Remove any existing parameters which would influence the + // behavior of the test. + config_params_.clear(); + + // Negative value is not allowed. + addParam(param, -3); + EXPECT_THROW(renderConfig(), DhcpConfigError) + << "test for negative value of '" << param << "' failed"; + + // Value greater than maximum is not allowed. + addParam(param, max_value + 1); + EXPECT_THROW(renderConfig(), DhcpConfigError) + << "test for out of range value of '" << param << "' failed"; + + // Value in range should be accepted. + addParam(param, max_value); + EXPECT_NO_THROW(renderConfig()) + << "test for in range value of '" << param << "' failed"; + + // Value of 0 should be accepted. + addParam(param, 0); + EXPECT_NO_THROW(renderConfig()) + << "test for zero value of '" << param << "' failed"; +} + + +// This test verifies that all parameters for the expiration may be configured. +TEST_F(ExpirationConfigParserTest, allParameters) { + // Create configuration which overrides default values of all parameters. + addParam("reclaim-timer-wait-time", 20); + addParam("flush-reclaimed-timer-wait-time", 35); + addParam("hold-reclaimed-time", 1800); + addParam("max-reclaim-leases", 50); + addParam("max-reclaim-time", 100); + addParam("unwarned-reclaim-cycles", 10); + + CfgExpirationPtr cfg; + ASSERT_NO_THROW(cfg = renderConfig()); + EXPECT_EQ(20, cfg->getReclaimTimerWaitTime()); + EXPECT_EQ(35, cfg->getFlushReclaimedTimerWaitTime()); + EXPECT_EQ(1800, cfg->getHoldReclaimedTime()); + EXPECT_EQ(50, cfg->getMaxReclaimLeases()); + EXPECT_EQ(100, cfg->getMaxReclaimTime()); + EXPECT_EQ(10, cfg->getUnwarnedReclaimCycles()); +} + +// This test verifies that default values are used if no parameter is +// specified. +TEST_F(ExpirationConfigParserTest, noParameters) { + CfgExpirationPtr cfg; + ASSERT_NO_THROW(cfg = renderConfig()); + EXPECT_EQ(CfgExpiration::DEFAULT_RECLAIM_TIMER_WAIT_TIME, + cfg->getReclaimTimerWaitTime()); + EXPECT_EQ(CfgExpiration::DEFAULT_FLUSH_RECLAIMED_TIMER_WAIT_TIME, + cfg->getFlushReclaimedTimerWaitTime()); + EXPECT_EQ(CfgExpiration::DEFAULT_HOLD_RECLAIMED_TIME, + cfg->getHoldReclaimedTime()); + EXPECT_EQ(CfgExpiration::DEFAULT_MAX_RECLAIM_LEASES, + cfg->getMaxReclaimLeases()); + EXPECT_EQ(CfgExpiration::DEFAULT_MAX_RECLAIM_TIME, + cfg->getMaxReclaimTime()); + EXPECT_EQ(CfgExpiration::DEFAULT_UNWARNED_RECLAIM_CYCLES, + cfg->getUnwarnedReclaimCycles()); +} + +// This test verifies that a subset of parameters may be specified and +// that default values are used for those that aren't specified. +TEST_F(ExpirationConfigParserTest, someParameters) { + addParam("reclaim-timer-wait-time", 15); + addParam("hold-reclaimed-time", 2000); + addParam("max-reclaim-time", 200); + + CfgExpirationPtr cfg; + ASSERT_NO_THROW(cfg = renderConfig()); + EXPECT_EQ(15, cfg->getReclaimTimerWaitTime()); + EXPECT_EQ(CfgExpiration::DEFAULT_FLUSH_RECLAIMED_TIMER_WAIT_TIME, + cfg->getFlushReclaimedTimerWaitTime()); + EXPECT_EQ(2000, cfg->getHoldReclaimedTime()); + EXPECT_EQ(CfgExpiration::DEFAULT_MAX_RECLAIM_LEASES, + cfg->getMaxReclaimLeases()); + EXPECT_EQ(200, cfg->getMaxReclaimTime()); + EXPECT_EQ(CfgExpiration::DEFAULT_UNWARNED_RECLAIM_CYCLES, + cfg->getUnwarnedReclaimCycles()); +} + +// This test verifies that another subset of parameters may be specified +// and that default values are used for those that aren't specified. +TEST_F(ExpirationConfigParserTest, otherParameters) { + addParam("flush-reclaimed-timer-wait-time", 50); + addParam("max-reclaim-leases", 60); + addParam("unwarned-reclaim-cycles", 20); + + CfgExpirationPtr cfg; + ASSERT_NO_THROW(cfg = renderConfig()); + + EXPECT_EQ(CfgExpiration::DEFAULT_RECLAIM_TIMER_WAIT_TIME, + cfg->getReclaimTimerWaitTime()); + EXPECT_EQ(50, cfg->getFlushReclaimedTimerWaitTime()); + EXPECT_EQ(CfgExpiration::DEFAULT_HOLD_RECLAIMED_TIME, + cfg->getHoldReclaimedTime()); + EXPECT_EQ(60, cfg->getMaxReclaimLeases()); + EXPECT_EQ(CfgExpiration::DEFAULT_MAX_RECLAIM_TIME, + cfg->getMaxReclaimTime()); + EXPECT_EQ(20, cfg->getUnwarnedReclaimCycles()); +} + +// This test verifies that negative parameter values are not allowed. +TEST_F(ExpirationConfigParserTest, outOfRangeValues) { + testOutOfRange("reclaim-timer-wait-time", + CfgExpiration::LIMIT_RECLAIM_TIMER_WAIT_TIME); + testOutOfRange("flush-reclaimed-timer-wait-time", + CfgExpiration::LIMIT_FLUSH_RECLAIMED_TIMER_WAIT_TIME); + testOutOfRange("hold-reclaimed-time", + CfgExpiration::LIMIT_HOLD_RECLAIMED_TIME); + testOutOfRange("max-reclaim-leases", + CfgExpiration::LIMIT_MAX_RECLAIM_LEASES); + testOutOfRange("max-reclaim-time", + CfgExpiration::LIMIT_MAX_RECLAIM_TIME); + testOutOfRange("unwarned-reclaim-cycles", + CfgExpiration::LIMIT_UNWARNED_RECLAIM_CYCLES); +} + +// This test verifies that it is not allowed to specify a value as +// a text. +TEST_F(ExpirationConfigParserTest, notNumberValue) { + // The value should not be in quotes. + std::string config = "{ \"reclaim-timer-wait-time\": \"10\" }"; + ElementPtr config_element = Element::fromJSON(config); + + // Parse the configuration. It should throw exception. + ExpirationConfigParser parser; + EXPECT_THROW(parser.parse(config_element), DhcpConfigError); +} + +} // end of anonymous namespace |