]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[392-search-of-reservations-by-hostname] Checkpoint: did tests, todo doc and hook
authorFrancis Dupont <fdupont@isc.org>
Mon, 30 Sep 2019 13:33:57 +0000 (15:33 +0200)
committerFrancis Dupont <fdupont@isc.org>
Tue, 15 Oct 2019 09:45:32 +0000 (11:45 +0200)
src/lib/dhcpsrv/cfg_hosts.cc
src/lib/dhcpsrv/mysql_host_data_source.cc
src/lib/dhcpsrv/tests/cql_host_data_source_unittest.cc
src/lib/dhcpsrv/tests/host_mgr_unittest.cc
src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc
src/lib/dhcpsrv/tests/pgsql_host_data_source_unittest.cc
src/lib/dhcpsrv/testutils/generic_host_data_source_unittest.cc
src/lib/dhcpsrv/testutils/generic_host_data_source_unittest.h

index f93467665c269bc24f7e68de0b774b6af040aba5..5ec8407f67234e379fdfec3f71ff09907a29cdfb 100644 (file)
@@ -367,7 +367,8 @@ CfgHosts::getAllbyHostnameInternal4(const std::string& hostname,
 
     LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
               HOSTS_CFG_GET_ALL_HOSTNAME_SUBNET_ID4)
-        .arg(hostname);
+        .arg(hostname)
+        .arg(subnet_id);
 
     // Use try hostname.
     const HostContainerIndex5& idx = hosts_.get<5>();
@@ -403,7 +404,8 @@ CfgHosts::getAllbyHostnameInternal6(const std::string& hostname,
 
     LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE,
               HOSTS_CFG_GET_ALL_HOSTNAME_SUBNET_ID6)
-        .arg(hostname);
+        .arg(hostname)
+        .arg(subnet_id);
 
     // Use try hostname.
     const HostContainerIndex5& idx = hosts_.get<5>();
index 3c0c2d7c386a6088b0f44e562c9aff820bb9bcb2..53400708819bdca4a002c5cbda639bb76d15b794 100644 (file)
@@ -3116,7 +3116,7 @@ MySqlHostDataSource::getAllbyHostname6(const std::string& hostname,
     inbind[1].is_unsigned = MLM_TRUE;
 
     ConstHostCollection result;
-    impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_HOSTNAME_SUBID4,
+    impl_->getHostCollection(MySqlHostDataSourceImpl::GET_HOST_HOSTNAME_SUBID6,
                              inbind, impl_->host_ipv6_exchange_,
                              result, false);
     return (result);
index bf8fe28bf16aa8cd3026b8753fa41988d0e66208..bf4602b928308e7dd236e987124c4911543485de 100644 (file)
@@ -332,6 +332,23 @@ TEST_F(CqlHostDataSourceTest, getAll6BySubnet) {
     testGetAll6();
 }
 
+// Verifies that host reservations with the same hostname can be retrieved
+TEST_F(CqlHostDataSourceTest, getAllbyHostname) {
+    testGetAllbyHostname();
+}
+
+// Verifies that IPv4 host reservations with the same hostname and in
+// the same subnet can be retrieved
+TEST_F(CqlHostDataSourceTest, getAllbyHostname4) {
+    testGetAllbyHostname4();
+}
+
+// Verifies that IPv6 host reservations with the same hostname and in
+// the same subnet can be retrieved
+TEST_F(CqlHostDataSourceTest, getAllbyHostname6) {
+    testGetAllbyHostname6();
+}
+
 // Verifies that IPv4 host reservations in the same subnet can be retrieved
 // by pages.
 TEST_F(CqlHostDataSourceTest, getPage4) {
index 6a540388bacd10d7fbd061ead1a05cde68b9403f..573cd2429766a323a692fb8f6283449946e855c6 100644 (file)
@@ -122,6 +122,45 @@ protected:
     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 testGetAllbyHostname4(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 testGetAllbyHostname6(BaseHostDataSource& data_source1,
+                               BaseHostDataSource& data_source2);
+
     /// @brief This test verifies that HostMgr returns all reservations for the
     /// specified DHCPv4 subnet by pages.
     ///
@@ -376,6 +415,150 @@ HostMgrTest::testGetAll6BySubnet(BaseHostDataSource& data_source1,
                 IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::6"))));
 }
 
+void
+HostMgrTest::testGetAllbyHostname(BaseHostDataSource& data_source1,
+                                  BaseHostDataSource& data_source2) {
+    // Initially, no reservations should be present.
+    ConstHostCollection hosts =
+        HostMgr::instance().getAllbyHostname("host");
+    ASSERT_TRUE(hosts.empty());
+
+    // Add two reservations with the same hostname.
+    HostPtr host1(new Host(hwaddrs_[0]->toText(false), "hw-address",
+                           SubnetID(1), SUBNET_ID_UNUSED,
+                           IOAddress("192.0.2.5")));
+    host1->setHostname("Host");
+    data_source1.add(host1);
+    HostPtr host2(new Host(hwaddrs_[1]->toText(false), "hw-address",
+                           SubnetID(10), SUBNET_ID_UNUSED,
+                           IOAddress("192.0.3.10")));
+    host2->setHostname("hosT");
+    data_source2.add(host2);
+
+    CfgMgr::instance().commit();
+
+    // If there non-matching hostname is specified, nothing should be
+    // returned.
+    hosts = HostMgr::instance().getAllbyHostname("foobar");
+    EXPECT_TRUE(hosts.empty());
+
+    // For the correct hostname, there should be two reservations.
+    hosts = HostMgr::instance().getAllbyHostname("host");
+    ASSERT_EQ(2, hosts.size());
+
+    // Make sure that subnet is correct.
+    EXPECT_EQ(1, hosts[0]->getIPv4SubnetID());
+    EXPECT_EQ(10, hosts[1]->getIPv4SubnetID());
+
+    // Make sure that hostname is correct including its case.
+    EXPECT_EQ("Host", hosts[0]->getHostname());
+    EXPECT_EQ("hosT", hosts[1]->getHostname());
+}
+
+void
+HostMgrTest::testGetAllbyHostname4(BaseHostDataSource& data_source1,
+                                   BaseHostDataSource& data_source2) {
+    // Initially, no reservations should be present.
+    ConstHostCollection hosts =
+        HostMgr::instance().getAllbyHostname4("host", SubnetID(1));
+    ASSERT_TRUE(hosts.empty());
+
+    // Add two reservations with the same hostname.
+    HostPtr host1(new Host(hwaddrs_[0]->toText(false), "hw-address",
+                           SubnetID(1), SUBNET_ID_UNUSED,
+                           IOAddress("192.0.2.5")));
+    host1->setHostname("Host");
+    data_source1.add(host1);
+    HostPtr host2(new Host(hwaddrs_[1]->toText(false), "hw-address",
+                           SubnetID(1), SUBNET_ID_UNUSED,
+                           IOAddress("192.0.2.6")));
+    host2->setHostname("hosT");
+    data_source2.add(host2);
+
+    CfgMgr::instance().commit();
+
+    // If there non-matching hostname is specified, nothing should be
+    // returned.
+    hosts = HostMgr::instance().getAllbyHostname4("foobar", SubnetID(1));
+    EXPECT_TRUE(hosts.empty());
+
+    // If there non-matching subnet is specified, nothing should be
+    // returned.
+    hosts = HostMgr::instance().getAllbyHostname4("host", SubnetID(10));
+    EXPECT_TRUE(hosts.empty());
+
+    // For the correct hostname, there should be two reservations.
+    hosts = HostMgr::instance().getAllbyHostname4("host", SubnetID(1));
+    ASSERT_EQ(2, hosts.size());
+
+    // Make sure that subnet is correct.
+    EXPECT_EQ(1, hosts[0]->getIPv4SubnetID());
+    EXPECT_EQ(1, hosts[1]->getIPv4SubnetID());
+
+    // Make sure that two different hosts were returned.
+    EXPECT_EQ("192.0.2.5", hosts[0]->getIPv4Reservation().toText());
+    EXPECT_EQ("192.0.2.6", hosts[1]->getIPv4Reservation().toText());
+
+    // Make sure that hostname is correct including its case.
+    EXPECT_EQ("Host", hosts[0]->getHostname());
+    EXPECT_EQ("hosT", hosts[1]->getHostname());
+}
+
+void
+HostMgrTest::testGetAllbyHostname6(BaseHostDataSource& data_source1,
+                                   BaseHostDataSource& data_source2) {
+    // Initially, no reservations should be present.
+    ConstHostCollection hosts =
+        HostMgr::instance().getAllbyHostname6("host", SubnetID(1));
+    ASSERT_TRUE(hosts.empty());
+
+    // Add two reservations with the same hostname.
+    HostPtr host1(new Host(duids_[0]->toText(), "duid",
+                           SubnetID(1), SubnetID(1),
+                           IOAddress::IPV4_ZERO_ADDRESS()));
+    host1->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
+                                    IOAddress("2001:db8:1::5"), 128));
+    host1->setHostname("Host");
+    data_source1.add(host1);
+    HostPtr host2(new Host(duids_[1]->toText(), "duid",
+                           SubnetID(1), SubnetID(1),
+                           IOAddress::IPV4_ZERO_ADDRESS()));
+    host2->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
+                                    IOAddress("2001:db8:1::6"), 128));
+    host2->setHostname("hosT");
+    data_source2.add(host2);
+
+    CfgMgr::instance().commit();
+
+    // If there non-matching hostname is specified, nothing should be
+    // returned.
+    hosts = HostMgr::instance().getAllbyHostname6("foobar", SubnetID(1));
+    EXPECT_TRUE(hosts.empty());
+
+    // If there non-matching subnet is specified, nothing should be
+    // returned.
+    hosts = HostMgr::instance().getAllbyHostname6("host", SubnetID(10));
+    EXPECT_TRUE(hosts.empty());
+
+    // For the correct hostname, there should be two reservations.
+    hosts = HostMgr::instance().getAllbyHostname6("host", SubnetID(1));
+    ASSERT_EQ(2, hosts.size());
+
+    // Make sure that subnet is correct.
+    EXPECT_EQ(1, hosts[0]->getIPv6SubnetID());
+    EXPECT_EQ(1, hosts[1]->getIPv6SubnetID());
+
+    // Make sure that two different hosts were returned.
+    EXPECT_TRUE(hosts[0]->hasReservation(
+                IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::5"))));
+    EXPECT_TRUE(hosts[1]->hasReservation(
+                IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::6"))));
+
+    // Make sure that hostname is correct including its case.
+    EXPECT_EQ("Host", hosts[0]->getHostname());
+    EXPECT_EQ("hosT", hosts[1]->getHostname());
+}
+
 void
 HostMgrTest::testGetPage4(bool use_database) {
     BaseHostDataSource& data_source1 = *getCfgHosts();
@@ -790,6 +973,26 @@ TEST_F(HostMgrTest, getAll6BySubnet) {
     testGetAll6BySubnet(*getCfgHosts(), *getCfgHosts());
 }
 
+// This test verifies that HostMgr returns all reservations for the specified
+// hostname. The reservations are defined in the server's configuration.
+TEST_F(HostMgrTest, getAllbyHostname) {
+    testGetAllbyHostname(*getCfgHosts(), *getCfgHosts());
+}
+
+// This test verifies that HostMgr returns all reservations for the specified
+// hostname and DHCPv4 subnet. The reservations are defined in the server's
+// configuration.
+TEST_F(HostMgrTest, getAllbyHostname4) {
+    testGetAllbyHostname4(*getCfgHosts(), *getCfgHosts());
+}
+
+// This test verifies that HostMgr returns all reservations for the specified
+// hostname and DHCPv6 subnet. The reservations are defined in the server's
+// configuration.
+TEST_F(HostMgrTest, getAllbyHostname6) {
+    testGetAllbyHostname4(*getCfgHosts(), *getCfgHosts());
+}
+
 // This test verifies that HostMgr returns all reservations for the
 // specified DHCPv4 subnet by pages. The reservations are defined in
 // the server's configuration.
@@ -1034,6 +1237,26 @@ TEST_F(MySQLHostMgrTest, getAll6BySubnet) {
     testGetAll6BySubnet(*getCfgHosts(), HostMgr::instance());
 }
 
+// This test verifies that reservations for a particular hostname can be
+// retrieved from the configuration file and a database simultaneously.
+TEST_F(MySQLHostMgrTest, getAllbyHostname) {
+    testGetAllbyHostname(*getCfgHosts(), HostMgr::instance());
+}
+
+// This test verifies that reservations for a particular hostname and
+// DHCPv4 subnet can be retrieved from the configuration file and a
+// database simultaneously.
+TEST_F(MySQLHostMgrTest, getAllbyHostname4) {
+    testGetAllbyHostname4(*getCfgHosts(), HostMgr::instance());
+}
+
+// This test verifies that reservations for a particular hostname and
+// DHCPv6 subnet can be retrieved from the configuration file and a
+// database simultaneously.
+TEST_F(MySQLHostMgrTest, getAllbyHostname6) {
+    testGetAllbyHostname6(*getCfgHosts(), HostMgr::instance());
+}
+
 // This test verifies that reservations for a particular subnet can
 // be retrieved by pages from the configuration file and a database
 // simultaneously.
@@ -1159,6 +1382,26 @@ TEST_F(PostgreSQLHostMgrTest, getAll6BySubnet) {
     testGetAll6BySubnet(*getCfgHosts(), HostMgr::instance());
 }
 
+// This test verifies that reservations for a particular hostname can be
+// retrieved from the configuration file and a database simultaneously.
+TEST_F(PostgreSQLHostMgrTest, getAllbyHostname) {
+    testGetAllbyHostname(*getCfgHosts(), HostMgr::instance());
+}
+
+// This test verifies that reservations for a particular hostname and
+// DHCPv4 subnet can be retrieved from the configuration file and a
+// database simultaneously.
+TEST_F(PostgreSQLHostMgrTest, getAllbyHostname4) {
+    testGetAllbyHostname4(*getCfgHosts(), HostMgr::instance());
+}
+
+// This test verifies that reservations for a particular hostname and
+// DHCPv6 subnet can be retrieved from the configuration file and a
+// database simultaneously.
+TEST_F(PostgreSQLHostMgrTest, getAllbyHostname6) {
+    testGetAllbyHostname6(*getCfgHosts(), HostMgr::instance());
+}
+
 // This test verifies that reservations for a particular subnet can
 // be retrieved by pages from the configuration file and a database
 // simultaneously.
@@ -1265,6 +1508,26 @@ TEST_F(CQLHostMgrTest, getAll6BySubnet) {
     testGetAll6BySubnet(*getCfgHosts(), HostMgr::instance());
 }
 
+// This test verifies that reservations for a particular hostname can be
+// retrieved from the configuration file and a database simultaneously.
+TEST_F(CQLHostMgrTest, getAllbyHostname) {
+    testGetAllbyHostname(*getCfgHosts(), HostMgr::instance());
+}
+
+// This test verifies that reservations for a particular hostname and
+// DHCPv4 subnet can be retrieved from the configuration file and a
+// database simultaneously.
+TEST_F(CQLHostMgrTest, getAllbyHostname4) {
+    testGetAllbyHostname4(*getCfgHosts(), HostMgr::instance());
+}
+
+// This test verifies that reservations for a particular hostname and
+// DHCPv6 subnet can be retrieved from the configuration file and a
+// database simultaneously.
+TEST_F(CQLHostMgrTest, getAllbyHostname6) {
+    testGetAllbyHostname6(*getCfgHosts(), HostMgr::instance());
+}
+
 // This test verifies that reservations for a particular subnet can
 // be retrieved by pages from the configuration file and a database
 // simultaneously.
index c1fd8bc9806549a10c3c383bf7f1d0ec65701a53..e6e8b4506c5e953a474ecee1ee420a7176ac3bc0 100644 (file)
@@ -321,6 +321,23 @@ TEST_F(MySqlHostDataSourceTest, getAll6BySubnet) {
     testGetAll6();
 }
 
+// Verifies that host reservations with the same hostname can be retrieved
+TEST_F(MySqlHostDataSourceTest, getAllbyHostname) {
+    testGetAllbyHostname();
+}
+
+// Verifies that IPv4 host reservations with the same hostname and in
+// the same subnet can be retrieved
+TEST_F(MySqlHostDataSourceTest, getAllbyHostname4) {
+    testGetAllbyHostname4();
+}
+
+// Verifies that IPv6 host reservations with the same hostname and in
+// the same subnet can be retrieved
+TEST_F(MySqlHostDataSourceTest, getAllbyHostname6) {
+    testGetAllbyHostname6();
+}
+
 // Verifies that IPv4 host reservations in the same subnet can be retrieved
 // by pages.
 TEST_F(MySqlHostDataSourceTest, getPage4) {
index 1925d7eedc45b725ddc930919f748a0d6733b6db..c456940cf00b4590cd4acbe060cdf069e293ec53 100644 (file)
@@ -307,6 +307,23 @@ TEST_F(PgSqlHostDataSourceTest, getAll6BySubnet) {
     testGetAll6();
 }
 
+// Verifies that host reservations with the same hostname can be retrieved
+TEST_F(PgSqlHostDataSourceTest, getAllbyHostname) {
+    testGetAllbyHostname();
+}
+
+// Verifies that IPv4 host reservations with the same hostname and in
+// the same subnet can be retrieved
+TEST_F(PgSqlHostDataSourceTest, getAllbyHostname4) {
+    testGetAllbyHostname4();
+}
+
+// Verifies that IPv6 host reservations with the same hostname and in
+// the same subnet can be retrieved
+TEST_F(PgSqlHostDataSourceTest, getAllbyHostname6) {
+    testGetAllbyHostname6();
+}
+
 // Verifies that IPv4 host reservations in the same subnet can be retrieved
 // by pages.
 TEST_F(PgSqlHostDataSourceTest, getPage4) {
index e75c2075672151d4eb4795d6c124ba519bec5933..b3e1c144296ce0111ca1f7711b1cf2bc2f01f5fd 100644 (file)
@@ -463,6 +463,229 @@ GenericHostDataSourceTest::testGetAll6() {
     }
 }
 
+void
+GenericHostDataSourceTest::testGetAllbyHostname() {
+    // Make sure we have a pointer to the host data source.
+    ASSERT_TRUE(hdsptr_);
+
+    // Let's create some hosts...
+    Host::IdentifierType id = Host::IDENT_HWADDR;
+    HostPtr host1 = HostDataSourceUtils::initializeHost4("192.0.2.1", id);
+    host1->setHostname("host");
+
+    id = Host::IDENT_DUID;
+    HostPtr host2 = HostDataSourceUtils::initializeHost4("192.0.2.2", id);
+    host2->setHostname("Host");
+
+    HostPtr host3 = HostDataSourceUtils::initializeHost6("2001:db8::1", id, false);
+    host3->setHostname("hOSt");
+
+    HostPtr host4 = HostDataSourceUtils::initializeHost6("2001:db8::2", id, false);
+    host4->setHostname("host.example.com");
+
+    // Now add them all to the host data source.
+    ASSERT_NO_THROW(hdsptr_->add(host1));
+    ASSERT_NO_THROW(hdsptr_->add(host2));
+    ASSERT_NO_THROW(hdsptr_->add(host3));
+    ASSERT_NO_THROW(hdsptr_->add(host4));
+
+    // Retrieve unknown name.
+    ConstHostCollection from_hds = hdsptr_->getAllbyHostname("foo");
+    EXPECT_TRUE(from_hds.empty());
+
+    // Retrieve one reservation.
+    from_hds = hdsptr_->getAllbyHostname("host.example.com");
+    ASSERT_EQ(1, from_hds.size());
+    HostDataSourceUtils::compareHosts(host4, from_hds[0]);
+
+    // Retrieve all reservations with host hostname.
+    from_hds = hdsptr_->getAllbyHostname("host");
+    EXPECT_EQ(3, from_hds.size());
+    bool got1 = false;
+    bool got2 = false;
+    bool got3 = false;
+    for (auto host : from_hds) {
+        if (host->getIdentifierType() == Host::IDENT_HWADDR) {
+            EXPECT_FALSE(got1);
+            got1 = true;
+            HostDataSourceUtils::compareHosts(host1, host);
+        } else if (host->getIPv4Reservation().isV4Zero()) {
+            EXPECT_FALSE(got3);
+            got3 = true;
+            HostDataSourceUtils::compareHosts(host3, host);
+        } else {
+            EXPECT_FALSE(got2);
+            got2 = true;
+            HostDataSourceUtils::compareHosts(host2, host);
+        }
+    }
+    EXPECT_TRUE(got1);
+    EXPECT_TRUE(got2);
+    EXPECT_TRUE(got3);
+}
+
+void
+GenericHostDataSourceTest::testGetAllbyHostname4() {
+    // Make sure we have a pointer to the host data source.
+    ASSERT_TRUE(hdsptr_);
+
+    // Let's create some hosts...
+    Host::IdentifierType id = Host::IDENT_HWADDR;
+    HostPtr host1 = HostDataSourceUtils::initializeHost4("192.0.2.1", id);
+    host1->setHostname("host");
+
+    id = Host::IDENT_DUID;
+    HostPtr host2 = HostDataSourceUtils::initializeHost4("192.0.2.2", id);
+    host2->setHostname("Host");
+    CfgOptionPtr opts = host2->getCfgOption4();
+    OptionDescriptor desc =
+        createOption<OptionString>(Option::V4, DHO_BOOT_FILE_NAME,
+                                   true, false, "my-boot-file");
+    opts->add(desc, DHCP4_OPTION_SPACE);
+
+    HostPtr host3 = HostDataSourceUtils::initializeHost4("192.0.2.3", id);
+    host3->setHostname("hOSt");
+
+    HostPtr host4 = HostDataSourceUtils::initializeHost4("192.0.2.4", id);
+    host4->setHostname("host.example.com");
+
+    // Set them in the same subnets.
+    SubnetID subnet4 = host1->getIPv4SubnetID();
+    host2->setIPv4SubnetID(subnet4);
+    host3->setIPv4SubnetID(subnet4);
+    host4->setIPv4SubnetID(subnet4);
+    SubnetID subnet6 = host1->getIPv6SubnetID();
+    host2->setIPv6SubnetID(subnet6);
+    host3->setIPv6SubnetID(subnet6);
+    host4->setIPv6SubnetID(subnet6);
+
+    // Now add them all to the host data source.
+    ASSERT_NO_THROW(hdsptr_->add(host1));
+    ASSERT_NO_THROW(hdsptr_->add(host2));
+    ASSERT_NO_THROW(hdsptr_->add(host3));
+    ASSERT_NO_THROW(hdsptr_->add(host4));
+
+    // Retrieve unknown name.
+    ConstHostCollection from_hds = hdsptr_->getAllbyHostname4("foo", subnet4);
+    EXPECT_TRUE(from_hds.empty());
+
+    // Retrieve one reservation.
+    from_hds = hdsptr_->getAllbyHostname4("host.example.com", subnet4);
+    ASSERT_EQ(1, from_hds.size());
+    HostDataSourceUtils::compareHosts(host4, from_hds[0]);
+
+    // Check that the subnet is checked.
+    from_hds = hdsptr_->getAllbyHostname4("host.example.com", subnet4 + 1);
+    EXPECT_TRUE(from_hds.empty());
+
+    // Retrieve all reservations with host hostname.
+    from_hds = hdsptr_->getAllbyHostname4("host", subnet4);
+    EXPECT_EQ(3, from_hds.size());
+    bool got1 = false;
+    bool got2 = false;
+    bool got3 = false;
+    bool got4 = false;
+    for (auto host : from_hds) {
+        if (host->getIdentifierType() == Host::IDENT_HWADDR) {
+            EXPECT_FALSE(got1);
+            got1 = true;
+            HostDataSourceUtils::compareHosts(host1, host);
+        } else if (!host->getCfgOption4()->empty()) {
+            EXPECT_FALSE(got2);
+            got2 = true;
+            HostDataSourceUtils::compareHosts(host2, host);
+        } else {
+            EXPECT_FALSE(got3);
+            got3 = true;
+            HostDataSourceUtils::compareHosts(host3, host);
+        }
+    }
+    EXPECT_TRUE(got1);
+    EXPECT_TRUE(got2);
+    EXPECT_TRUE(got3);
+}
+
+void
+GenericHostDataSourceTest::testGetAllbyHostname6() {
+    // Make sure we have a pointer to the host data source.
+    ASSERT_TRUE(hdsptr_);
+
+    // Let's create some hosts...
+    Host::IdentifierType id = Host::IDENT_HWADDR;
+    HostPtr host1 = HostDataSourceUtils::initializeHost6("2001:db8::1", id, false);
+    host1->setHostname("host");
+
+    id = Host::IDENT_DUID;
+    HostPtr host2 = HostDataSourceUtils::initializeHost6("2001:db8::2", id, false);
+    host2->setHostname("Host");
+    CfgOptionPtr opts = host2->getCfgOption6();
+    OptionDescriptor desc =
+        createOption<OptionString>(Option::V6, D6O_BOOTFILE_URL,
+                                   true, true, "my-boot-file");
+    opts->add(desc, DHCP6_OPTION_SPACE);
+
+    HostPtr host3 = HostDataSourceUtils::initializeHost6("2001:db8::3", id, false);
+    host3->setHostname("hOSt");
+
+    HostPtr host4 = HostDataSourceUtils::initializeHost6("2001:db8::4", id, false);
+    host4->setHostname("host.example.com");
+
+    // Set them in the same subnets.
+    SubnetID subnet4 = host1->getIPv4SubnetID();
+    host2->setIPv4SubnetID(subnet4);
+    host3->setIPv4SubnetID(subnet4);
+    host4->setIPv4SubnetID(subnet4);
+    SubnetID subnet6 = host1->getIPv6SubnetID();
+    host2->setIPv6SubnetID(subnet6);
+    host3->setIPv6SubnetID(subnet6);
+    host4->setIPv6SubnetID(subnet6);
+
+    // Now add them all to the host data source.
+    ASSERT_NO_THROW(hdsptr_->add(host1));
+    ASSERT_NO_THROW(hdsptr_->add(host2));
+    ASSERT_NO_THROW(hdsptr_->add(host3));
+    ASSERT_NO_THROW(hdsptr_->add(host4));
+
+    // Retrieve unknown name.
+    ConstHostCollection from_hds = hdsptr_->getAllbyHostname6("foo", subnet6);
+    EXPECT_TRUE(from_hds.empty());
+
+    // Retrieve one reservation.
+    from_hds = hdsptr_->getAllbyHostname6("host.example.com", subnet6);
+    ASSERT_EQ(1, from_hds.size());
+    HostDataSourceUtils::compareHosts(host4, from_hds[0]);
+
+    // Check that the subnet is checked.
+    from_hds = hdsptr_->getAllbyHostname6("host.example.com", subnet6 + 1);
+    EXPECT_TRUE(from_hds.empty());
+
+    // Retrieve all reservations with host hostname.
+    from_hds = hdsptr_->getAllbyHostname6("host", subnet6);
+    EXPECT_EQ(3, from_hds.size());
+    bool got1 = false;
+    bool got2 = false;
+    bool got3 = false;
+    bool got4 = false;
+    for (auto host : from_hds) {
+        if (host->getIdentifierType() == Host::IDENT_HWADDR) {
+            EXPECT_FALSE(got1);
+            got1 = true;
+            HostDataSourceUtils::compareHosts(host1, host);
+        } else if (!host->getCfgOption6()->empty()) {
+            EXPECT_FALSE(got2);
+            got2 = true;
+            HostDataSourceUtils::compareHosts(host2, host);
+        } else {
+            EXPECT_FALSE(got3);
+            got3 = true;
+            HostDataSourceUtils::compareHosts(host3, host);
+        }
+    }
+    EXPECT_TRUE(got1);
+    EXPECT_TRUE(got2);
+    EXPECT_TRUE(got3);
+}
+
 void
 GenericHostDataSourceTest::testGetPage4() {
     // Make sure we have a pointer to the host data source.
index d398bb77e5528715c455a3f26be95328f08a3a92..7c4103f8727f3076b63582c289fe8b0bcc28abf6 100644 (file)
@@ -202,6 +202,24 @@ public:
     /// 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 testGetAllbyHostname4();
+
+    /// @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 testGetAllbyHostname6();
+
     /// @brief Test that Verifies that pages of host reservations in the
     /// same subnet can be retrieved properly.
     ///