extern const isc::log::MessageID DHCPSRV_MYSQL_GET_HWADDR = "DHCPSRV_MYSQL_GET_HWADDR";
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_IAID_DUID = "DHCPSRV_MYSQL_GET_IAID_DUID";
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_IAID_SUBID_DUID = "DHCPSRV_MYSQL_GET_IAID_SUBID_DUID";
+extern const isc::log::MessageID DHCPSRV_MYSQL_GET_LINKADDR6 = "DHCPSRV_MYSQL_GET_LINKADDR6";
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_PAGE4 = "DHCPSRV_MYSQL_GET_PAGE4";
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_PAGE6 = "DHCPSRV_MYSQL_GET_PAGE6";
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_RELAYID4 = "DHCPSRV_MYSQL_GET_RELAYID4";
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_HWADDR = "DHCPSRV_PGSQL_GET_HWADDR";
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_IAID_DUID = "DHCPSRV_PGSQL_GET_IAID_DUID";
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_IAID_SUBID_DUID = "DHCPSRV_PGSQL_GET_IAID_SUBID_DUID";
+extern const isc::log::MessageID DHCPSRV_PGSQL_GET_LINKADDR6 = "DHCPSRV_PGSQL_GET_LINKADDR6";
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_PAGE4 = "DHCPSRV_PGSQL_GET_PAGE4";
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_PAGE6 = "DHCPSRV_PGSQL_GET_PAGE6";
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_RELAYID4 = "DHCPSRV_PGSQL_GET_RELAYID4";
"DHCPSRV_MYSQL_GET_HWADDR", "obtaining IPv4 leases for hardware address %1",
"DHCPSRV_MYSQL_GET_IAID_DUID", "obtaining IPv6 leases for IAID %1, DUID %2, lease type %3",
"DHCPSRV_MYSQL_GET_IAID_SUBID_DUID", "obtaining IPv6 leases for IAID %1, Subnet ID %2, DUID %3, lease type %4",
+ "DHCPSRV_MYSQL_GET_LINKADDR6", "obtaining at most %1 IPv6 leases starting from address %2 with link %3/%4",
"DHCPSRV_MYSQL_GET_PAGE4", "obtaining at most %1 IPv4 leases starting from address %2",
"DHCPSRV_MYSQL_GET_PAGE6", "obtaining at most %1 IPv6 leases starting from address %2",
"DHCPSRV_MYSQL_GET_RELAYID4", "obtaining at most %1 IPv4 leases starting from address %2 with relay id %3 and cltt between %4 and %5",
"DHCPSRV_PGSQL_GET_HWADDR", "obtaining IPv4 leases for hardware address %1",
"DHCPSRV_PGSQL_GET_IAID_DUID", "obtaining IPv4 leases for IAID %1 and DUID %2, lease type %3",
"DHCPSRV_PGSQL_GET_IAID_SUBID_DUID", "obtaining IPv4 leases for IAID %1, Subnet ID %2, DUID %3, and lease type %4",
+ "DHCPSRV_PGSQL_GET_LINKADDR6", "obtaining at most %1 IPv6 leases starting from address %2 with link %3/%4",
"DHCPSRV_PGSQL_GET_PAGE4", "obtaining at most %1 IPv4 leases starting from address %2",
"DHCPSRV_PGSQL_GET_PAGE6", "obtaining at most %1 IPv6 leases starting from address %2",
"DHCPSRV_PGSQL_GET_RELAYID4", "obtaining at most %1 IPv4 leases starting from address %2 with relay id %3 and cltt between %4 and %5",
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_HWADDR;
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_IAID_DUID;
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_IAID_SUBID_DUID;
+extern const isc::log::MessageID DHCPSRV_MYSQL_GET_LINKADDR6;
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_PAGE4;
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_PAGE6;
extern const isc::log::MessageID DHCPSRV_MYSQL_GET_RELAYID4;
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_HWADDR;
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_IAID_DUID;
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_IAID_SUBID_DUID;
+extern const isc::log::MessageID DHCPSRV_PGSQL_GET_LINKADDR6;
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_PAGE4;
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_PAGE6;
extern const isc::log::MessageID DHCPSRV_PGSQL_GET_RELAYID4;
lease from the MySQL database for a client with the specified IAID
(Identity Association ID), Subnet ID and DUID (DHCP Unique Identifier).
+% DHCPSRV_MYSQL_GET_LINKADDR6 obtaining at most %1 IPv6 leases starting from address %2 with link %3/%4
+A debug message issued when the server is attempting to obtain a page of
+IPv6 leases beginning with the specified address within a link.
+
% DHCPSRV_MYSQL_GET_PAGE4 obtaining at most %1 IPv4 leases starting from address %2
A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address.
lease from the PostgreSQL database for a client with the specified IAID
(Identity Association ID), Subnet ID and DUID (DHCP Unique Identifier).
+% DHCPSRV_PGSQL_GET_LINKADDR6 obtaining at most %1 IPv6 leases starting from address %2 with link %3/%4
+A debug message issued when the server is attempting to obtain a page of
+IPv6 leases beginning with the specified address within a link.
+
% DHCPSRV_PGSQL_GET_PAGE4 obtaining at most %1 IPv4 leases starting from address %2
A debug message issued when the server is attempting to obtain a page
of leases beginning with the specified address.
#include <config.h>
-#include <asiolink/io_address.h>
+#include <asiolink/addr_utilities.h>
#include <dhcp/duid.h>
#include <dhcp/hwaddr.h>
#include <dhcpsrv/cfg_db_access.h>
"AND expire < ? "
"ORDER BY expire ASC "
"LIMIT ?"},
+ {MySqlLeaseMgr::GET_LEASE6_LINK,
+ "SELECT address, duid, valid_lifetime, "
+ "expire, subnet_id, pref_lifetime, "
+ "lease_type, iaid, prefix_len, "
+ "fqdn_fwd, fqdn_rev, hostname, "
+ "hwaddr, hwtype, hwaddr_source, "
+ "state, user_context "
+ "FROM lease6 "
+ "WHERE binaddr IS NOT NULL "
+ "AND binaddr BETWEEN ? AND ? "
+ "ORDER BY binaddr "
+ "LIMIT ?"},
{MySqlLeaseMgr::INSERT_LEASE4,
"INSERT INTO lease4(address, hwaddr, client_id, "
"valid_lifetime, expire, subnet_id, "
}
Lease6Collection
-MySqlLeaseMgr::getLeases6ByLink(const IOAddress& /* link_addr */,
- uint8_t /* link_len */,
- const IOAddress& /* lower_bound_address */,
- const LeasePageSize& /* page_size */) {
- isc_throw(NotImplemented, "MySqlLeaseMgr::getLeases6ByLink not implemented");
+MySqlLeaseMgr::getLeases6ByLink(const IOAddress& link_addr,
+ uint8_t link_len,
+ const IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) {
+ // Expecting IPv6 valid prefix and address.
+ if (!link_addr.isV6()) {
+ isc_throw(InvalidAddressFamily, "expected IPv6 address while "
+ "retrieving leases from the lease database, got "
+ << link_addr);
+ }
+ if ((link_len == 0) || (link_len > 128)) {
+ isc_throw(OutOfRange, "invalid IPv6 prefix length "
+ << static_cast<unsigned>(link_len));
+ }
+ if (!lower_bound_address.isV6()) {
+ isc_throw(InvalidAddressFamily, "expected IPv6 address while "
+ "retrieving leases from the lease database, got "
+ << lower_bound_address);
+ }
+
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
+ DHCPSRV_MYSQL_GET_LINKADDR6)
+ .arg(page_size.page_size_)
+ .arg(lower_bound_address.toText())
+ .arg(link_addr.toText())
+ .arg(static_cast<unsigned>(link_len));
+
+ Lease6Collection result;
+ const IOAddress& first_addr = firstAddrInPrefix(link_addr, link_len);
+ const IOAddress& last_addr = lastAddrInPrefix(link_addr, link_len);
+ IOAddress start_addr = lower_bound_address;
+ if (lower_bound_address < first_addr) {
+ start_addr = first_addr;
+ } else if (last_addr <= lower_bound_address) {
+ // Range was already done.
+ return (result);
+ } else {
+ // The lower bound address is from the last call so skip it.
+ start_addr = IOAddress::increase(lower_bound_address);
+ }
+
+ // Prepare WHERE clause
+ MYSQL_BIND inbind[3];
+ memset(inbind, 0, sizeof(inbind));
+
+ // Bind start address
+ std::vector<uint8_t> start_addr_data = start_addr.toBytes();
+ if (start_addr_data.size() != 16) {
+ isc_throw(DbOperationError, "start address is not 16 byte long");
+ }
+ unsigned long start_addr_size = 16;
+ inbind[0].buffer_type = MYSQL_TYPE_BLOB;
+ inbind[0].buffer = reinterpret_cast<char*>(&start_addr_data[0]);
+ inbind[0].buffer_length = 16;
+ inbind[0].length = &start_addr_size;
+
+ // Bind last address
+ std::vector<uint8_t> last_addr_data = last_addr.toBytes();
+ if (last_addr_data.size() != 16) {
+ isc_throw(DbOperationError, "last address is not 16 byte long");
+ }
+ unsigned long last_addr_size = 16;
+ inbind[1].buffer_type = MYSQL_TYPE_BLOB;
+ inbind[1].buffer = reinterpret_cast<char*>(&last_addr_data[0]);
+ inbind[1].buffer_length = 16;
+ inbind[1].length = &last_addr_size;
+
+ // Bind page size value
+ uint32_t ps = static_cast<uint32_t>(page_size.page_size_);
+ inbind[2].buffer_type = MYSQL_TYPE_LONG;
+ inbind[2].buffer = reinterpret_cast<char*>(&ps);
+ inbind[2].is_unsigned = MLM_TRUE;
+
+ // Get a context
+ MySqlLeaseContextAlloc get_context(*this);
+ MySqlLeaseContextPtr ctx = get_context.ctx_;
+
+ // Get the leases
+ getLeaseCollection(ctx, GET_LEASE6_LINK, inbind, result);
+
+ return (result);
}
size_t
GET_LEASE6_DUID, // Get IPv6 leases by DUID
GET_LEASE6_HOSTNAME, // Get IPv6 leases by hostname
GET_LEASE6_EXPIRE, // Get lease6 by expiration.
+ GET_LEASE6_LINK, // Get page of lease6 by link
INSERT_LEASE4, // Add entry to lease4 table
INSERT_LEASE6, // Add entry to lease6 table
UPDATE_LEASE4, // Update a Lease4 entry
#include <config.h>
-#include <asiolink/io_address.h>
+#include <asiolink/addr_utilities.h>
#include <dhcp/duid.h>
#include <dhcp/hwaddr.h>
#include <dhcpsrv/cfg_db_access.h>
"ORDER BY expire "
"LIMIT $3"},
+ // GET_LEASE6_LINK
+ { 3, { OID_BYTEA, OID_BYTEA, OID_INT8 },
+ "get_lease6_link",
+ "SELECT address, duid, valid_lifetime, "
+ "extract(epoch from expire)::bigint, subnet_id, pref_lifetime, "
+ "lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, "
+ "hwaddr, hwtype, hwaddr_source, "
+ "state, user_context "
+ "FROM lease6 "
+ "WHERE binaddr IS NOT NULL "
+ "AND binaddr BETWEEN $1 and $2 "
+ "ORDER BY binaddr "
+ "LIMIT $3"},
+
// INSERT_LEASE4
{ 13, { OID_INT8, OID_BYTEA, OID_BYTEA, OID_INT8, OID_TIMESTAMP, OID_INT8,
OID_BOOL, OID_BOOL, OID_VARCHAR, OID_INT8, OID_TEXT, OID_BYTEA,
bind_array.add(lb_address_data);
// Bind page size value
- std::string page_size_data = boost::lexical_cast<std::string>(page_size.page_size_);
+ std::string page_size_data =
+ boost::lexical_cast<std::string>(page_size.page_size_);
bind_array.add(page_size_data);
// Get the leases
}
Lease6Collection
-PgSqlLeaseMgr::getLeases6ByLink(const IOAddress& /* link_addr */,
- uint8_t /* link_len */,
- const IOAddress& /* lower_bound_address */,
- const LeasePageSize& /* page_size */) {
- isc_throw(NotImplemented, "PgSqlLeaseMgr::getLeases6ByLink not implemented");
+PgSqlLeaseMgr::getLeases6ByLink(const IOAddress& link_addr,
+ uint8_t link_len,
+ const IOAddress& lower_bound_address,
+ const LeasePageSize& page_size) {
+ // Expecting IPv6 valid prefix and address.
+ if (!link_addr.isV6()) {
+ isc_throw(InvalidAddressFamily, "expected IPv6 address while "
+ "retrieving leases from the lease database, got "
+ << link_addr);
+ }
+ if ((link_len == 0) || (link_len > 128)) {
+ isc_throw(OutOfRange, "invalid IPv6 prefix length "
+ << static_cast<unsigned>(link_len));
+ }
+ if (!lower_bound_address.isV6()) {
+ isc_throw(InvalidAddressFamily, "expected IPv6 address while "
+ "retrieving leases from the lease database, got "
+ << lower_bound_address);
+ }
+
+ LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
+ DHCPSRV_PGSQL_GET_LINKADDR6)
+ .arg(page_size.page_size_)
+ .arg(lower_bound_address.toText())
+ .arg(link_addr.toText())
+ .arg(static_cast<unsigned>(link_len));
+
+ Lease6Collection result;
+ const IOAddress& first_addr = firstAddrInPrefix(link_addr, link_len);
+ const IOAddress& last_addr = lastAddrInPrefix(link_addr, link_len);
+ IOAddress start_addr = lower_bound_address;
+ if (lower_bound_address < first_addr) {
+ start_addr = first_addr;
+ } else if (last_addr <= lower_bound_address) {
+ // Range was already done.
+ return (result);
+ } else {
+ // The lower bound address is from the last call so skip it.
+ start_addr = IOAddress::increase(lower_bound_address);
+ }
+
+ // Prepare WHERE clause
+ PsqlBindArray bind_array;
+
+ // Bind start address
+ std::vector<uint8_t> start_addr_data = start_addr.toBytes();
+ if (start_addr_data.size() != 16) {
+ isc_throw(DbOperationError, "start address is not 16 byte long");
+ }
+ bind_array.add(start_addr_data);
+
+ // Bind last address
+ std::vector<uint8_t> last_addr_data = last_addr.toBytes();
+ if (last_addr_data.size() != 16) {
+ isc_throw(DbOperationError, "last address is not 16 byte long");
+ }
+ bind_array.add(last_addr_data);
+
+ // Bind page size value
+ std::string page_size_data =
+ boost::lexical_cast<std::string>(page_size.page_size_);
+ bind_array.add(page_size_data);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ // Get the leases
+ getLeaseCollection(ctx, GET_LEASE6_LINK, bind_array, result);
+
+ return (result);
}
size_t
GET_LEASE6_DUID, // Get IPv6 leases by DUID
GET_LEASE6_HOSTNAME, // Get IPv6 leases by hostname
GET_LEASE6_EXPIRE, // Get lease6 by expiration.
+ GET_LEASE6_LINK, // Get page of lease6 by link
INSERT_LEASE4, // Add entry to lease4 table
INSERT_LEASE6, // Add entry to lease6 table
UPDATE_LEASE4, // Update a Lease4 entry
"192.0.2.4", "192.0.2.5", "192.0.2.6", "192.0.2.7"
};
+/// @brief IPv6 addresses used in the tests.
+const vector<string> ADDRESS6 = {
+ "2001:db8::0", "2001:db8::1", "2001:db8::2", "2001:db8::3",
+ "2001:db8::4", "2001:db8::5", "2001:db8::6", "2001:db8::7"
+};
+
/// @brief DUIDs used in the tests.
const vector<string> DUIDS = {
"wwwwwwww", "BBBBBBBB", "::::::::", "0123456789acdef",
lease_mgr_ = &(LeaseMgrFactory::instance());
leases4.clear();
+ leases6.clear();
MultiThreadingMgr::instance().setMode(false);
now_ = time(0);
}
destroyMySQLSchema();
leases4.clear();
+ leases6.clear();
MultiThreadingMgr::instance().setMode(false);
}
ASSERT_EQ(ADDRESS4.size(), leases4.size());
}
+ /// @brief Create and set v6 leases.
+ void initLease6() {
+ ASSERT_EQ(ADDRESS6.size(), DUIDS.size());
+ for (size_t i = 0; i < ADDRESS6.size(); ++i) {
+ Lease6Ptr lease;
+ vector<uint8_t> duid_data = createFromString(DUIDS[i]);
+ DuidPtr duid(new DUID(duid_data));
+ IOAddress addr(ADDRESS6[i]);
+ ASSERT_NO_THROW(lease.reset(new Lease6(((i % 2) ? Lease::TYPE_NA : Lease::TYPE_PD), addr, duid,
+ 123, 1000, 2000,
+ static_cast<SubnetID>(i))));
+ leases6.push_back(lease);
+ EXPECT_TRUE(lease_mgr_->addLease(lease));
+ }
+ ASSERT_EQ(ADDRESS6.size(), leases6.size());
+ }
+
/// @brief Create a vector of uint8_t from a string.
///
/// @param content A not empty string holding the content.
/// @brief Test initLease4.
void testInitLease4();
+ /// @brief Test initLease6.
+ void testInitLease6();
+
/// @brief Test getLease4ByRelayId.
void testGetLeases4ByRelayId();
void testUpgradeExtendedInfo4(const CfgConsistency::ExtendedInfoSanity& check,
const LeasePageSize& page_size);
+ /// @brief Test getLeases6ByLink.
+ void testGetLeases6ByLink();
+
/// @brief Lease manager.
LeaseMgr* lease_mgr_;
/// @brief V4 leases.
Lease4Collection leases4;
+ /// @brief V6 leases.
+ Lease6Collection leases6;
+
/// @brief Current timestamp.
time_t now_;
};
LeasePageSize(1));
}
+/// @brief Verifies that the lease manager can add the v6 leases.
+void
+MySqlExtendedInfoTest::testInitLease6() {
+ initLease6();
+ EXPECT_EQ(8, leases6.size());
+ Lease6Collection got;
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6());
+ ASSERT_EQ(leases6.size(), got.size());
+ for (size_t i = 0; i < leases6.size(); ++i) {
+ ConstElementPtr expected = leases6[i]->toElement();
+ LeasePtr lease = got[i];
+ ASSERT_TRUE(lease);
+ EXPECT_TRUE(expected->equals(*lease->toElement()))
+ << "expected: " << expected->str() << "\n"
+ << "got: " << lease->toElement()->str() << "\n";
+ }
+}
+
+TEST_F(MySqlExtendedInfoTest, initLease6) {
+ testInitLease6();
+}
+
+TEST_F(MySqlExtendedInfoTest, initLease6MultiThreading) {
+ MultiThreadingTest mt(true);
+ testInitLease6();
+}
+
+/// @brief Verifies that getLeases6ByLink works as expected.
+void
+MySqlExtendedInfoTest::testGetLeases6ByLink() {
+ // Lease manager is created with empty tables.
+ initLease6();
+
+ // Create parameter values.
+ IOAddress link_addr(ADDRESS6[4]);
+ IOAddress other_link_addr("2001:db8:1::4");
+ IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS();
+
+ Lease6Collection got;
+ // Other link: nothing.
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(other_link_addr,
+ 64,
+ zero,
+ LeasePageSize(10)));
+ EXPECT_EQ(0, got.size());
+
+ // Link: 8 entries.
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr,
+ 64,
+ zero,
+ LeasePageSize(10)));
+
+ ASSERT_EQ(8, got.size());
+ Lease6Ptr lease;
+ for (size_t i = 0; i < 8; ++i) {
+ lease = got[i];
+ ASSERT_TRUE(lease);
+ EXPECT_EQ(IOAddress(ADDRESS6[i]), lease->addr_);
+ }
+
+ // Link: initial partial: 4 entries.
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr,
+ 64,
+ zero,
+ LeasePageSize(4)));
+ ASSERT_EQ(4, got.size());
+ for (size_t i = 0; i < 4; ++i) {
+ lease = got[i];
+ ASSERT_TRUE(lease);
+ EXPECT_EQ(IOAddress(ADDRESS6[i]), lease->addr_);
+ }
+
+ // Link: next partial: 4 entries.
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr,
+ 64,
+ lease->addr_,
+ LeasePageSize(4)));
+ ASSERT_EQ(4, got.size());
+ for (size_t i = 0; i < 4; ++i) {
+ lease = got[i];
+ ASSERT_TRUE(lease);
+ EXPECT_EQ(IOAddress(ADDRESS6[i + 4]), lease->addr_);
+ }
+
+ // Link: further partial: nothing.
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr,
+ 64,
+ lease->addr_,
+ LeasePageSize(4)));
+ EXPECT_EQ(0, got.size());
+}
+
+TEST_F(MySqlExtendedInfoTest, getLeases6ByLink) {
+ testGetLeases6ByLink();
+}
+
+TEST_F(MySqlExtendedInfoTest, getLeases6ByLinkMultiThreading) {
+ MultiThreadingTest mt(true);
+ testGetLeases6ByLink();
+}
+
} // namespace
"192.0.2.4", "192.0.2.5", "192.0.2.6", "192.0.2.7"
};
+/// @brief IPv6 addresses used in the tests.
+const vector<string> ADDRESS6 = {
+ "2001:db8::0", "2001:db8::1", "2001:db8::2", "2001:db8::3",
+ "2001:db8::4", "2001:db8::5", "2001:db8::6", "2001:db8::7"
+};
+
/// @brief DUIDs used in the tests.
const vector<string> DUIDS = {
"wwwwwwww", "BBBBBBBB", "::::::::", "0123456789acdef",
lease_mgr_ = &(LeaseMgrFactory::instance());
leases4.clear();
+ leases6.clear();
MultiThreadingMgr::instance().setMode(false);
now_ = time(0);
}
destroyPgSQLSchema();
leases4.clear();
+ leases6.clear();
MultiThreadingMgr::instance().setMode(false);
}
ASSERT_EQ(ADDRESS4.size(), leases4.size());
}
+ /// @brief Create and set v6 leases.
+ void initLease6() {
+ ASSERT_EQ(ADDRESS6.size(), DUIDS.size());
+ for (size_t i = 0; i < ADDRESS6.size(); ++i) {
+ Lease6Ptr lease;
+ vector<uint8_t> duid_data = createFromString(DUIDS[i]);
+ DuidPtr duid(new DUID(duid_data));
+ IOAddress addr(ADDRESS6[i]);
+ ASSERT_NO_THROW(lease.reset(new Lease6(((i % 2) ? Lease::TYPE_NA : Lease::TYPE_PD), addr, duid,
+ 123, 1000, 2000,
+ static_cast<SubnetID>(i))));
+ leases6.push_back(lease);
+ EXPECT_TRUE(lease_mgr_->addLease(lease));
+ }
+ ASSERT_EQ(ADDRESS6.size(), leases6.size());
+ }
+
/// @brief Create a vector of uint8_t from a string.
///
/// @param content A not empty string holding the content.
/// @brief Test initLease4.
void testInitLease4();
+ /// @brief Test initLease6.
+ void testInitLease6();
+
/// @brief Test getLease4ByRelayId.
void testGetLeases4ByRelayId();
void testUpgradeExtendedInfo4(const CfgConsistency::ExtendedInfoSanity& check,
const LeasePageSize& page_size);
+ /// @brief Test getLeases6ByLink.
+ void testGetLeases6ByLink();
+
/// @brief Lease manager.
LeaseMgr* lease_mgr_;
/// @brief V4 leases.
Lease4Collection leases4;
+ /// @brief V6 leases.
+ Lease6Collection leases6;
+
/// @brief Current timestamp.
time_t now_;
};
LeasePageSize(1));
}
+/// @brief Verifies that the lease manager can add the v6 leases.
+void
+PgSqlExtendedInfoTest::testInitLease6() {
+ initLease6();
+ EXPECT_EQ(8, leases6.size());
+ Lease6Collection got;
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6());
+ ASSERT_EQ(leases6.size(), got.size());
+ for (size_t i = 0; i < leases6.size(); ++i) {
+ ConstElementPtr expected = leases6[i]->toElement();
+ LeasePtr lease = got[i];
+ ASSERT_TRUE(lease);
+ EXPECT_TRUE(expected->equals(*lease->toElement()))
+ << "expected: " << expected->str() << "\n"
+ << "got: " << lease->toElement()->str() << "\n";
+ }
+}
+
+TEST_F(PgSqlExtendedInfoTest, initLease6) {
+ testInitLease6();
+}
+
+TEST_F(PgSqlExtendedInfoTest, initLease6MultiThreading) {
+ MultiThreadingTest mt(true);
+ testInitLease6();
+}
+
+/// @brief Verifies that getLeases6ByLink works as expected.
+void
+PgSqlExtendedInfoTest::testGetLeases6ByLink() {
+ // Lease manager is created with empty tables.
+ initLease6();
+
+ // Create parameter values.
+ IOAddress link_addr(ADDRESS6[4]);
+ IOAddress other_link_addr("2001:db8:1::4");
+ IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS();
+
+ Lease6Collection got;
+ // Other link: nothing.
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(other_link_addr,
+ 64,
+ zero,
+ LeasePageSize(10)));
+ EXPECT_EQ(0, got.size());
+
+ // Link: 8 entries.
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr,
+ 64,
+ zero,
+ LeasePageSize(10)));
+
+ ASSERT_EQ(8, got.size());
+ Lease6Ptr lease;
+ for (size_t i = 0; i < 8; ++i) {
+ lease = got[i];
+ ASSERT_TRUE(lease);
+ EXPECT_EQ(IOAddress(ADDRESS6[i]), lease->addr_);
+ }
+
+ // Link: initial partial: 4 entries.
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr,
+ 64,
+ zero,
+ LeasePageSize(4)));
+ ASSERT_EQ(4, got.size());
+ for (size_t i = 0; i < 4; ++i) {
+ lease = got[i];
+ ASSERT_TRUE(lease);
+ EXPECT_EQ(IOAddress(ADDRESS6[i]), lease->addr_);
+ }
+
+ // Link: next partial: 4 entries.
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr,
+ 64,
+ lease->addr_,
+ LeasePageSize(4)));
+ ASSERT_EQ(4, got.size());
+ for (size_t i = 0; i < 4; ++i) {
+ lease = got[i];
+ ASSERT_TRUE(lease);
+ EXPECT_EQ(IOAddress(ADDRESS6[i + 4]), lease->addr_);
+ }
+
+ // Link: further partial: nothing.
+ EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr,
+ 64,
+ lease->addr_,
+ LeasePageSize(4)));
+ EXPECT_EQ(0, got.size());
+}
+
+TEST_F(PgSqlExtendedInfoTest, getLeases6ByLink) {
+ testGetLeases6ByLink();
+}
+
+TEST_F(PgSqlExtendedInfoTest, getLeases6ByLinkMultiThreading) {
+ MultiThreadingTest mt(true);
+ testGetLeases6ByLink();
+}
+
} // namespace