]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#893] added unittests
authorRazvan Becheriu <razvan@isc.org>
Fri, 10 Apr 2020 18:20:43 +0000 (21:20 +0300)
committerRazvan Becheriu <razvan@isc.org>
Tue, 14 Apr 2020 19:30:13 +0000 (22:30 +0300)
src/bin/dhcp4/dhcp4_parser.yy
src/bin/dhcp4/tests/config_parser_unittest.cc
src/bin/dhcp6/dhcp6_parser.yy
src/bin/dhcp6/tests/config_parser_unittest.cc
src/lib/dhcpsrv/parsers/multi_threading_config_parser.cc
src/lib/dhcpsrv/tests/Makefile.am
src/lib/dhcpsrv/tests/cfg_multi_threading_unittest.cc [new file with mode: 0644]
src/lib/dhcpsrv/tests/multi_threading_config_parser_unittest.cc [new file with mode: 0644]
src/lib/dhcpsrv/tests/srv_config_unittest.cc

index 8dc7d611c52b871b3ca52baa2f4a2ae62b722771..c4dec986356171ed3e885c1ad3a038ac82fdad5a 100644 (file)
@@ -1038,19 +1038,19 @@ flex_id: FLEX_ID {
 // --- multi-threading ------------------------------------------------
 
 dhcp_multi_threading: DHCP_MULTI_THREADING {
-    ElementPtr qc(new MapElement(ctx.loc2pos(@1)));
-    ctx.stack_.back()->set("multi-threading", qc);
-    ctx.stack_.push_back(qc);
+    ElementPtr mt(new MapElement(ctx.loc2pos(@1)));
+    ctx.stack_.back()->set("multi-threading", mt);
+    ctx.stack_.push_back(mt);
     ctx.enter(ctx.DHCP_MULTI_THREADING);
 } COLON LCURLY_BRACKET multi_threading_params RCURLY_BRACKET {
-    // The enable queue parameter is required.
+    // The enable parameter is required.
     ctx.require("enable-multi-threading", ctx.loc2pos(@4), ctx.loc2pos(@6));
     ctx.stack_.pop_back();
     ctx.leave();
 };
 
 multi_threading_params: multi_threading_param
-                      | multi_threading_param COMMA multi_threading_param
+                      | multi_threading_params COMMA multi_threading_param
                       ;
 
 multi_threading_param: enable_multi_threading
index a7d1bf8a13a37509dabc77fcfd3e5b0f6e45c839..e757409624cee64cd768d011bfa92a88337f2499 100644 (file)
@@ -7134,6 +7134,7 @@ TEST_F(Dhcp4ParserTest, storeExtendedInfoGlobal) {
     EXPECT_TRUE(subnet2->getStoreExtendedInfo());
 }
 
+<<<<<<< HEAD
 /// This test checks that the statistic-default-sample-count and age
 /// global parameters are committed to the stats manager as expected.
 TEST_F(Dhcp4ParserTest, statsDefaultLimits) {
@@ -7160,4 +7161,26 @@ TEST_F(Dhcp4ParserTest, statsDefaultLimits) {
               util::durationToText(stats_mgr.getMaxSampleAgeDefault(), 0));
 }
     
+// This test checks that adding multi threadding settings works.
+TEST_F(Dhcp4ParserTest, multiThreadingSettings) {
+    std::string config = "{ " + genIfaceConfig() + "," +
+        "\"subnet4\": [  ], "
+        "\"multi-threading\": { "
+        "    \"enable-multi-threading\": false,"
+        "    \"thread-pool-size\": 0,"
+        "    \"packet-queue-size\": 0 }"
+        "}";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP4(config));
+    extractConfig(config);
+
+    ConstElementPtr status;
+    ASSERT_NO_THROW(status = configureDhcp4Server(*srv_, json));
+    checkResult(status, 0);
+
+    ASSERT_TRUE(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading());
+    ASSERT_EQ(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading()->size(), 3);
 }
+
+}  // namespace
index cfee4f49c26850f1dcba0719c0f10133a7408974..90155775c0f1a1170f21d47b1da944adc35bf42c 100644 (file)
@@ -1049,19 +1049,19 @@ relay_supplied_options: RELAY_SUPPLIED_OPTIONS {
 // --- multi-threading ------------------------------------------------
 
 dhcp_multi_threading: DHCP_MULTI_THREADING {
-    ElementPtr qc(new MapElement(ctx.loc2pos(@1)));
-    ctx.stack_.back()->set("multi-threading", qc);
-    ctx.stack_.push_back(qc);
+    ElementPtr mt(new MapElement(ctx.loc2pos(@1)));
+    ctx.stack_.back()->set("multi-threading", mt);
+    ctx.stack_.push_back(mt);
     ctx.enter(ctx.DHCP_MULTI_THREADING);
 } COLON LCURLY_BRACKET multi_threading_params RCURLY_BRACKET {
-    // The enable queue parameter is required.
+    // The enable parameter is required.
     ctx.require("enable-multi-threading", ctx.loc2pos(@4), ctx.loc2pos(@6));
     ctx.stack_.pop_back();
     ctx.leave();
 };
 
 multi_threading_params: multi_threading_param
-                      | multi_threading_param COMMA multi_threading_param
+                      | multi_threading_params COMMA multi_threading_param
                       ;
 
 multi_threading_param: enable_multi_threading
index aa70d2d408c1cf827f51ed10f26765f3975a208e..b69b7e5f1f1579964b344fcbae6862e2cde332b8 100644 (file)
@@ -7701,6 +7701,7 @@ TEST_F(Dhcp6ParserTest, storeExtendedInfoNoGlobal) {
     EXPECT_TRUE(subnet->getStoreExtendedInfo());
 }
 
+<<<<<<< HEAD
 /// This test checks that the statistic-default-sample-count and age
 /// global parameters are committed to the stats manager as expected.
 TEST_F(Dhcp6ParserTest, statsDefaultLimits) {
@@ -7728,4 +7729,26 @@ TEST_F(Dhcp6ParserTest, statsDefaultLimits) {
               util::durationToText(stats_mgr.getMaxSampleAgeDefault(), 0));
 }
 
+// This test checks that adding multi threadding settings works.
+TEST_F(Dhcp6ParserTest, multiThreadingSettings) {
+    std::string config = "{ " + genIfaceConfig() + "," +
+        "\"subnet6\": [  ], "
+        "\"multi-threading\": { "
+        "    \"enable-multi-threading\": false,"
+        "    \"thread-pool-size\": 0,"
+        "    \"packet-queue-size\": 0 }"
+        "}";
+
+    ConstElementPtr json;
+    ASSERT_NO_THROW(json = parseDHCP6(config));
+    extractConfig(config);
+
+    ConstElementPtr status;
+    ASSERT_NO_THROW(status = configureDhcp6Server(srv_, json));
+    checkResult(status, 0);
+
+    ASSERT_TRUE(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading());
+    ASSERT_EQ(CfgMgr::instance().getStagingCfg()->getDHCPMultiThreading()->size(), 3);
 }
+
+}  // namespace
index 63df30c634f53f5cfc56fa7afccc0c43afe5466c..e50fe2fd4bd65d443427eb47b1bb55026a87d316 100644 (file)
@@ -22,6 +22,10 @@ MultiThreadingConfigParser::parse(const ConstElementPtr& value) {
         isc_throw(DhcpConfigError, "multi-threading is supposed to be a map");
     }
 
+    // enable-multi-threading is mandatory
+    getBoolean(value, "enable-multi-threading");
+
+    // thread-pool-size is not mandatory
     if (value->get("thread-pool-size")) {
         auto thread_pool_size = getInteger(value, "thread-pool-size");
         uint32_t max_size = std::numeric_limits<uint16_t>::max();
@@ -38,6 +42,7 @@ MultiThreadingConfigParser::parse(const ConstElementPtr& value) {
         }
     }
 
+    // packet-queue-size is not mandatory
     if (value->get("packet-queue-size")) {
         auto packet_queue_size = getInteger(value, "packet-queue-size");
         uint32_t max_size = std::numeric_limits<uint16_t>::max();
index d9cac94776fa096b9da89fee85c20e181f6ae346..74191ef0b7faa7ab1503a0713c6cc2085db5a55e 100644 (file)
@@ -71,6 +71,7 @@ libdhcpsrv_unittests_SOURCES += cfg_host_operations_unittest.cc
 libdhcpsrv_unittests_SOURCES += cfg_hosts_unittest.cc
 libdhcpsrv_unittests_SOURCES += cfg_iface_unittest.cc
 libdhcpsrv_unittests_SOURCES += cfg_mac_source_unittest.cc
+libdhcpsrv_unittests_SOURCES += cfg_multi_threading_unittest.cc
 libdhcpsrv_unittests_SOURCES += cfg_option_unittest.cc
 libdhcpsrv_unittests_SOURCES += cfg_option_def_unittest.cc
 libdhcpsrv_unittests_SOURCES += cfg_rsoo_unittest.cc
@@ -102,6 +103,7 @@ libdhcpsrv_unittests_SOURCES += lease_mgr_factory_unittest.cc
 libdhcpsrv_unittests_SOURCES += lease_mgr_unittest.cc
 libdhcpsrv_unittests_SOURCES += generic_lease_mgr_unittest.cc generic_lease_mgr_unittest.h
 libdhcpsrv_unittests_SOURCES += memfile_lease_mgr_unittest.cc
+libdhcpsrv_unittests_SOURCES += multi_threading_config_parser_unittest.cc
 libdhcpsrv_unittests_SOURCES += dhcp_parsers_unittest.cc
 libdhcpsrv_unittests_SOURCES += ncr_generator_unittest.cc
 if HAVE_MYSQL
diff --git a/src/lib/dhcpsrv/tests/cfg_multi_threading_unittest.cc b/src/lib/dhcpsrv/tests/cfg_multi_threading_unittest.cc
new file mode 100644 (file)
index 0000000..5654118
--- /dev/null
@@ -0,0 +1,65 @@
+// Copyright (C) 2020 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/cfg_multi_threading.h>
+#include <util/multi_threading_mgr.h>
+
+#include <gtest/gtest.h>
+
+using namespace isc::data;
+using namespace isc::dhcp;
+using namespace isc::util;
+
+namespace {
+
+/// @brief Test fixture class for @c MultiThreadingConfigParser
+class CfgMultiThreadingTest : public ::testing::Test {
+protected:
+
+    /// @brief Setup for each test.
+    ///
+    /// Clears the configuration in the @c MultiThreadingMgr.
+    virtual void SetUp();
+
+    /// @brief Cleans up after each test.
+    ///
+    /// Clears the configuration in the @c MultiThreadingMgr.
+    virtual void TearDown();
+};
+
+void
+CfgMultiThreadingTest::SetUp() {
+    MultiThreadingMgr::instance().apply(false, 0, 0);
+}
+
+void
+CfgMultiThreadingTest::TearDown() {
+    MultiThreadingMgr::instance().apply(false, 0 , 0);
+}
+
+// Verifies that applying multi threading setting works
+TEST_F(CfgMultiThreadingTest, apply) {
+    EXPECT_FALSE(MultiThreadingMgr::instance().getMode());
+    EXPECT_EQ(MultiThreadingMgr::instance().getThreadPoolSize(), 0);
+    EXPECT_EQ(MultiThreadingMgr::instance().getThreadQueueSize(), 0);
+    ElementPtr param = Element::createMap();
+    param->set("enable-multi-threading", Element::create(true));
+    param->set("thread-pool-size", Element::create(4));
+    param->set("packet-queue-size", Element::create(64));
+    CfgMultiThreading::apply(-1, param);
+    EXPECT_TRUE(MultiThreadingMgr::instance().getMode());
+    EXPECT_EQ(MultiThreadingMgr::instance().getThreadPoolSize(), 4);
+    EXPECT_EQ(MultiThreadingMgr::instance().getThreadQueueSize(), 64);
+    CfgMultiThreading::apply(8, param);
+    EXPECT_TRUE(MultiThreadingMgr::instance().getMode());
+    EXPECT_EQ(MultiThreadingMgr::instance().getThreadPoolSize(), 8);
+    EXPECT_EQ(MultiThreadingMgr::instance().getThreadQueueSize(), 0);
+}
+
+}  // namespace
diff --git a/src/lib/dhcpsrv/tests/multi_threading_config_parser_unittest.cc b/src/lib/dhcpsrv/tests/multi_threading_config_parser_unittest.cc
new file mode 100644 (file)
index 0000000..82d9b0a
--- /dev/null
@@ -0,0 +1,164 @@
+// Copyright (C) 2020 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/parsers/multi_threading_config_parser.h>
+#include <testutils/test_to_element.h>
+
+#include <gtest/gtest.h>
+
+using namespace isc::data;
+using namespace isc::dhcp;
+using namespace isc::test;
+
+namespace {
+
+/// @brief Test fixture class for @c MultiThreadingConfigParser
+class MultiThreadingConfigParserTest : public ::testing::Test {
+protected:
+
+    /// @brief Setup for each test.
+    virtual void SetUp();
+
+    /// @brief Cleans up after each test.
+    virtual void TearDown();
+};
+
+void
+MultiThreadingConfigParserTest::SetUp() {
+}
+
+void
+MultiThreadingConfigParserTest::TearDown() {
+}
+
+// Verifies that MultiThreadingConfigParser handles
+// expected valid content
+TEST_F(MultiThreadingConfigParserTest, validContent) {
+    struct Scenario {
+        std::string description_;
+        std::string json_;
+    };
+
+    std::vector<Scenario> scenarios = {
+        {
+        "enable-multi-threading disabled",
+        "{ \n"
+        "   \"enable-multi-threading\": false \n"
+        "} \n"
+        },
+        {
+        "enable-multi-threading, with thread-pool-size and packet-queue-size",
+        "{ \n"
+        "   \"enable-multi-threading\": true, \n"
+        "   \"thread-pool-size\": 4, \n"
+        "   \"packet-queue-size\": 64 \n"
+        "} \n"
+        }
+    };
+
+    // Iterate over the valid scenarios and verify they succeed.
+    ConstElementPtr config_elems;
+    ConstElementPtr multi_threading_config;
+    for (auto scenario : scenarios) {
+        SCOPED_TRACE(scenario.description_);
+        {
+            // Construct the config JSON
+            ASSERT_NO_THROW(config_elems = Element::fromJSON(scenario.json_))
+                            << "invalid JSON, test is broken";
+
+            // Parsing config should succeed.
+            MultiThreadingConfigParser parser;
+            try {
+                multi_threading_config = parser.parse(config_elems);
+            } catch (const std::exception& ex) {
+                ADD_FAILURE() << "parser threw an exception: " << ex.what();
+            }
+
+            // Verify the resultant configuration.
+            ASSERT_TRUE(multi_threading_config);
+
+            // The parser should have created a duplicate of the
+            // configuration elements.
+            ASSERT_TRUE(multi_threading_config.get() != config_elems.get());
+            EXPECT_TRUE(multi_threading_config->equals(*config_elems));
+        }
+    }
+}
+
+// Verifies that MultiThreadingConfigParser correctly catches
+// invalid content
+TEST_F(MultiThreadingConfigParserTest, invalidContent) {
+    struct Scenario {
+        std::string description_;
+        std::string json_;
+    };
+
+    std::vector<Scenario> scenarios = {
+        {
+        "enable-multi-threading not boolean",
+        "{ \n"
+        "   \"enable-multi-threading\": \"always\" \n"
+        "} \n"
+        },
+        {
+        "thread-pool-size not integer",
+        "{ \n"
+        "   \"thread-pool-size\": true \n"
+        "} \n"
+        },
+        {
+        "thread-pool-size negative",
+        "{ \n"
+        "   \"thread-pool-size\": -1 \n"
+        "} \n"
+        },
+        {
+        "thread-pool-size too large",
+        "{ \n"
+        "   \"thread-pool-size\": 200000 \n"
+        "} \n"
+        },
+        {
+        "packet-queue-size not integer",
+        "{ \n"
+        "   \"packet-queue-size\": true \n"
+        "} \n"
+        },
+        {
+        "packet-queue-size-size negative",
+        "{ \n"
+        "   \"packet-queue-size\": -1 \n"
+        "} \n"
+        },
+        {
+        "packet-queue-size too large",
+        "{ \n"
+        "   \"packet-queue-size\": 200000 \n"
+        "} \n"
+        }
+    };
+
+    // Iterate over the valid scenarios and verify they succeed.
+    ConstElementPtr config_elems;
+    ConstElementPtr queue_control;
+    for (auto scenario : scenarios) {
+        SCOPED_TRACE(scenario.description_);
+        {
+            // Construct the config JSON
+            ASSERT_NO_THROW(config_elems = Element::fromJSON(scenario.json_))
+                            << "invalid JSON, test is broken";
+
+            // Parsing config into a queue control should succeed.
+            MultiThreadingConfigParser parser;
+            EXPECT_THROW(parser.parse(config_elems), DhcpConfigError);
+        }
+    }
+}
+
+}  // namespace
index 6b4b5690f11bc8a0640f267649c73f810396fdc9..b2a5d7d9c84ac6260eb25c7ac1a5177db5923dfa 100644 (file)
@@ -12,6 +12,7 @@
 #include <dhcpsrv/subnet.h>
 #include <process/logging_info.h>
 #include <testutils/test_to_element.h>
+
 #include <gtest/gtest.h>
 
 using namespace isc::asiolink;
@@ -1561,4 +1562,13 @@ TEST_F(SrvConfigTest, getDdnsParamsNoSubnetTest6) {
     EXPECT_TRUE(params->getHostnameCharReplacement().empty());
 }
 
+// Verifies that adding multi threading settings works
+TEST_F(SrvConfigTest, multiThreadingSettings) {
+    SrvConfig conf(32);
+    ElementPtr param = Element::createMap();
+    param->set("enable-multi-threading", Element::create(true));
+    conf.setDHCPMultiThreading(param);
+    EXPECT_TRUE(isEquivalent(param, conf.getDHCPMultiThreading()));
+}
+
 } // end of anonymous namespace