diff options
Diffstat (limited to 'src')
59 files changed, 1287 insertions, 718 deletions
diff --git a/src/bin/dhcp4/Makefile.am b/src/bin/dhcp4/Makefile.am index f941d99902..218ab5b5dd 100644 --- a/src/bin/dhcp4/Makefile.am +++ b/src/bin/dhcp4/Makefile.am @@ -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 diff --git a/src/bin/dhcp4/dhcp4_srv.cc b/src/bin/dhcp4/dhcp4_srv.cc index f6e734fa34..a4225b0c83 100644 --- a/src/bin/dhcp4/dhcp4_srv.cc +++ b/src/bin/dhcp4/dhcp4_srv.cc @@ -56,15 +56,14 @@ #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> diff --git a/src/bin/dhcp4/json_config_parser.cc b/src/bin/dhcp4/json_config_parser.cc index d22f8028cf..e2de46da74 100644 --- a/src/bin/dhcp4/json_config_parser.cc +++ b/src/bin/dhcp4/json_config_parser.cc @@ -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> @@ -46,6 +47,16 @@ #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. /// diff --git a/src/bin/dhcp4/tests/Makefile.am b/src/bin/dhcp4/tests/Makefile.am index bbd53d9ec9..69cb5a857e 100644 --- a/src/bin/dhcp4/tests/Makefile.am +++ b/src/bin/dhcp4/tests/Makefile.am @@ -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 diff --git a/src/bin/dhcp4/tests/d2_unittest.cc b/src/bin/dhcp4/tests/d2_unittest.cc index c45afa5f01..0a352227f2 100644 --- a/src/bin/dhcp4/tests/d2_unittest.cc +++ b/src/bin/dhcp4/tests/d2_unittest.cc @@ -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 diff --git a/src/bin/dhcp4/tests/fqdn_unittest.cc b/src/bin/dhcp4/tests/fqdn_unittest.cc index edc0b3c445..7cd9333a4c 100644 --- a/src/bin/dhcp4/tests/fqdn_unittest.cc +++ b/src/bin/dhcp4/tests/fqdn_unittest.cc @@ -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) { diff --git a/src/bin/dhcp6/Makefile.am b/src/bin/dhcp6/Makefile.am index 0852a425fb..796f29e080 100644 --- a/src/bin/dhcp6/Makefile.am +++ b/src/bin/dhcp6/Makefile.am @@ -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 diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 750eac9d86..137b908749 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -55,14 +55,14 @@ #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> diff --git a/src/bin/dhcp6/json_config_parser.cc b/src/bin/dhcp6/json_config_parser.cc index f5e283a422..6590e8239e 100644 --- a/src/bin/dhcp6/json_config_parser.cc +++ b/src/bin/dhcp6/json_config_parser.cc @@ -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> @@ -50,6 +51,16 @@ #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. diff --git a/src/bin/dhcp6/tests/Makefile.am b/src/bin/dhcp6/tests/Makefile.am index 795445f50e..7fd8de836c 100644 --- a/src/bin/dhcp6/tests/Makefile.am +++ b/src/bin/dhcp6/tests/Makefile.am @@ -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 diff --git a/src/bin/lfc/Makefile.am b/src/bin/lfc/Makefile.am index 653838fbc6..7f3ae858bd 100644 --- a/src/bin/lfc/Makefile.am +++ b/src/bin/lfc/Makefile.am @@ -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 diff --git a/src/hooks/dhcp/Makefile.am b/src/hooks/dhcp/Makefile.am index 1b77976424..feb1f5cde2 100644 --- a/src/hooks/dhcp/Makefile.am +++ b/src/hooks/dhcp/Makefile.am @@ -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 diff --git a/src/lib/database/database_connection.h b/src/lib/database/database_connection.h index 00dbc03424..0ea887e1d2 100644 --- a/src/lib/database/database_connection.h +++ b/src/lib/database/database_connection.h @@ -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 diff --git a/src/lib/dhcpsrv/host_data_source_factory.cc b/src/lib/dhcpsrv/host_data_source_factory.cc index bb2e388bdd..c97406ed1f 100644 --- a/src/lib/dhcpsrv/host_data_source_factory.cc +++ b/src/lib/dhcpsrv/host_data_source_factory.cc @@ -11,14 +11,6 @@ #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 diff --git a/src/lib/dhcpsrv/lease_mgr_factory.cc b/src/lib/dhcpsrv/lease_mgr_factory.cc index 02050b2ad3..22497f0076 100644 --- a/src/lib/dhcpsrv/lease_mgr_factory.cc +++ b/src/lib/dhcpsrv/lease_mgr_factory.cc @@ -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 diff --git a/src/lib/dhcpsrv/tests/Makefile.am b/src/lib/dhcpsrv/tests/Makefile.am index ac92958441..ca021a1105 100644 --- a/src/lib/dhcpsrv/tests/Makefile.am +++ b/src/lib/dhcpsrv/tests/Makefile.am @@ -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 diff --git a/src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc index 906c3a9952..a9ec22fb8b 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc +++ b/src/lib/dhcpsrv/tests/alloc_engine4_unittest.cc @@ -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) { diff --git a/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc index 33c7a39aa9..8a61dbba58 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc +++ b/src/lib/dhcpsrv/tests/alloc_engine6_unittest.cc @@ -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> diff --git a/src/lib/dhcpsrv/tests/alloc_engine_expiration_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine_expiration_unittest.cc index 0b7fb1dbe6..2477d5d54c 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine_expiration_unittest.cc +++ b/src/lib/dhcpsrv/tests/alloc_engine_expiration_unittest.cc @@ -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> diff --git a/src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc index 99ea60503c..4bbb320a67 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc +++ b/src/lib/dhcpsrv/tests/alloc_engine_hooks_unittest.cc @@ -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> diff --git a/src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc b/src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc index 738ddfc98c..c97be45d89 100644 --- a/src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc +++ b/src/lib/dhcpsrv/tests/cfg_db_access_unittest.cc @@ -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 diff --git a/src/lib/dhcpsrv/tests/flq_allocator_unittest.cc b/src/lib/dhcpsrv/tests/flq_allocator_unittest.cc index eb9a368e8c..10f5aff10a 100644 --- a/src/lib/dhcpsrv/tests/flq_allocator_unittest.cc +++ b/src/lib/dhcpsrv/tests/flq_allocator_unittest.cc @@ -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> diff --git a/src/lib/dhcpsrv/tests/iterative_allocator_unittest.cc b/src/lib/dhcpsrv/tests/iterative_allocator_unittest.cc index 649a9994b4..85525a1fc1 100644 --- a/src/lib/dhcpsrv/tests/iterative_allocator_unittest.cc +++ b/src/lib/dhcpsrv/tests/iterative_allocator_unittest.cc @@ -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> diff --git a/src/lib/dhcpsrv/tests/random_allocator_unittest.cc b/src/lib/dhcpsrv/tests/random_allocator_unittest.cc index caf27f4745..283b8de878 100644 --- a/src/lib/dhcpsrv/tests/random_allocator_unittest.cc +++ b/src/lib/dhcpsrv/tests/random_allocator_unittest.cc @@ -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> diff --git a/src/lib/dhcpsrv/testutils/Makefile.am b/src/lib/dhcpsrv/testutils/Makefile.am index 471d61deeb..81d350175f 100644 --- a/src/lib/dhcpsrv/testutils/Makefile.am +++ b/src/lib/dhcpsrv/testutils/Makefile.am @@ -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 diff --git a/src/lib/dhcpsrv/tests/alloc_engine_utils.cc b/src/lib/dhcpsrv/testutils/alloc_engine_utils.cc index cab3c9386c..21ef2ba6b7 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine_utils.cc +++ b/src/lib/dhcpsrv/testutils/alloc_engine_utils.cc @@ -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> diff --git a/src/lib/dhcpsrv/tests/alloc_engine_utils.h b/src/lib/dhcpsrv/testutils/alloc_engine_utils.h index 756b92c7e5..756b92c7e5 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine_utils.h +++ b/src/lib/dhcpsrv/testutils/alloc_engine_utils.h diff --git a/src/lib/mysql_host_backend/Makefile.am b/src/lib/mysql_host_backend/Makefile.am index 2469a386b3..18eecd2e63 100644 --- a/src/lib/mysql_host_backend/Makefile.am +++ b/src/lib/mysql_host_backend/Makefile.am @@ -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) diff --git a/src/lib/mysql_host_backend/mysql_host_data_source.cc b/src/lib/mysql_host_backend/mysql_host_data_source.cc index 87559d0a5c..b9cd69d41d 100644 --- a/src/lib/mysql_host_backend/mysql_host_data_source.cc +++ b/src/lib/mysql_host_backend/mysql_host_data_source.cc @@ -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> diff --git a/src/lib/mysql_host_backend/mysql_host_data_source.h b/src/lib/mysql_host_backend/mysql_host_data_source.h index 10643d1183..390eb9cb18 100644 --- a/src/lib/mysql_host_backend/mysql_host_data_source.h +++ b/src/lib/mysql_host_backend/mysql_host_data_source.h @@ -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 index 0000000000..8b96f60333 --- /dev/null +++ b/src/lib/mysql_host_backend/tests/.gitignore @@ -0,0 +1 @@ +libmysql_host_backend_unittests diff --git a/src/lib/mysql_host_backend/tests/Makefile.am b/src/lib/mysql_host_backend/tests/Makefile.am index e69de29bb2..83f5dd87d8 100644 --- a/src/lib/mysql_host_backend/tests/Makefile.am +++ b/src/lib/mysql_host_backend/tests/Makefile.am @@ -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) diff --git a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc b/src/lib/mysql_host_backend/tests/mysql_host_data_source_unittest.cc index 8b21b09161..d1a8dc04b6 100644 --- a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc +++ b/src/lib/mysql_host_backend/tests/mysql_host_data_source_unittest.cc @@ -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 index 0000000000..63b2d4a794 --- /dev/null +++ b/src/lib/mysql_host_backend/tests/run_unittests.cc @@ -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()); +} diff --git a/src/lib/mysql_lease_backend/Makefile.am b/src/lib/mysql_lease_backend/Makefile.am index 85d94126ec..0a1ca53df3 100644 --- a/src/lib/mysql_lease_backend/Makefile.am +++ b/src/lib/mysql_lease_backend/Makefile.am @@ -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) diff --git a/src/lib/mysql_lease_backend/mysql_lease_mgr.cc b/src/lib/mysql_lease_backend/mysql_lease_mgr.cc index b403d66ae1..f16b8865b1 100644 --- a/src/lib/mysql_lease_backend/mysql_lease_mgr.cc +++ b/src/lib/mysql_lease_backend/mysql_lease_mgr.cc @@ -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> diff --git a/src/lib/mysql_lease_backend/mysql_lease_mgr.h b/src/lib/mysql_lease_backend/mysql_lease_mgr.h index af1c964eaf..cde5f21198 100644 --- a/src/lib/mysql_lease_backend/mysql_lease_mgr.h +++ b/src/lib/mysql_lease_backend/mysql_lease_mgr.h @@ -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 index 0000000000..b48dc34053 --- /dev/null +++ b/src/lib/mysql_lease_backend/tests/.gitignore @@ -0,0 +1 @@ +libmysql_lease_backend_unittests diff --git a/src/lib/mysql_lease_backend/tests/Makefile.am b/src/lib/mysql_lease_backend/tests/Makefile.am index e69de29bb2..e94db7edd2 100644 --- a/src/lib/mysql_lease_backend/tests/Makefile.am +++ b/src/lib/mysql_lease_backend/tests/Makefile.am @@ -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 index 0000000000..2731d55f99 --- /dev/null +++ b/src/lib/mysql_lease_backend/tests/mysql_bootp_unittest.cc @@ -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); +} + +} diff --git a/src/lib/dhcpsrv/tests/mysql_lease_extended_info_unittest.cc b/src/lib/mysql_lease_backend/tests/mysql_lease_extended_info_unittest.cc index ed491ccb59..458bc9d89d 100644 --- a/src/lib/dhcpsrv/tests/mysql_lease_extended_info_unittest.cc +++ b/src/lib/mysql_lease_backend/tests/mysql_lease_extended_info_unittest.cc @@ -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) { diff --git a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc b/src/lib/mysql_lease_backend/tests/mysql_lease_mgr_unittest.cc index 4132dd9af3..7a372b173e 100644 --- a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc +++ b/src/lib/mysql_lease_backend/tests/mysql_lease_mgr_unittest.cc @@ -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 index 0000000000..63b2d4a794 --- /dev/null +++ b/src/lib/mysql_lease_backend/tests/run_unittests.cc @@ -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()); +} diff --git a/src/lib/pgsql_host_backend/Makefile.am b/src/lib/pgsql_host_backend/Makefile.am index ac788ea45b..a181c3dc15 100644 --- a/src/lib/pgsql_host_backend/Makefile.am +++ b/src/lib/pgsql_host_backend/Makefile.am @@ -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) diff --git a/src/lib/pgsql_host_backend/pgsql_host_data_source.cc b/src/lib/pgsql_host_backend/pgsql_host_data_source.cc index 249e549165..d4e12273ea 100644 --- a/src/lib/pgsql_host_backend/pgsql_host_data_source.cc +++ b/src/lib/pgsql_host_backend/pgsql_host_data_source.cc @@ -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> diff --git a/src/lib/pgsql_host_backend/pgsql_host_data_source.h b/src/lib/pgsql_host_backend/pgsql_host_data_source.h index 61043c575a..83e40a5c97 100644 --- a/src/lib/pgsql_host_backend/pgsql_host_data_source.h +++ b/src/lib/pgsql_host_backend/pgsql_host_data_source.h @@ -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 index 0000000000..efb5bce039 --- /dev/null +++ b/src/lib/pgsql_host_backend/tests/.gitignore @@ -0,0 +1 @@ +libpgsql_host_backend_unittests diff --git a/src/lib/pgsql_host_backend/tests/Makefile.am b/src/lib/pgsql_host_backend/tests/Makefile.am index e69de29bb2..2fd06c8a5f 100644 --- a/src/lib/pgsql_host_backend/tests/Makefile.am +++ b/src/lib/pgsql_host_backend/tests/Makefile.am @@ -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 diff --git a/src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc b/src/lib/pgsql_host_backend/tests/pgsql_host_data_source_unittest.cc index 63c48e7fc1..015e594845 100644 --- a/src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc +++ b/src/lib/pgsql_host_backend/tests/pgsql_host_data_source_unittest.cc @@ -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 index 0000000000..63b2d4a794 --- /dev/null +++ b/src/lib/pgsql_host_backend/tests/run_unittests.cc @@ -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()); +} diff --git a/src/lib/pgsql_lease_backend/Makefile.am b/src/lib/pgsql_lease_backend/Makefile.am index 87b33d9a54..8e7eefc8b0 100644 --- a/src/lib/pgsql_lease_backend/Makefile.am +++ b/src/lib/pgsql_lease_backend/Makefile.am @@ -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) diff --git a/src/lib/pgsql_lease_backend/pgsql_lease_mgr.cc b/src/lib/pgsql_lease_backend/pgsql_lease_mgr.cc index c860ebbf6b..806e2d4d0d 100644 --- a/src/lib/pgsql_lease_backend/pgsql_lease_mgr.cc +++ b/src/lib/pgsql_lease_backend/pgsql_lease_mgr.cc @@ -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> diff --git a/src/lib/pgsql_lease_backend/pgsql_lease_mgr.h b/src/lib/pgsql_lease_backend/pgsql_lease_mgr.h index d6bc94a212..b6fd5353f9 100644 --- a/src/lib/pgsql_lease_backend/pgsql_lease_mgr.h +++ b/src/lib/pgsql_lease_backend/pgsql_lease_mgr.h @@ -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 index 0000000000..01778b1368 --- /dev/null +++ b/src/lib/pgsql_lease_backend/tests/.gitignore @@ -0,0 +1 @@ +libpgsql_lease_backend_unittests diff --git a/src/lib/pgsql_lease_backend/tests/Makefile.am b/src/lib/pgsql_lease_backend/tests/Makefile.am index e69de29bb2..b49947d7b5 100644 --- a/src/lib/pgsql_lease_backend/tests/Makefile.am +++ b/src/lib/pgsql_lease_backend/tests/Makefile.am @@ -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 index 0000000000..f80324e6e5 --- /dev/null +++ b/src/lib/pgsql_lease_backend/tests/pgsql_bootp_unittest.cc @@ -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); +} + +} diff --git a/src/lib/dhcpsrv/tests/pgsql_lease_extended_info_unittest.cc b/src/lib/pgsql_lease_backend/tests/pgsql_lease_extended_info_unittest.cc index bdb6cd8ecb..a0cd296e22 100644 --- a/src/lib/dhcpsrv/tests/pgsql_lease_extended_info_unittest.cc +++ b/src/lib/pgsql_lease_backend/tests/pgsql_lease_extended_info_unittest.cc @@ -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) { diff --git a/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc b/src/lib/pgsql_lease_backend/tests/pgsql_lease_mgr_unittest.cc index 4b614c2d45..c34c9ef626 100644 --- a/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc +++ b/src/lib/pgsql_lease_backend/tests/pgsql_lease_mgr_unittest.cc @@ -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 index 0000000000..63b2d4a794 --- /dev/null +++ b/src/lib/pgsql_lease_backend/tests/run_unittests.cc @@ -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()); +} |