]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3536] moved lease and host backends
authorRazvan Becheriu <razvan@isc.org>
Wed, 11 Sep 2024 18:01:30 +0000 (21:01 +0300)
committerRazvan Becheriu <razvan@isc.org>
Mon, 16 Sep 2024 13:31:01 +0000 (13:31 +0000)
59 files changed:
src/bin/dhcp4/Makefile.am
src/bin/dhcp4/dhcp4_srv.cc
src/bin/dhcp4/json_config_parser.cc
src/bin/dhcp4/tests/Makefile.am
src/bin/dhcp4/tests/d2_unittest.cc
src/bin/dhcp4/tests/fqdn_unittest.cc
src/bin/dhcp6/Makefile.am
src/bin/dhcp6/dhcp6_srv.cc
src/bin/dhcp6/json_config_parser.cc
src/bin/dhcp6/tests/Makefile.am
src/bin/lfc/Makefile.am
src/hooks/dhcp/Makefile.am
src/lib/database/database_connection.h
src/lib/dhcpsrv/host_data_source_factory.cc
src/lib/dhcpsrv/lease_mgr_factory.cc
src/lib/dhcpsrv/tests/Makefile.am
src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc
src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc
src/lib/dhcpsrv/tests/alloc_engine_expiration_unittest.cc
src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc
src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc
src/lib/dhcpsrv/tests/flq_allocator_unittest.cc
src/lib/dhcpsrv/tests/iterative_allocator_unittest.cc
src/lib/dhcpsrv/tests/random_allocator_unittest.cc
src/lib/dhcpsrv/testutils/Makefile.am
src/lib/dhcpsrv/testutils/alloc_engine_utils.cc [moved from src/lib/dhcpsrv/tests/alloc_engine_utils.cc with 99% similarity]
src/lib/dhcpsrv/testutils/alloc_engine_utils.h [moved from src/lib/dhcpsrv/tests/alloc_engine_utils.h with 100% similarity]
src/lib/mysql_host_backend/Makefile.am
src/lib/mysql_host_backend/mysql_host_data_source.cc
src/lib/mysql_host_backend/mysql_host_data_source.h
src/lib/mysql_host_backend/tests/.gitignore [new file with mode: 0644]
src/lib/mysql_host_backend/tests/Makefile.am
src/lib/mysql_host_backend/tests/mysql_host_data_source_unittest.cc [moved from src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc with 95% similarity]
src/lib/mysql_host_backend/tests/run_unittests.cc [new file with mode: 0644]
src/lib/mysql_lease_backend/Makefile.am
src/lib/mysql_lease_backend/mysql_lease_mgr.cc
src/lib/mysql_lease_backend/mysql_lease_mgr.h
src/lib/mysql_lease_backend/tests/.gitignore [new file with mode: 0644]
src/lib/mysql_lease_backend/tests/Makefile.am
src/lib/mysql_lease_backend/tests/mysql_bootp_unittest.cc [new file with mode: 0644]
src/lib/mysql_lease_backend/tests/mysql_lease_extended_info_unittest.cc [moved from src/lib/dhcpsrv/tests/mysql_lease_extended_info_unittest.cc with 95% similarity]
src/lib/mysql_lease_backend/tests/mysql_lease_mgr_unittest.cc [moved from src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc with 97% similarity]
src/lib/mysql_lease_backend/tests/run_unittests.cc [new file with mode: 0644]
src/lib/pgsql_host_backend/Makefile.am
src/lib/pgsql_host_backend/pgsql_host_data_source.cc
src/lib/pgsql_host_backend/pgsql_host_data_source.h
src/lib/pgsql_host_backend/tests/.gitignore [new file with mode: 0644]
src/lib/pgsql_host_backend/tests/Makefile.am
src/lib/pgsql_host_backend/tests/pgsql_host_data_source_unittest.cc [moved from src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc with 94% similarity]
src/lib/pgsql_host_backend/tests/run_unittests.cc [new file with mode: 0644]
src/lib/pgsql_lease_backend/Makefile.am
src/lib/pgsql_lease_backend/pgsql_lease_mgr.cc
src/lib/pgsql_lease_backend/pgsql_lease_mgr.h
src/lib/pgsql_lease_backend/tests/.gitignore [new file with mode: 0644]
src/lib/pgsql_lease_backend/tests/Makefile.am
src/lib/pgsql_lease_backend/tests/pgsql_bootp_unittest.cc [new file with mode: 0644]
src/lib/pgsql_lease_backend/tests/pgsql_lease_extended_info_unittest.cc [moved from src/lib/dhcpsrv/tests/pgsql_lease_extended_info_unittest.cc with 95% similarity]
src/lib/pgsql_lease_backend/tests/pgsql_lease_mgr_unittest.cc [moved from src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc with 97% similarity]
src/lib/pgsql_lease_backend/tests/run_unittests.cc [new file with mode: 0644]

index f941d999023cbe61027d6a804ec249250abcfa8e..218ab5b5dd9d60f3235f41a12643145b6eb5a475 100644 (file)
@@ -54,12 +54,18 @@ kea_dhcp4_LDADD += $(top_builddir)/src/lib/http/libkea-http.la
 kea_dhcp4_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
 kea_dhcp4_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
 
+# to be removed
 if HAVE_PGSQL
 kea_dhcp4_LDADD += $(top_builddir)/src/lib/pgsql/libkea-pgsql.la
+kea_dhcp4_LDADD += $(top_builddir)/src/lib/pgsql_lease_backend/libkea-pgsql-lease-backend.la
+kea_dhcp4_LDADD += $(top_builddir)/src/lib/pgsql_host_backend/libkea-pgsql-host-backend.la
 endif
 
+# to be removed
 if HAVE_MYSQL
 kea_dhcp4_LDADD += $(top_builddir)/src/lib/mysql/libkea-mysql.la
+kea_dhcp4_LDADD += $(top_builddir)/src/lib/mysql_lease_backend/libkea-mysql-lease-backend.la
+kea_dhcp4_LDADD += $(top_builddir)/src/lib/mysql_host_backend/libkea-mysql-host-backend.la
 endif
 
 kea_dhcp4_LDADD += $(top_builddir)/src/lib/database/libkea-database.la
index f6e734fa3492d3860f64684b4e57593a6c0c5643..a4225b0c83badbf5e0e36627046e2ab15bf0b8b3 100644 (file)
 #include <log/logger.h>
 #include <cryptolink/cryptolink.h>
 #include <process/cfgrpt/config_report.h>
-
+#include <dhcpsrv/memfile_lease_mgr.h>
 
 #ifdef HAVE_MYSQL
-#include <dhcpsrv/mysql_lease_mgr.h>
+#include <mysql_lease_backend/mysql_lease_mgr.h>
 #endif
 #ifdef HAVE_PGSQL
-#include <dhcpsrv/pgsql_lease_mgr.h>
+#include <pgsql_lease_backend/pgsql_lease_mgr.h>
 #endif
-#include <dhcpsrv/memfile_lease_mgr.h>
 
 #include <boost/algorithm/string.hpp>
 #include <boost/foreach.hpp>
index d22f8028cfad6a45ac7a423c8a5fe0f6927069db..e2de46da743da5e7526ca38aa7c29a0d95f5f60a 100644 (file)
@@ -10,6 +10,7 @@
 #include <cc/command_interpreter.h>
 #include <config/command_mgr.h>
 #include <config/http_command_mgr.h>
+#include <database/database_connection.h>
 #include <database/dbaccess_parser.h>
 #include <database/backend_selector.h>
 #include <database/server_selector.h>
 #include <util/encode/encode.h>
 #include <util/multi_threading_mgr.h>
 
+#ifdef HAVE_MYSQL
+#include <mysql_lease_backend/mysql_lease_mgr.h>
+#include <mysql_host_backend/mysql_host_data_source.h>
+#endif
+
+#ifdef HAVE_PGSQL
+#include <pgsql_lease_backend/pgsql_lease_mgr.h>
+#include <pgsql_host_backend/pgsql_host_data_source.h>
+#endif
+
 #include <boost/algorithm/string.hpp>
 #include <boost/lexical_cast.hpp>
 
@@ -59,6 +70,7 @@
 using namespace isc::asiolink;
 using namespace isc::config;
 using namespace isc::data;
+using namespace isc::db;
 using namespace isc::dhcp;
 using namespace isc::hooks;
 using namespace isc::process;
@@ -66,8 +78,25 @@ using namespace isc::util;
 using namespace isc;
 using namespace std;
 
+//
+// Register database backends
+//
 namespace {
 
+// Code will be moved to appropriate hook library.
+#ifdef HAVE_MYSQL
+// Database backend will be registered at object initialization
+MySqlLeaseMgrInit mysql_init_lease;
+MySqlHostDataSourceInit mysql_init_host;
+#endif
+
+// Code will be moved to appropriate hook library.
+#ifdef HAVE_PGSQL
+// Database backend will be registered at object initialization
+PgSqlLeaseMgrInit pgsql_init_lease;
+PgSqlHostDataSourceInit pgsql_init_host;
+#endif
+
 /// @brief Parser that takes care of global DHCPv4 parameters and utility
 ///        functions that work on global level.
 ///
index bbd53d9ec944874831315d8cdb3611274055c993..69cb5a857ed1bc62bfb1514b6b0cf0a5a3095282 100644 (file)
@@ -16,8 +16,9 @@ DISTCLEANFILES += test_data_files_config.h
 DISTCLEANFILES += test_libraries.h
 
 AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib
-AM_CPPFLAGS += -I$(top_srcdir)/src -I$(top_builddir)/src
 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) $(CRYPTO_CFLAGS) $(CRYPTO_INCLUDES)
 AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/bin/dhcp4/tests\"
 AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\"
@@ -75,35 +76,38 @@ noinst_LTLIBRARIES = libco1.la libco2.la libco3.la libco4.la
 # C++ tests
 PROGRAM_TESTS = dhcp4_unittests
 
-dhcp4_unittests_SOURCES  = d2_unittest.h d2_unittest.cc
-dhcp4_unittests_SOURCES += dhcp4_unittests.cc
+# This list is ordered alphabetically. When adding new files, please maintain
+# this order.
+dhcp4_unittests_SOURCES  = classify_unittest.cc
+dhcp4_unittests_SOURCES += client_handler_unittest.cc
+dhcp4_unittests_SOURCES += config_parser_unittest.cc
+dhcp4_unittests_SOURCES += config_backend_unittest.cc
+dhcp4_unittests_SOURCES += ctrl_dhcp4_srv_unittest.cc
+dhcp4_unittests_SOURCES += http_control_socket_unittest.cc
+dhcp4_unittests_SOURCES += d2_unittest.h d2_unittest.cc
+dhcp4_unittests_SOURCES += decline_unittest.cc
+dhcp4_unittests_SOURCES += dhcp4_client.cc dhcp4_client.h
 dhcp4_unittests_SOURCES += dhcp4_srv_unittest.cc
 dhcp4_unittests_SOURCES += dhcp4_test_utils.cc dhcp4_test_utils.h
+dhcp4_unittests_SOURCES += dhcp4_unittests.cc
+dhcp4_unittests_SOURCES += dhcp4to6_ipc_unittest.cc
 dhcp4_unittests_SOURCES += direct_client_unittest.cc
-dhcp4_unittests_SOURCES += ctrl_dhcp4_srv_unittest.cc
-dhcp4_unittests_SOURCES += http_control_socket_unittest.cc
-dhcp4_unittests_SOURCES += classify_unittest.cc
-dhcp4_unittests_SOURCES += config_backend_unittest.cc
-dhcp4_unittests_SOURCES += config_parser_unittest.cc
+dhcp4_unittests_SOURCES += dora_unittest.cc
 dhcp4_unittests_SOURCES += fqdn_unittest.cc
-dhcp4_unittests_SOURCES += marker_file.cc
-dhcp4_unittests_SOURCES += dhcp4_client.cc dhcp4_client.h
+dhcp4_unittests_SOURCES += get_config_unittest.cc get_config_unittest.h
 dhcp4_unittests_SOURCES += hooks_unittest.cc
-dhcp4_unittests_SOURCES += inform_unittest.cc
-dhcp4_unittests_SOURCES += dora_unittest.cc
 dhcp4_unittests_SOURCES += host_options_unittest.cc
-dhcp4_unittests_SOURCES += release_unittest.cc
-dhcp4_unittests_SOURCES += parser_unittest.cc
-dhcp4_unittests_SOURCES += out_of_range_unittest.cc
-dhcp4_unittests_SOURCES += decline_unittest.cc
+dhcp4_unittests_SOURCES += host_unittest.cc
+dhcp4_unittests_SOURCES += inform_unittest.cc
 dhcp4_unittests_SOURCES += kea_controller_unittest.cc
-dhcp4_unittests_SOURCES += dhcp4to6_ipc_unittest.cc
+dhcp4_unittests_SOURCES += marker_file.cc
+dhcp4_unittests_SOURCES += out_of_range_unittest.cc
+dhcp4_unittests_SOURCES += parser_unittest.cc
+dhcp4_unittests_SOURCES += release_unittest.cc
+
 dhcp4_unittests_SOURCES += simple_parser4_unittest.cc
-dhcp4_unittests_SOURCES += get_config_unittest.cc get_config_unittest.h
 dhcp4_unittests_SOURCES += shared_network_unittest.cc
-dhcp4_unittests_SOURCES += host_unittest.cc
 dhcp4_unittests_SOURCES += vendor_opts_unittest.cc
-dhcp4_unittests_SOURCES += client_handler_unittest.cc
 
 nodist_dhcp4_unittests_SOURCES = marker_file.h test_libraries.h
 
@@ -133,11 +137,15 @@ dhcp4_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
 if HAVE_PGSQL
 dhcp4_unittests_LDADD += $(top_builddir)/src/lib/pgsql/testutils/libpgsqltest.la
 dhcp4_unittests_LDADD += $(top_builddir)/src/lib/pgsql/libkea-pgsql.la
+dhcp4_unittests_LDADD += $(top_builddir)/src/lib/pgsql_lease_backend/libkea-pgsql-lease-backend.la
+dhcp4_unittests_LDADD += $(top_builddir)/src/lib/pgsql_host_backend/libkea-pgsql-host-backend.la
 endif
 
 if HAVE_MYSQL
 dhcp4_unittests_LDADD += $(top_builddir)/src/lib/mysql/testutils/libmysqltest.la
 dhcp4_unittests_LDADD += $(top_builddir)/src/lib/mysql/libkea-mysql.la
+dhcp4_unittests_LDADD += $(top_builddir)/src/lib/mysql_lease_backend/libkea-mysql-lease-backend.la
+dhcp4_unittests_LDADD += $(top_builddir)/src/lib/mysql_host_backend/libkea-mysql-host-backend.la
 endif
 
 dhcp4_unittests_LDADD += $(top_builddir)/src/lib/database/testutils/libdatabasetest.la
index c45afa5f01de5f355496657c01c08748fbe1446f..0a352227f26bee7655c7931306fbcd20059400a6 100644 (file)
@@ -402,6 +402,7 @@ TEST_F(Dhcp4SrvD2Test, queueMaxError) {
     // Verify that updates are disabled and we are no longer sending.
     ASSERT_FALSE(mgr.ddnsEnabled());
     ASSERT_FALSE(mgr.amSending());
+    mgr.clearQueue();
 }
 
 // Tests invalid config with TCP protocol
index edc0b3c44553b1b8e99d93b116ee1900427447dc..7cd9333a4c590ced0b2009ebc2534c380867595f 100644 (file)
@@ -377,8 +377,7 @@ public:
     NameDhcpv4SrvTest()
         : Dhcpv4SrvTest(),
           d2_mgr_(CfgMgr::instance().getD2ClientMgr()),
-          iface_mgr_test_config_(true)
-    {
+          iface_mgr_test_config_(true) {
         srv_ = boost::make_shared<NakedDhcpv4Srv>(0);
         IfaceMgr::instance().openSockets4();
         // Config DDNS to be enabled, all controls off
@@ -853,7 +852,7 @@ public:
     /// @param client_flags Mask of client FQDN flags which are true
     /// @param response_flags Mask of expected FQDN flags in the response
     void flagVsConfigScenario(const uint8_t client_flags,
-                       const uint8_t response_flags) {
+                              const uint8_t response_flags) {
         // Create fake interfaces and open fake sockets.
         IfaceMgrTestConfig iface_config(true);
         IfaceMgr::instance().openSockets4();
@@ -891,7 +890,6 @@ public:
         }
     }
 
-
     /// @brief Checks the value of an integer statistic for a given subnet.
     ///
     /// @param subnet_id identifier of a subnet for which the statistic should be checked
@@ -1160,7 +1158,6 @@ TEST_F(NameDhcpv4SrvTest, noConflictResolution) {
                             lease->cltt_, 100, false, NO_CHECK_WITH_DHCID);
 }
 
-
 // Verifies that createNameChange request only generates requests
 // if the situation dictates that it should. It checks:
 //
@@ -1348,7 +1345,6 @@ TEST_F(NameDhcpv4SrvTest, processRequestEmptyDomainNameDisabled) {
     EXPECT_EQ(Option4ClientFqdn::FULL, fqdn->getDomainNameType());
 }
 
-
 // Test that server generates client's hostname from the IP address assigned
 // to it when Hostname option carries the top level domain-name.
 TEST_F(NameDhcpv4SrvTest, processRequestTopLevelHostname) {
@@ -2184,7 +2180,6 @@ TEST_F(NameDhcpv4SrvTest, sanitizeHostDefault) {
     }
 }
 
-
 // Verifies that setting hostname-char-set sanitizes Hostname option
 // values received from clients.
 TEST_F(NameDhcpv4SrvTest, sanitizeHost) {
index 0852a425fbbd85191d84d63ae0aabfe73e6bc02a..796f29e0807e7674f075cb2bade2e7c4031104b3 100644 (file)
@@ -17,19 +17,20 @@ if USE_STATIC_LINK
 AM_LDFLAGS = -static
 endif
 
+CLEANFILES  = *.gcno *.gcda
+
 EXTRA_DIST = dhcp6.dox dhcp6_hooks.dox dhcp4o6.dox
 EXTRA_DIST += dhcp6_parser.yy
 
-
 # convenience archive
 
 noinst_LTLIBRARIES = libdhcp6.la
 
 libdhcp6_la_SOURCES  =
-libdhcp6_la_SOURCES += dhcp6_log.cc dhcp6_log.h
-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 += dhcp6_log.cc dhcp6_log.h
+libdhcp6_la_SOURCES += dhcp6_srv.cc dhcp6_srv.h
 libdhcp6_la_SOURCES += dhcp6to4_ipc.cc dhcp6to4_ipc.h
 libdhcp6_la_SOURCES += client_handler.cc client_handler.h
 libdhcp6_la_SOURCES += dhcp6_lexer.ll location.hh
@@ -53,12 +54,18 @@ kea_dhcp6_LDADD += $(top_builddir)/src/lib/http/libkea-http.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
 
+# to be removed
 if HAVE_PGSQL
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/pgsql/libkea-pgsql.la
+kea_dhcp6_LDADD += $(top_builddir)/src/lib/pgsql_lease_backend/libkea-pgsql-lease-backend.la
+kea_dhcp6_LDADD += $(top_builddir)/src/lib/pgsql_host_backend/libkea-pgsql-host-backend.la
 endif
 
+# to be removed
 if HAVE_MYSQL
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/mysql/libkea-mysql.la
+kea_dhcp6_LDADD += $(top_builddir)/src/lib/mysql_lease_backend/libkea-mysql-lease-backend.la
+kea_dhcp6_LDADD += $(top_builddir)/src/lib/mysql_host_backend/libkea-mysql-host-backend.la
 endif
 
 kea_dhcp6_LDADD += $(top_builddir)/src/lib/database/libkea-database.la
index 750eac9d861d992596bbd0a44850d7cdf1fcfc24..137b9087499f1b100bdfc8da05b346ed95767da1 100644 (file)
 #include <log/logger.h>
 #include <cryptolink/cryptolink.h>
 #include <process/cfgrpt/config_report.h>
+#include <dhcpsrv/memfile_lease_mgr.h>
 
 #ifdef HAVE_MYSQL
-#include <dhcpsrv/mysql_lease_mgr.h>
+#include <mysql_lease_backend/mysql_lease_mgr.h>
 #endif
 #ifdef HAVE_PGSQL
-#include <dhcpsrv/pgsql_lease_mgr.h>
+#include <pgsql_lease_backend/pgsql_lease_mgr.h>
 #endif
-#include <dhcpsrv/memfile_lease_mgr.h>
 
 #include <boost/tokenizer.hpp>
 #include <boost/foreach.hpp>
index f5e283a42286f3266b1a1fee72e5a69cb4af5fe6..6590e8239e78fda457378a0b90639891aa08c64c 100644 (file)
@@ -12,6 +12,7 @@
 #include <cc/command_interpreter.h>
 #include <config/command_mgr.h>
 #include <config/http_command_mgr.h>
+#include <database/database_connection.h>
 #include <database/dbaccess_parser.h>
 #include <dhcp6/ctrl_dhcp6_srv.h>
 #include <dhcp6/dhcp6_log.h>
 #include <util/multi_threading_mgr.h>
 #include <util/triplet.h>
 
+#ifdef HAVE_MYSQL
+#include <mysql_lease_backend/mysql_lease_mgr.h>
+#include <mysql_host_backend/mysql_host_data_source.h>
+#endif
+
+#ifdef HAVE_PGSQL
+#include <pgsql_lease_backend/pgsql_lease_mgr.h>
+#include <pgsql_host_backend/pgsql_host_data_source.h>
+#endif
+
 #include <boost/algorithm/string.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/scoped_ptr.hpp>
@@ -66,6 +77,7 @@
 using namespace isc::asiolink;
 using namespace isc::config;
 using namespace isc::data;
+using namespace isc::db;
 using namespace isc::dhcp;
 using namespace isc::hooks;
 using namespace isc::process;
@@ -73,8 +85,25 @@ using namespace isc::util;
 using namespace isc;
 using namespace std;
 
+//
+// Register database backends
+//
 namespace {
 
+// Code will be moved to appropriate hook library.
+#ifdef HAVE_MYSQL
+// Database backend will be registered at object initialization
+MySqlLeaseMgrInit mysql_init_lease;
+MySqlHostDataSourceInit mysql_init_host;
+#endif
+
+// Code will be moved to appropriate hook library.
+#ifdef HAVE_PGSQL
+// Database backend will be registered at object initialization
+PgSqlLeaseMgrInit pgsql_init_lease;
+PgSqlHostDataSourceInit pgsql_init_host;
+#endif
+
 /// @brief Checks if specified directory exists.
 ///
 /// @param dir_path Path to a directory.
index 795445f50ead71e4e944cc088387d6aeded11ca4..7fd8de836cb09dc908765d113d2567008cbbf30f 100644 (file)
@@ -137,11 +137,15 @@ dhcp6_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
 if HAVE_PGSQL
 dhcp6_unittests_LDADD += $(top_builddir)/src/lib/pgsql/testutils/libpgsqltest.la
 dhcp6_unittests_LDADD += $(top_builddir)/src/lib/pgsql/libkea-pgsql.la
+dhcp6_unittests_LDADD += $(top_builddir)/src/lib/pgsql_lease_backend/libkea-pgsql-lease-backend.la
+dhcp6_unittests_LDADD += $(top_builddir)/src/lib/pgsql_host_backend/libkea-pgsql-host-backend.la
 endif
 
 if HAVE_MYSQL
 dhcp6_unittests_LDADD += $(top_builddir)/src/lib/mysql/testutils/libmysqltest.la
 dhcp6_unittests_LDADD += $(top_builddir)/src/lib/mysql/libkea-mysql.la
+dhcp6_unittests_LDADD += $(top_builddir)/src/lib/mysql_lease_backend/libkea-mysql-lease-backend.la
+dhcp6_unittests_LDADD += $(top_builddir)/src/lib/mysql_host_backend/libkea-mysql-host-backend.la
 endif
 
 dhcp6_unittests_LDADD += $(top_builddir)/src/lib/database/testutils/libdatabasetest.la
index 653838fbc6efe85ace36dfc9413cffaed630581a..7f3ae858bd6867c7dc05963df152cfb31c91673d 100644 (file)
@@ -36,15 +36,6 @@ kea_lfc_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
 kea_lfc_LDADD += $(top_builddir)/src/lib/http/libkea-http.la
 kea_lfc_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
 kea_lfc_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
-
-if HAVE_PGSQL
-kea_lfc_LDADD += $(top_builddir)/src/lib/pgsql/libkea-pgsql.la
-endif
-
-if HAVE_MYSQL
-kea_lfc_LDADD += $(top_builddir)/src/lib/mysql/libkea-mysql.la
-endif
-
 kea_lfc_LDADD += $(top_builddir)/src/lib/database/libkea-database.la
 kea_lfc_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
 kea_lfc_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
index 1b779764240b6e0aec6a92ef065801ffd31b2cfe..feb1f5cde23e38130b37b4c3e5bfa5865c673385 100644 (file)
@@ -1,10 +1,14 @@
 SUBDIRS = bootp flex_option high_availability lease_cmds perfmon
 
 if HAVE_MYSQL
+SUBDIRS += mysql_lb
+SUBDIRS += mysql_hb
 SUBDIRS += mysql_cb
 endif
 
 if HAVE_PGSQL
+SUBDIRS += pgsql_lb
+SUBDIRS += pgsql_hb
 SUBDIRS += pgsql_cb
 endif
 
index 00dbc0342410a43205d1d127d4bcb061a6a066c5..0ea887e1d22971bf5e4abbc9b24cd34148ac2f38 100644 (file)
@@ -351,6 +351,19 @@ public:
     }
 };
 
+template <typename T>
+struct Initializer {
+    /// @brief Constructor.
+    Initializer() : init_(new T()) {
+    }
+
+    /// @brief Destructo.
+    ~Initializer() = default;
+
+    /// @brief smart pointer to an instance of an initializer.
+    std::unique_ptr<T> init_;
+};
+
 }  // namespace db
 }  // namespace isc
 
index bb2e388bdd0ae047a60dec42fd413bc6de1627b3..c97406ed1fc69d80fce4e731f1aaa9caf34827c0 100644 (file)
 #include <dhcpsrv/hosts_log.h>
 #include <log/logger_support.h>
 
-#ifdef HAVE_MYSQL
-#include <dhcpsrv/mysql_host_data_source.h>
-#endif
-
-#ifdef HAVE_PGSQL
-#include <dhcpsrv/pgsql_host_data_source.h>
-#endif
-
 #include <boost/algorithm/string.hpp>
 
 #include <algorithm>
@@ -178,65 +170,3 @@ HostDataSourceFactory::logRegistered() {
 
 }  // namespace dhcp
 }  // namespace isc
-
-//
-// Register database backends
-//
-
-using namespace isc::dhcp;
-
-namespace {
-
-// Code will be moved to appropriate hook library.
-#ifdef HAVE_MYSQL
-struct MySqlHostDataSourceInit {
-    // Constructor registers
-    MySqlHostDataSourceInit() {
-        HostDataSourceFactory::registerFactory("mysql", factory, true);
-    }
-
-    // Destructor deregisters
-    ~MySqlHostDataSourceInit() {
-        HostDataSourceFactory::deregisterFactory("mysql", true);
-    }
-
-    // Factory class method
-    static HostDataSourcePtr
-    factory(const DatabaseConnection::ParameterMap& parameters) {
-        LOG_INFO(hosts_logger, DHCPSRV_MYSQL_HOST_DB)
-            .arg(DatabaseConnection::redactedAccessString(parameters));
-        return (HostDataSourcePtr(new MySqlHostDataSource(parameters)));
-    }
-};
-
-// Database backend will be registered at object initialization
-MySqlHostDataSourceInit mysql_init_;
-#endif
-
-// Code will be moved to appropriate hook library.
-#ifdef HAVE_PGSQL
-struct PgSqlHostDataSourceInit {
-    // Constructor registers
-    PgSqlHostDataSourceInit() {
-        HostDataSourceFactory::registerFactory("postgresql", factory, true);
-    }
-
-    // Destructor deregisters
-    ~PgSqlHostDataSourceInit() {
-        HostDataSourceFactory::deregisterFactory("postgresql", true);
-    }
-
-    // Factory class method
-    static HostDataSourcePtr
-    factory(const DatabaseConnection::ParameterMap& parameters) {
-        LOG_INFO(hosts_logger, DHCPSRV_PGSQL_HOST_DB)
-            .arg(DatabaseConnection::redactedAccessString(parameters));
-        return (HostDataSourcePtr(new PgSqlHostDataSource(parameters)));
-    }
-};
-
-// Database backend will be registered at object initialization
-PgSqlHostDataSourceInit pgsql_init_;
-#endif
-
-} // end of anonymous namespace
index 02050b2ad396acb8ea58352127e128ddc2619c42..22497f00761c20f350a2e1afaafcc77cf3faf253 100644 (file)
@@ -9,13 +9,6 @@
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/lease_mgr_factory.h>
 #include <dhcpsrv/memfile_lease_mgr.h>
-#ifdef HAVE_MYSQL
-#include <dhcpsrv/mysql_lease_mgr.h>
-#endif
-#ifdef HAVE_PGSQL
-#include <dhcpsrv/pgsql_lease_mgr.h>
-#endif
-
 #include <boost/algorithm/string.hpp>
 
 #include <algorithm>
@@ -55,28 +48,6 @@ LeaseMgrFactory::create(const std::string& dbaccess) {
                   "contain the 'type' keyword");
     }
 
-    // Code will be moved to appropriate hook library.
-#ifdef HAVE_MYSQL
-    // Factory method
-    auto mysql_factory = [](const DatabaseConnection::ParameterMap& parameters) -> TrackingLeaseMgrPtr {
-        LOG_INFO(dhcpsrv_logger, DHCPSRV_MYSQL_DB)
-            .arg(DatabaseConnection::redactedAccessString(parameters));
-        return (TrackingLeaseMgrPtr(new MySqlLeaseMgr(parameters)));
-    };
-    LeaseMgrFactory::registerFactory("mysql", mysql_factory, true);
-#endif
-
-    // Code will be moved to appropriate hook library.
-#ifdef HAVE_PGSQL
-    // Factory method
-    auto pgsql_factory = [](const DatabaseConnection::ParameterMap& parameters) -> TrackingLeaseMgrPtr {
-        LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_DB)
-            .arg(DatabaseConnection::redactedAccessString(parameters));
-        return (TrackingLeaseMgrPtr(new PgSqlLeaseMgr(parameters)));
-    };
-    LeaseMgrFactory::registerFactory("postgresql", pgsql_factory, true);
-#endif
-
     // Factory method
     auto memfile_factory = [](const DatabaseConnection::ParameterMap& parameters) -> TrackingLeaseMgrPtr {
         LOG_INFO(dhcpsrv_logger, DHCPSRV_MEMFILE_DB)
@@ -124,14 +95,6 @@ LeaseMgrFactory::destroy() {
     }
     getLeaseMgrPtr().reset();
     LeaseMgrFactory::deregisterFactory("memfile", true);
-    // Code will be moved to appropriate hook library.
-#ifdef HAVE_MYSQL
-    LeaseMgrFactory::deregisterFactory("mysql", true);
-#endif
-    // Code will be moved to appropriate hook library.
-#ifdef HAVE_PGSQL
-    LeaseMgrFactory::deregisterFactory("postgresql", true);
-#endif
 }
 
 void
index ac92958441d0a0c8df7520a51bb0a5b4e580b1bd..ca021a1105c7a8929ffc9e2976a06ad294f9cb8b 100644 (file)
@@ -59,7 +59,6 @@ libco3_la_LDFLAGS = -avoid-version -export-dynamic -module -rpath /nowhere
 TESTS += libdhcpsrv_unittests
 
 libdhcpsrv_unittests_SOURCES  = run_unittests.cc
-libdhcpsrv_unittests_SOURCES += alloc_engine_utils.cc alloc_engine_utils.h
 libdhcpsrv_unittests_SOURCES += alloc_engine_expiration_unittest.cc
 libdhcpsrv_unittests_SOURCES += alloc_engine_hooks_unittest.cc
 libdhcpsrv_unittests_SOURCES += alloc_engine4_unittest.cc
@@ -116,16 +115,6 @@ 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
-libdhcpsrv_unittests_SOURCES += mysql_lease_mgr_unittest.cc
-libdhcpsrv_unittests_SOURCES += mysql_lease_extended_info_unittest.cc
-libdhcpsrv_unittests_SOURCES += mysql_host_data_source_unittest.cc
-endif
-if HAVE_PGSQL
-libdhcpsrv_unittests_SOURCES += pgsql_lease_mgr_unittest.cc
-libdhcpsrv_unittests_SOURCES += pgsql_lease_extended_info_unittest.cc
-libdhcpsrv_unittests_SOURCES += pgsql_host_data_source_unittest.cc
-endif
 libdhcpsrv_unittests_SOURCES += pool_unittest.cc
 libdhcpsrv_unittests_SOURCES += random_allocation_state_unittest.cc
 libdhcpsrv_unittests_SOURCES += random_allocator_unittest.cc
index 906c3a9952b03e32ec7c1e49670201256760330b..a9ec22fb8b3ca4dab1ff61536b61c39c2d5894fc 100644 (file)
@@ -12,7 +12,7 @@
 #include <dhcpsrv/shared_network.h>
 #include <dhcpsrv/host_mgr.h>
 #include <dhcpsrv/parsers/client_class_def_parser.h>
-#include <dhcpsrv/tests/alloc_engine_utils.h>
+#include <dhcpsrv/testutils/alloc_engine_utils.h>
 #include <dhcpsrv/testutils/test_utils.h>
 #include <eval/eval_context.h>
 #include <hooks/hooks_manager.h>
@@ -5436,342 +5436,6 @@ TEST_F(AllocEngine4Test, excludeFirstLastReserver) {
     EXPECT_EQ("10.0.1.255", lease->addr_.toText());
 }
 
-#ifdef HAVE_MYSQL
-/// @brief Extension of the fixture class to use the MySQL backend.
-class MySqlAllocEngine4Test : public AllocEngine4Test {
-public:
-    /// @brief Constructor.
-    MySqlAllocEngine4Test() {
-        // Ensure we have the proper schema with no transient data.
-        db::test::createMySQLSchema();
-        factory_.create(db::test::validMySQLConnectionString());
-    }
-
-    /// @brief Destructor.
-    ~MySqlAllocEngine4Test() {
-        // If data wipe enabled, delete transient data otherwise destroy
-        // the schema.
-        db::test::destroyMySQLSchema();
-        LeaseMgrFactory::destroy();
-    }
-};
-
-// This test checks that simple allocation handles BOOTP queries.
-TEST_F(MySqlAllocEngine4Test, bootpAlloc4) {
-    boost::scoped_ptr<AllocEngine> engine;
-    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
-    ASSERT_TRUE(engine);
-
-    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
-                                    false, true, "somehost.example.com.", false);
-    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
-    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
-
-    // Make the query a BOOTP one.
-    ctx.query_->addClass("BOOTP");
-
-    Lease4Ptr lease = engine->allocateLease4(ctx);
-    // The new lease has been allocated, so the old lease should not exist.
-    ASSERT_FALSE(ctx.old_lease_);
-
-    // Check that we got a lease
-    ASSERT_TRUE(lease);
-
-    // Check that is belongs to the right subnet and client.
-    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
-    EXPECT_TRUE(subnet_->inRange(lease->addr_));
-    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
-    ASSERT_TRUE(lease->client_id_);
-    EXPECT_TRUE(*lease->client_id_ == *clientid_);
-    ASSERT_TRUE(lease->hwaddr_);
-    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
-
-    // Check the valid lifetime is infinite.
-    uint32_t infinity_lft = Lease::INFINITY_LFT;
-    EXPECT_EQ(infinity_lft, lease->valid_lft_);
-
-    // Check that the lease is indeed in LeaseMgr
-    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
-    ASSERT_TRUE(from_mgr);
-    // The MySQL database does not keep the hwtype for DHCPv4 leases.
-    from_mgr->hwaddr_->htype_ = HTYPE_FDDI;
-
-    // Now check that the lease in LeaseMgr has the same parameters
-    detailCompareLease(lease, from_mgr);
-}
-
-// This test checks simple renewal handles BOOTP queries.
-TEST_F(MySqlAllocEngine4Test, bootpRenew4) {
-    boost::scoped_ptr<AllocEngine> engine;
-    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
-    ASSERT_TRUE(engine);
-
-    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
-                                    false, true, "somehost.example.com.", false);
-    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
-    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
-
-    // Make the query a BOOTP one.
-    ctx.query_->addClass("BOOTP");
-
-    Lease4Ptr lease = engine->allocateLease4(ctx);
-
-    // Check that we got a lease.
-    ASSERT_TRUE(lease);
-
-    // Check that is belongs to the right subnet and client.
-    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
-    EXPECT_TRUE(subnet_->inRange(lease->addr_));
-    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
-    ASSERT_TRUE(lease->client_id_);
-    EXPECT_TRUE(*lease->client_id_ == *clientid_);
-    ASSERT_TRUE(lease->hwaddr_);
-    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
-
-    // Check the valid lifetime is infinite.
-    uint32_t infinity_lft = Lease::INFINITY_LFT;
-    EXPECT_EQ(infinity_lft, lease->valid_lft_);
-
-    // The new lease has been allocated, so the old lease should not exist.
-    ASSERT_FALSE(ctx.old_lease_);
-
-    // Do it again, this should amount to the renew of an existing lease
-    Lease4Ptr lease2 = engine->allocateLease4(ctx);
-
-    // Check that we got a lease.
-    ASSERT_TRUE(lease2);
-
-    // Check that is belongs to the right subnet and client.
-    EXPECT_EQ(lease2->subnet_id_, subnet_->getID());
-    EXPECT_TRUE(subnet_->inRange(lease2->addr_));
-    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease2->addr_));
-    ASSERT_TRUE(lease2->client_id_);
-    EXPECT_TRUE(*lease2->client_id_ == *clientid_);
-    ASSERT_TRUE(lease2->hwaddr_);
-    EXPECT_TRUE(*lease2->hwaddr_ == *hwaddr_);
-
-    // Lease already existed, so old_lease should be set.
-    EXPECT_TRUE(ctx.old_lease_);
-
-    // Check the renewed valid lifetime has the max value.
-    EXPECT_EQ(infinity_lft, lease2->valid_lft_);
-}
-
-// This test checks that deleteRelease handles BOOTP leases.
-TEST_F(MySqlAllocEngine4Test, bootpDelete) {
-    boost::scoped_ptr<AllocEngine> engine;
-    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
-    ASSERT_TRUE(engine);
-
-    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
-                                    false, true, "somehost.example.com.", false);
-    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
-    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
-
-    // Make the query a BOOTP one.
-    ctx.query_->addClass("BOOTP");
-
-    Lease4Ptr lease = engine->allocateLease4(ctx);
-    // The new lease has been allocated, so the old lease should not exist.
-    ASSERT_FALSE(ctx.old_lease_);
-
-    // Check that we got a lease
-    ASSERT_TRUE(lease);
-
-    // Check that is belongs to the right subnet and client.
-    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
-    EXPECT_TRUE(subnet_->inRange(lease->addr_));
-    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
-    ASSERT_TRUE(lease->client_id_);
-    EXPECT_TRUE(*lease->client_id_ == *clientid_);
-    ASSERT_TRUE(lease->hwaddr_);
-    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
-
-    // Check the valid lifetime is infinite.
-    uint32_t infinity_lft = Lease::INFINITY_LFT;
-    EXPECT_EQ(infinity_lft, lease->valid_lft_);
-
-    // Check that the lease is indeed in LeaseMgr
-    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
-    ASSERT_TRUE(from_mgr);
-
-    // Now delete it.
-    bool deleted = false;
-    ASSERT_NO_THROW(deleted = LeaseMgrFactory::instance().deleteLease(lease));
-    EXPECT_TRUE(deleted);
-    from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
-    EXPECT_FALSE(from_mgr);
-}
-#endif
-
-#ifdef HAVE_PGSQL
-/// @brief Extension of the fixture class to use the PostgreSql backend.
-class PgSqlAllocEngine4Test : public AllocEngine4Test {
-public:
-    /// @brief Constructor.
-    PgSqlAllocEngine4Test() {
-        // Ensure we have the proper schema with no transient data.
-        db::test::createPgSQLSchema();
-        factory_.create(db::test::validPgSQLConnectionString());
-    }
-
-    /// @brief Destructor.
-    ~PgSqlAllocEngine4Test() {
-        // If data wipe enabled, delete transient data otherwise destroy
-        // the schema.
-        db::test::destroyPgSQLSchema();
-        LeaseMgrFactory::destroy();
-    }
-};
-
-// This test checks that simple allocation handles BOOTP queries.
-TEST_F(PgSqlAllocEngine4Test, bootpAlloc4) {
-    boost::scoped_ptr<AllocEngine> engine;
-    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
-    ASSERT_TRUE(engine);
-
-    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
-                                    false, true, "somehost.example.com.", false);
-    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
-    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
-
-    // Make the query a BOOTP one.
-    ctx.query_->addClass("BOOTP");
-
-    Lease4Ptr lease = engine->allocateLease4(ctx);
-    // The new lease has been allocated, so the old lease should not exist.
-    ASSERT_FALSE(ctx.old_lease_);
-
-    // Check that we got a lease
-    ASSERT_TRUE(lease);
-
-    // Check that is belongs to the right subnet and client.
-    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
-    EXPECT_TRUE(subnet_->inRange(lease->addr_));
-    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
-    ASSERT_TRUE(lease->client_id_);
-    EXPECT_TRUE(*lease->client_id_ == *clientid_);
-    ASSERT_TRUE(lease->hwaddr_);
-    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
-
-    // Check the valid lifetime is infinite.
-    uint32_t infinity_lft = Lease::INFINITY_LFT;
-    EXPECT_EQ(infinity_lft, lease->valid_lft_);
-
-    // Check that the lease is indeed in LeaseMgr
-    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
-    ASSERT_TRUE(from_mgr);
-    // The PostgreSql database does not keep the hwtype for DHCPv4 leases.
-    from_mgr->hwaddr_->htype_ = HTYPE_FDDI;
-
-    // Now check that the lease in LeaseMgr has the same parameters
-    detailCompareLease(lease, from_mgr);
-}
-
-// This test checks simple renewal handles BOOTP queries.
-TEST_F(PgSqlAllocEngine4Test, bootpRenew4) {
-    boost::scoped_ptr<AllocEngine> engine;
-    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
-    ASSERT_TRUE(engine);
-
-    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
-                                    false, true, "somehost.example.com.", false);
-    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
-    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
-
-    // Make the query a BOOTP one.
-    ctx.query_->addClass("BOOTP");
-
-    Lease4Ptr lease = engine->allocateLease4(ctx);
-
-    // Check that we got a lease.
-    ASSERT_TRUE(lease);
-
-    // Check that is belongs to the right subnet and client.
-    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
-    EXPECT_TRUE(subnet_->inRange(lease->addr_));
-    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
-    ASSERT_TRUE(lease->client_id_);
-    EXPECT_TRUE(*lease->client_id_ == *clientid_);
-    ASSERT_TRUE(lease->hwaddr_);
-    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
-
-    // Check the valid lifetime is infinite.
-    uint32_t infinity_lft = Lease::INFINITY_LFT;
-    EXPECT_EQ(infinity_lft, lease->valid_lft_);
-
-    // The new lease has been allocated, so the old lease should not exist.
-    ASSERT_FALSE(ctx.old_lease_);
-
-    // Do it again, this should amount to the renew of an existing lease
-    Lease4Ptr lease2 = engine->allocateLease4(ctx);
-
-    // Check that we got a lease.
-    ASSERT_TRUE(lease2);
-
-    // Check that is belongs to the right subnet and client.
-    EXPECT_EQ(lease2->subnet_id_, subnet_->getID());
-    EXPECT_TRUE(subnet_->inRange(lease2->addr_));
-    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease2->addr_));
-    ASSERT_TRUE(lease2->client_id_);
-    EXPECT_TRUE(*lease2->client_id_ == *clientid_);
-    ASSERT_TRUE(lease2->hwaddr_);
-    EXPECT_TRUE(*lease2->hwaddr_ == *hwaddr_);
-
-    // Lease already existed, so old_lease should be set.
-    EXPECT_TRUE(ctx.old_lease_);
-
-    // Check the renewed valid lifetime has the max value.
-    EXPECT_EQ(infinity_lft, lease2->valid_lft_);
-}
-
-// This test checks that deleteRelease handles BOOTP leases.
-TEST_F(PgSqlAllocEngine4Test, bootpDelete) {
-    boost::scoped_ptr<AllocEngine> engine;
-    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
-    ASSERT_TRUE(engine);
-
-    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
-                                    false, true, "somehost.example.com.", false);
-    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
-    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
-
-    // Make the query a BOOTP one.
-    ctx.query_->addClass("BOOTP");
-
-    Lease4Ptr lease = engine->allocateLease4(ctx);
-    // The new lease has been allocated, so the old lease should not exist.
-    ASSERT_FALSE(ctx.old_lease_);
-
-    // Check that we got a lease
-    ASSERT_TRUE(lease);
-
-    // Check that is belongs to the right subnet and client.
-    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
-    EXPECT_TRUE(subnet_->inRange(lease->addr_));
-    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
-    ASSERT_TRUE(lease->client_id_);
-    EXPECT_TRUE(*lease->client_id_ == *clientid_);
-    ASSERT_TRUE(lease->hwaddr_);
-    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
-
-    // Check the valid lifetime is infinite.
-    uint32_t infinity_lft = Lease::INFINITY_LFT;
-    EXPECT_EQ(infinity_lft, lease->valid_lft_);
-
-    // Check that the lease is indeed in LeaseMgr
-    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
-    ASSERT_TRUE(from_mgr);
-
-    // Now delete it.
-    bool deleted = false;
-    ASSERT_NO_THROW(deleted = LeaseMgrFactory::instance().deleteLease(lease));
-    EXPECT_TRUE(deleted);
-    from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
-    EXPECT_FALSE(from_mgr);
-}
-#endif
-
 // Verifies that offer_lft is non-zero, that an offered lease is stored
 // in the lease database.
 TEST_F(AllocEngine4Test, discoverOfferLft) {
index 33c7a39aa90a94fa890ceafccfe05544749692b5..8a61dbba5876d4a0fa03bc9d8b93971c4e46dbc5 100644 (file)
@@ -7,10 +7,10 @@
 #include <config.h>
 #include <dhcp/pkt4.h>
 #include <dhcp/pkt6.h>
+#include <dhcpsrv/allocator.h>
 #include <dhcpsrv/host_mgr.h>
 #include <dhcpsrv/parsers/client_class_def_parser.h>
-#include <dhcpsrv/tests/alloc_engine_utils.h>
-#include <dhcpsrv/allocator.h>
+#include <dhcpsrv/testutils/alloc_engine_utils.h>
 #include <dhcpsrv/testutils/test_utils.h>
 #include <eval/eval_context.h>
 #include <stats/stats_mgr.h>
index 0b7fb1dbe6843059990db7642208585d8c34da3a..2477d5d54ce92058292ca66b9f8fdebe09a7926c 100644 (file)
@@ -8,7 +8,7 @@
 #include <dhcp/duid.h>
 #include <dhcp/option_data_types.h>
 #include <dhcp_ddns/ncr_msg.h>
-#include <dhcpsrv/tests/alloc_engine_utils.h>
+#include <dhcpsrv/testutils/alloc_engine_utils.h>
 #include <dhcpsrv/testutils/test_utils.h>
 #include <hooks/hooks_manager.h>
 #include <stats/stats_mgr.h>
index 99ea60503c1685703ce6af5852dd483ded0c0930..4bbb320a67cb6bd1c13c9e3339af390b5699e9f8 100644 (file)
@@ -5,7 +5,7 @@
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 #include <config.h>
-#include <dhcpsrv/tests/alloc_engine_utils.h>
+#include <dhcpsrv/testutils/alloc_engine_utils.h>
 #include <dhcpsrv/testutils/test_utils.h>
 
 #include <hooks/server_hooks.h>
index 738ddfc98cbaf50f31cca5d067f59541640f6a1a..c97be45d89fd7cd448f1cddabf1a83ff9ff892aa 100644 (file)
@@ -143,196 +143,4 @@ TEST(CfgDbAccessTest, createLeaseMgr) {
     });
 }
 
-// The following tests require MySQL enabled.
-#if defined HAVE_MYSQL
-
-/// @brief Test fixture class for testing @ref CfgDbAccessTest using MySQL
-/// backend.
-class CfgMySQLDbAccessTest : public ::testing::Test {
-public:
-
-    /// @brief Constructor.
-    CfgMySQLDbAccessTest() {
-        // Ensure we have the proper schema with no transient data.
-        db::test::createMySQLSchema();
-    }
-
-    /// @brief Destructor.
-    virtual ~CfgMySQLDbAccessTest() {
-        // If data wipe enabled, delete transient data otherwise destroy the schema
-        db::test::destroyMySQLSchema();
-        LeaseMgrFactory::destroy();
-    }
-};
-
-
-// Tests that MySQL lease manager and host data source can be created from a
-// specified configuration.
-TEST_F(CfgMySQLDbAccessTest, createManagers) {
-    CfgDbAccess cfg;
-    ASSERT_NO_THROW(cfg.setLeaseDbAccessString(db::test::validMySQLConnectionString()));
-    ASSERT_NO_THROW(cfg.setHostDbAccessString(db::test::validMySQLConnectionString()));
-    ASSERT_NO_THROW(cfg.createManagers());
-
-    ASSERT_NO_THROW({
-        LeaseMgr& lease_mgr = LeaseMgrFactory::instance();
-        EXPECT_EQ("mysql", lease_mgr.getType());
-    });
-
-    ASSERT_NO_THROW({
-        const HostDataSourcePtr& host_data_source =
-            HostMgr::instance().getHostDataSource();
-        ASSERT_TRUE(host_data_source);
-        EXPECT_EQ("mysql", host_data_source->getType());
-    });
-
-    // Because of the lazy initialization of the HostMgr instance, it is
-    // possible that the first call to the instance() function tosses
-    // existing connection to the database created by the call to
-    // createManagers(). Let's make sure that this doesn't happen.
-    ASSERT_NO_THROW(HostMgr::instance());
-
-    ASSERT_NO_THROW({
-        const HostDataSourcePtr& host_data_source =
-            HostMgr::instance().getHostDataSource();
-        ASSERT_TRUE(host_data_source);
-        EXPECT_EQ("mysql", host_data_source->getType());
-    });
-
-    EXPECT_TRUE(HostMgr::instance().getIPReservationsUnique());
-}
-
-// Tests that the createManagers function utilizes the setting in the
-// CfgDbAccess class which controls whether the IP reservations must
-// be unique or can be non-unique.
-TEST_F(CfgMySQLDbAccessTest, createManagersIPResrvUnique) {
-    CfgDbAccess cfg;
-
-    cfg.setIPReservationsUnique(false);
-
-    ASSERT_NO_THROW(cfg.setLeaseDbAccessString(db::test::validMySQLConnectionString()));
-    ASSERT_NO_THROW(cfg.setHostDbAccessString(db::test::validMySQLConnectionString()));
-    ASSERT_NO_THROW(cfg.createManagers());
-
-    ASSERT_NO_THROW({
-        const HostDataSourcePtr& host_data_source =
-            HostMgr::instance().getHostDataSource();
-        ASSERT_TRUE(host_data_source);
-        EXPECT_EQ("mysql", host_data_source->getType());
-    });
-
-    // Because of the lazy initialization of the HostMgr instance, it is
-    // possible that the first call to the instance() function tosses
-    // existing connection to the database created by the call to
-    // createManagers(). Let's make sure that this doesn't happen.
-    ASSERT_NO_THROW(HostMgr::instance());
-
-    ASSERT_NO_THROW({
-        const HostDataSourcePtr& host_data_source =
-            HostMgr::instance().getHostDataSource();
-        ASSERT_TRUE(host_data_source);
-        EXPECT_EQ("mysql", host_data_source->getType());
-    });
-
-    EXPECT_FALSE(HostMgr::instance().getIPReservationsUnique());
-}
-
-#endif
-
-// The following tests require PgSQL enabled.
-#if defined HAVE_PGSQL
-
-/// @brief Test fixture class for testing @ref CfgDbAccessTest using PgSQL
-/// backend.
-class CfgPgSQLDbAccessTest : public ::testing::Test {
-public:
-
-    /// @brief Constructor.
-    CfgPgSQLDbAccessTest() {
-        // Ensure we have the proper schema with no transient data.
-        db::test::createPgSQLSchema();
-    }
-
-    /// @brief Destructor.
-    virtual ~CfgPgSQLDbAccessTest() {
-        // If data wipe enabled, delete transient data otherwise destroy the schema
-        db::test::destroyPgSQLSchema();
-        LeaseMgrFactory::destroy();
-    }
-};
-
-
-// Tests that PgSQL lease manager and host data source can be created from a
-// specified configuration.
-TEST_F(CfgPgSQLDbAccessTest, createManagers) {
-    CfgDbAccess cfg;
-    ASSERT_NO_THROW(cfg.setLeaseDbAccessString(db::test::validPgSQLConnectionString()));
-    ASSERT_NO_THROW(cfg.setHostDbAccessString(db::test::validPgSQLConnectionString()));
-    ASSERT_NO_THROW(cfg.createManagers());
-
-    ASSERT_NO_THROW({
-        LeaseMgr& lease_mgr = LeaseMgrFactory::instance();
-        EXPECT_EQ("postgresql", lease_mgr.getType());
-    });
-
-    ASSERT_NO_THROW({
-        const HostDataSourcePtr& host_data_source =
-            HostMgr::instance().getHostDataSource();
-        ASSERT_TRUE(host_data_source);
-        EXPECT_EQ("postgresql", host_data_source->getType());
-    });
-
-    // Because of the lazy initialization of the HostMgr instance, it is
-    // possible that the first call to the instance() function tosses
-    // existing connection to the database created by the call to
-    // createManagers(). Let's make sure that this doesn't happen.
-    ASSERT_NO_THROW(HostMgr::instance());
-
-    ASSERT_NO_THROW({
-        const HostDataSourcePtr& host_data_source =
-            HostMgr::instance().getHostDataSource();
-        ASSERT_TRUE(host_data_source);
-        EXPECT_EQ("postgresql", host_data_source->getType());
-    });
-
-    EXPECT_TRUE(HostMgr::instance().getIPReservationsUnique());
-}
-
-// Tests that the createManagers function utilizes the setting in the
-// CfgDbAccess class which controls whether the IP reservations must
-// be unique or can be non-unique.
-TEST_F(CfgPgSQLDbAccessTest, createManagersIPResrvUnique) {
-    CfgDbAccess cfg;
-
-    cfg.setIPReservationsUnique(false);
-
-    ASSERT_NO_THROW(cfg.setLeaseDbAccessString(db::test::validPgSQLConnectionString()));
-    ASSERT_NO_THROW(cfg.setHostDbAccessString(db::test::validPgSQLConnectionString()));
-    ASSERT_NO_THROW(cfg.createManagers());
-
-    ASSERT_NO_THROW({
-        const HostDataSourcePtr& host_data_source =
-            HostMgr::instance().getHostDataSource();
-        ASSERT_TRUE(host_data_source);
-        EXPECT_EQ("postgresql", host_data_source->getType());
-    });
-
-    // Because of the lazy initialization of the HostMgr instance, it is
-    // possible that the first call to the instance() function tosses
-    // existing connection to the database created by the call to
-    // createManagers(). Let's make sure that this doesn't happen.
-    ASSERT_NO_THROW(HostMgr::instance());
-
-    ASSERT_NO_THROW({
-        const HostDataSourcePtr& host_data_source =
-            HostMgr::instance().getHostDataSource();
-        ASSERT_TRUE(host_data_source);
-        EXPECT_EQ("postgresql", host_data_source->getType());
-    });
-
-    EXPECT_FALSE(HostMgr::instance().getIPReservationsUnique());
-}
-
-#endif
-
 } // end of anonymous namespace
index eb9a368e8c4d2fde7d4d2c0ed4f4298b84ae81f8..10f5aff10ad55d27cd3ffa257dafd4d62216bb66 100644 (file)
@@ -8,7 +8,7 @@
 #include <asiolink/io_address.h>
 #include <dhcp/hwaddr.h>
 #include <dhcpsrv/flq_allocator.h>
-#include <dhcpsrv/tests/alloc_engine_utils.h>
+#include <dhcpsrv/testutils/alloc_engine_utils.h>
 #include <boost/make_shared.hpp>
 #include <gtest/gtest.h>
 
index 649a9994b4cfc95bcce45ca85caf3bb79864b176..85525a1fc1b0b5378bb19571e8546472631955eb 100644 (file)
@@ -7,7 +7,7 @@
 #include <config.h>
 #include <asiolink/io_address.h>
 #include <dhcpsrv/iterative_allocator.h>
-#include <dhcpsrv/tests/alloc_engine_utils.h>
+#include <dhcpsrv/testutils/alloc_engine_utils.h>
 #include <gtest/gtest.h>
 #include <sstream>
 
index caf27f4745634fa1a4f22d6a5690e419b89aadbc..283b8de878e1b0720ad0ee0ddec0a390255901e0 100644 (file)
@@ -7,7 +7,7 @@
 #include <config.h>
 #include <asiolink/io_address.h>
 #include <dhcpsrv/random_allocator.h>
-#include <dhcpsrv/tests/alloc_engine_utils.h>
+#include <dhcpsrv/testutils/alloc_engine_utils.h>
 #include <boost/make_shared.hpp>
 #include <gtest/gtest.h>
 #include <set>
index 471d61deeb69ea4a7a99035ecff58a614a725628..81d350175f8b1555ba24bd417de0328a23ad1337 100644 (file)
@@ -12,7 +12,8 @@ if HAVE_GTEST
 
 noinst_LTLIBRARIES = libdhcpsrvtest.la
 
-libdhcpsrvtest_la_SOURCES  = concrete_lease_mgr.cc concrete_lease_mgr.h
+libdhcpsrvtest_la_SOURCES  = alloc_engine_utils.cc alloc_engine_utils.h
+libdhcpsrvtest_la_SOURCES += concrete_lease_mgr.cc concrete_lease_mgr.h
 libdhcpsrvtest_la_SOURCES += config_result_check.cc config_result_check.h
 libdhcpsrvtest_la_SOURCES += dhcp4o6_test_ipc.cc dhcp4o6_test_ipc.h
 libdhcpsrvtest_la_SOURCES += host_data_source_utils.cc host_data_source_utils.h
similarity index 99%
rename from src/lib/dhcpsrv/tests/alloc_engine_utils.cc
rename to src/lib/dhcpsrv/testutils/alloc_engine_utils.cc
index cab3c9386ceb8a30a84c29672d48e0e7cf43981a..21ef2ba6b77e7f21a16dde0691bcf1cf81f3a97e 100644 (file)
@@ -19,7 +19,7 @@
 #include <stats/stats_mgr.h>
 
 #include <dhcpsrv/testutils/test_utils.h>
-#include <dhcpsrv/tests/alloc_engine_utils.h>
+#include <dhcpsrv/testutils/alloc_engine_utils.h>
 
 #include <boost/shared_ptr.hpp>
 #include <boost/scoped_ptr.hpp>
index 2469a386b3ba0b56fa2516686d2b8f3845a11969..18eecd2e63a0f50277067e17cd8a22953f281e5e 100644 (file)
@@ -1,5 +1,9 @@
 SUBDIRS = . tests
 
+AM_CPPFLAGS  = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(MYSQL_CPPFLAGS)
+
 AM_CXXFLAGS = $(KEA_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda
@@ -9,6 +13,15 @@ lib_LTLIBRARIES = libkea-mysql-host-backend.la
 libkea_mysql_host_backend_la_SOURCES = mysql_host_data_source.cc mysql_host_data_source.h
 
 libkea_mysql_host_backend_la_LIBADD = $(top_builddir)/src/lib/mysql/libkea-mysql.la
+libkea_mysql_host_backend_la_LIBADD += $(top_builddir)/src/lib/database/libkea-database.la
+libkea_mysql_host_backend_la_LIBADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+libkea_mysql_host_backend_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+libkea_mysql_host_backend_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
+libkea_mysql_host_backend_la_LIBADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
+libkea_mysql_host_backend_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la
+libkea_mysql_host_backend_la_LIBADD += $(top_builddir)/src/lib/util/libkea-util.la
+libkea_mysql_host_backend_la_LIBADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+libkea_mysql_host_backend_la_LIBADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS)
 
 libkea_mysql_host_backend_la_LDFLAGS = $(MYSQL_LIBS)
 
index 87559d0a5c0384037a5d4cc65de54d18f5d241f5..b9cd69d41de83c31878816e641d5de2c7af360e4 100644 (file)
@@ -17,7 +17,7 @@
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/host_mgr.h>
-#include <dhcpsrv/mysql_host_data_source.h>
+#include <mysql_host_data_source.h>
 #include <dhcpsrv/timer_mgr.h>
 #include <util/buffer.h>
 #include <util/multi_threading_mgr.h>
index 10643d1183f8e3354e8a562a5106c9b5101c028c..390eb9cb18c13aaeceb896c10f118d5682e7cb37 100644 (file)
@@ -10,6 +10,7 @@
 #include <database/database_connection.h>
 #include <database/db_exceptions.h>
 #include <dhcpsrv/base_host_data_source.h>
+#include <dhcpsrv/host_data_source_factory.h>
 #include <mysql/mysql_connection.h>
 
 #include <stdint.h>
@@ -531,6 +532,27 @@ private:
     MySqlHostDataSourceImplPtr impl_;
 };
 
+struct MySqlHostDataSourceInit {
+    // Constructor registers
+    MySqlHostDataSourceInit() {
+        isc::dhcp::HostDataSourceFactory::registerFactory("mysql", factory, true);
+    }
+
+    // Destructor deregisters
+    ~MySqlHostDataSourceInit() {
+        isc::dhcp::HostDataSourceFactory::deregisterFactory("mysql", true);
+    }
+
+    // Factory class method
+    static HostDataSourcePtr
+    factory(const isc::db::DatabaseConnection::ParameterMap& parameters) {
+        // TODO - fix messages
+        //LOG_INFO(hosts_logger, DHCPSRV_MYSQL_HOST_DB)
+        //    .arg(DatabaseConnection::redactedAccessString(parameters));
+        return (HostDataSourcePtr(new MySqlHostDataSource(parameters)));
+    }
+};
+
 }
 }
 
diff --git a/src/lib/mysql_host_backend/tests/.gitignore b/src/lib/mysql_host_backend/tests/.gitignore
new file mode 100644 (file)
index 0000000..8b96f60
--- /dev/null
@@ -0,0 +1 @@
+libmysql_host_backend_unittests
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..83f5dd87d8e4047eeee801daaad98c5f6d82f639 100644 (file)
@@ -0,0 +1,56 @@
+SUBDIRS = .
+
+AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CXXFLAGS = $(KEA_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
+
+TESTS =
+if HAVE_GTEST
+TESTS += libmysql_host_backend_unittests
+
+libmysql_host_backend_unittests_SOURCES  = run_unittests.cc
+libmysql_host_backend_unittests_SOURCES += mysql_host_data_source_unittest.cc
+
+libmysql_host_backend_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+libmysql_host_backend_unittests_CPPFLAGS += $(MYSQL_CPPFLAGS)
+
+libmysql_host_backend_unittests_CXXFLAGS = $(AM_CXXFLAGS)
+
+libmysql_host_backend_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
+libmysql_host_backend_unittests_LDFLAGS += $(MYSQL_LIBS)
+
+libmysql_host_backend_unittests_LDADD = $(top_builddir)/src/lib/mysql_host_backend/libkea-mysql-host-backend.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/testutils/libdhcpsrvtest.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/http/libkea-http.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp/testutils/libdhcptest.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/mysql/testutils/libmysqltest.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/mysql/libkea-mysql.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/database/libkea-database.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
+libmysql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+libmysql_host_backend_unittests_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS) $(GTEST_LDADD)
+endif
+
+noinst_PROGRAMS = $(TESTS)
similarity index 95%
rename from src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc
rename to src/lib/mysql_host_backend/tests/mysql_host_data_source_unittest.cc
index 8b21b0916153e9c49d766dbfaecab2bb8f530782..d1a8dc04b660c8e4982757dd8b579b6dd3bbd3fb 100644 (file)
@@ -10,7 +10,7 @@
 #include <dhcpsrv/testutils/test_utils.h>
 #include <exceptions/exceptions.h>
 #include <dhcpsrv/host.h>
-#include <dhcpsrv/mysql_host_data_source.h>
+#include <mysql_host_backend/mysql_host_data_source.h>
 #include <dhcpsrv/testutils/generic_host_data_source_unittest.h>
 #include <dhcpsrv/testutils/host_data_source_utils.h>
 #include <dhcpsrv/host_mgr.h>
@@ -153,6 +153,8 @@ public:
         return (countRowsInTable("ipv6_reservations"));
     }
 
+    /// @brief Initializer.
+    Initializer<MySqlHostDataSourceInit> init_;
 };
 
 /// @brief Check that database can be opened
@@ -162,6 +164,7 @@ public:
 /// MySqlHostMgr test fixture set.  This test checks that the database can be
 /// opened: the fixtures assume that and check basic operations.
 TEST(MySqlHostDataSource, OpenDatabase) {
+    Initializer<MySqlHostDataSourceInit> init;
     // Schema needs to be created for the test to work.
     destroyMySQLSchema();
     createMySQLSchema();
@@ -250,6 +253,7 @@ TEST(MySqlHostDataSource, OpenDatabase) {
 /// MySqlHostMgr test fixture set.  This test checks that the database can be
 /// opened: the fixtures assume that and check basic operations.
 TEST(MySqlHostDataSource, OpenDatabaseMultiThreading) {
+    Initializer<MySqlHostDataSourceInit> init;
     // Enable Multi-Threading.
     MultiThreadingTest mt(true);
 
@@ -351,6 +355,7 @@ bool db_lost_callback(ReconnectCtlPtr /* db_conn_retry */) {
 /// in a unit test is next to impossible. That has to be done
 /// as a system test.
 TEST(MySqlHostDataSource, NoCallbackOnOpenFail) {
+    Initializer<MySqlHostDataSourceInit> init;
     // Schema needs to be created for the test to work.
     destroyMySQLSchema();
     createMySQLSchema();
@@ -375,6 +380,7 @@ TEST(MySqlHostDataSource, NoCallbackOnOpenFail) {
 /// in a unit test is next to impossible. That has to be done
 /// as a system test.
 TEST(MySqlHostDataSource, NoCallbackOnOpenFailMultiThreading) {
+    Initializer<MySqlHostDataSourceInit> init;
     // Enable Multi-Threading.
     MultiThreadingTest mt(true);
 
@@ -1525,6 +1531,9 @@ protected:
 
     /// @brief Rollback and drop MySQL schema after the test.
     virtual void TearDown();
+
+    /// @brief Initializer.
+    Initializer<MySqlHostDataSourceInit> init_;
 };
 
 void
@@ -1582,6 +1591,9 @@ public:
         return (connectionString(MYSQL_VALID_TYPE, INVALID_NAME, VALID_HOST,
                                  VALID_USER, VALID_PASSWORD));
     }
+
+    /// @brief Initializer.
+    Initializer<MySqlHostDataSourceInit> init_;
 };
 
 // This test verifies that reservations for a particular client can
@@ -1842,4 +1854,90 @@ TEST_F(MySQLHostMgrDbLostCallbackTest, testDbLostAndFailedAfterTimeoutCallbackMu
     testDbLostAndFailedAfterTimeoutCallback();
 }
 
+/// @brief Test fixture class for testing @ref CfgDbAccessTest using MySQL
+/// backend.
+class CfgMySqlDbAccessTest : public ::testing::Test {
+public:
+
+    /// @brief Constructor.
+    CfgMySqlDbAccessTest() {
+        // Ensure we have the proper schema with no transient data.
+        db::test::createMySQLSchema();
+    }
+
+    /// @brief Destructor.
+    virtual ~CfgMySqlDbAccessTest() {
+        // If data wipe enabled, delete transient data otherwise destroy the schema
+        db::test::destroyMySQLSchema();
+    }
+
+    /// @brief Initializer.
+    Initializer<MySqlHostDataSourceInit> init_;
+};
+
+// Tests that MySQL lease manager and host data source can be created from a
+// specified configuration.
+TEST_F(CfgMySqlDbAccessTest, createManagers) {
+    CfgDbAccess cfg;
+    ASSERT_NO_THROW(cfg.setLeaseDbAccessString("type=memfile persist=false universe=4"));
+    ASSERT_NO_THROW(cfg.setHostDbAccessString(db::test::validMySQLConnectionString()));
+    ASSERT_NO_THROW(cfg.createManagers());
+
+    ASSERT_NO_THROW({
+        const HostDataSourcePtr& host_data_source =
+            HostMgr::instance().getHostDataSource();
+        ASSERT_TRUE(host_data_source);
+        EXPECT_EQ("mysql", host_data_source->getType());
+    });
+
+    // Because of the lazy initialization of the HostMgr instance, it is
+    // possible that the first call to the instance() function tosses
+    // existing connection to the database created by the call to
+    // createManagers(). Let's make sure that this doesn't happen.
+    ASSERT_NO_THROW(HostMgr::instance());
+
+    ASSERT_NO_THROW({
+        const HostDataSourcePtr& host_data_source =
+            HostMgr::instance().getHostDataSource();
+        ASSERT_TRUE(host_data_source);
+        EXPECT_EQ("mysql", host_data_source->getType());
+    });
+
+    EXPECT_TRUE(HostMgr::instance().getIPReservationsUnique());
+}
+
+// Tests that the createManagers function utilizes the setting in the
+// CfgDbAccess class which controls whether the IP reservations must
+// be unique or can be non-unique.
+TEST_F(CfgMySqlDbAccessTest, createManagersIPResrvUnique) {
+    CfgDbAccess cfg;
+
+    cfg.setIPReservationsUnique(false);
+    ASSERT_NO_THROW(cfg.setLeaseDbAccessString("type=memfile persist=false universe=6"));
+    ASSERT_NO_THROW(cfg.setHostDbAccessString(db::test::validMySQLConnectionString()));
+    ASSERT_NO_THROW(cfg.createManagers());
+
+    ASSERT_NO_THROW({
+        const HostDataSourcePtr& host_data_source =
+            HostMgr::instance().getHostDataSource();
+        ASSERT_TRUE(host_data_source);
+        EXPECT_EQ("mysql", host_data_source->getType());
+    });
+
+    // Because of the lazy initialization of the HostMgr instance, it is
+    // possible that the first call to the instance() function tosses
+    // existing connection to the database created by the call to
+    // createManagers(). Let's make sure that this doesn't happen.
+    ASSERT_NO_THROW(HostMgr::instance());
+
+    ASSERT_NO_THROW({
+        const HostDataSourcePtr& host_data_source =
+            HostMgr::instance().getHostDataSource();
+        ASSERT_TRUE(host_data_source);
+        EXPECT_EQ("mysql", host_data_source->getType());
+    });
+
+    EXPECT_FALSE(HostMgr::instance().getIPReservationsUnique());
+}
+
 }  // namespace
diff --git a/src/lib/mysql_host_backend/tests/run_unittests.cc b/src/lib/mysql_host_backend/tests/run_unittests.cc
new file mode 100644 (file)
index 0000000..63b2d4a
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (C) 2024 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 <gtest/gtest.h>
+
+#include <util/unittests/run_all.h>
+#include <log/logger_support.h>
+
+int
+main(int argc, char* argv[]) {
+    ::testing::InitGoogleTest(&argc, argv);
+    isc::log::initLogger();
+    return (isc::util::unittests::run_all());
+}
index 85d94126ec27775dd86cb058d28691fecfe017ba..0a1ca53df36c02982a14ed1a2b4fccb20b1c22ce 100644 (file)
@@ -1,5 +1,9 @@
 SUBDIRS = . tests
 
+AM_CPPFLAGS  = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(MYSQL_CPPFLAGS)
+
 AM_CXXFLAGS = $(KEA_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda
@@ -9,6 +13,15 @@ lib_LTLIBRARIES = libkea-mysql-lease-backend.la
 libkea_mysql_lease_backend_la_SOURCES = mysql_lease_mgr.cc mysql_lease_mgr.h
 
 libkea_mysql_lease_backend_la_LIBADD = $(top_builddir)/src/lib/mysql/libkea-mysql.la
+libkea_mysql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/database/libkea-database.la
+libkea_mysql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+libkea_mysql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+libkea_mysql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
+libkea_mysql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
+libkea_mysql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la
+libkea_mysql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/util/libkea-util.la
+libkea_mysql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+libkea_mysql_lease_backend_la_LIBADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS)
 
 libkea_mysql_lease_backend_la_LDFLAGS = $(MYSQL_LIBS)
 
index b403d66ae19d86a914223e39d32a124d30d7c6f7..f16b8865b1524b1baf318372abf33845bd060a12 100644 (file)
@@ -13,7 +13,7 @@
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/lease_mgr_factory.h>
-#include <dhcpsrv/mysql_lease_mgr.h>
+#include <mysql_lease_mgr.h>
 #include <dhcpsrv/timer_mgr.h>
 #include <mysql/mysql_connection.h>
 #include <util/multi_threading_mgr.h>
index af1c964eafe4ba6896c7869668b0d5b2ff6af61f..cde5f21198c948a46d2ff7de2c36c0f862b69ca9 100644 (file)
@@ -1297,6 +1297,27 @@ private:
     std::string timer_name_;
 };
 
+struct MySqlLeaseMgrInit {
+    // Constructor registers
+    MySqlLeaseMgrInit() {
+        LeaseMgrFactory::registerFactory("mysql", factory, true);
+    }
+
+    // Destructor deregisters
+    ~MySqlLeaseMgrInit() {
+        LeaseMgrFactory::deregisterFactory("mysql", true);
+    }
+
+    // Factory class method
+    static TrackingLeaseMgrPtr
+    factory(const isc::db::DatabaseConnection::ParameterMap& parameters) {
+        // TODO - fix messages
+        //LOG_INFO(dhcpsrv_logger, DHCPSRV_MYSQL_DB)
+        //    .arg(DatabaseConnection::redactedAccessString(parameters));
+        return (TrackingLeaseMgrPtr(new MySqlLeaseMgr(parameters)));
+    }
+};
+
 }  // namespace dhcp
 }  // namespace isc
 
diff --git a/src/lib/mysql_lease_backend/tests/.gitignore b/src/lib/mysql_lease_backend/tests/.gitignore
new file mode 100644 (file)
index 0000000..b48dc34
--- /dev/null
@@ -0,0 +1 @@
+libmysql_lease_backend_unittests
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e94db7edd2c2b40f50f4843acd157a664109f633 100644 (file)
@@ -0,0 +1,58 @@
+SUBDIRS = .
+
+AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CXXFLAGS = $(KEA_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
+
+TESTS =
+if HAVE_GTEST
+TESTS += libmysql_lease_backend_unittests
+
+libmysql_lease_backend_unittests_SOURCES  = run_unittests.cc
+libmysql_lease_backend_unittests_SOURCES += mysql_lease_mgr_unittest.cc
+libmysql_lease_backend_unittests_SOURCES += mysql_lease_extended_info_unittest.cc
+libmysql_lease_backend_unittests_SOURCES += mysql_bootp_unittest.cc
+
+libmysql_lease_backend_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+libmysql_lease_backend_unittests_CPPFLAGS += $(MYSQL_CPPFLAGS)
+
+libmysql_lease_backend_unittests_CXXFLAGS = $(AM_CXXFLAGS)
+
+libmysql_lease_backend_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
+libmysql_lease_backend_unittests_LDFLAGS += $(MYSQL_LIBS)
+
+libmysql_lease_backend_unittests_LDADD = $(top_builddir)/src/lib/mysql_lease_backend/libkea-mysql-lease-backend.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/testutils/libdhcpsrvtest.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/http/libkea-http.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp/testutils/libdhcptest.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/mysql/testutils/libmysqltest.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/mysql/libkea-mysql.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/database/libkea-database.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
+libmysql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+libmysql_lease_backend_unittests_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS) $(GTEST_LDADD)
+endif
+
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/mysql_lease_backend/tests/mysql_bootp_unittest.cc b/src/lib/mysql_lease_backend/tests/mysql_bootp_unittest.cc
new file mode 100644 (file)
index 0000000..2731d55
--- /dev/null
@@ -0,0 +1,196 @@
+// Copyright (C) 2024 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 <dhcpsrv/lease_mgr_factory.h>
+#include <dhcpsrv/testutils/alloc_engine_utils.h>
+#include <dhcpsrv/testutils/test_utils.h>
+#include <mysql/testutils/mysql_schema.h>
+#include <mysql_lease_backend/mysql_lease_mgr.h>
+#include <util/triplet.h>
+
+#include <gtest/gtest.h>
+
+using namespace isc::asiolink;
+using namespace isc::db;
+using namespace isc::db::test;
+using namespace isc::dhcp;
+using namespace isc::dhcp::test;
+using namespace isc::util;
+
+namespace {
+
+/// @brief Extension of the fixture class to use the MySQL backend.
+class MySqlAllocEngine4Test : public AllocEngine4Test {
+public:
+    /// @brief Constructor.
+    MySqlAllocEngine4Test() {
+        // Ensure we have the proper schema with no transient data.
+        isc::db::test::createMySQLSchema();
+        factory_.create(isc::db::test::validMySQLConnectionString());
+    }
+
+    /// @brief Destructor.
+    ~MySqlAllocEngine4Test() {
+        // If data wipe enabled, delete transient data otherwise destroy
+        // the schema.
+        isc::db::test::destroyMySQLSchema();
+        LeaseMgrFactory::destroy();
+    }
+
+    /// @brief Initializer.
+    Initializer<MySqlLeaseMgrInit> init_;
+};
+
+// This test checks that simple allocation handles BOOTP queries.
+TEST_F(MySqlAllocEngine4Test, bootpAlloc4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
+    ASSERT_TRUE(engine);
+
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
+                                    false, true, "somehost.example.com.", false);
+    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+
+    // Make the query a BOOTP one.
+    ctx.query_->addClass("BOOTP");
+
+    Lease4Ptr lease = engine->allocateLease4(ctx);
+    // The new lease has been allocated, so the old lease should not exist.
+    ASSERT_FALSE(ctx.old_lease_);
+
+    // Check that we got a lease
+    ASSERT_TRUE(lease);
+
+    // Check that is belongs to the right subnet and client.
+    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+    EXPECT_TRUE(subnet_->inRange(lease->addr_));
+    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
+    ASSERT_TRUE(lease->client_id_);
+    EXPECT_TRUE(*lease->client_id_ == *clientid_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+
+    // Check the valid lifetime is infinite.
+    uint32_t infinity_lft = Lease::INFINITY_LFT;
+    EXPECT_EQ(infinity_lft, lease->valid_lft_);
+
+    // Check that the lease is indeed in LeaseMgr
+    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
+    ASSERT_TRUE(from_mgr);
+    // The MySQL database does not keep the hwtype for DHCPv4 leases.
+    from_mgr->hwaddr_->htype_ = HTYPE_FDDI;
+
+    // Now check that the lease in LeaseMgr has the same parameters
+    detailCompareLease(lease, from_mgr);
+}
+
+// This test checks simple renewal handles BOOTP queries.
+TEST_F(MySqlAllocEngine4Test, bootpRenew4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
+    ASSERT_TRUE(engine);
+
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
+                                    false, true, "somehost.example.com.", false);
+    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+
+    // Make the query a BOOTP one.
+    ctx.query_->addClass("BOOTP");
+
+    Lease4Ptr lease = engine->allocateLease4(ctx);
+
+    // Check that we got a lease.
+    ASSERT_TRUE(lease);
+
+    // Check that is belongs to the right subnet and client.
+    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+    EXPECT_TRUE(subnet_->inRange(lease->addr_));
+    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
+    ASSERT_TRUE(lease->client_id_);
+    EXPECT_TRUE(*lease->client_id_ == *clientid_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+
+    // Check the valid lifetime is infinite.
+    uint32_t infinity_lft = Lease::INFINITY_LFT;
+    EXPECT_EQ(infinity_lft, lease->valid_lft_);
+
+    // The new lease has been allocated, so the old lease should not exist.
+    ASSERT_FALSE(ctx.old_lease_);
+
+    // Do it again, this should amount to the renew of an existing lease
+    Lease4Ptr lease2 = engine->allocateLease4(ctx);
+
+    // Check that we got a lease.
+    ASSERT_TRUE(lease2);
+
+    // Check that is belongs to the right subnet and client.
+    EXPECT_EQ(lease2->subnet_id_, subnet_->getID());
+    EXPECT_TRUE(subnet_->inRange(lease2->addr_));
+    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease2->addr_));
+    ASSERT_TRUE(lease2->client_id_);
+    EXPECT_TRUE(*lease2->client_id_ == *clientid_);
+    ASSERT_TRUE(lease2->hwaddr_);
+    EXPECT_TRUE(*lease2->hwaddr_ == *hwaddr_);
+
+    // Lease already existed, so old_lease should be set.
+    EXPECT_TRUE(ctx.old_lease_);
+
+    // Check the renewed valid lifetime has the max value.
+    EXPECT_EQ(infinity_lft, lease2->valid_lft_);
+}
+
+// This test checks that deleteRelease handles BOOTP leases.
+TEST_F(MySqlAllocEngine4Test, bootpDelete) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
+    ASSERT_TRUE(engine);
+
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
+                                    false, true, "somehost.example.com.", false);
+    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+
+    // Make the query a BOOTP one.
+    ctx.query_->addClass("BOOTP");
+
+    Lease4Ptr lease = engine->allocateLease4(ctx);
+    // The new lease has been allocated, so the old lease should not exist.
+    ASSERT_FALSE(ctx.old_lease_);
+
+    // Check that we got a lease
+    ASSERT_TRUE(lease);
+
+    // Check that is belongs to the right subnet and client.
+    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+    EXPECT_TRUE(subnet_->inRange(lease->addr_));
+    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
+    ASSERT_TRUE(lease->client_id_);
+    EXPECT_TRUE(*lease->client_id_ == *clientid_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+
+    // Check the valid lifetime is infinite.
+    uint32_t infinity_lft = Lease::INFINITY_LFT;
+    EXPECT_EQ(infinity_lft, lease->valid_lft_);
+
+    // Check that the lease is indeed in LeaseMgr
+    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
+    ASSERT_TRUE(from_mgr);
+
+    // Now delete it.
+    bool deleted = false;
+    ASSERT_NO_THROW(deleted = LeaseMgrFactory::instance().deleteLease(lease));
+    EXPECT_TRUE(deleted);
+    from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
+    EXPECT_FALSE(from_mgr);
+}
+
+}
similarity index 95%
rename from src/lib/dhcpsrv/tests/mysql_lease_extended_info_unittest.cc
rename to src/lib/mysql_lease_backend/tests/mysql_lease_extended_info_unittest.cc
index ed491ccb598c6d3b1b69597226a1615563352559..458bc9d89d11536695e8790eea20d36c16156b57 100644 (file)
@@ -10,7 +10,7 @@
 #include <cc/data.h>
 #include <dhcpsrv/testutils/generic_lease_extended_info_unittest.h>
 #include <mysql/testutils/mysql_schema.h>
-#include <dhcpsrv/mysql_lease_mgr.h>
+#include <mysql_lease_backend/mysql_lease_mgr.h>
 
 using namespace isc;
 using namespace isc::asiolink;
@@ -59,11 +59,16 @@ public:
     static void destroySchema() {
         destroyMySQLSchema();
     }
+
+    /// @brief Initializer.
+    Initializer<MySqlLeaseMgrInit> init_;
 };
 
 /// @brief Test fixture class for extended info tests.
-class MySqlExtendedInfoTest :
-    public isc::dhcp::test::GenericExtendedInfoTest<NakedMySqlLeaseMgr> { };
+class MySqlExtendedInfoTest : public isc::dhcp::test::GenericExtendedInfoTest<NakedMySqlLeaseMgr> {
+    /// @brief Initializer.
+    Initializer<MySqlLeaseMgrInit> init_;
+};
 
 /// @brief Verifies that the lease manager can start.
 TEST_F(MySqlExtendedInfoTest, startWithoutExtendedTables) {
similarity index 97%
rename from src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
rename to src/lib/mysql_lease_backend/tests/mysql_lease_mgr_unittest.cc
index 4132dd9af3e5cbaba6f769967792d749a879d92d..7a372b173ef4eea2e93f26909b4face43502f718 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <asiolink/io_address.h>
 #include <dhcpsrv/lease_mgr_factory.h>
-#include <dhcpsrv/mysql_lease_mgr.h>
+#include <mysql_lease_backend/mysql_lease_mgr.h>
 #include <dhcpsrv/testutils/test_utils.h>
 #include <dhcpsrv/testutils/generic_lease_mgr_unittest.h>
 #include <dhcpsrv/testutils/mysql_generic_backend_unittest.h>
@@ -39,7 +39,6 @@ using namespace std;
 
 namespace {
 
-
 /// @brief Test fixture class for testing MySQL Lease Manager
 ///
 /// Opens the database prior to each test and closes it afterwards.
@@ -106,6 +105,9 @@ public:
         LeaseMgrFactory::create(validMySQLConnectionString());
         lmptr_ = &(LeaseMgrFactory::instance());
     }
+
+    /// @brief Initializer.
+    Initializer<MySqlLeaseMgrInit> init_;
 };
 
 /// @brief Check that database can be opened
@@ -115,6 +117,7 @@ public:
 /// MySqlLeaseMgr test fixture set.  This test checks that the database can be
 /// opened: the fixtures assume that and check basic operations.
 TEST(MySqlOpenTest, OpenDatabase) {
+    Initializer<MySqlLeaseMgrInit> init;
     // Explicitly disable Multi-Threading.
     MultiThreadingMgr::instance().setMode(false);
 
@@ -217,6 +220,7 @@ TEST(MySqlOpenTest, OpenDatabase) {
 
 /// @brief Check that database can be opened with Multi-Threading
 TEST(MySqlOpenTest, OpenDatabaseMultiThreading) {
+    Initializer<MySqlLeaseMgrInit> init;
     // Enable Multi-Threading.
     MultiThreadingTest mt(true);
 
@@ -990,6 +994,9 @@ public:
         return (connectionString(MYSQL_VALID_TYPE, INVALID_NAME, VALID_HOST,
                                  VALID_USER, VALID_PASSWORD));
     }
+
+    /// @brief Initializer.
+    Initializer<MySqlLeaseMgrInit> init_;
 };
 
 /// @brief Verifies that loss of connectivity to MySQL is handled correctly.
@@ -1354,4 +1361,39 @@ TEST_F(MySqlLeaseMgrTest, bigStats) {
     testBigStats();
 }
 
+/// @brief Test fixture class for testing @ref CfgDbAccessTest using MySQL
+/// backend.
+class CfgMySqlDbAccessTest : public ::testing::Test {
+public:
+
+    /// @brief Constructor.
+    CfgMySqlDbAccessTest() {
+        // Ensure we have the proper schema with no transient data.
+        db::test::createMySQLSchema();
+    }
+
+    /// @brief Destructor.
+    virtual ~CfgMySqlDbAccessTest() {
+        // If data wipe enabled, delete transient data otherwise destroy the schema
+        db::test::destroyMySQLSchema();
+        LeaseMgrFactory::destroy();
+    }
+
+    /// @brief Initializer.
+    Initializer<MySqlLeaseMgrInit> init_;
+};
+
+// Tests that MySQL lease manager and host data source can be created from a
+// specified configuration.
+TEST_F(CfgMySqlDbAccessTest, createManagers) {
+    CfgDbAccess cfg;
+    ASSERT_NO_THROW(cfg.setLeaseDbAccessString(db::test::validMySQLConnectionString()));
+    ASSERT_NO_THROW(cfg.createManagers());
+
+    ASSERT_NO_THROW({
+        LeaseMgr& lease_mgr = LeaseMgrFactory::instance();
+        EXPECT_EQ("mysql", lease_mgr.getType());
+    });
+}
+
 }  // namespace
diff --git a/src/lib/mysql_lease_backend/tests/run_unittests.cc b/src/lib/mysql_lease_backend/tests/run_unittests.cc
new file mode 100644 (file)
index 0000000..63b2d4a
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (C) 2024 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 <gtest/gtest.h>
+
+#include <util/unittests/run_all.h>
+#include <log/logger_support.h>
+
+int
+main(int argc, char* argv[]) {
+    ::testing::InitGoogleTest(&argc, argv);
+    isc::log::initLogger();
+    return (isc::util::unittests::run_all());
+}
index ac788ea45b2223ff075db07155eab7a4787a255d..a181c3dc15718b4a162bdab078068a2b87459257 100644 (file)
@@ -1,5 +1,9 @@
 SUBDIRS = . tests
 
+AM_CPPFLAGS  = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(PGSQL_CPPFLAGS)
+
 AM_CXXFLAGS = $(KEA_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda
@@ -9,6 +13,15 @@ lib_LTLIBRARIES = libkea-pgsql-host-backend.la
 libkea_pgsql_host_backend_la_SOURCES = pgsql_host_data_source.cc pgsql_host_data_source.h
 
 libkea_pgsql_host_backend_la_LIBADD = $(top_builddir)/src/lib/pgsql/libkea-pgsql.la
+libkea_pgsql_host_backend_la_LIBADD += $(top_builddir)/src/lib/database/libkea-database.la
+libkea_pgsql_host_backend_la_LIBADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+libkea_pgsql_host_backend_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+libkea_pgsql_host_backend_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
+libkea_pgsql_host_backend_la_LIBADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
+libkea_pgsql_host_backend_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la
+libkea_pgsql_host_backend_la_LIBADD += $(top_builddir)/src/lib/util/libkea-util.la
+libkea_pgsql_host_backend_la_LIBADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+libkea_pgsql_host_backend_la_LIBADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS)
 
 libkea_pgsql_host_backend_la_LDFLAGS = $(PGSQL_LIBS)
 
index 249e5491650090db3b44bd0c2dd936e1246815b4..d4e12273ea111405a97b4bd48e019ba3b4345a6c 100644 (file)
@@ -17,7 +17,7 @@
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/host_mgr.h>
-#include <dhcpsrv/pgsql_host_data_source.h>
+#include <pgsql_host_data_source.h>
 #include <dhcpsrv/timer_mgr.h>
 #include <util/buffer.h>
 #include <util/multi_threading_mgr.h>
index 61043c575a45dbb969cd7d2290d812a1b743d341..83e40a5c973526b8b8ce1603fbd400ddc72dc732 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <database/database_connection.h>
 #include <dhcpsrv/base_host_data_source.h>
+#include <dhcpsrv/host_data_source_factory.h>
 #include <pgsql/pgsql_connection.h>
 #include <pgsql/pgsql_exchange.h>
 
@@ -583,6 +584,27 @@ private:
     PgSqlHostDataSourceImplPtr impl_;
 };
 
+struct PgSqlHostDataSourceInit {
+    // Constructor registers
+    PgSqlHostDataSourceInit() {
+        isc::dhcp::HostDataSourceFactory::registerFactory("postgresql", factory, true);
+    }
+
+    // Destructor deregisters
+    ~PgSqlHostDataSourceInit() {
+        isc::dhcp::HostDataSourceFactory::deregisterFactory("postgresql", true);
+    }
+
+    // Factory class method
+    static HostDataSourcePtr
+    factory(const isc::db::DatabaseConnection::ParameterMap& parameters) {
+        // TODO - fix messages
+        //LOG_INFO(hosts_logger, DHCPSRV_PGSQL_HOST_DB)
+        //    .arg(DatabaseConnection::redactedAccessString(parameters));
+        return (HostDataSourcePtr(new PgSqlHostDataSource(parameters)));
+    }
+};
+
 }  // namespace dhcp
 }  // namespace isc
 
diff --git a/src/lib/pgsql_host_backend/tests/.gitignore b/src/lib/pgsql_host_backend/tests/.gitignore
new file mode 100644 (file)
index 0000000..efb5bce
--- /dev/null
@@ -0,0 +1 @@
+libpgsql_host_backend_unittests
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..2fd06c8a5fbcfaadffea08ffb8438e51f10512bb 100644 (file)
@@ -0,0 +1,56 @@
+SUBDIRS = .
+
+AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CXXFLAGS = $(KEA_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
+
+TESTS =
+if HAVE_GTEST
+TESTS += libpgsql_host_backend_unittests
+
+libpgsql_host_backend_unittests_SOURCES  = run_unittests.cc
+libpgsql_host_backend_unittests_SOURCES += pgsql_host_data_source_unittest.cc
+
+libpgsql_host_backend_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+libpgsql_host_backend_unittests_CPPFLAGS += $(PGSQL_CPPFLAGS)
+
+libpgsql_host_backend_unittests_CXXFLAGS = $(AM_CXXFLAGS)
+
+libpgsql_host_backend_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
+libpgsql_host_backend_unittests_LDFLAGS += $(PGSQL_LIBS)
+
+libpgsql_host_backend_unittests_LDADD = $(top_builddir)/src/lib/pgsql_host_backend/libkea-pgsql-host-backend.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/testutils/libdhcpsrvtest.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/http/libkea-http.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp/testutils/libdhcptest.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/pgsql/testutils/libpgsqltest.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/pgsql/libkea-pgsql.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/database/libkea-database.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
+libpgsql_host_backend_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+libpgsql_host_backend_unittests_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS) $(GTEST_LDADD)
+endif
+
+noinst_PROGRAMS = $(TESTS)
\ No newline at end of file
similarity index 94%
rename from src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc
rename to src/lib/pgsql_host_backend/tests/pgsql_host_data_source_unittest.cc
index 63c48e7fc1d6b73a0841ae5f039e3b851ef48d28..015e59484574c506d7c5edadc9625a96cda46b66 100644 (file)
@@ -10,7 +10,7 @@
 #include <dhcpsrv/testutils/test_utils.h>
 #include <exceptions/exceptions.h>
 #include <dhcpsrv/host.h>
-#include <dhcpsrv/pgsql_host_data_source.h>
+#include <pgsql_host_backend/pgsql_host_data_source.h>
 #include <dhcpsrv/testutils/generic_host_data_source_unittest.h>
 #include <dhcpsrv/testutils/host_data_source_utils.h>
 #include <dhcpsrv/host_mgr.h>
@@ -151,6 +151,8 @@ public:
         return (countRowsInTable("ipv6_reservations"));
     }
 
+    /// @brief Initializer.
+    Initializer<PgSqlHostDataSourceInit> init_;
 };
 
 /// @brief Check that database can be opened
@@ -160,6 +162,7 @@ public:
 /// PgSqlHostMgr test fixture set.  This test checks that the database can be
 /// opened: the fixtures assume that and check basic operations.
 TEST(PgSqlHostDataSource, OpenDatabase) {
+    Initializer<PgSqlHostDataSourceInit> init;
     // Schema needs to be created for the test to work.
     destroyPgSQLSchema();
     createPgSQLSchema();
@@ -259,6 +262,7 @@ TEST(PgSqlHostDataSource, OpenDatabase) {
 /// PgSqlHostMgr test fixture set.  This test checks that the database can be
 /// opened: the fixtures assume that and check basic operations.
 TEST(PgSqlHostDataSource, OpenDatabaseMultiThreading) {
+    Initializer<PgSqlHostDataSourceInit> init;
     // Enable Multi-Threading.
     MultiThreadingTest mt(true);
 
@@ -360,6 +364,7 @@ bool db_lost_callback(ReconnectCtlPtr /* db_conn_retry */) {
 /// in a unit test is next to impossible. That has to be done
 /// as a system test.
 TEST(PgSqlHostDataSource, NoCallbackOnOpenFail) {
+    Initializer<PgSqlHostDataSourceInit> init;
     // Schema needs to be created for the test to work.
     destroyPgSQLSchema();
     createPgSQLSchema();
@@ -384,6 +389,7 @@ TEST(PgSqlHostDataSource, NoCallbackOnOpenFail) {
 /// in a unit test is next to impossible. That has to be done
 /// as a system test.
 TEST(PgSqlHostDataSource, NoCallbackOnOpenFailMultiThreading) {
+    Initializer<PgSqlHostDataSourceInit> init;
     // Enable Multi-Threading.
     MultiThreadingTest mt(true);
 
@@ -1493,6 +1499,9 @@ protected:
 
     /// @brief Rollback and drop PostgreSQL schema after the test.
     virtual void TearDown();
+
+    /// @brief Initializer.
+    Initializer<PgSqlHostDataSourceInit> init_;
 };
 
 void
@@ -1550,6 +1559,9 @@ public:
         return (connectionString(PGSQL_VALID_TYPE, INVALID_NAME, VALID_HOST,
                                  VALID_USER, VALID_PASSWORD));
     }
+
+    /// @brief Initializer.
+    Initializer<PgSqlHostDataSourceInit> init_;
 };
 
 // This test verifies that reservations for a particular client can
@@ -1810,4 +1822,90 @@ TEST_F(PgSQLHostMgrDbLostCallbackTest, testDbLostAndFailedAfterTimeoutCallbackMu
     testDbLostAndFailedAfterTimeoutCallback();
 }
 
+/// @brief Test fixture class for testing @ref CfgDbAccessTest using PgSQL
+/// backend.
+class CfgPgSqlDbAccessTest : public ::testing::Test {
+public:
+
+    /// @brief Constructor.
+    CfgPgSqlDbAccessTest() {
+        // Ensure we have the proper schema with no transient data.
+        db::test::createPgSQLSchema();
+    }
+
+    /// @brief Destructor.
+    virtual ~CfgPgSqlDbAccessTest() {
+        // If data wipe enabled, delete transient data otherwise destroy the schema
+        db::test::destroyPgSQLSchema();
+    }
+
+    /// @brief Initializer.
+    Initializer<PgSqlHostDataSourceInit> init_;
+};
+
+// Tests that PostgreSQL lease manager and host data source can be created from a
+// specified configuration.
+TEST_F(CfgPgSqlDbAccessTest, createManagers) {
+    CfgDbAccess cfg;
+    ASSERT_NO_THROW(cfg.setLeaseDbAccessString("type=memfile persist=false universe=4"));
+    ASSERT_NO_THROW(cfg.setHostDbAccessString(db::test::validPgSQLConnectionString()));
+    ASSERT_NO_THROW(cfg.createManagers());
+
+    ASSERT_NO_THROW({
+        const HostDataSourcePtr& host_data_source =
+            HostMgr::instance().getHostDataSource();
+        ASSERT_TRUE(host_data_source);
+        EXPECT_EQ("postgresql", host_data_source->getType());
+    });
+
+    // Because of the lazy initialization of the HostMgr instance, it is
+    // possible that the first call to the instance() function tosses
+    // existing connection to the database created by the call to
+    // createManagers(). Let's make sure that this doesn't happen.
+    ASSERT_NO_THROW(HostMgr::instance());
+
+    ASSERT_NO_THROW({
+        const HostDataSourcePtr& host_data_source =
+            HostMgr::instance().getHostDataSource();
+        ASSERT_TRUE(host_data_source);
+        EXPECT_EQ("postgresql", host_data_source->getType());
+    });
+
+    EXPECT_TRUE(HostMgr::instance().getIPReservationsUnique());
+}
+
+// Tests that the createManagers function utilizes the setting in the
+// CfgDbAccess class which controls whether the IP reservations must
+// be unique or can be non-unique.
+TEST_F(CfgPgSqlDbAccessTest, createManagersIPResrvUnique) {
+    CfgDbAccess cfg;
+
+    cfg.setIPReservationsUnique(false);
+    ASSERT_NO_THROW(cfg.setLeaseDbAccessString("type=memfile persist=false universe=6"));
+    ASSERT_NO_THROW(cfg.setHostDbAccessString(db::test::validPgSQLConnectionString()));
+    ASSERT_NO_THROW(cfg.createManagers());
+
+    ASSERT_NO_THROW({
+        const HostDataSourcePtr& host_data_source =
+            HostMgr::instance().getHostDataSource();
+        ASSERT_TRUE(host_data_source);
+        EXPECT_EQ("postgresql", host_data_source->getType());
+    });
+
+    // Because of the lazy initialization of the HostMgr instance, it is
+    // possible that the first call to the instance() function tosses
+    // existing connection to the database created by the call to
+    // createManagers(). Let's make sure that this doesn't happen.
+    ASSERT_NO_THROW(HostMgr::instance());
+
+    ASSERT_NO_THROW({
+        const HostDataSourcePtr& host_data_source =
+            HostMgr::instance().getHostDataSource();
+        ASSERT_TRUE(host_data_source);
+        EXPECT_EQ("postgresql", host_data_source->getType());
+    });
+
+    EXPECT_FALSE(HostMgr::instance().getIPReservationsUnique());
+}
+
 }  // namespace
diff --git a/src/lib/pgsql_host_backend/tests/run_unittests.cc b/src/lib/pgsql_host_backend/tests/run_unittests.cc
new file mode 100644 (file)
index 0000000..63b2d4a
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (C) 2024 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 <gtest/gtest.h>
+
+#include <util/unittests/run_all.h>
+#include <log/logger_support.h>
+
+int
+main(int argc, char* argv[]) {
+    ::testing::InitGoogleTest(&argc, argv);
+    isc::log::initLogger();
+    return (isc::util::unittests::run_all());
+}
index 87b33d9a54dc2a6b56003d324eca2c7d48bcacac..8e7eefc8b007977845443712df8c8f3347a61fd9 100644 (file)
@@ -1,5 +1,9 @@
 SUBDIRS = . tests
 
+AM_CPPFLAGS  = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CPPFLAGS += $(PGSQL_CPPFLAGS)
+
 AM_CXXFLAGS = $(KEA_CXXFLAGS)
 
 CLEANFILES = *.gcno *.gcda
@@ -9,6 +13,15 @@ lib_LTLIBRARIES = libkea-pgsql-lease-backend.la
 libkea_pgsql_lease_backend_la_SOURCES = pgsql_lease_mgr.cc pgsql_lease_mgr.h
 
 libkea_pgsql_lease_backend_la_LIBADD = $(top_builddir)/src/lib/pgsql/libkea-pgsql.la
+libkea_pgsql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/database/libkea-database.la
+libkea_pgsql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+libkea_pgsql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+libkea_pgsql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
+libkea_pgsql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
+libkea_pgsql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la
+libkea_pgsql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/util/libkea-util.la
+libkea_pgsql_lease_backend_la_LIBADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+libkea_pgsql_lease_backend_la_LIBADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS)
 
 libkea_pgsql_lease_backend_la_LDFLAGS = $(PGSQL_LIBS)
 
index c860ebbf6bead9fc5a5f99b3bf8f98afd571885e..806e2d4d0dca2ba73756f065006ffdb006dd1eac 100644 (file)
@@ -14,7 +14,7 @@
 #include <dhcpsrv/dhcpsrv_log.h>
 #include <dhcpsrv/dhcpsrv_exceptions.h>
 #include <dhcpsrv/lease_mgr_factory.h>
-#include <dhcpsrv/pgsql_lease_mgr.h>
+#include <pgsql_lease_mgr.h>
 #include <dhcpsrv/timer_mgr.h>
 #include <util/multi_threading_mgr.h>
 
index d6bc94a212282672639cd484fd86c7c496fd3314..b6fd5353f95d943268bee2a189b88c1bf6f92664 100644 (file)
@@ -1257,6 +1257,27 @@ private:
     std::string timer_name_;
 };
 
+struct PgSqlLeaseMgrInit {
+    // Constructor registers
+    PgSqlLeaseMgrInit() {
+        LeaseMgrFactory::registerFactory("postgresql", factory, true);
+    }
+
+    // Destructor deregisters
+    ~PgSqlLeaseMgrInit() {
+        LeaseMgrFactory::deregisterFactory("postgresql", true);
+    }
+
+    // Factory class method
+    static TrackingLeaseMgrPtr
+    factory(const isc::db::DatabaseConnection::ParameterMap& parameters) {
+        // TODO - fix messages
+        //LOG_INFO(dhcpsrv_logger, DHCPSRV_PGSQL_DB)
+        //    .arg(DatabaseConnection::redactedAccessString(parameters));
+        return (TrackingLeaseMgrPtr(new PgSqlLeaseMgr(parameters)));
+    }
+};
+
 }  // namespace dhcp
 }  // namespace isc
 
diff --git a/src/lib/pgsql_lease_backend/tests/.gitignore b/src/lib/pgsql_lease_backend/tests/.gitignore
new file mode 100644 (file)
index 0000000..01778b1
--- /dev/null
@@ -0,0 +1 @@
+libpgsql_lease_backend_unittests
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b49947d7b594fe001101eeb861aadd44af6ebe75 100644 (file)
@@ -0,0 +1,58 @@
+SUBDIRS = .
+
+AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS += $(BOOST_INCLUDES)
+AM_CXXFLAGS = $(KEA_CXXFLAGS)
+
+if USE_STATIC_LINK
+AM_LDFLAGS = -static
+endif
+
+CLEANFILES = *.gcno *.gcda
+
+TESTS_ENVIRONMENT = $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND)
+
+TESTS =
+if HAVE_GTEST
+TESTS += libpgsql_lease_backend_unittests
+
+libpgsql_lease_backend_unittests_SOURCES  = run_unittests.cc
+libpgsql_lease_backend_unittests_SOURCES += pgsql_lease_mgr_unittest.cc
+libpgsql_lease_backend_unittests_SOURCES += pgsql_lease_extended_info_unittest.cc
+libpgsql_lease_backend_unittests_SOURCES += pgsql_bootp_unittest.cc
+
+libpgsql_lease_backend_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+libpgsql_lease_backend_unittests_CPPFLAGS += $(PGSQL_CPPFLAGS)
+
+libpgsql_lease_backend_unittests_CXXFLAGS = $(AM_CXXFLAGS)
+
+libpgsql_lease_backend_unittests_LDFLAGS = $(AM_LDFLAGS) $(CRYPTO_LDFLAGS) $(GTEST_LDFLAGS)
+libpgsql_lease_backend_unittests_LDFLAGS += $(PGSQL_LIBS)
+
+libpgsql_lease_backend_unittests_LDADD = $(top_builddir)/src/lib/pgsql_lease_backend/libkea-pgsql-lease-backend.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/testutils/libdhcpsrvtest.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libkea-dhcpsrv.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/process/libkea-process.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/eval/libkea-eval.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp_ddns/libkea-dhcp_ddns.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/stats/libkea-stats.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/config/libkea-cfgclient.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/http/libkea-http.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp/testutils/libdhcptest.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libkea-dhcp++.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/hooks/libkea-hooks.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/pgsql/testutils/libpgsqltest.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/pgsql/libkea-pgsql.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/database/libkea-database.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/cc/libkea-cc.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libkea-asiolink.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/dns/libkea-dns++.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/cryptolink/libkea-cryptolink.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/log/libkea-log.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/util/libkea-util.la
+libpgsql_lease_backend_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libkea-exceptions.la
+libpgsql_lease_backend_unittests_LDADD += $(LOG4CPLUS_LIBS) $(CRYPTO_LIBS) $(BOOST_LIBS) $(GTEST_LDADD)
+endif
+
+noinst_PROGRAMS = $(TESTS)
diff --git a/src/lib/pgsql_lease_backend/tests/pgsql_bootp_unittest.cc b/src/lib/pgsql_lease_backend/tests/pgsql_bootp_unittest.cc
new file mode 100644 (file)
index 0000000..f80324e
--- /dev/null
@@ -0,0 +1,196 @@
+// Copyright (C) 2024 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 <dhcpsrv/lease_mgr_factory.h>
+#include <dhcpsrv/testutils/alloc_engine_utils.h>
+#include <dhcpsrv/testutils/test_utils.h>
+#include <pgsql/testutils/pgsql_schema.h>
+#include <pgsql_lease_backend/pgsql_lease_mgr.h>
+#include <util/triplet.h>
+
+#include <gtest/gtest.h>
+
+using namespace isc::asiolink;
+using namespace isc::db;
+using namespace isc::db::test;
+using namespace isc::dhcp;
+using namespace isc::dhcp::test;
+using namespace isc::util;
+
+namespace {
+
+/// @brief Extension of the fixture class to use the PostgreSQL backend.
+class PgSqlAllocEngine4Test : public AllocEngine4Test {
+public:
+    /// @brief Constructor.
+    PgSqlAllocEngine4Test() {
+        // Ensure we have the proper schema with no transient data.
+        isc::db::test::createPgSQLSchema();
+        factory_.create(isc::db::test::validPgSQLConnectionString());
+    }
+
+    /// @brief Destructor.
+    ~PgSqlAllocEngine4Test() {
+        // If data wipe enabled, delete transient data otherwise destroy
+        // the schema.
+        isc::db::test::destroyPgSQLSchema();
+        LeaseMgrFactory::destroy();
+    }
+
+    /// @brief Initializer.
+    Initializer<PgSqlLeaseMgrInit> init_;
+};
+
+// This test checks that simple allocation handles BOOTP queries.
+TEST_F(PgSqlAllocEngine4Test, bootpAlloc4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
+    ASSERT_TRUE(engine);
+
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
+                                    false, true, "somehost.example.com.", false);
+    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+
+    // Make the query a BOOTP one.
+    ctx.query_->addClass("BOOTP");
+
+    Lease4Ptr lease = engine->allocateLease4(ctx);
+    // The new lease has been allocated, so the old lease should not exist.
+    ASSERT_FALSE(ctx.old_lease_);
+
+    // Check that we got a lease
+    ASSERT_TRUE(lease);
+
+    // Check that is belongs to the right subnet and client.
+    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+    EXPECT_TRUE(subnet_->inRange(lease->addr_));
+    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
+    ASSERT_TRUE(lease->client_id_);
+    EXPECT_TRUE(*lease->client_id_ == *clientid_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+
+    // Check the valid lifetime is infinite.
+    uint32_t infinity_lft = Lease::INFINITY_LFT;
+    EXPECT_EQ(infinity_lft, lease->valid_lft_);
+
+    // Check that the lease is indeed in LeaseMgr
+    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
+    ASSERT_TRUE(from_mgr);
+    // The PostgreSql database does not keep the hwtype for DHCPv4 leases.
+    from_mgr->hwaddr_->htype_ = HTYPE_FDDI;
+
+    // Now check that the lease in LeaseMgr has the same parameters
+    detailCompareLease(lease, from_mgr);
+}
+
+// This test checks simple renewal handles BOOTP queries.
+TEST_F(PgSqlAllocEngine4Test, bootpRenew4) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
+    ASSERT_TRUE(engine);
+
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
+                                    false, true, "somehost.example.com.", false);
+    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+
+    // Make the query a BOOTP one.
+    ctx.query_->addClass("BOOTP");
+
+    Lease4Ptr lease = engine->allocateLease4(ctx);
+
+    // Check that we got a lease.
+    ASSERT_TRUE(lease);
+
+    // Check that is belongs to the right subnet and client.
+    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+    EXPECT_TRUE(subnet_->inRange(lease->addr_));
+    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
+    ASSERT_TRUE(lease->client_id_);
+    EXPECT_TRUE(*lease->client_id_ == *clientid_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+
+    // Check the valid lifetime is infinite.
+    uint32_t infinity_lft = Lease::INFINITY_LFT;
+    EXPECT_EQ(infinity_lft, lease->valid_lft_);
+
+    // The new lease has been allocated, so the old lease should not exist.
+    ASSERT_FALSE(ctx.old_lease_);
+
+    // Do it again, this should amount to the renew of an existing lease
+    Lease4Ptr lease2 = engine->allocateLease4(ctx);
+
+    // Check that we got a lease.
+    ASSERT_TRUE(lease2);
+
+    // Check that is belongs to the right subnet and client.
+    EXPECT_EQ(lease2->subnet_id_, subnet_->getID());
+    EXPECT_TRUE(subnet_->inRange(lease2->addr_));
+    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease2->addr_));
+    ASSERT_TRUE(lease2->client_id_);
+    EXPECT_TRUE(*lease2->client_id_ == *clientid_);
+    ASSERT_TRUE(lease2->hwaddr_);
+    EXPECT_TRUE(*lease2->hwaddr_ == *hwaddr_);
+
+    // Lease already existed, so old_lease should be set.
+    EXPECT_TRUE(ctx.old_lease_);
+
+    // Check the renewed valid lifetime has the max value.
+    EXPECT_EQ(infinity_lft, lease2->valid_lft_);
+}
+
+// This test checks that deleteRelease handles BOOTP leases.
+TEST_F(PgSqlAllocEngine4Test, bootpDelete) {
+    boost::scoped_ptr<AllocEngine> engine;
+    ASSERT_NO_THROW(engine.reset(new AllocEngine(0)));
+    ASSERT_TRUE(engine);
+
+    AllocEngine::ClientContext4 ctx(subnet_, clientid_, hwaddr_, IOAddress("0.0.0.0"),
+                                    false, true, "somehost.example.com.", false);
+    subnet_->setValid(Triplet<uint32_t>(1, 3, 5));
+    ctx.query_.reset(new Pkt4(DHCPREQUEST, 1234));
+
+    // Make the query a BOOTP one.
+    ctx.query_->addClass("BOOTP");
+
+    Lease4Ptr lease = engine->allocateLease4(ctx);
+    // The new lease has been allocated, so the old lease should not exist.
+    ASSERT_FALSE(ctx.old_lease_);
+
+    // Check that we got a lease
+    ASSERT_TRUE(lease);
+
+    // Check that is belongs to the right subnet and client.
+    EXPECT_EQ(lease->subnet_id_, subnet_->getID());
+    EXPECT_TRUE(subnet_->inRange(lease->addr_));
+    EXPECT_TRUE(subnet_->inPool(Lease::TYPE_V4, lease->addr_));
+    ASSERT_TRUE(lease->client_id_);
+    EXPECT_TRUE(*lease->client_id_ == *clientid_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_TRUE(*lease->hwaddr_ == *hwaddr_);
+
+    // Check the valid lifetime is infinite.
+    uint32_t infinity_lft = Lease::INFINITY_LFT;
+    EXPECT_EQ(infinity_lft, lease->valid_lft_);
+
+    // Check that the lease is indeed in LeaseMgr
+    Lease4Ptr from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
+    ASSERT_TRUE(from_mgr);
+
+    // Now delete it.
+    bool deleted = false;
+    ASSERT_NO_THROW(deleted = LeaseMgrFactory::instance().deleteLease(lease));
+    EXPECT_TRUE(deleted);
+    from_mgr = LeaseMgrFactory::instance().getLease4(lease->addr_);
+    EXPECT_FALSE(from_mgr);
+}
+
+}
similarity index 95%
rename from src/lib/dhcpsrv/tests/pgsql_lease_extended_info_unittest.cc
rename to src/lib/pgsql_lease_backend/tests/pgsql_lease_extended_info_unittest.cc
index bdb6cd8ecb074a5e38938346b5e5497bd7c36a87..a0cd296e22f1bc603207d26e607de4ced471c7db 100644 (file)
@@ -10,7 +10,7 @@
 #include <cc/data.h>
 #include <dhcpsrv/testutils/generic_lease_extended_info_unittest.h>
 #include <pgsql/testutils/pgsql_schema.h>
-#include <dhcpsrv/pgsql_lease_mgr.h>
+#include <pgsql_lease_backend/pgsql_lease_mgr.h>
 
 using namespace isc;
 using namespace isc::asiolink;
@@ -59,11 +59,16 @@ public:
     static void destroySchema() {
         destroyPgSQLSchema();
     }
+
+    /// @brief Initializer.
+    Initializer<PgSqlLeaseMgrInit> init_;
 };
 
 /// @brief Test fixture class for extended info tests.
-class PgSqlExtendedInfoTest :
-    public isc::dhcp::test::GenericExtendedInfoTest<NakedPgSqlLeaseMgr> { };
+class PgSqlExtendedInfoTest : public isc::dhcp::test::GenericExtendedInfoTest<NakedPgSqlLeaseMgr> {
+    /// @brief Initializer.
+    Initializer<PgSqlLeaseMgrInit> init_;
+};
 
 /// @brief Verifies that the lease manager can start.
 TEST_F(PgSqlExtendedInfoTest, startWithoutExtendedTables) {
similarity index 97%
rename from src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc
rename to src/lib/pgsql_lease_backend/tests/pgsql_lease_mgr_unittest.cc
index 4b614c2d45ecf7f3e555704be8130ec1afd201bf..c34c9ef626f82dfb4ee23017262dc7f7b570a47e 100644 (file)
@@ -8,7 +8,7 @@
 
 #include <asiolink/io_address.h>
 #include <dhcpsrv/lease_mgr_factory.h>
-#include <dhcpsrv/pgsql_lease_mgr.h>
+#include <pgsql_lease_backend/pgsql_lease_mgr.h>
 #include <dhcpsrv/testutils/test_utils.h>
 #include <dhcpsrv/testutils/generic_lease_mgr_unittest.h>
 #include <dhcpsrv/testutils/pgsql_generic_backend_unittest.h>
@@ -39,7 +39,6 @@ using namespace std;
 
 namespace {
 
-
 /// @brief Test fixture class for testing PostgreSQL Lease Manager
 ///
 /// Opens the database prior to each test and closes it afterwards.
@@ -106,6 +105,9 @@ public:
         LeaseMgrFactory::create(validPgSQLConnectionString());
         lmptr_ = &(LeaseMgrFactory::instance());
     }
+
+    /// @brief Initializer.
+    Initializer<PgSqlLeaseMgrInit> init_;
 };
 
 /// @brief Check that database can be opened
@@ -115,6 +117,7 @@ public:
 /// PgSqlLeaseMgr test fixture set.  This test checks that the database can be
 /// opened: the fixtures assume that and check basic operations.
 TEST(PgSqlOpenTest, OpenDatabase) {
+    Initializer<PgSqlLeaseMgrInit> init;
     // Explicitly disable Multi-Threading.
     MultiThreadingMgr::instance().setMode(false);
 
@@ -225,6 +228,7 @@ TEST(PgSqlOpenTest, OpenDatabase) {
 
 /// @brief Check that database can be opened with Multi-Threading
 TEST(PgSqlOpenTest, OpenDatabaseMultiThreading) {
+    Initializer<PgSqlLeaseMgrInit> init;
     // Enable Multi-Threading.
     MultiThreadingTest mt(true);
 
@@ -957,6 +961,9 @@ public:
         return (connectionString(PGSQL_VALID_TYPE, INVALID_NAME, VALID_HOST,
                                  VALID_USER, VALID_PASSWORD));
     }
+
+    /// @brief Initializer.
+    Initializer<PgSqlLeaseMgrInit> init_;
 };
 
 /// @brief Verifies that loss of connectivity to PostgreSQL is handled correctly.
@@ -1348,4 +1355,39 @@ TEST_F(PgSqlLeaseMgrTest, bigStats) {
     testBigStats();
 }
 
+/// @brief Test fixture class for testing @ref CfgDbAccessTest using PgSQL
+/// backend.
+class CfgPgSqlDbAccessTest : public ::testing::Test {
+public:
+
+    /// @brief Constructor.
+    CfgPgSqlDbAccessTest() {
+        // Ensure we have the proper schema with no transient data.
+        db::test::createPgSQLSchema();
+    }
+
+    /// @brief Destructor.
+    virtual ~CfgPgSqlDbAccessTest() {
+        // If data wipe enabled, delete transient data otherwise destroy the schema
+        db::test::destroyPgSQLSchema();
+        LeaseMgrFactory::destroy();
+    }
+
+    /// @brief Initializer.
+    Initializer<PgSqlLeaseMgrInit> init_;
+};
+
+// Tests that PostgreSQL lease manager and host data source can be created from a
+// specified configuration.
+TEST_F(CfgPgSqlDbAccessTest, createManagers) {
+    CfgDbAccess cfg;
+    ASSERT_NO_THROW(cfg.setLeaseDbAccessString(db::test::validPgSQLConnectionString()));
+    ASSERT_NO_THROW(cfg.createManagers());
+
+    ASSERT_NO_THROW({
+        LeaseMgr& lease_mgr = LeaseMgrFactory::instance();
+        EXPECT_EQ("postgresql", lease_mgr.getType());
+    });
+}
+
 }  // namespace
diff --git a/src/lib/pgsql_lease_backend/tests/run_unittests.cc b/src/lib/pgsql_lease_backend/tests/run_unittests.cc
new file mode 100644 (file)
index 0000000..63b2d4a
--- /dev/null
@@ -0,0 +1,19 @@
+// Copyright (C) 2024 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 <gtest/gtest.h>
+
+#include <util/unittests/run_all.h>
+#include <log/logger_support.h>
+
+int
+main(int argc, char* argv[]) {
+    ::testing::InitGoogleTest(&argc, argv);
+    isc::log::initLogger();
+    return (isc::util::unittests::run_all());
+}