diff options
author | Francis Dupont <fdupont@isc.org> | 2022-10-14 22:39:14 +0200 |
---|---|---|
committer | Francis Dupont <fdupont@isc.org> | 2022-10-18 19:28:45 +0200 |
commit | 4806d1adea94d130f63af2817208ddaf6c7c0455 (patch) | |
tree | 8f354c4d13da0f9ae227abe58df0d098e3a74030 | |
parent | [#2585] Checkpoint: finish unit tests (diff) | |
download | kea-4806d1adea94d130f63af2817208ddaf6c7c0455.tar.xz kea-4806d1adea94d130f63af2817208ddaf6c7c0455.zip |
[#2585] Checkpoint: almost done
-rw-r--r-- | src/lib/dhcpsrv/dhcpsrv_messages.cc | 10 | ||||
-rw-r--r-- | src/lib/dhcpsrv/dhcpsrv_messages.h | 5 | ||||
-rw-r--r-- | src/lib/dhcpsrv/dhcpsrv_messages.mes | 24 | ||||
-rw-r--r-- | src/lib/dhcpsrv/memfile_lease_mgr.cc | 121 | ||||
-rw-r--r-- | src/lib/dhcpsrv/memfile_lease_mgr.h | 3 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/memfile_lease_extended_info_unittest.cc | 1080 |
6 files changed, 1224 insertions, 19 deletions
diff --git a/src/lib/dhcpsrv/dhcpsrv_messages.cc b/src/lib/dhcpsrv/dhcpsrv_messages.cc index a8bae75492..c7de9c5514 100644 --- a/src/lib/dhcpsrv/dhcpsrv_messages.cc +++ b/src/lib/dhcpsrv/dhcpsrv_messages.cc @@ -90,8 +90,13 @@ extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_HOSTNAME6 = "DHCPSRV_MEMFIL extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_HWADDR = "DHCPSRV_MEMFILE_GET_HWADDR"; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_IAID_DUID = "DHCPSRV_MEMFILE_GET_IAID_DUID"; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_IAID_SUBID_DUID = "DHCPSRV_MEMFILE_GET_IAID_SUBID_DUID"; +extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_LINKADDR6 = "DHCPSRV_MEMFILE_GET_LINKADDR6"; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_PAGE4 = "DHCPSRV_MEMFILE_GET_PAGE4"; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_PAGE6 = "DHCPSRV_MEMFILE_GET_PAGE6"; +extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_RELAYID4 = "DHCPSRV_MEMFILE_GET_RELAYID4"; +extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_RELAYID6 = "DHCPSRV_MEMFILE_GET_RELAYID6"; +extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_REMOTEID4 = "DHCPSRV_MEMFILE_GET_REMOTEID4"; +extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_REMOTEID6 = "DHCPSRV_MEMFILE_GET_REMOTEID6"; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_SUBID4 = "DHCPSRV_MEMFILE_GET_SUBID4"; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_SUBID6 = "DHCPSRV_MEMFILE_GET_SUBID6"; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_SUBID_CLIENTID = "DHCPSRV_MEMFILE_GET_SUBID_CLIENTID"; @@ -326,8 +331,13 @@ const char* values[] = { "DHCPSRV_MEMFILE_GET_HWADDR", "obtaining IPv4 leases for hardware address %1", "DHCPSRV_MEMFILE_GET_IAID_DUID", "obtaining IPv6 leases for IAID %1 and DUID %2 and lease type %3", "DHCPSRV_MEMFILE_GET_IAID_SUBID_DUID", "obtaining IPv6 leases for IAID %1, Subnet ID %2, DUID %3 and lease type %4", + "DHCPSRV_MEMFILE_GET_LINKADDR6", "obtaining at most %1 IPv6 leases starting from address %2 with link address %3", "DHCPSRV_MEMFILE_GET_PAGE4", "obtaining at most %1 IPv4 leases starting from address %2", "DHCPSRV_MEMFILE_GET_PAGE6", "obtaining at most %1 IPv6 leases starting from address %2", + "DHCPSRV_MEMFILE_GET_RELAYID4", "obtaining at most %1 IPv4 leases starting from address %2 with relay id %3 and cltt between %4 and %5", + "DHCPSRV_MEMFILE_GET_RELAYID6", "obtaining at most %1 IPv6 leases starting from address %2 with relay id %3 and link address %4", + "DHCPSRV_MEMFILE_GET_REMOTEID4", "obtaining at most %1 IPv4 leases starting from address %2 with remote id %3 and cltt between %4 and %5", + "DHCPSRV_MEMFILE_GET_REMOTEID6", "obtaining at most %1 IPv6 leases starting from address %2 with remote id %3 and link address %4", "DHCPSRV_MEMFILE_GET_SUBID4", "obtaining IPv4 leases for subnet ID %1", "DHCPSRV_MEMFILE_GET_SUBID6", "obtaining IPv6 leases for subnet ID %1", "DHCPSRV_MEMFILE_GET_SUBID_CLIENTID", "obtaining IPv4 lease for subnet ID %1 and client ID %2", diff --git a/src/lib/dhcpsrv/dhcpsrv_messages.h b/src/lib/dhcpsrv/dhcpsrv_messages.h index de72a098a5..cc17421a4a 100644 --- a/src/lib/dhcpsrv/dhcpsrv_messages.h +++ b/src/lib/dhcpsrv/dhcpsrv_messages.h @@ -91,8 +91,13 @@ extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_HOSTNAME6; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_HWADDR; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_IAID_DUID; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_IAID_SUBID_DUID; +extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_LINKADDR6; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_PAGE4; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_PAGE6; +extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_RELAYID4; +extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_RELAYID6; +extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_REMOTEID4; +extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_REMOTEID6; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_SUBID4; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_SUBID6; extern const isc::log::MessageID DHCPSRV_MEMFILE_GET_SUBID_CLIENTID; diff --git a/src/lib/dhcpsrv/dhcpsrv_messages.mes b/src/lib/dhcpsrv/dhcpsrv_messages.mes index a9896569a9..ab271d7d38 100644 --- a/src/lib/dhcpsrv/dhcpsrv_messages.mes +++ b/src/lib/dhcpsrv/dhcpsrv_messages.mes @@ -473,6 +473,10 @@ A debug message issued when the server is attempting to obtain an IPv6 lease from the memory file database for a client with the specified IAID (Identity Association ID), Subnet ID and DUID (DHCP Unique Identifier). +% DHCPSRV_MEMFILE_GET_LINKADDR6 obtaining at most %1 IPv6 leases starting from address %2 with link address %3 +A debug message issued when the server is attempting to obtain a page of +IPv6 leases beginning with the specified address with a link address. + % DHCPSRV_MEMFILE_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. @@ -481,6 +485,26 @@ of leases beginning with the specified address. A debug message issued when the server is attempting to obtain a page of leases beginning with the specified address. +% DHCPSRV_MEMFILE_GET_RELAYID4 obtaining at most %1 IPv4 leases starting from address %2 with relay id %3 and cltt between %4 and %5 +A debug message issued when the server is attempting to obtain a page of +IPv4 leases beginning with the specified address with a relay id and client +transaction time between start and end dates. + +% DHCPSRV_MEMFILE_GET_RELAYID6 obtaining at most %1 IPv6 leases starting from address %2 with relay id %3 and link address %4 +A debug message issued when the server is attempting to obtain a page of +IPv6 leases beginning with the specified address with a relay id and +a link address. + +% DHCPSRV_MEMFILE_GET_REMOTEID4 obtaining at most %1 IPv4 leases starting from address %2 with remote id %3 and cltt between %4 and %5 +A debug message issued when the server is attempting to obtain a page of +IPv4 leases beginning with the specified address with a remote id and +client transaction time between start and end dates. + +% DHCPSRV_MEMFILE_GET_REMOTEID6 obtaining at most %1 IPv6 leases starting from address %2 with remote id %3 and link address %4 +A debug message issued when the server is attempting to obtain a page of +IPv6 leases beginning with the specified address with a remote id and +a link address. + % DHCPSRV_MEMFILE_GET_SUBID4 obtaining IPv4 leases for subnet ID %1 A debug message issued when the server is attempting to obtain all IPv4 leases for a given subnet identifier from the memory file database. diff --git a/src/lib/dhcpsrv/memfile_lease_mgr.cc b/src/lib/dhcpsrv/memfile_lease_mgr.cc index d20ca9503e..051215d8a3 100644 --- a/src/lib/dhcpsrv/memfile_lease_mgr.cc +++ b/src/lib/dhcpsrv/memfile_lease_mgr.cc @@ -2396,12 +2396,46 @@ Memfile_LeaseMgr::getLeaseLimit(ConstElementPtr parent, Lease::Type ltype, size_ return (false); } +namespace { +std::string +idtoText(const OptionBuffer& id) { + std::stringstream tmp; + tmp << std::hex; + bool delim = false; + for (std::vector<uint8_t>::const_iterator it = id.begin(); + it != id.end(); ++it) { + if (delim) { + tmp << ":"; + } + tmp << std::setw(2) << std::setfill('0') + << static_cast<unsigned int>(*it); + delim = true; + } + return (tmp.str()); +} +} // anonymous namespace + Lease4Collection Memfile_LeaseMgr::getLeases4ByRelayId(const OptionBuffer& relay_id, const IOAddress& lower_bound_address, const LeasePageSize& page_size, const time_t& qry_start_time /* = 0 */, const time_t& qry_end_time /* = 0 */) { + // Expecting IPv4 address. + if (!lower_bound_address.isV4()) { + isc_throw(InvalidAddressFamily, "expected IPv4 address while " + "retrieving leases from the lease database, got " + << lower_bound_address); + } + + LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, + DHCPSRV_MEMFILE_GET_RELAYID4) + .arg(page_size.page_size_) + .arg(lower_bound_address.toText()) + .arg(idtoText(relay_id)) + .arg(qry_start_time) + .arg(qry_end_time); + if (MultiThreadingMgr::instance().getMode()) { std::lock_guard<std::mutex> lock(*mutex_); return (getLeases4ByRelayIdInternal(relay_id, @@ -2433,6 +2467,21 @@ Memfile_LeaseMgr::getLeases4ByRemoteId(const OptionBuffer& remote_id, const LeasePageSize& page_size, const time_t& qry_start_time /* = 0 */, const time_t& qry_end_time /* = 0 */) { + // Expecting IPv4 address. + if (!lower_bound_address.isV4()) { + isc_throw(InvalidAddressFamily, "expected IPv4 address while " + "retrieving leases from the lease database, got " + << lower_bound_address); + } + + LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, + DHCPSRV_MEMFILE_GET_REMOTEID4) + .arg(page_size.page_size_) + .arg(lower_bound_address.toText()) + .arg(idtoText(remote_id)) + .arg(qry_start_time) + .arg(qry_end_time); + if (MultiThreadingMgr::instance().getMode()) { std::lock_guard<std::mutex> lock(*mutex_); return (getLeases4ByRemoteIdInternal(remote_id, @@ -2463,6 +2512,25 @@ Memfile_LeaseMgr::getLeases6ByRelayId(const DUID& relay_id, const IOAddress& link_addr, const IOAddress& lower_bound_address, const LeasePageSize& page_size) { + // Expecting IPv6 addresses. + if (!link_addr.isV6()) { + isc_throw(InvalidAddressFamily, "expected IPv6 address while " + "retrieving leases from the lease database, got " + << link_addr); + } + 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_MEMFILE_GET_RELAYID6) + .arg(page_size.page_size_) + .arg(lower_bound_address.toText()) + .arg(relay_id.toText()) + .arg(link_addr.toText()); + if (MultiThreadingMgr::instance().getMode()) { std::lock_guard<std::mutex> lock(*mutex_); return (getLeases6ByRelayIdInternal(relay_id, @@ -2497,6 +2565,10 @@ Memfile_LeaseMgr::getLeases6ByRelayIdInternal(const DUID& relay_id, // Already seen: skip it. continue; } + if ((*lb)->id_ != relay_id_data) { + // Gone after the relay id index. + break; + } last_addr = (*lb)->lease_addr_; Lease6Ptr lease = getLease6Internal(Lease::TYPE_NA, last_addr); if (lease) { @@ -2521,6 +2593,14 @@ Memfile_LeaseMgr::getLeases6ByRelayIdInternal(const DUID& relay_id, // Already seen: skip it. continue; } + if ((*lb)->link_addr_ != link_addr) { + // Gone after the link address. + break; + } + if ((*lb)->id_ != relay_id_data) { + // Gone after the relay id index. + break; + } last_addr = (*lb)->lease_addr_; Lease6Ptr lease = getLease6Internal(Lease::TYPE_NA, last_addr); if (lease) { @@ -2539,6 +2619,25 @@ Memfile_LeaseMgr::getLeases6ByRemoteId(const OptionBuffer& remote_id, const IOAddress& link_addr, const IOAddress& lower_bound_address, const LeasePageSize& page_size) { + // Expecting IPv6 addresses. + if (!link_addr.isV6()) { + isc_throw(InvalidAddressFamily, "expected IPv6 address while " + "retrieving leases from the lease database, got " + << link_addr); + } + 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_MEMFILE_GET_REMOTEID6) + .arg(page_size.page_size_) + .arg(lower_bound_address.toText()) + .arg(idtoText(remote_id)) + .arg(link_addr.toText()); + if (MultiThreadingMgr::instance().getMode()) { std::lock_guard<std::mutex> lock(*mutex_); return (getLeases6ByRemoteIdInternal(remote_id, @@ -2616,6 +2715,24 @@ Lease6Collection Memfile_LeaseMgr::getLeases6ByLink(const IOAddress& link_addr, const IOAddress& lower_bound_address, const LeasePageSize& page_size) { + // Expecting IPv6 addresses. + if (!link_addr.isV6()) { + isc_throw(InvalidAddressFamily, "expected IPv6 address while " + "retrieving leases from the lease database, got " + << link_addr); + } + 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_MEMFILE_GET_LINKADDR6) + .arg(page_size.page_size_) + .arg(lower_bound_address.toText()) + .arg(link_addr.toText()); + if (MultiThreadingMgr::instance().getMode()) { std::lock_guard<std::mutex> lock(*mutex_); return (getLeases6ByLinkInternal(link_addr, @@ -2644,6 +2761,10 @@ Memfile_LeaseMgr::getLeases6ByLinkInternal(const IOAddress& link_addr, // Already seen: skip it. continue; } + if ((*lb)->link_addr_ != link_addr) { + // Gone after the link address. + break; + } last_addr = (*lb)->lease_addr_; Lease6Ptr lease = getLease6Internal(Lease::TYPE_NA, last_addr); if (lease) { diff --git a/src/lib/dhcpsrv/memfile_lease_mgr.h b/src/lib/dhcpsrv/memfile_lease_mgr.h index f29fa0704e..7128fb6b1f 100644 --- a/src/lib/dhcpsrv/memfile_lease_mgr.h +++ b/src/lib/dhcpsrv/memfile_lease_mgr.h @@ -1065,6 +1065,8 @@ private: /// @brief stores IPv6 leases Lease6Storage storage6_; +protected: + /// @brief stores IPv6 by-relay-id cross-reference table Lease6ExtendedInfoRelayIdTable relay_id6_; @@ -1074,7 +1076,6 @@ private: /// @brief stores IPv6 by-link-addr cross-reference table Lease6SimpleExtendedInfoLinkAddrTable link_addr6_; -protected: /// @brief Holds the pointer to the DHCPv4 lease file IO. boost::shared_ptr<CSVLeaseFile4> lease_file4_; diff --git a/src/lib/dhcpsrv/tests/memfile_lease_extended_info_unittest.cc b/src/lib/dhcpsrv/tests/memfile_lease_extended_info_unittest.cc index 093d0ae30f..d3e46636ae 100644 --- a/src/lib/dhcpsrv/tests/memfile_lease_extended_info_unittest.cc +++ b/src/lib/dhcpsrv/tests/memfile_lease_extended_info_unittest.cc @@ -11,7 +11,7 @@ #include <dhcpsrv/lease_mgr.h> #include <dhcpsrv/memfile_lease_mgr.h> #include <testutils/gtest_utils.h> -#include <util/multi_threading_mgr.h> +#include <testutils/multi_threading_utils.h> #include <gtest/gtest.h> @@ -20,17 +20,36 @@ using namespace isc::asiolink; using namespace isc::data; using namespace isc::db; using namespace isc::dhcp; +using namespace isc::test; using namespace isc::util; using namespace std; namespace { +/// @brief IPv4 addresses used in the tests. +const vector<string> ADDRESS4 = { + "192.0.2.0", "192.0.2.1", "192.0.2.2", "192.0.2.3", + "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> DUID6 = { + "wwwwwwww", "BBBBBBBB", "::::::::", "0123456789acdef", + "BBBBBBBB", "$$$$$$$$", "^^^^^^^^", "\xe5\xe5\xe5\xe5\xe5\xe5\xe5\xe5" +}; + /// @brief A derivation of the lease manager exposing protected methods. class NakedMemfileLeaseMgr : public Memfile_LeaseMgr { public: /// @brief Constructor. /// - /// Creates anto create an instance of the lease manager. + /// Creates an instance of the lease manager. /// /// @param parameters Parameter map. NakedMemfileLeaseMgr(const DatabaseConnection::ParameterMap& parameters) @@ -41,7 +60,10 @@ public: virtual ~NakedMemfileLeaseMgr() { } - /// @brief Exposes protected methods. + /// @brief Exposes protected methods and members. + using Memfile_LeaseMgr::relay_id6_; + using Memfile_LeaseMgr::remote_id6_; + using Memfile_LeaseMgr::link_addr6_; using Memfile_LeaseMgr::deleteExtendedInfo6; using Memfile_LeaseMgr::addRelayId6; using Memfile_LeaseMgr::addRemoteId6; @@ -52,47 +74,1069 @@ public: typedef unique_ptr<NakedMemfileLeaseMgr> NakedMemfileLeaseMgrPtr; /// @brief Test fixture class for extended info tests. -class MemfileLeaseExtendedInfoTest : public ::testing::Test { +class MemfileExtendedInfoTest : public ::testing::Test { public: /// @brief Constructor. - MemfileLeaseExtendedInfoTest() { + MemfileExtendedInfoTest() { pmap_.clear(); lease_mgr_.reset(); + leases6.clear(); MultiThreadingMgr::instance().setMode(false); } /// @brief Destructor. - ~MemfileLeaseExtendedInfoTest() { + ~MemfileExtendedInfoTest() { pmap_.clear(); lease_mgr_.reset(); + leases6.clear(); MultiThreadingMgr::instance().setMode(false); } + /// @brief Start lease manager. + /// + /// @param universe Universe (@c Memfile_LeaseMgr::V4 or + // @c Memfile_LeaseMgr::v6). + void start(Memfile_LeaseMgr::Universe u) { + pmap_["universe"] = (u == Memfile_LeaseMgr::V4 ? "4" : "6"); + pmap_["persist"] = "false"; + pmap_["extended-info-tables"] = "true"; + + ASSERT_NO_THROW(lease_mgr_.reset(new NakedMemfileLeaseMgr(pmap_))); + EXPECT_TRUE(lease_mgr_->getExtendedInfoEnabled()); + } + + /// @brief Create and set v6 leases. + void initLease6() { + ASSERT_EQ(ADDRESS6.size(), DUID6.size()); + for (size_t i = 0; i < ADDRESS6.size(); ++i) { + Lease6Ptr lease; + string duid_str = DUID6[i]; + vector<uint8_t> duid_data; + duid_data.resize(duid_str.size()); + memmove(&duid_data[0], &duid_str[0], duid_data.size()); + DuidPtr duid(new DUID(duid_data)); + IOAddress addr(ADDRESS6[i]); + ASSERT_NO_THROW(lease.reset(new Lease6(Lease::TYPE_NA, addr, duid, + 123, 1000, 2000, + static_cast<SubnetID>(i)))); + leases6.push_back(lease); + EXPECT_TRUE(lease_mgr_->addLease(lease)); + } + } + /// @brief Parameter map. DatabaseConnection::ParameterMap pmap_; /// @brief Lease manager. NakedMemfileLeaseMgrPtr lease_mgr_; + + /// @brief V6 leases. + Lease6Collection leases6; }; /// @brief Verifies that the lease manager can start in V4. -TEST_F(MemfileLeaseExtendedInfoTest, v4) { - pmap_["universe"] = "4"; - pmap_["persist"] = "false"; - pmap_["extended-info-tables"] = "true"; +TEST_F(MemfileExtendedInfoTest, startV4) { + start(Memfile_LeaseMgr::V4); +} - EXPECT_NO_THROW(lease_mgr_.reset(new NakedMemfileLeaseMgr(pmap_))); - EXPECT_TRUE(lease_mgr_->getExtendedInfoEnabled()); +/// @brief Verifies that the lease manager can start in V4 with MT. +TEST_F(MemfileExtendedInfoTest, startV4MultiThreading) { + MultiThreadingTest mt(true); + start(Memfile_LeaseMgr::V4); } /// @brief Verifies that the lease manager can start in V6. -TEST_F(MemfileLeaseExtendedInfoTest, v6) { - pmap_["universe"] = "6"; - pmap_["persist"] = "false"; - pmap_["extended-info-tables"] = "true"; +TEST_F(MemfileExtendedInfoTest, startV6) { + start(Memfile_LeaseMgr::V6); +} + +/// @brief Verifies that the lease manager can start in V6 with MT. +TEST_F(MemfileExtendedInfoTest, startV6MultiThreading) { + MultiThreadingTest mt(true); + start(Memfile_LeaseMgr::V6); +} + +/// @brief Verifies that the lease manager can add the v6 leases. +TEST_F(MemfileExtendedInfoTest, initLease6) { + start(Memfile_LeaseMgr::V6); + 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"; + } +} + +/// @brief Verifies that the lease manager can add the v6 leases with MT. +TEST_F(MemfileExtendedInfoTest, initLease6MultiThreading) { + MultiThreadingTest mt(true); + start(Memfile_LeaseMgr::V6); + 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"; + } +} + +/// @brief Verifies that add and delete work on the by relay id table. +TEST_F(MemfileExtendedInfoTest, relayIdTable) { + // Lease manager is created with empty tables. + start(Memfile_LeaseMgr::V6); + EXPECT_EQ(0, lease_mgr_->relay_id6_.size()); + + // Create parameter values. + IOAddress lease_addr0(ADDRESS6[0]); + IOAddress lease_addr1(ADDRESS6[1]); + IOAddress lease_addr2(ADDRESS6[2]); + IOAddress link_addr4(ADDRESS6[4]); + IOAddress link_addr5(ADDRESS6[5]); + IOAddress link_addr6(ADDRESS6[6]); + IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS(); + string relay_id_str0 = DUID6[0]; + vector<uint8_t> relay_id0; + relay_id0.resize(relay_id_str0.size()); + memmove(&relay_id0[0], &relay_id_str0[0], relay_id0.size()); + string relay_id_str1 = DUID6[1]; + vector<uint8_t> relay_id1; + relay_id1.resize(relay_id_str1.size()); + memmove(&relay_id1[0], &relay_id_str1[0], relay_id1.size()); + + // Fill the table. + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, link_addr4, relay_id0)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, link_addr5, relay_id0)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, zero, relay_id1)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr1, link_addr6, relay_id0)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr1, link_addr6, relay_id1)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr2, link_addr4, relay_id1)); + + // Check delete. + EXPECT_EQ(6, lease_mgr_->relay_id6_.size()); + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(link_addr6)); + // No match so doing nothing. + EXPECT_EQ(6, lease_mgr_->relay_id6_.size()); + + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr0)); + // Removed 3 entries. + EXPECT_EQ(3, lease_mgr_->relay_id6_.size()); + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr0)); + // Already removed: doing nothing again. + EXPECT_EQ(3, lease_mgr_->relay_id6_.size()); + + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr1)); + // Removed 2 entries. + EXPECT_EQ(1, lease_mgr_->relay_id6_.size()); + + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr2)); + // Removed last entry. + EXPECT_EQ(0, lease_mgr_->relay_id6_.size()); +} + +/// @brief Verifies that add and delete work on the by remote id table. +TEST_F(MemfileExtendedInfoTest, remoteIdTable) { + // Lease manager is created with empty tables. + start(Memfile_LeaseMgr::V6); + EXPECT_EQ(0, lease_mgr_->remote_id6_.size()); + + // Create parameter values. + IOAddress lease_addr0(ADDRESS6[0]); + IOAddress lease_addr1(ADDRESS6[1]); + IOAddress lease_addr2(ADDRESS6[2]); + IOAddress link_addr4(ADDRESS6[4]); + IOAddress link_addr5(ADDRESS6[5]); + IOAddress link_addr6(ADDRESS6[6]); + IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS(); + string remote_id_str0 = DUID6[0]; + vector<uint8_t> remote_id0; + remote_id0.resize(remote_id_str0.size()); + memmove(&remote_id0[0], &remote_id_str0[0], remote_id0.size()); + string remote_id_str1 = DUID6[1]; + vector<uint8_t> remote_id1; + remote_id1.resize(remote_id_str1.size()); + memmove(&remote_id1[0], &remote_id_str1[0], remote_id1.size()); + + // Fill the table. + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, link_addr4, remote_id0)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, link_addr5, remote_id0)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, zero, remote_id1)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr1, link_addr6, remote_id0)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr1, link_addr6, remote_id1)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr2, link_addr4, remote_id1)); + + // Check delete. + EXPECT_EQ(6, lease_mgr_->remote_id6_.size()); + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(link_addr6)); + // No match so doing nothing. + EXPECT_EQ(6, lease_mgr_->remote_id6_.size()); + + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr0)); + // Removed 3 entries. + EXPECT_EQ(3, lease_mgr_->remote_id6_.size()); + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr0)); + // Already removed: doing nothing again. + EXPECT_EQ(3, lease_mgr_->remote_id6_.size()); + + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr1)); + // Removed 2 entries. + EXPECT_EQ(1, lease_mgr_->remote_id6_.size()); + + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr2)); + // Removed last entry. + EXPECT_EQ(0, lease_mgr_->remote_id6_.size()); +} + +/// @brief Verifies that add and delete work on the by link address table. +TEST_F(MemfileExtendedInfoTest, linkAddressTable) { + // Lease manager is created with empty tables. + start(Memfile_LeaseMgr::V6); + EXPECT_EQ(0, lease_mgr_->link_addr6_.size()); + + // Create parameter values. + IOAddress lease_addr0(ADDRESS6[0]); + IOAddress lease_addr1(ADDRESS6[1]); + IOAddress lease_addr2(ADDRESS6[2]); + IOAddress link_addr4(ADDRESS6[4]); + IOAddress link_addr5(ADDRESS6[5]); + IOAddress link_addr6(ADDRESS6[6]); + IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS(); + + // Fill the table. + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr0, link_addr4)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr0, link_addr5)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr0, zero)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr1, link_addr6)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr1, link_addr6)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr2, link_addr4)); + + // Check delete. + EXPECT_EQ(6, lease_mgr_->link_addr6_.size()); + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(link_addr6)); + // No match so doing nothing. + EXPECT_EQ(6, lease_mgr_->link_addr6_.size()); + + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr0)); + // Removed 3 entries. + EXPECT_EQ(3, lease_mgr_->link_addr6_.size()); + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr0)); + // Already removed: doing nothing again. + EXPECT_EQ(3, lease_mgr_->link_addr6_.size()); + + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr1)); + // Removed 2 entries. + EXPECT_EQ(1, lease_mgr_->link_addr6_.size()); + + EXPECT_NO_THROW(lease_mgr_->deleteExtendedInfo6(lease_addr2)); + // Removed last entry. + EXPECT_EQ(0, lease_mgr_->link_addr6_.size()); +} + +/// @brief Verifies that getLeases6ByRelayId works as expected. +TEST_F(MemfileExtendedInfoTest, getLeases6ByRelayId) { + // Lease manager is created with empty tables. + start(Memfile_LeaseMgr::V6); + initLease6(); + EXPECT_EQ(0, lease_mgr_->relay_id6_.size()); + + // Create parameter values. + IOAddress lease_addr0(ADDRESS6[0]); + IOAddress lease_addr1(ADDRESS6[1]); + IOAddress lease_addr2(ADDRESS6[2]); + IOAddress link_addr4(ADDRESS6[4]); + IOAddress link_addr5(ADDRESS6[5]); + IOAddress link_addr6(ADDRESS6[6]); + IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS(); + string relay_id_str0 = DUID6[0]; + vector<uint8_t> relay_id_data0; + relay_id_data0.resize(relay_id_str0.size()); + memmove(&relay_id_data0[0], &relay_id_str0[0], relay_id_data0.size()); + DUID relay_id0(relay_id_data0); + string relay_id_str1 = DUID6[1]; + vector<uint8_t> relay_id_data1; + relay_id_data1.resize(relay_id_str1.size()); + memmove(&relay_id_data1[0], &relay_id_str1[0], relay_id_data1.size()); + DUID relay_id1(relay_id_data1); + string relay_id_str2 = DUID6[2]; + vector<uint8_t> relay_id_data2; + relay_id_data2.resize(relay_id_str2.size()); + memmove(&relay_id_data2[0], &relay_id_str2[0], relay_id_data2.size()); + DUID relay_id2(relay_id_data2); + + // Fill the table. + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, + link_addr4, + relay_id_data0)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, + link_addr5, + relay_id_data0)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, + zero, + relay_id_data1)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr1, + link_addr6, + relay_id_data0)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr1, + link_addr6, + relay_id_data1)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr2, + link_addr4, + relay_id_data1)); + EXPECT_EQ(6, lease_mgr_->relay_id6_.size()); + + Lease6Collection got; + // Unknown relay id #2, no link address: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id2, + zero, + zero, + LeasePageSize(100))); + EXPECT_EQ(0, got.size()); + + // Unknown relay id #2, link address #4: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id2, + link_addr4, + zero, + LeasePageSize(100))); + EXPECT_EQ(0, got.size()); + + // Relay id #0, no link address: 3 entries but 2 addresses. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id0, + zero, + zero, + LeasePageSize(100))); + ASSERT_EQ(2, got.size()); + Lease6Ptr lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Relay id #1, no link address, partial: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + zero, + zero, + LeasePageSize(2))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Relay id #1, no link address, partial from previous: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + zero, + lease->addr_, + LeasePageSize(2))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Add another entry for last tests. + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, + link_addr4, + relay_id_data1)); + EXPECT_EQ(7, lease_mgr_->relay_id6_.size()); + + // Relay id #1, link address #4: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + link_addr4, + zero, + LeasePageSize(100))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Relay id #1, link address #4, initial partial: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + link_addr4, + zero, + LeasePageSize(1))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + + // Relay id #1, link address #4, next partial: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + link_addr4, + lease->addr_, + LeasePageSize(1))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Relay id #1, link address #4, final partial: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + link_addr4, + lease->addr_, + LeasePageSize(1))); + EXPECT_EQ(0, got.size()); +} + +/// @brief Verifies that getLeases6ByRelayId works as expected with MT. +TEST_F(MemfileExtendedInfoTest, getLeases6ByRelayIdMultiThreading) { + MultiThreadingTest mt(true); + // Lease manager is created with empty tables. + start(Memfile_LeaseMgr::V6); + initLease6(); + EXPECT_EQ(0, lease_mgr_->relay_id6_.size()); + + // Create parameter values. + IOAddress lease_addr0(ADDRESS6[0]); + IOAddress lease_addr1(ADDRESS6[1]); + IOAddress lease_addr2(ADDRESS6[2]); + IOAddress link_addr4(ADDRESS6[4]); + IOAddress link_addr5(ADDRESS6[5]); + IOAddress link_addr6(ADDRESS6[6]); + IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS(); + string relay_id_str0 = DUID6[0]; + vector<uint8_t> relay_id_data0; + relay_id_data0.resize(relay_id_str0.size()); + memmove(&relay_id_data0[0], &relay_id_str0[0], relay_id_data0.size()); + DUID relay_id0(relay_id_data0); + string relay_id_str1 = DUID6[1]; + vector<uint8_t> relay_id_data1; + relay_id_data1.resize(relay_id_str1.size()); + memmove(&relay_id_data1[0], &relay_id_str1[0], relay_id_data1.size()); + DUID relay_id1(relay_id_data1); + string relay_id_str2 = DUID6[2]; + vector<uint8_t> relay_id_data2; + relay_id_data2.resize(relay_id_str2.size()); + memmove(&relay_id_data2[0], &relay_id_str2[0], relay_id_data2.size()); + DUID relay_id2(relay_id_data2); + + // Fill the table. + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, + link_addr4, + relay_id_data0)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, + link_addr5, + relay_id_data0)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, + zero, + relay_id_data1)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr1, + link_addr6, + relay_id_data0)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr1, + link_addr6, + relay_id_data1)); + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr2, + link_addr4, + relay_id_data1)); + EXPECT_EQ(6, lease_mgr_->relay_id6_.size()); + + Lease6Collection got; + // Unknown relay id #2, no link address: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id2, + zero, + zero, + LeasePageSize(100))); + EXPECT_EQ(0, got.size()); + + // Unknown relay id #2, link address #4: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id2, + link_addr4, + zero, + LeasePageSize(100))); + EXPECT_EQ(0, got.size()); + + // Relay id #0, no link address: 3 entries but 2 addresses. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id0, + zero, + zero, + LeasePageSize(100))); + ASSERT_EQ(2, got.size()); + Lease6Ptr lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Relay id #1, no link address, partial: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + zero, + zero, + LeasePageSize(2))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Relay id #1, no link address, partial from previous: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + zero, + lease->addr_, + LeasePageSize(2))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Add another entry for last tests. + EXPECT_NO_THROW(lease_mgr_->addRelayId6(lease_addr0, + link_addr4, + relay_id_data1)); + EXPECT_EQ(7, lease_mgr_->relay_id6_.size()); + + // Relay id #1, link address #4: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + link_addr4, + zero, + LeasePageSize(100))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Relay id #1, link address #4, initial partial: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + link_addr4, + zero, + LeasePageSize(1))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + + // Relay id #1, link address #4, next partial: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + link_addr4, + lease->addr_, + LeasePageSize(1))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Relay id #1, link address #4, final partial: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRelayId(relay_id1, + link_addr4, + lease->addr_, + LeasePageSize(1))); + EXPECT_EQ(0, got.size()); +} + +/// @brief Verifies that getLeases6ByRemoteId works as expected. +TEST_F(MemfileExtendedInfoTest, getLeases6ByRemoteId) { + // Lease manager is created with empty tables. + start(Memfile_LeaseMgr::V6); + initLease6(); + EXPECT_EQ(0, lease_mgr_->remote_id6_.size()); + + // Create parameter values. + IOAddress lease_addr0(ADDRESS6[0]); + IOAddress lease_addr1(ADDRESS6[1]); + IOAddress lease_addr2(ADDRESS6[2]); + IOAddress link_addr4(ADDRESS6[4]); + IOAddress link_addr5(ADDRESS6[5]); + IOAddress link_addr6(ADDRESS6[6]); + IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS(); + string remote_id_str0 = DUID6[0]; + vector<uint8_t> remote_id0; + remote_id0.resize(remote_id_str0.size()); + memmove(&remote_id0[0], &remote_id_str0[0], remote_id0.size()); + string remote_id_str1 = DUID6[1]; + vector<uint8_t> remote_id1; + remote_id1.resize(remote_id_str1.size()); + memmove(&remote_id1[0], &remote_id_str1[0], remote_id1.size()); + string remote_id_str2 = DUID6[2]; + vector<uint8_t> remote_id2; + remote_id2.resize(remote_id_str2.size()); + memmove(&remote_id2[0], &remote_id_str2[0], remote_id2.size()); + + // Fill the table. + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, + link_addr4, + remote_id0)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, + link_addr5, + remote_id0)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, + zero, + remote_id1)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr1, + link_addr6, + remote_id0)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr1, + link_addr6, + remote_id1)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr2, + link_addr4, + remote_id1)); + EXPECT_EQ(6, lease_mgr_->remote_id6_.size()); + + Lease6Collection got; + // Unknown remote id #2, no link address: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id2, + zero, + zero, + LeasePageSize(10))); + EXPECT_EQ(0, got.size()); + + // Unknown remote id #2, link address #4: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id2, + link_addr4, + zero, + LeasePageSize(10))); + EXPECT_EQ(0, got.size()); + + // Remote id #0, no link address: 3 entries but 2 addresses. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id0, + zero, + zero, + LeasePageSize(10))); + ASSERT_EQ(2, got.size()); + Lease6Ptr lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Remote id #1, no link address, partial: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + zero, + zero, + LeasePageSize(2))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Remote id #1, no link address, partial from previous: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + zero, + lease->addr_, + LeasePageSize(2))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Add another entry for last tests. + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, + link_addr4, + remote_id1)); + EXPECT_EQ(7, lease_mgr_->remote_id6_.size()); + + // Remote id #1, link address #4: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + link_addr4, + zero, + LeasePageSize(10))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Remote id #1, link address #4, initial partial: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + link_addr4, + zero, + LeasePageSize(1))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + + // Remote id #1, link address #4, next partial: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + link_addr4, + lease->addr_, + LeasePageSize(1))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Remote id #1, link address #4, final partial: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + link_addr4, + lease->addr_, + LeasePageSize(1))); + EXPECT_EQ(0, got.size()); +} + +/// @brief Verifies that getLeases6ByRemoteId works as expected with MT. +TEST_F(MemfileExtendedInfoTest, getLeases6ByRemoteIdMultiThreading) { + MultiThreadingTest mt(true); + // Lease manager is created with empty tables. + start(Memfile_LeaseMgr::V6); + initLease6(); + EXPECT_EQ(0, lease_mgr_->remote_id6_.size()); + + // Create parameter values. + IOAddress lease_addr0(ADDRESS6[0]); + IOAddress lease_addr1(ADDRESS6[1]); + IOAddress lease_addr2(ADDRESS6[2]); + IOAddress link_addr4(ADDRESS6[4]); + IOAddress link_addr5(ADDRESS6[5]); + IOAddress link_addr6(ADDRESS6[6]); + IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS(); + string remote_id_str0 = DUID6[0]; + vector<uint8_t> remote_id0; + remote_id0.resize(remote_id_str0.size()); + memmove(&remote_id0[0], &remote_id_str0[0], remote_id0.size()); + string remote_id_str1 = DUID6[1]; + vector<uint8_t> remote_id1; + remote_id1.resize(remote_id_str1.size()); + memmove(&remote_id1[0], &remote_id_str1[0], remote_id1.size()); + string remote_id_str2 = DUID6[2]; + vector<uint8_t> remote_id2; + remote_id2.resize(remote_id_str2.size()); + memmove(&remote_id2[0], &remote_id_str2[0], remote_id2.size()); + + // Fill the table. + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, + link_addr4, + remote_id0)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, + link_addr5, + remote_id0)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, + zero, + remote_id1)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr1, + link_addr6, + remote_id0)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr1, + link_addr6, + remote_id1)); + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr2, + link_addr4, + remote_id1)); + EXPECT_EQ(6, lease_mgr_->remote_id6_.size()); + + Lease6Collection got; + // Unknown remote id #2, no link address: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id2, + zero, + zero, + LeasePageSize(10))); + EXPECT_EQ(0, got.size()); + + // Unknown remote id #2, link address #4: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id2, + link_addr4, + zero, + LeasePageSize(10))); + EXPECT_EQ(0, got.size()); + + // Remote id #0, no link address: 3 entries but 2 addresses. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id0, + zero, + zero, + LeasePageSize(10))); + ASSERT_EQ(2, got.size()); + Lease6Ptr lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Remote id #1, no link address, partial: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + zero, + zero, + LeasePageSize(2))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Remote id #1, no link address, partial from previous: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + zero, + lease->addr_, + LeasePageSize(2))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Add another entry for last tests. + EXPECT_NO_THROW(lease_mgr_->addRemoteId6(lease_addr0, + link_addr4, + remote_id1)); + EXPECT_EQ(7, lease_mgr_->remote_id6_.size()); + + // Remote id #1, link address #4: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + link_addr4, + zero, + LeasePageSize(10))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Remote id #1, link address #4, initial partial: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + link_addr4, + zero, + LeasePageSize(1))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + + // Remote id #1, link address #4, next partial: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + link_addr4, + lease->addr_, + LeasePageSize(1))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Remote id #1, link address #4, final partial: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByRemoteId(remote_id1, + link_addr4, + lease->addr_, + LeasePageSize(1))); + EXPECT_EQ(0, got.size()); +} + +/// @brief Verifies that getLeases6ByLink works as expected. +TEST_F(MemfileExtendedInfoTest, getLeases6ByLink) { + // Lease manager is created with empty tables. + start(Memfile_LeaseMgr::V6); + initLease6(); + EXPECT_EQ(0, lease_mgr_->link_addr6_.size()); + + // Create parameter values. + IOAddress lease_addr0(ADDRESS6[0]); + IOAddress lease_addr1(ADDRESS6[1]); + IOAddress lease_addr2(ADDRESS6[2]); + IOAddress link_addr4(ADDRESS6[4]); + IOAddress link_addr5(ADDRESS6[5]); + IOAddress link_addr6(ADDRESS6[6]); + IOAddress link_addr7(ADDRESS6[7]); + IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS(); + + // Fill the table. + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr0, link_addr4)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr0, link_addr5)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr0, link_addr6)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr1, link_addr6)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr1, link_addr6)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr2, link_addr4)); + EXPECT_EQ(6, lease_mgr_->link_addr6_.size()); + + Lease6Collection got; + // Unknown link address #7: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr7, + zero, + LeasePageSize(10))); + EXPECT_EQ(0, got.size()); + + // Link address #4: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr4, + zero, + LeasePageSize(10))); + + ASSERT_EQ(2, got.size()); + Lease6Ptr lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Link address #5: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr5, + zero, + LeasePageSize(10))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + + // Link address #6: 3 entries but 2 addresses. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr6, + zero, + LeasePageSize(10))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Add another entry for last tests. + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr2, link_addr6)); + EXPECT_EQ(7, lease_mgr_->link_addr6_.size()); + + // Link address #6: initial partial: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr6, + zero, + LeasePageSize(2))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Link address #6: next partial: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr6, + lease->addr_, + LeasePageSize(2))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Link address #6: further partial: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr6, + lease->addr_, + LeasePageSize(2))); + EXPECT_EQ(0, got.size()); +} + +/// @brief Verifies that getLeases6ByLink works as expected with MT. +TEST_F(MemfileExtendedInfoTest, getLeases6ByLinkMultiThreading) { + MultiThreadingTest mt(true); + // Lease manager is created with empty tables. + start(Memfile_LeaseMgr::V6); + initLease6(); + EXPECT_EQ(0, lease_mgr_->link_addr6_.size()); + + // Create parameter values. + IOAddress lease_addr0(ADDRESS6[0]); + IOAddress lease_addr1(ADDRESS6[1]); + IOAddress lease_addr2(ADDRESS6[2]); + IOAddress link_addr4(ADDRESS6[4]); + IOAddress link_addr5(ADDRESS6[5]); + IOAddress link_addr6(ADDRESS6[6]); + IOAddress link_addr7(ADDRESS6[7]); + IOAddress zero = IOAddress::IPV6_ZERO_ADDRESS(); + + // Fill the table. + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr0, link_addr4)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr0, link_addr5)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr0, link_addr6)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr1, link_addr6)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr1, link_addr6)); + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr2, link_addr4)); + EXPECT_EQ(6, lease_mgr_->link_addr6_.size()); + + Lease6Collection got; + // Unknown link address #7: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr7, + zero, + LeasePageSize(10))); + EXPECT_EQ(0, got.size()); + + // Link address #4: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr4, + zero, + LeasePageSize(10))); + + ASSERT_EQ(2, got.size()); + Lease6Ptr lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); + + // Link address #5: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr5, + zero, + LeasePageSize(10))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + + // Link address #6: 3 entries but 2 addresses. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr6, + zero, + LeasePageSize(10))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Add another entry for last tests. + EXPECT_NO_THROW(lease_mgr_->addLinkAddr6(lease_addr2, link_addr6)); + EXPECT_EQ(7, lease_mgr_->link_addr6_.size()); + + // Link address #6: initial partial: 2 entries. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr6, + zero, + LeasePageSize(2))); + ASSERT_EQ(2, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr0, lease->addr_); + lease = got[1]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr1, lease->addr_); + + // Link address #6: next partial: 1 entry. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr6, + lease->addr_, + LeasePageSize(2))); + ASSERT_EQ(1, got.size()); + lease = got[0]; + ASSERT_TRUE(lease); + EXPECT_EQ(lease_addr2, lease->addr_); - EXPECT_NO_THROW(lease_mgr_.reset(new NakedMemfileLeaseMgr(pmap_))); - EXPECT_TRUE(lease_mgr_->getExtendedInfoEnabled()); + // Link address #6: further partial: nothing. + EXPECT_NO_THROW(got = lease_mgr_->getLeases6ByLink(link_addr6, + lease->addr_, + LeasePageSize(2))); + EXPECT_EQ(0, got.size()); } } // namespace |