expiration_config_parser_unittest.cc 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. // Copyright (C) 2015,2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <config.h>
  7. #include <cc/data.h>
  8. #include <dhcpsrv/cfgmgr.h>
  9. #include <dhcpsrv/cfg_expiration.h>
  10. #include <dhcpsrv/parsers/expiration_config_parser.h>
  11. #include <dhcpsrv/parsers/dhcp_parsers.h>
  12. #include <gtest/gtest.h>
  13. #include <sstream>
  14. #include <stdint.h>
  15. #include <string>
  16. using namespace isc::data;
  17. using namespace isc::dhcp;
  18. namespace {
  19. /// @brief Test fixture class for @c ExpirationConfigParser.
  20. class ExpirationConfigParserTest : public ::testing::Test {
  21. protected:
  22. /// @brief Setup for each test.
  23. ///
  24. /// Clears the configuration in the @c CfgMgr.
  25. virtual void SetUp();
  26. /// @brief Cleans up after each test.
  27. ///
  28. /// Clears the configuration in the @c CfgMgr.
  29. virtual void TearDown();
  30. /// @brief Include a specified parameter in the configuration.
  31. ///
  32. /// If the specified parameter already exists, its value is replaced.
  33. ///
  34. /// @param param_name Parameter name.
  35. /// @param value Parameter value.
  36. void addParam(const std::string& param_name, const int64_t value);
  37. /// @brief Creates configuration and parses it with the parser under test.
  38. ///
  39. /// This method creates the JSON configuration form the parameters
  40. /// specified using the @c ExpirationConfigParserTest::addParam method.
  41. /// It then uses the parser to parse this configuration. Any exceptions
  42. /// emitted by the parser are propagated to the caller (they aren't
  43. /// caught by this method).
  44. ///
  45. /// @return Pointer to the parsed configuration.
  46. CfgExpirationPtr renderConfig() const;
  47. /// @brief Tests that the out of range parameter value is not accepted.
  48. ///
  49. /// This test checks that the negative value and the value which is
  50. /// greater than the maximum for the given parameter is not accepted.
  51. ///
  52. /// @param param Parameter name.
  53. /// @param max_value Maximum value allowed for the parameter.
  54. void testOutOfRange(const std::string& param, const uint64_t max_value);
  55. private:
  56. /// @brief Holds configuration parameters specified for a test.
  57. std::map<std::string, int64_t> config_params_;
  58. };
  59. void
  60. ExpirationConfigParserTest::SetUp() {
  61. CfgMgr::instance().clear();
  62. }
  63. void
  64. ExpirationConfigParserTest::TearDown() {
  65. CfgMgr::instance().clear();
  66. }
  67. void
  68. ExpirationConfigParserTest::addParam(const std::string& param_name,
  69. const int64_t value) {
  70. config_params_[param_name] = value;
  71. }
  72. CfgExpirationPtr
  73. ExpirationConfigParserTest::renderConfig() const {
  74. std::ostringstream s;
  75. // Create JSON configuration from the parameters in the map.
  76. s << "{";
  77. for (std::map<std::string, int64_t>::const_iterator param =
  78. config_params_.begin(); param != config_params_.end();
  79. ++param) {
  80. // Include comma sign if we're at the subsequent parameter.
  81. if (std::distance(config_params_.begin(), param) > 0) {
  82. s << ",";
  83. }
  84. s << "\"" << param->first << "\": " << param->second;
  85. }
  86. s << "}";
  87. ElementPtr config_element = Element::fromJSON(s.str());
  88. // Parse the configuration. This may emit exceptions.
  89. ExpirationConfigParser parser;
  90. parser.parse(config_element);
  91. // No exception so return configuration.
  92. return (CfgMgr::instance().getStagingCfg()->getCfgExpiration());
  93. }
  94. void
  95. ExpirationConfigParserTest::testOutOfRange(const std::string& param,
  96. const uint64_t max_value) {
  97. // Remove any existing parameters which would influence the
  98. // behavior of the test.
  99. config_params_.clear();
  100. // Negative value is not allowed.
  101. addParam(param, -3);
  102. EXPECT_THROW(renderConfig(), DhcpConfigError)
  103. << "test for negative value of '" << param << "' failed";
  104. // Value greater than maximum is not allowed.
  105. addParam(param, max_value + 1);
  106. EXPECT_THROW(renderConfig(), DhcpConfigError)
  107. << "test for out of range value of '" << param << "' failed";
  108. // Value in range should be accepted.
  109. addParam(param, max_value);
  110. EXPECT_NO_THROW(renderConfig())
  111. << "test for in range value of '" << param << "' failed";
  112. // Value of 0 should be accepted.
  113. addParam(param, 0);
  114. EXPECT_NO_THROW(renderConfig())
  115. << "test for zero value of '" << param << "' failed";
  116. }
  117. // This test verifies that all parameters for the expiration may be configured.
  118. TEST_F(ExpirationConfigParserTest, allParameters) {
  119. // Create configuration which overrides default values of all parameters.
  120. addParam("reclaim-timer-wait-time", 20);
  121. addParam("flush-reclaimed-timer-wait-time", 35);
  122. addParam("hold-reclaimed-time", 1800);
  123. addParam("max-reclaim-leases", 50);
  124. addParam("max-reclaim-time", 100);
  125. addParam("unwarned-reclaim-cycles", 10);
  126. CfgExpirationPtr cfg;
  127. ASSERT_NO_THROW(cfg = renderConfig());
  128. EXPECT_EQ(20, cfg->getReclaimTimerWaitTime());
  129. EXPECT_EQ(35, cfg->getFlushReclaimedTimerWaitTime());
  130. EXPECT_EQ(1800, cfg->getHoldReclaimedTime());
  131. EXPECT_EQ(50, cfg->getMaxReclaimLeases());
  132. EXPECT_EQ(100, cfg->getMaxReclaimTime());
  133. EXPECT_EQ(10, cfg->getUnwarnedReclaimCycles());
  134. }
  135. // This test verifies that default values are used if no parameter is
  136. // specified.
  137. TEST_F(ExpirationConfigParserTest, noParameters) {
  138. CfgExpirationPtr cfg;
  139. ASSERT_NO_THROW(cfg = renderConfig());
  140. EXPECT_EQ(CfgExpiration::DEFAULT_RECLAIM_TIMER_WAIT_TIME,
  141. cfg->getReclaimTimerWaitTime());
  142. EXPECT_EQ(CfgExpiration::DEFAULT_FLUSH_RECLAIMED_TIMER_WAIT_TIME,
  143. cfg->getFlushReclaimedTimerWaitTime());
  144. EXPECT_EQ(CfgExpiration::DEFAULT_HOLD_RECLAIMED_TIME,
  145. cfg->getHoldReclaimedTime());
  146. EXPECT_EQ(CfgExpiration::DEFAULT_MAX_RECLAIM_LEASES,
  147. cfg->getMaxReclaimLeases());
  148. EXPECT_EQ(CfgExpiration::DEFAULT_MAX_RECLAIM_TIME,
  149. cfg->getMaxReclaimTime());
  150. EXPECT_EQ(CfgExpiration::DEFAULT_UNWARNED_RECLAIM_CYCLES,
  151. cfg->getUnwarnedReclaimCycles());
  152. }
  153. // This test verifies that a subset of parameters may be specified and
  154. // that default values are used for those that aren't specified.
  155. TEST_F(ExpirationConfigParserTest, someParameters) {
  156. addParam("reclaim-timer-wait-time", 15);
  157. addParam("hold-reclaimed-time", 2000);
  158. addParam("max-reclaim-time", 200);
  159. CfgExpirationPtr cfg;
  160. ASSERT_NO_THROW(cfg = renderConfig());
  161. EXPECT_EQ(15, cfg->getReclaimTimerWaitTime());
  162. EXPECT_EQ(CfgExpiration::DEFAULT_FLUSH_RECLAIMED_TIMER_WAIT_TIME,
  163. cfg->getFlushReclaimedTimerWaitTime());
  164. EXPECT_EQ(2000, cfg->getHoldReclaimedTime());
  165. EXPECT_EQ(CfgExpiration::DEFAULT_MAX_RECLAIM_LEASES,
  166. cfg->getMaxReclaimLeases());
  167. EXPECT_EQ(200, cfg->getMaxReclaimTime());
  168. EXPECT_EQ(CfgExpiration::DEFAULT_UNWARNED_RECLAIM_CYCLES,
  169. cfg->getUnwarnedReclaimCycles());
  170. }
  171. // This test verifies that another subset of parameters may be specified
  172. // and that default values are used for those that aren't specified.
  173. TEST_F(ExpirationConfigParserTest, otherParameters) {
  174. addParam("flush-reclaimed-timer-wait-time", 50);
  175. addParam("max-reclaim-leases", 60);
  176. addParam("unwarned-reclaim-cycles", 20);
  177. CfgExpirationPtr cfg;
  178. ASSERT_NO_THROW(cfg = renderConfig());
  179. EXPECT_EQ(CfgExpiration::DEFAULT_RECLAIM_TIMER_WAIT_TIME,
  180. cfg->getReclaimTimerWaitTime());
  181. EXPECT_EQ(50, cfg->getFlushReclaimedTimerWaitTime());
  182. EXPECT_EQ(CfgExpiration::DEFAULT_HOLD_RECLAIMED_TIME,
  183. cfg->getHoldReclaimedTime());
  184. EXPECT_EQ(60, cfg->getMaxReclaimLeases());
  185. EXPECT_EQ(CfgExpiration::DEFAULT_MAX_RECLAIM_TIME,
  186. cfg->getMaxReclaimTime());
  187. EXPECT_EQ(20, cfg->getUnwarnedReclaimCycles());
  188. }
  189. // This test verifies that negative parameter values are not allowed.
  190. TEST_F(ExpirationConfigParserTest, outOfRangeValues) {
  191. testOutOfRange("reclaim-timer-wait-time",
  192. CfgExpiration::LIMIT_RECLAIM_TIMER_WAIT_TIME);
  193. testOutOfRange("flush-reclaimed-timer-wait-time",
  194. CfgExpiration::LIMIT_FLUSH_RECLAIMED_TIMER_WAIT_TIME);
  195. testOutOfRange("hold-reclaimed-time",
  196. CfgExpiration::LIMIT_HOLD_RECLAIMED_TIME);
  197. testOutOfRange("max-reclaim-leases",
  198. CfgExpiration::LIMIT_MAX_RECLAIM_LEASES);
  199. testOutOfRange("max-reclaim-time",
  200. CfgExpiration::LIMIT_MAX_RECLAIM_TIME);
  201. testOutOfRange("unwarned-reclaim-cycles",
  202. CfgExpiration::LIMIT_UNWARNED_RECLAIM_CYCLES);
  203. }
  204. // This test verifies that it is not allowed to specify a value as
  205. // a text.
  206. TEST_F(ExpirationConfigParserTest, notNumberValue) {
  207. // The value should not be in quotes.
  208. std::string config = "{ \"reclaim-timer-wait-time\": \"10\" }";
  209. ElementPtr config_element = Element::fromJSON(config);
  210. // Parse the configuration. It should throw exception.
  211. ExpirationConfigParser parser;
  212. EXPECT_THROW(parser.parse(config_element), DhcpConfigError);
  213. }
  214. } // end of anonymous namespace