-// Copyright (C) 2014-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2014-2020 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
EXPECT_EQ(0, page.size());
}
+// This test checks that all hosts can be retrieved from the host
+// configuration by pages.
+TEST_F(CfgHostsTest, getPage4All) {
+ CfgHosts cfg;
+ // Add 25 hosts identified by DUID.
+ for (unsigned i = 0; i < 25; ++i) {
+ cfg.add(HostPtr(new Host(duids_[i]->toText(), "duid",
+ SubnetID(i), SubnetID(i),
+ addressesa_[i])));
+ }
+ size_t idx(0);
+ uint64_t host_id(0);
+ HostPageSize page_size(10);
+
+ // Try to retrieve all added reservations.
+ // Get first page.
+ HostCollection page = cfg.getPage4(idx, host_id, page_size);
+ EXPECT_EQ(10, page.size());
+ host_id = page[9]->getHostId();
+
+ // Get second and last pages.
+ page = cfg.getPage4(idx, host_id, page_size);
+ EXPECT_EQ(10, page.size());
+ host_id = page[9]->getHostId();
+ page = cfg.getPage4(idx, host_id, page_size);
+ EXPECT_EQ(5, page.size());
+ host_id = page[4]->getHostId();
+
+ // Verify we have everything.
+ page = cfg.getPage4(idx, host_id, page_size);
+ EXPECT_EQ(0, page.size());
+}
+
+// This test checks that all hosts can be retrieved from the host
+// configuration by pages.
+TEST_F(CfgHostsTest, getPage6All) {
+ CfgHosts cfg;
+ // Add 25 hosts identified by HW address.
+ for (unsigned i = 0; i < 25; ++i) {
+ HostPtr host = HostPtr(new Host(hwaddrs_[i]->toText(false),
+ "hw-address",
+ SubnetID(i), SubnetID(i),
+ IOAddress("0.0.0.0")));
+ host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_NA,
+ increase(IOAddress("2001:db8:1::1"),
+ i)));
+ cfg.add(host);
+ }
+ size_t idx(0);
+ uint64_t host_id(0);
+ HostPageSize page_size(10);
+
+ // Try to retrieve all added reservations.
+ // Get first page.
+ HostCollection page = cfg.getPage6(idx, host_id, page_size);
+ EXPECT_EQ(10, page.size());
+ host_id = page[9]->getHostId();
+
+ // Get second and last pages.
+ page = cfg.getPage6(idx, host_id, page_size);
+ EXPECT_EQ(10, page.size());
+ host_id = page[9]->getHostId();
+ page = cfg.getPage6(idx, host_id, page_size);
+ EXPECT_EQ(5, page.size());
+ host_id = page[4]->getHostId();
+
+ // Verify we have everything.
+ page = cfg.getPage6(idx, host_id, page_size);
+ EXPECT_EQ(0, page.size());
+}
+
// This test checks that all reservations for the specified IPv4 address can
// be retrieved.
TEST_F(CfgHostsTest, getAll4ByAddress) {
testGetPage6Subnets();
}
+// Verifies that all IPv4 host reservations can be retrieved by pages.
+TEST_F(CqlHostDataSourceTest, getPage4All) {
+ testGetPage4All();
+}
+
+// Verifies that all IPv6 host reservations can be retrieved by pages.
+TEST_F(CqlHostDataSourceTest, getPage6All) {
+ testGetPage6All();
+}
+
// Test verifies if a host reservation can be added and later retrieved by IPv4
// address. Host uses client-id (DUID) as identifier.
TEST_F(CqlHostDataSourceTest, basic4ClientId) {
/// 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.
///
}
}
+void
+HostMgrTest::testGetPage4All(bool use_database) {
+ BaseHostDataSource& data_source1 = *getCfgHosts();
+ BaseHostDataSource& data_source2 = HostMgr::instance();
+
+ // Initially, no reservations should be present.
+ size_t idx(0);
+ HostPageSize page_size(10);
+ ConstHostCollection hosts =
+ HostMgr::instance().getPage4(idx, 0, page_size);
+ ASSERT_TRUE(hosts.empty());
+ if (use_database) {
+ EXPECT_EQ(2, idx);
+ } else {
+ EXPECT_EQ(1, idx);
+ }
+
+ // Add two reservations.
+ addHost4(data_source1, hwaddrs_[0], SubnetID(1), IOAddress("192.0.2.5"));
+ addHost4(use_database ? data_source2 : data_source1,
+ hwaddrs_[1], SubnetID(2), IOAddress("192.0.2.6"));
+
+ CfgMgr::instance().commit();
+
+ // There should be two reservations.
+ idx = 0;
+ hosts = HostMgr::instance().getPage4(idx, 0, page_size);
+ if (use_database) {
+ ASSERT_EQ(1, hosts.size());
+ } else {
+ ASSERT_EQ(2, hosts.size());
+ }
+
+ // Make sure that returned values are correct.
+ EXPECT_EQ(1, hosts[0]->getIPv4SubnetID());
+ EXPECT_EQ("192.0.2.5", hosts[0]->getIPv4Reservation().toText());
+ if (!use_database) {
+ EXPECT_EQ(2, hosts[1]->getIPv4SubnetID());
+ EXPECT_EQ("192.0.2.6", hosts[1]->getIPv4Reservation().toText());
+
+ // Check it was the last page.
+ uint64_t hid = hosts[1]->getHostId();
+ hosts = HostMgr::instance().getPage4(idx, hid, page_size);
+ ASSERT_EQ(0, hosts.size());
+ idx = 1;
+ hosts = HostMgr::instance().getPage4(idx, 0, page_size);
+ ASSERT_EQ(0, hosts.size());
+ }
+
+ if (use_database) {
+ uint64_t hid = hosts[0]->getHostId();
+ ASSERT_NE(0, hid);
+ ASSERT_EQ(0, idx);
+ hosts = HostMgr::instance().getPage4(idx, hid, page_size);
+ ASSERT_EQ(1, hosts.size());
+ ASSERT_NE(0, idx);
+ EXPECT_EQ(2, hosts[0]->getIPv4SubnetID());
+ EXPECT_EQ("192.0.2.6", hosts[0]->getIPv4Reservation().toText());
+
+ // Alternate way to use the database.
+ idx = 1;
+ hosts = HostMgr::instance().getPage4(idx, 0, page_size);
+ ASSERT_EQ(1, hosts.size());
+ EXPECT_EQ(2, hosts[0]->getIPv4SubnetID());
+ EXPECT_EQ("192.0.2.6", hosts[0]->getIPv4Reservation().toText());
+
+ // Check it was the last page.
+ hid = hosts[0]->getHostId();
+ ASSERT_NE(0, hid);
+ hosts = HostMgr::instance().getPage4(idx, hid, page_size);
+ ASSERT_EQ(0, hosts.size());
+ idx = 2;
+ hosts = HostMgr::instance().getPage4(idx, 0, page_size);
+ ASSERT_EQ(0, hosts.size());
+ }
+}
+
+void
+HostMgrTest::testGetPage6All(bool use_database) {
+ BaseHostDataSource& data_source1 = *getCfgHosts();
+ BaseHostDataSource& data_source2 = HostMgr::instance();
+
+ // Initially, no reservations should be present.
+ size_t idx(0);
+ HostPageSize page_size(10);
+ ConstHostCollection hosts =
+ HostMgr::instance().getPage6(idx, 0, page_size);
+ ASSERT_TRUE(hosts.empty());
+ if (use_database) {
+ EXPECT_EQ(2, idx);
+ } else {
+ EXPECT_EQ(1, idx);
+ }
+
+ // Add two reservations.
+ addHost6(data_source1, duids_[0], SubnetID(1), IOAddress("2001:db8:1::5"));
+ addHost6(use_database ? data_source2 : data_source1,
+ duids_[1], SubnetID(2), IOAddress("2001:db8:1::6"));
+
+ CfgMgr::instance().commit();
+
+ // There should be two reservations.
+ idx = 0;
+ hosts = HostMgr::instance().getPage6(idx, 0, page_size);
+ if (use_database) {
+ ASSERT_EQ(1, hosts.size());
+ } else {
+ ASSERT_EQ(2, hosts.size());
+ }
+
+ // Make sure that returned values are correct.
+ EXPECT_EQ(1, hosts[0]->getIPv6SubnetID());
+ EXPECT_TRUE(hosts[0]->hasReservation(
+ IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::5"))));
+ if (!use_database) {
+ EXPECT_EQ(2, hosts[1]->getIPv6SubnetID());
+ EXPECT_TRUE(hosts[1]->hasReservation(
+ IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::6"))));
+
+ // Check it was the last page.
+ uint64_t hid = hosts[1]->getHostId();
+ hosts = HostMgr::instance().getPage6(idx, hid, page_size);
+ ASSERT_EQ(0, hosts.size());
+ idx = 1;
+ hosts = HostMgr::instance().getPage6(idx, 0, page_size);
+ ASSERT_EQ(0, hosts.size());
+ }
+
+ if (use_database) {
+ uint64_t hid = hosts[0]->getHostId();
+ ASSERT_NE(0, hid);
+ ASSERT_EQ(0, idx);
+ hosts = HostMgr::instance().getPage6(idx, hid, page_size);
+ ASSERT_EQ(1, hosts.size());
+ ASSERT_NE(0, idx);
+ EXPECT_EQ(2, hosts[0]->getIPv6SubnetID());
+ EXPECT_TRUE(hosts[0]->hasReservation(
+ IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::6"))));
+
+ // Alternate way to use the database.
+ idx = 1;
+ hosts = HostMgr::instance().getPage6(idx, 0, page_size);
+ ASSERT_EQ(1, hosts.size());
+ EXPECT_EQ(2, hosts[0]->getIPv6SubnetID());
+ EXPECT_TRUE(hosts[0]->hasReservation(
+ IPv6Resrv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8:1::6"))));
+
+ // Check it was the last page.
+ hid = hosts[0]->getHostId();
+ ASSERT_NE(0, hid);
+ hosts = HostMgr::instance().getPage6(idx, hid, page_size);
+ ASSERT_EQ(0, hosts.size());
+ idx = 2;
+ hosts = HostMgr::instance().getPage6(idx, 0, page_size);
+ ASSERT_EQ(0, hosts.size());
+ }
+}
+
void
HostMgrTest::testGetAll4(BaseHostDataSource& data_source1,
BaseHostDataSource& data_source2) {
testGetPage4(false);
}
+// This test verifies that HostMgr returns all v4 reservations by pages.
+// The reservations are defined in the server's configuration.
+TEST_F(HostMgrTest, getPage4All) {
+ testGetPage4All(false);
+}
+
// This test verifies that HostMgr returns all reservations for the
// specified DHCPv6 subnet by pages. The reservations are defined in
// the server's configuration.
testGetPage6(false);
}
+// This test verifies that HostMgr returns all v6 reservations by pages.
+// The reservations are defined in the server's configuration.
+TEST_F(HostMgrTest, getPage6All) {
+ testGetPage6All(false);
+}
+
// This test verifies that it is possible to gather all reservations for the
// specified IPv4 address from the HostMgr. The reservations are specified in
// the server's configuration.
testGetPage4(true);
}
+// This test verifies that all v4 reservations be retrieved by pages
+// from the configuration file and a database simultaneously.
+TEST_F(MySQLHostMgrTest, getPage4All) {
+ testGetPage4All(true);
+}
+
// This test verifies that reservations for a particular subnet can
// be retrieved by pages from the configuration file and a database
// simultaneously.
testGetPage6(true);
}
+// This test verifies that all v6 reservations be retrieved by pages
+// from the configuration file and a database simultaneously.
+TEST_F(MySQLHostMgrTest, getPage6All) {
+ testGetPage6All(true);
+}
+
// This test verifies that IPv4 reservations for a particular client can
// be retrieved from the configuration file and a database simultaneously.
TEST_F(MySQLHostMgrTest, getAll4) {
testGetPage4(true);
}
+// This test verifies that all v4 reservations be retrieved by pages
+// from the configuration file and a database simultaneously.
+TEST_F(PostgreSQLHostMgrTest, getPage4All) {
+ testGetPage4All(true);
+}
+
// This test verifies that reservations for a particular subnet can
// be retrieved by pages from the configuration file and a database
// simultaneously.
testGetPage6(true);
}
+// This test verifies that all v6 reservations be retrieved by pages
+// from the configuration file and a database simultaneously.
+TEST_F(PostgreSQLHostMgrTest, getPage6All) {
+ testGetPage6All(true);
+}
+
// This test verifies that IPv4 reservations for a particular client can
// be retrieved from the configuration file and a database simultaneously.
TEST_F(PostgreSQLHostMgrTest, getAll4) {
testGetPage4(true);
}
+// This test verifies that all v4 reservations be retrieved by pages
+// from the configuration file and a database simultaneously.
+TEST_F(CQLHostMgrTest, getPage4All) {
+ testGetPage4All(true);
+}
+
// This test verifies that reservations for a particular subnet can
// be retrieved by pages from the configuration file and a database
// simultaneously.
testGetPage6(true);
}
+// This test verifies that all v6 reservations be retrieved by pages
+// from the configuration file and a database simultaneously.
+TEST_F(CQLHostMgrTest, getPage6All) {
+ testGetPage6All(true);
+}
+
// This test verifies that IPv4 reservations for a particular client can
// be retrieved from the configuration file and a database simultaneously.
TEST_F(CQLHostMgrTest, getAll4) {
testGetPage6Subnets();
}
+// Verifies that all IPv4 host reservations can be retrieved by pages.
+TEST_F(MySqlHostDataSourceTest, getPage4All) {
+ testGetPage4All();
+}
+
+// Verifies that all IPv4 host reservations can be retrieved by pages.
+TEST_F(MySqlHostDataSourceTest, getPage4AllMultiThreading) {
+ MultiThreadingTest mt(true);
+ testGetPage4All();
+}
+
+// Verifies that all IPv6 host reservations can be retrieved by pages.
+TEST_F(MySqlHostDataSourceTest, getPage6All) {
+ testGetPage6All();
+}
+
+// Verifies that all IPv6 host reservations can be retrieved by pages.
+TEST_F(MySqlHostDataSourceTest, getPage6AllMultiThreading) {
+ MultiThreadingTest mt(true);
+ testGetPage6All();
+}
+
/// @brief Test verifies if a host reservation can be added and later retrieved by IPv4
/// address. Host uses client-id (DUID) as identifier.
TEST_F(MySqlHostDataSourceTest, basic4ClientId) {
testGetPage6Subnets();
}
+// Verifies that all IPv4 host reservations can be retrieved by pages.
+TEST_F(PgSqlHostDataSourceTest, getPage4All) {
+ testGetPage4All();
+}
+
+// Verifies that all IPv4 host reservations can be retrieved by pages.
+TEST_F(PgSqlHostDataSourceTest, getPage4AllMultiThreading) {
+ MultiThreadingTest mt(true);
+ testGetPage4All();
+}
+
+// Verifies that all IPv6 host reservations can be retrieved by pages.
+TEST_F(PgSqlHostDataSourceTest, getPage6All) {
+ testGetPage6All();
+}
+
+// Verifies that all IPv6 host reservations can be retrieved by pages.
+TEST_F(PgSqlHostDataSourceTest, getPage6AllMultiThreading) {
+ MultiThreadingTest mt(true);
+ testGetPage6All();
+}
+
/// @brief Test verifies if a host reservation can be added and later retrieved by IPv4
/// address. Host uses client-id (DUID) as identifier.
TEST_F(PgSqlHostDataSourceTest, basic4ClientId) {
-// Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2020 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// From the ticket: add 5 hosts each with 3 options.
// call getPage4 with limit of 4.
// The first page should return 4 hosts,
- // the second should return one host.b
+ // the second should return one host.
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
// From the ticket: add one host to subnet1, add one host to subnet2.
// repeat 5 times. Get hosts from subnet1 with page size 3.
// Make sure the right hosts are returned and in expected page
- //sizes (3, then 2).
+ // sizes (3, then 2).
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
// From the ticket: add one host to subnet1, add one host to subnet2.
// repeat 5 times. Get hosts from subnet1 with page size 3.
// Make sure the right hosts are returned and in expected page
- //sizes (3, then 2).
+ // sizes (3, then 2).
// Make sure we have a pointer to the host data source.
ASSERT_TRUE(hdsptr_);
}
}
+void
+GenericHostDataSourceTest::testGetPage4All() {
+ // From the ticket: add one host to subnet1, add one host to subnet2.
+ // repeat 4 times. Get all hosts with page size 3.
+ // Make sure all hosts are returned and in expected page
+ // sizes (3, 3, then 2).
+
+ // Make sure we have a pointer to the host data source.
+ ASSERT_TRUE(hdsptr_);
+
+ // Let's create some hosts...
+ const Host::IdentifierType& id = Host::IDENT_HWADDR;
+ IOAddress addr("192.0.2.0");
+ SubnetID subnet4(4);
+ SubnetID subnet6(6);
+ vector<HostPtr> hosts;
+ for (unsigned i = 0; i < 8; ++i) {
+ addr = IOAddress::increase(addr);
+
+ HostPtr host = HostDataSourceUtils::initializeHost4(addr.toText(), id);
+ host->setIPv4SubnetID(subnet4 + (i & 1));
+ host->setIPv6SubnetID(subnet6 + (i & 1));
+
+ ASSERT_NO_THROW(hdsptr_->add(host));
+ hosts.push_back(host);
+ }
+
+ // Get first page.
+ size_t idx(1);
+ uint64_t host_id(0);
+ HostPageSize page_size(3);
+ ConstHostCollection page;
+ ConstHostCollection all_pages;
+ ASSERT_NO_THROW(page = hdsptr_->getPage4(idx, host_id, page_size));
+ ASSERT_EQ(3, page.size());
+ host_id = page[2]->getHostId();
+ ASSERT_NE(0, host_id);
+
+ std::copy(page.begin(), page.end(), std::back_inserter(all_pages));
+
+ // Get second page.
+ ASSERT_NO_THROW(page = hdsptr_->getPage4(idx, host_id, page_size));
+ ASSERT_EQ(3, page.size());
+ host_id = page[2]->getHostId();
+
+ std::copy(page.begin(), page.end(), std::back_inserter(all_pages));
+
+ // Get last page.
+ ASSERT_NO_THROW(page = hdsptr_->getPage4(idx, host_id, page_size));
+ ASSERT_EQ(2, page.size());
+ host_id = page[1]->getHostId();
+
+ std::copy(page.begin(), page.end(), std::back_inserter(all_pages));
+
+ // Verify we have everything.
+ ASSERT_NO_THROW(page = hdsptr_->getPage4(idx, host_id, page_size));
+ ASSERT_EQ(0, page.size());
+
+ // hosts are sorted by generated host_id (which is an auto increment for
+ // MySql and PostgreSql and a hash for Cassandra) so the hosts must be
+ // sorted by host identifier
+ std::sort(all_pages.begin(), all_pages.end(), compareHostsIdentifier);
+
+ // Verify we got what we expected.
+ for (size_t i = 0; i < 8; ++i) {
+ HostDataSourceUtils::compareHosts(hosts[i], all_pages[i]);
+ }
+}
+
+void
+GenericHostDataSourceTest::testGetPage6All() {
+ // From the ticket: add one host to subnet1, add one host to subnet2.
+ // repeat 4 times. Get all hosts with page size 3.
+ // Make sure all hosts are returned and in expected page
+ // sizes (3, 3, then 2).
+
+ // Make sure we have a pointer to the host data source.
+ ASSERT_TRUE(hdsptr_);
+
+ // Let's create some hosts...
+ const Host::IdentifierType& id = Host::IDENT_DUID;
+ IOAddress addr("2001:db8:1::");
+ SubnetID subnet4(4);
+ SubnetID subnet6(6);
+ vector<HostPtr> hosts;
+ for (unsigned i = 0; i < 8; ++i) {
+ addr = IOAddress::increase(addr);
+
+ HostPtr host = HostDataSourceUtils::initializeHost6(addr.toText(), id, false);
+ host->setIPv4SubnetID(subnet4 + (i & 1));
+ host->setIPv6SubnetID(subnet6 + (i & 1));
+
+ ASSERT_NO_THROW(hdsptr_->add(host));
+ hosts.push_back(host);
+ }
+
+ // Get first page.
+ size_t idx(1);
+ uint64_t host_id(0);
+ HostPageSize page_size(3);
+ ConstHostCollection page;
+ ConstHostCollection all_pages;
+ ASSERT_NO_THROW(page = hdsptr_->getPage6(idx, host_id, page_size));
+ ASSERT_EQ(3, page.size());
+ host_id = page[2]->getHostId();
+ ASSERT_NE(0, host_id);
+
+ std::copy(page.begin(), page.end(), std::back_inserter(all_pages));
+
+ // Get second page.
+ ASSERT_NO_THROW(page = hdsptr_->getPage6(idx, host_id, page_size));
+ ASSERT_EQ(3, page.size());
+ host_id = page[2]->getHostId();
+
+ std::copy(page.begin(), page.end(), std::back_inserter(all_pages));
+
+ // Get last page.
+ ASSERT_NO_THROW(page = hdsptr_->getPage6(idx, host_id, page_size));
+ ASSERT_EQ(2, page.size());
+ host_id = page[1]->getHostId();
+
+ std::copy(page.begin(), page.end(), std::back_inserter(all_pages));
+
+ // Verify we have everything.
+ ASSERT_NO_THROW(page = hdsptr_->getPage6(idx, host_id, page_size));
+ ASSERT_EQ(0, page.size());
+
+ // hosts are sorted by generated host_id (which is an auto increment for
+ // MySql and PostgreSql and a hash for Cassandra) so the hosts must be
+ // sorted by host identifier
+ std::sort(all_pages.begin(), all_pages.end(), compareHostsIdentifier);
+
+ // Verify we got what we expected.
+ for (size_t i = 0; i < 8; ++i) {
+ HostDataSourceUtils::compareHosts(hosts[i], all_pages[i]);
+ }
+}
+
void
GenericHostDataSourceTest::testGetByIPv4(const Host::IdentifierType& id) {
// Make sure we have a pointer to the host data source.
-// Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2020 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
/// 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.
///