diff options
Diffstat (limited to 'src/lib/dhcpsrv/testutils/generic_host_data_source_unittest.h')
-rw-r--r-- | src/lib/dhcpsrv/testutils/generic_host_data_source_unittest.h | 937 |
1 files changed, 937 insertions, 0 deletions
diff --git a/src/lib/dhcpsrv/testutils/generic_host_data_source_unittest.h b/src/lib/dhcpsrv/testutils/generic_host_data_source_unittest.h new file mode 100644 index 0000000..0eb1ddf --- /dev/null +++ b/src/lib/dhcpsrv/testutils/generic_host_data_source_unittest.h @@ -0,0 +1,937 @@ +// Copyright (C) 2015-2022 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/. + +#ifndef GENERIC_HOST_DATA_SOURCE_UNITTEST_H +#define GENERIC_HOST_DATA_SOURCE_UNITTEST_H + +#include <asiolink/io_address.h> +#include <util/reconnect_ctl.h> +#include <dhcpsrv/base_host_data_source.h> +#include <dhcpsrv/cfgmgr.h> +#include <dhcpsrv/host.h> +#include <dhcpsrv/host_mgr.h> +#include <dhcpsrv/testutils/generic_backend_unittest.h> +#include <dhcp/classify.h> +#include <dhcp/option.h> +#include <boost/algorithm/string/join.hpp> +#include <boost/shared_ptr.hpp> +#include <gtest/gtest.h> +#include <sstream> +#include <vector> + +namespace isc { +namespace dhcp { +namespace test { + +/// @brief Test Fixture class with utility functions for HostDataSource backends +/// +/// It contains utility functions for test purposes. +/// All concrete HostDataSource test classes should be derived from it. +class GenericHostDataSourceTest : public GenericBackendTest { +public: + + /// @brief Universe (V4 or V6). + enum Universe { + V4, + V6 + }; + + /// @brief Options to be inserted into a host. + /// + /// Parameter of this type is passed to the @ref addTestOptions to + /// control which option types should be inserted into a host. + enum AddedOptions { + DHCP4_ONLY, + DHCP6_ONLY, + DHCP4_AND_DHCP6 + }; + + /// @brief Default constructor. + GenericHostDataSourceTest(); + + /// @brief Virtual destructor. + virtual ~GenericHostDataSourceTest(); + + /// @brief Used to sort a host collection by IPv4 subnet id. + /// @param host1 first host to be compared + /// @param host2 second host to be compared + /// @result return true if host1's subnet id is smaller than host2's + /// subnet id + static bool compareHostsForSort4(const ConstHostPtr& host1, + const ConstHostPtr& host2); + + /// @brief Used to sort a host collection by IPv6 subnet id. + /// @param host1 first host to be compared + /// @param host2 second host to be compared + /// @result return true if host1's subnet id is smaller than host2's + /// subnet id + static bool compareHostsForSort6(const ConstHostPtr& host1, + const ConstHostPtr& host2); + + /// @brief Used to sort a host collection by host identifier. + /// @param host1 first host to be compared + /// @param host2 second host to be compared + /// @result return true if host1's identifier is smaller than host2's + /// identifier + static bool compareHostsIdentifier(const ConstHostPtr& host1, + const ConstHostPtr& host2); + + /// @brief Returns number of entries in the v4 options table. + /// + /// This utility method is expected to be implemented by specific backends. + /// The code here is just a boilerplate for backends that do not store + /// host options in a table. + /// + /// @param number of existing entries in options table + virtual int countDBOptions4() { + return (-1); + } + + /// @brief Returns number of entries in the v6 options table. + /// + /// This utility method is expected to be implemented by specific backends. + /// The code here is just a boilerplate for backends that do not store + /// host options in a table. + /// + /// @param number of existing entries in options table + virtual int countDBOptions6() { + return (-1); + } + + /// @brief Returns number of entries in the v6 reservations table. + /// + /// This utility method is expected to be implemented by specific backends. + /// The code here is just a boilerplate for backends that do not store + /// v6 reservations in a table. + /// + /// @param number of existing entries in v6_reservations table + virtual int countDBReservations6() { + return (-1); + } + + /// @brief Adds multiple options into the host. + /// + /// This method creates the following options into the host object: + /// - DHCPv4 boot file name option, + /// - DHCPv4 default ip ttl option, + /// - DHCPv4 option 1 within vendor-encapsulated-options space, + /// - DHCPv4 option 254 with a single IPv4 address, + /// - DHCPv4 option 1 within isc option space, + /// - DHCPv6 boot file url option, + /// - DHCPv6 information refresh time option, + /// - DHCPv6 vendor option with vendor id 2495, + /// - DHCPv6 option 1024, with a single IPv6 address, + /// - DHCPv6 empty option 1, within isc2 option space, + /// - DHCPv6 option 2, within isc2 option space with 3 IPv6 addresses, + /// + /// This method also creates option definitions for the non-standard + /// options and registers them in the LibDHCP as runtime option + /// definitions. + /// + /// @param host Host object into which options should be added. + /// @param formatted A boolean value selecting if the formatted option + /// value should be used (if true), or binary value (if false). + /// @param added_options Controls which options should be inserted into + /// a host: DHCPv4, DHCPv6 options or both. + /// @param user_context Optional user context + void addTestOptions(const HostPtr& host, const bool formatted, + const AddedOptions& added_options, + isc::data::ConstElementPtr user_context = + isc::data::ConstElementPtr()) const; + + /// @brief Pointer to the host data source + HostDataSourcePtr hdsptr_; + + /// @brief Test that backend can be started in read-only mode. + /// + /// Some backends can operate when the database is read only, e.g. + /// host reservation tables are read only, or the database user has + /// read only privileges on the entire database. In such cases, the + /// Kea server administrator can specify in the backend configuration + /// that the database should be opened in read only mode, i.e. + /// INSERT, UPDATE, DELETE statements can't be issued. If any of the + /// functions updating the database is called for the backend, the + /// error is reported. The database running in read only mode can + /// be merely used to retrieve existing host reservations from the + /// database. This test verifies that this is the case. + /// + /// @param valid_db_type Parameter specifying type of backend to + /// be used, e.g. type=mysql. + void testReadOnlyDatabase(const char* valid_db_type); + + /// @brief Test that checks that simple host with IPv4 reservation + /// can be inserted and later retrieved. + /// + /// Uses gtest macros to report failures. + /// @param id Identifier type. + void testBasic4(const Host::IdentifierType& id); + + /// @brief Test that verifies that an IPv4 host reservation with + /// options can have the global subnet id value. + /// + /// Uses gtest macros to report failures. + void testGlobalSubnetId4(); + + /// @brief Test that verifies that an IPv6 host reservation with + /// options can have the global subnet id value. + /// + /// Uses gtest macros to report failures. + void testGlobalSubnetId6(); + + /// @brief Test that verifies that an IPv4 host reservation with + /// options can have a max value for dhcp4_subnet id + /// + /// Uses gtest macros to report failures. + void testMaxSubnetId4(); + + /// @brief Test that Verifies that an IPv6 host reservation with + /// options can have a max value for dhcp6_subnet id + /// + /// Uses gtest macros to report failures. + void testMaxSubnetId6(); + + /// @brief Test that Verifies that IPv4 host reservations in the + /// same subnet can be retrieved properly. + /// + /// Uses gtest macros to report failures. + void testGetAll4(); + + /// @brief Test that Verifies that IPv6 host reservations in the + /// same subnet can be retrieved properly. + /// + /// Uses gtest macros to report failures. + void testGetAll6(); + + /// @brief Test that Verifies that host reservations with the same + /// hostname can be retrieved properly. + /// + /// Uses gtest macros to report failures. + void testGetAllbyHostname(); + + /// @brief Test that Verifies that IPv4 host reservations with the same + /// hostname and in the same subnet can be retrieved properly. + /// + /// Uses gtest macros to report failures. + void testGetAllbyHostnameSubnet4(); + + /// @brief Test that Verifies that IPv6 host reservations with the same + /// hostname and in the same subnet can be retrieved properly. + /// + /// Uses gtest macros to report failures. + void testGetAllbyHostnameSubnet6(); + + /// @brief Test that Verifies that pages of host reservations in the + /// same subnet can be retrieved properly. + /// + /// Uses gtest macros to report failures. + void testGetPage4(); + + /// @brief Test that Verifies that pages of host reservations in the + /// same subnet can be retrieved properly. + /// + /// Uses gtest macros to report failures. + void testGetPage6(); + + /// @brief Test that Verifies that pages of complex host reservations + /// are not truncated, i.e. the limit applies on the number of hosts + /// and not on the number of rows. + /// + /// Uses gtest macros to report failures. + /// @param id Identifier type (hwaddr or duid). + void testGetPageLimit4(const Host::IdentifierType& id); + + /// @brief Test that Verifies that pages of complex host reservations + /// are not truncated, i.e. the limit applies on the number of hosts + /// and not on the number of rows. + /// + /// Uses gtest macros to report failures. + /// @param id Identifier type (hwaddr or duid). + void testGetPageLimit6(const Host::IdentifierType& id); + + /// @brief Test that Verifies that pages of host reservations in the + /// same subnet can be retrieved properly even with multiple subnets. + /// + /// Uses gtest macros to report failures. + void testGetPage4Subnets(); + + /// @brief Test that Verifies that pages of host reservations in the + /// same subnet can be retrieved properly even with multiple subnets. + /// + /// Uses gtest macros to report failures. + void testGetPage6Subnets(); + + /// @brief Test that Verifies that pages of all host reservations + /// can be retrieved properly. + /// + /// Uses gtest macros to report failures. + void testGetPage4All(); + + /// @brief Test that Verifies that pages of all host reservations + /// can be retrieved properly. + /// + /// Uses gtest macros to report failures. + void testGetPage6All(); + + /// @brief Test inserts several hosts with unique IPv4 address and + /// checks that they can be retrieved properly. + /// + /// Uses gtest macros to report failures. + /// @param id Identifier type. + void testGetByIPv4(const Host::IdentifierType& id); + + /// @brief Test that hosts can be retrieved by host identifier. + /// + /// Uses gtest macros to report failures. + void testGet4ByIdentifier(const Host::IdentifierType& identifier_type); + + /// @brief Test that clients with stored HW address can't be retrieved + /// by DUID with the same value. + /// + /// Test procedure: add host reservation with hardware address X, try to retrieve + /// host by client-identifier X, verify that the reservation is not returned. + /// + /// Uses gtest macros to report failures. + void testHWAddrNotClientId(); + + /// @brief Test that clients with stored DUID can't be retrieved + /// by HW address of the same value. + /// + /// Test procedure: add host reservation with client identifier X, try to + /// retrieve host by hardware address X, verify that the reservation is not + /// returned. + /// + /// Uses gtest macros to report failures. + void testClientIdNotHWAddr(); + + /// @brief Test adds specified number of hosts with unique hostnames, then + /// retrieves them and checks that the hostnames are set properly. + /// + /// Uses gtest macros to report failures. + /// + /// @param name hostname to be used (if n>1, numbers will be appended) + /// @param num number of hostnames to be added. + void testHostname(std::string name, int num); + + /// @brief Test insert and retrieve a host with user context. + /// + /// Uses gtest macros to report failures. + /// + /// @param user_context The user context. + void testUserContext(isc::data::ConstElementPtr user_context); + + /// @brief Test inserts multiple reservations for the same host for different + /// subnets and check that they can be retrieved properly. + /// + /// Uses gtest macros to report failures. + /// + /// @param subnets number of subnets to test + /// @param id Host identifier type. + void testMultipleSubnets(int subnets, const Host::IdentifierType& id); + + /// @brief Test inserts several hosts with unique IPv6 addresses and + /// checks that they can be retrieved properly. + /// + /// Uses gtest macros to report failures. + /// @param id type of the identifier to be used (IDENT_HWADDR or IDENT_DUID) + /// @param prefix true - reserve IPv6 prefix, false - reserve IPv6 address + void testGetByIPv6(Host::IdentifierType id, bool prefix); + + /// @brief Test inserts several hosts with unique prefixes and checks + /// that the can be retrieved by subnet id and prefix value. + void testGetBySubnetIPv6(); + + /// @brief Test that hosts can be retrieved by hardware address. + /// + /// Uses gtest macros to report failures. + void testGet6ByHWAddr(); + + /// @brief Test that hosts can be retrieved by client-id + /// + /// Uses gtest macros to report failures. + void testGet6ByClientId(); + + /// @brief Test verifies if a host reservation can be stored with both + /// IPv6 address and prefix. + /// Uses gtest macros to report failures. + void testAddr6AndPrefix(); + + /// @brief Tests if host with multiple IPv6 reservations can be added and then + /// retrieved correctly. + void testMultipleReservations(); + + /// @brief Tests if compareIPv6Reservations() method treats same pool of + /// reservations but added in different order as equal. + void testMultipleReservationsDifferentOrder(); + + /// @brief Test if host reservations made for different IPv6 subnets + /// are handled correctly. + /// + /// Uses gtest macros to report failures. + /// + /// @param subnets number of subnets to test + /// @param id identifier type (IDENT_HWADDR or IDENT_DUID) + void testSubnetId6(int subnets, Host::IdentifierType id); + + /// @brief Test if the duplicate host with same DUID can't be inserted. + /// + /// Uses gtest macros to report failures. + void testAddDuplicate6WithSameDUID(); + + /// @brief Test if the duplicate host with same HWAddr can't be inserted. + /// + /// Uses gtest macros to report failures. + void testAddDuplicate6WithSameHWAddr(); + + /// @brief Test that duplicate IPv6 reservation can't be inserted. + /// + /// Uses gtest macros to report failures. + void testAddDuplicateIPv6(); + + /// @brief Test if the reservation for the same IPv6 address can be + /// inserted when allowed by the configuration. + /// + /// Uses gtest macros to report failures. + void testAllowDuplicateIPv6(); + + /// @brief Test that duplicate IPv4 reservation can't be inserted. + /// + /// Uses gtest macros to report failures. + void testAddDuplicateIPv4(); + + /// @brief Test if the reservation for the same IPv4 address can be + /// inserted when allowed by the configuration. + /// + /// Uses gtest macros to report failures. + void testAllowDuplicateIPv4(); + + /// @brief Test that the backend does not support a mode in which multiple + /// host reservations for the same IP address can be created. + void testDisallowDuplicateIP(); + + /// @brief Test that DHCPv4 options can be inserted and retrieved from + /// the database. + /// + /// Uses gtest macros to report failures. + /// + /// @param formatted Boolean value indicating if the option values + /// should be stored in the textual format in the database. + /// @param user_context Optional user context. + void testOptionsReservations4(const bool formatted, + isc::data::ConstElementPtr user_context = + isc::data::ConstElementPtr()); + + /// @brief Test that DHCPv6 options can be inserted and retrieved from + /// the database. + /// + /// Uses gtest macros to report failures. + /// + /// @param formatted Boolean value indicating if the option values + /// should be stored in the textual format in the database. + /// @param user_context Optional user context. + void testOptionsReservations6(const bool formatted, + isc::data::ConstElementPtr user_context = + isc::data::ConstElementPtr()); + + /// @brief Test that DHCPv4 and DHCPv6 options can be inserted and retrieved + /// with a single query to the database. + /// + /// Uses gtest macros to report failures. + /// + /// @param formatted Boolean value indicating if the option values + /// should be stored in the textual format in the database. + void testOptionsReservations46(const bool formatted); + + /// @brief Test that multiple client classes for IPv4 can be inserted and + /// retrieved for a given host reservation. + /// + /// Uses gtest macros to report failures. + /// + void testMultipleClientClasses4(); + + /// @brief Test that multiple client classes for IPv6 can be inserted and + /// retrieved for a given host reservation. + /// + /// Uses gtest macros to report failures. + /// + void testMultipleClientClasses6(); + + /// @brief Test that multiple client classes for both IPv4 and IPv6 can + /// be inserted and retrieved for a given host reservation. + /// + /// Uses gtest macros to report failures. + /// + void testMultipleClientClassesBoth(); + + /// @brief Test that siaddr, sname, file fields can be retrieved + /// from a database for a host. + /// + /// Uses gtest macros to report failures. + void testMessageFields4(); + + /// @brief Stress test on adding and retrieving hosts + /// + /// Rather than checking for correctness, this test gives interpretable + /// performance results. + /// + /// @param n_of_hosts number of hosts to insert into and retrieve from the + /// database + void stressTest(uint32_t n_of_hosts); + /// @brief Tests that delete(subnet-id, addr4) call works. + /// + /// Uses gtest macros to report failures. + void testDeleteByAddr4(); + + /// @brief Tests that delete(subnet4-id, identifier-type, identifier) works. + /// + /// Uses gtest macros to report failures. + void testDeleteById4(); + + /// @brief Tests that delete(subnet4-id, id-type, id) also deletes options. + void testDeleteById4Options(); + + /// @brief Tests that delete(subnet6-id, identifier-type, identifier) works. + /// + /// Uses gtest macros to report failures. + void testDeleteById6(); + + /// @brief Tests that delete(subnet6-id, id-type, id) also deletes options. + /// + /// Uses gtest macros to report failures. + void testDeleteById6Options(); + + /// @brief Tests that multiple reservations without IPv4 addresses can be + /// specified within a subnet. + /// + /// Uses gtest macros to report failures. + void testMultipleHostsNoAddress4(); + + /// @brief Tests that multiple hosts can be specified within an IPv6 subnet. + /// + /// Uses gtest macros to report failures. + void testMultipleHosts6(); + + /// @brief Returns DUID with identical content as specified HW address + /// + /// This method does not have any sense in real life and is only useful + /// in testing corner cases in the database backends (e.g. whether the DB + /// is able to tell the difference between hwaddr and duid) + /// + /// @param hwaddr hardware address to be copied + /// @return duid with the same value as specified HW address + DuidPtr HWAddrToDuid(const HWAddrPtr& hwaddr); + + /// @brief Returns HW address with identical content as specified DUID + /// + /// This method does not have any sense in real life and is only useful + /// in testing corner cases in the database backends (e.g. whether the DB + /// is able to tell the difference between hwaddr and duid) + /// + /// @param duid DUID to be copied + /// @return HW address with the same value as specified DUID + HWAddrPtr DuidToHWAddr(const DuidPtr& duid); + +}; + +class HostMgrDbLostCallbackTest : public ::testing::Test { +public: + HostMgrDbLostCallbackTest() + : db_lost_callback_called_(0), db_recovered_callback_called_(0), + db_failed_callback_called_(0), + io_service_(boost::make_shared<isc::asiolink::IOService>()) { + isc::db::DatabaseConnection::db_lost_callback_ = 0; + isc::db::DatabaseConnection::db_recovered_callback_ = 0; + isc::db::DatabaseConnection::db_failed_callback_ = 0; + isc::dhcp::HostMgr::setIOService(io_service_); + isc::dhcp::TimerMgr::instance()->setIOService(io_service_); + isc::dhcp::CfgMgr::instance().clear(); + } + + virtual ~HostMgrDbLostCallbackTest() { + isc::db::DatabaseConnection::db_lost_callback_ = 0; + isc::db::DatabaseConnection::db_recovered_callback_ = 0; + isc::db::DatabaseConnection::db_failed_callback_ = 0; + isc::dhcp::HostMgr::setIOService(isc::asiolink::IOServicePtr()); + isc::dhcp::TimerMgr::instance()->unregisterTimers(); + isc::dhcp::CfgMgr::instance().clear(); + } + + /// @brief Prepares the class for a test. + /// + /// Invoked by gtest prior test entry, we create the + /// appropriate schema and create a basic host manager to + /// wipe out any prior instance + virtual void SetUp() { + // Ensure we have the proper schema with no transient data. + createSchema(); + // Wipe out any pre-existing mgr + isc::dhcp::HostMgr::create(); + isc::dhcp::CfgMgr::instance().clear(); + } + + /// @brief Pre-text exit clean up + /// + /// Invoked by gtest upon test exit, we destroy the schema + /// we created. + virtual void TearDown() { + // If data wipe enabled, delete transient data otherwise destroy the schema + destroySchema(); + isc::dhcp::CfgMgr::instance().clear(); + } + + /// @brief Abstract method for destroying the back end specific schema + virtual void destroySchema() = 0; + + /// @brief Abstract method for creating the back end specific schema + virtual void createSchema() = 0; + + /// @brief Abstract method which returns the back end specific connection + /// string + virtual std::string validConnectString() = 0; + + /// @brief Abstract method which returns invalid back end specific connection + /// string + virtual std::string invalidConnectString() = 0; + + /// @brief Verifies open failures do NOT invoke db lost callback + /// + /// The db lost callback should only be invoked after successfully + /// opening the DB and then subsequently losing it. Failing to + /// open should be handled directly by the application layer. + void testNoCallbackOnOpenFailure(); + + /// @brief Verifies the host manager's behavior if DB connection is lost + /// + /// This function creates a host manager with a back end that supports + /// connectivity lost callback (currently only MySQL and PostgreSQL). It + /// verifies connectivity by issuing a known valid query. Next it simulates + /// connectivity lost by identifying and closing the socket connection to + /// the CB backend. It then reissues the query and verifies that: + /// -# The Query throws DbOperationError (rather than exiting) + /// -# The registered DbLostCallback was invoked + /// -# The registered DbRecoveredCallback was invoked + void testDbLostAndRecoveredCallback(); + + /// @brief Verifies the host manager's behavior if DB connection is lost + /// + /// This function creates a host manager with a back end that supports + /// connectivity lost callback (currently only MySQL and PostgreSQL). It + /// verifies connectivity by issuing a known valid query. Next it simulates + /// connectivity lost by identifying and closing the socket connection to + /// the CB backend. It then reissues the query and verifies that: + /// -# The Query throws DbOperationError (rather than exiting) + /// -# The registered DbLostCallback was invoked + /// -# The registered DbFailedCallback was invoked + void testDbLostAndFailedCallback(); + + /// @brief Verifies the host manager's behavior if DB connection is lost + /// + /// This function creates a host manager with a back end that supports + /// connectivity lost callback (currently only MySQL and PostgreSQL). It + /// verifies connectivity by issuing a known valid query. Next it simulates + /// connectivity lost by identifying and closing the socket connection to + /// the CB backend. It then reissues the query and verifies that: + /// -# The Query throws DbOperationError (rather than exiting) + /// -# The registered DbLostCallback was invoked + /// -# The registered DbRecoveredCallback was invoked after two reconnect + /// attempts (once failing and second triggered by timer) + void testDbLostAndRecoveredAfterTimeoutCallback(); + + /// @brief Verifies the host manager's behavior if DB connection is lost + /// + /// This function creates a host manager with a back end that supports + /// connectivity lost callback (currently only MySQL and PostgreSQL). It + /// verifies connectivity by issuing a known valid query. Next it simulates + /// connectivity lost by identifying and closing the socket connection to + /// the CB backend. It then reissues the query and verifies that: + /// -# The Query throws DbOperationError (rather than exiting) + /// -# The registered DbLostCallback was invoked + /// -# The registered DbFailedCallback was invoked after two reconnect + /// attempts (once failing and second triggered by timer) + void testDbLostAndFailedAfterTimeoutCallback(); + + /// @brief Callback function registered with the host manager + bool db_lost_callback(util::ReconnectCtlPtr /* not_used */) { + return (++db_lost_callback_called_); + } + + /// @brief Flag used to detect calls to db_lost_callback function + uint32_t db_lost_callback_called_; + + /// @brief Callback function registered with the host manager + bool db_recovered_callback(util::ReconnectCtlPtr /* not_used */) { + return (++db_recovered_callback_called_); + } + + /// @brief Flag used to detect calls to db_recovered_callback function + uint32_t db_recovered_callback_called_; + + /// @brief Callback function registered with the host manager + bool db_failed_callback(util::ReconnectCtlPtr /* not_used */) { + return (++db_failed_callback_called_); + } + + /// @brief Flag used to detect calls to db_failed_callback function + uint32_t db_failed_callback_called_; + + /// The IOService object, used for all ASIO operations. + isc::asiolink::IOServicePtr io_service_; +}; + +/// @brief Test fixture class for @c HostMgr class. +class HostMgrTest : public ::testing::Test { +public: + + /// @brief Constructor + HostMgrTest() = default; + + /// @brief Destructor + virtual ~HostMgrTest() = default; + +protected: + + /// @brief Prepares the class for a test. + /// + /// This method crates a handful of unique HW address and DUID objects + /// for use in unit tests. These objects are held in the @c hwaddrs_ and + /// @c duids_ members respectively. + /// + /// This method also resets the @c CfgMgr configuration and re-creates + /// the @c HostMgr object. + virtual void SetUp(); + + /// @brief Convenience method returning a pointer to the @c CfgHosts object + /// in the @c CfgMgr. + CfgHostsPtr getCfgHosts() const; + + /// @brief Inserts IPv4 reservation into the host data source. + /// + /// @param data_source Reference to the data source to which the reservation + /// should be inserted. + /// @param hwaddr Pointer to the hardware address to be associated with the + /// reservation. + /// @param subnet_id IPv4 subnet id. + /// @param address IPv4 address to be reserved. + void addHost4(BaseHostDataSource& data_source, + const HWAddrPtr& hwaddr, + const SubnetID& subnet_id, + const isc::asiolink::IOAddress& address); + + /// @brief Inserts IPv6 reservation into the host data source. + /// + /// @param data_source Reference to the data source to which the reservation + /// should be inserted. + /// @param duid Pointer to the DUID to be associated with the reservation. + /// @param subnet_id IPv6 subnet id. + /// @param address IPv6 address/prefix to be reserved. + /// @param prefix_len Prefix length. The default value is 128 which + /// indicates that the reservation is for an IPv6 address rather than a + /// prefix. + void addHost6(BaseHostDataSource& data_source, + const DuidPtr& duid, + const SubnetID& subnet_id, + const isc::asiolink::IOAddress& address, + const uint8_t prefix_len = 128); + + /// @brief This test verifies that HostMgr returns all reservations for the + /// specified HW address. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param data_source1 Host data source to which first reservation is + /// inserted. + /// @param data_source2 Host data source to which second reservation is + /// inserted. + void testGetAll(BaseHostDataSource& data_source1, + BaseHostDataSource& data_source2); + + /// @brief This test verifies that HostMgr returns all reservations for the + /// specified DHCPv4 subnet. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param data_source1 Host data source to which first reservation is + /// inserted. + /// @param data_source2 Host data source to which second reservation is + /// inserted. + void testGetAll4BySubnet(BaseHostDataSource& data_source1, + BaseHostDataSource& data_source2); + + /// @brief This test verifies that HostMgr returns all reservations for the + /// specified DHCPv6 subnet. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param data_source1 Host data source to which first reservation is + /// inserted. + /// @param data_source2 Host data source to which second reservation is + /// inserted. + void testGetAll6BySubnet(BaseHostDataSource& data_source1, + BaseHostDataSource& data_source2); + + /// @brief This test verifies that HostMgr returns all reservations for the + /// specified hostname. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param data_source1 Host data source to which first reservation is + /// inserted. + /// @param data_source2 Host data source to which second reservation is + /// inserted. + void testGetAllbyHostname(BaseHostDataSource& data_source1, + BaseHostDataSource& data_source2); + + /// @brief This test verifies that HostMgr returns all reservations for the + /// specified hostname and DHCPv4 subnet. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param data_source1 Host data source to which first reservation is + /// inserted. + /// @param data_source2 Host data source to which second reservation is + /// inserted. + void testGetAllbyHostnameSubnet4(BaseHostDataSource& data_source1, + BaseHostDataSource& data_source2); + + /// @brief This test verifies that HostMgr returns all reservations for the + /// specified hostname and DHCPv6 subnet. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param data_source1 Host data source to which first reservation is + /// inserted. + /// @param data_source2 Host data source to which second reservation is + /// inserted. + void testGetAllbyHostnameSubnet6(BaseHostDataSource& data_source1, + BaseHostDataSource& data_source2); + + /// @brief This test verifies that HostMgr returns all reservations for the + /// specified DHCPv4 subnet by pages. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param use_database True when the second reservation is inserted + /// in a database. + void testGetPage4(bool use_database); + + /// @brief This test verifies that HostMgr returns all reservations for the + /// specified DHCPv6 subnet by pages. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param use_database True when the second reservation is inserted + /// in a database. + void testGetPage6(bool use_database); + + /// @brief This test verifies that HostMgr returns all reservations + /// by pages. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param use_database True when the second reservation is inserted + /// in a database. + void testGetPage4All(bool use_database); + + /// @brief This test verifies that HostMgr returns all reservations + /// by pages. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param use_database True when the second reservation is inserted + /// in a database. + void testGetPage6All(bool use_database); + + /// @brief This test verifies that it is possible to retrieve IPv4 + /// reservation for the particular host using HostMgr. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param data_source1 Host data source to which first reservation is + /// inserted. + /// @param data_source2 Host data source to which second reservation is + /// inserted. + void testGetAll4(BaseHostDataSource& data_source1, + BaseHostDataSource& data_source2); + + /// @brief This test verifies that it is possible to retrieve an IPv4 + /// reservation for the particular host using HostMgr. + /// + /// @param data_source Host data source to which reservation is inserted and + /// from which it will be retrieved. + void testGet4(BaseHostDataSource& data_source); + + /// @brief This test verifies that it is possible to retrieve negative + /// cached reservation with and only with get4Any. + void testGet4Any(); + + /// @brief This test verifies that it is possible to retrieve an IPv6 + /// reservation for the particular host using HostMgr. + /// + /// @param data_source Host data source to which reservation is inserted and + /// from which it will be retrieved. + void testGet6(BaseHostDataSource& data_source); + + /// @brief This test verifies that it is possible to retrieve negative + /// cached reservation with and only with get6Any. + void testGet6Any(); + + /// @brief This test verifies that it is possible to retrieve an IPv6 + /// prefix reservation for the particular host using HostMgr. + /// + /// @param data_source1 Host data source to which first reservation is + /// inserted. + /// @param data_source2 Host data source to which second reservation is + /// inserted. + void testGet6ByPrefix(BaseHostDataSource& data_source1, + BaseHostDataSource& data_source2); + + /// @brief This test verifies that HostMgr returns all reservations for the + /// specified DHCPv4 subnet and IPv4 address. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param data_source1 Host data source to which first reservation is + /// inserted. + /// @param data_source2 Host data source to which second reservation is + /// inserted. + void testGetAll4BySubnetIP(BaseHostDataSource& data_source1, + BaseHostDataSource& data_source2); + + /// @brief This test verifies that HostMgr returns all reservations for the + /// specified DHCPv6 subnet and IPv6 address. + /// + /// If reservations are added to different host data sources, it is expected + /// that the @c HostMgr will retrieve reservations from both of them. + /// + /// @param data_source1 Host data source to which first reservation is + /// inserted. + /// @param data_source2 Host data source to which second reservation is + /// inserted. + void testGetAll6BySubnetIP(BaseHostDataSource& data_source1, + BaseHostDataSource& data_source2); + + /// @brief HW addresses to be used by the tests. + std::vector<HWAddrPtr> hwaddrs_; + /// @brief DUIDs to be used by the tests. + std::vector<DuidPtr> duids_; +}; + +} // namespace test +} // namespace dhcp +} // namespace isc + +#endif |