]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5651] Implemented LeaseMgr methods retrieving ranges/pages of IPv4 leases.
authorMarcin Siodelski <marcin@isc.org>
Mon, 25 Jun 2018 19:47:20 +0000 (21:47 +0200)
committerMarcin Siodelski <marcin@isc.org>
Mon, 25 Jun 2018 19:47:20 +0000 (21:47 +0200)
19 files changed:
src/lib/dhcpsrv/cql_lease_mgr.cc
src/lib/dhcpsrv/cql_lease_mgr.h
src/lib/dhcpsrv/db_exceptions.h
src/lib/dhcpsrv/dhcpsrv_messages.mes
src/lib/dhcpsrv/lease_mgr.cc
src/lib/dhcpsrv/lease_mgr.h
src/lib/dhcpsrv/memfile_lease_mgr.cc
src/lib/dhcpsrv/memfile_lease_mgr.h
src/lib/dhcpsrv/mysql_lease_mgr.cc
src/lib/dhcpsrv/mysql_lease_mgr.h
src/lib/dhcpsrv/pgsql_lease_mgr.cc
src/lib/dhcpsrv/pgsql_lease_mgr.h
src/lib/dhcpsrv/tests/cql_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.h
src/lib/dhcpsrv/tests/lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc

index a225585ab28cedfaca16f6f1324beaeb461ee8f5..377efc3ddd8d4cc1a05bdb2598acc82a3d9ecb0b 100644 (file)
@@ -217,6 +217,12 @@ public:
     static constexpr StatementTag GET_LEASE4_HWADDR = "GET_LEASE4_HWADDR";
     // Get lease4 by HW address & subnet ID
     static constexpr StatementTag GET_LEASE4_HWADDR_SUBID = "GET_LEASE4_HWADDR_SUBID";
+    // Get range of lease4 from first lease with a limit
+    static constexpr StatementTag GET_LEASE4_LIMIT = "GET_LEASE4_LIMIT";
+    // Get range of lease4 from address with limit (paging)
+    static constexpr StatementTag GET_LEASE4_PAGE = "GET_LEASE4_PAGE";
+    // Get range of lease4 between two addresses
+    static constexpr StatementTag GET_LEASE4_RANGE = "GET_LEASE4_RANGE";
     // Get lease4 by subnet ID
     static constexpr StatementTag GET_LEASE4_SUBID = "GET_LEASE4_SUBID";
     /// @}
@@ -240,6 +246,9 @@ constexpr StatementTag CqlLease4Exchange::GET_LEASE4_CLIENTID;
 constexpr StatementTag CqlLease4Exchange::GET_LEASE4_CLIENTID_SUBID;
 constexpr StatementTag CqlLease4Exchange::GET_LEASE4_HWADDR;
 constexpr StatementTag CqlLease4Exchange::GET_LEASE4_HWADDR_SUBID;
+constexpr StatementTag CqlLease4Exchange::GET_LEASE4_LIMIT;
+constexpr StatementTag CqlLease4Exchange::GET_LEASE4_PAGE;
+constexpr StatementTag CqlLease4Exchange::GET_LEASE4_RANGE;
 constexpr StatementTag CqlLease4Exchange::GET_LEASE4_SUBID;
 
 StatementMap CqlLease4Exchange::tagged_statements_{
@@ -349,6 +358,38 @@ StatementMap CqlLease4Exchange::tagged_statements_{
       "AND subnet_id = ? "
       "ALLOW FILTERING "}},
 
+    // Get range of lease4 from first lease with a limit (paging)
+    {GET_LEASE4_LIMIT,
+     {GET_LEASE4_LIMIT,
+      "SELECT "
+      "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
+      "fqdn_fwd, fqdn_rev, hostname, state "
+      "FROM lease4 "
+      "LIMIT ? "
+      "ALLOW FILTERING "}},
+
+    // Get range of lease4 from address with a limit (paging)
+    {GET_LEASE4_PAGE,
+     {GET_LEASE4_PAGE,
+      "SELECT "
+      "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
+      "fqdn_fwd, fqdn_rev, hostname, state "
+      "FROM lease4 "
+      "WHERE TOKEN(address) > TOKEN(?) "
+      "LIMIT ? "
+      "ALLOW FILTERING "}},
+
+    // Get range of lease4 between two addresses
+    {GET_LEASE4_RANGE,
+     {GET_LEASE4_RANGE,
+      "SELECT "
+      "address, hwaddr, client_id, valid_lifetime, expire, subnet_id, "
+      "fqdn_fwd, fqdn_rev, hostname, state "
+      "FROM lease4 "
+      "WHERE address >= ? "
+      "AND address <= ? "
+      "ALLOW FILTERING "}},
+
      // Gets an IPv4 lease(s) with specified subnet-id
      {GET_LEASE4_SUBID,
       {GET_LEASE4_SUBID,
@@ -2082,6 +2123,73 @@ CqlLeaseMgr::getLeases4() const {
     return (result);
 }
 
+Lease4Collection
+CqlLeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address,
+                        const LeasePageSize& page_size) const {
+    if (page_size.page_size_ == 0) {
+        isc_throw(OutOfRange, "page size of retrieved leases must not be 0");
+    }
+
+    if (page_size.page_size_ > std::numeric_limits<uint32_t>::max()) {
+        isc_throw(OutOfRange, "page size of retrieved leases must not be greater than "
+                  << std::numeric_limits<uint32_t>::max());
+    }
+
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_PAGE4)
+        .arg(page_size.page_size_)
+        .arg(lower_bound_address.toText());
+
+    AnyArray data;
+
+    cass_int32_t address_data = 0;
+    if (!lower_bound_address.isV4Zero()) {
+        address_data = static_cast<cass_int32_t>(lower_bound_address.toUint32());
+        data.add(&address_data);
+    }
+
+    cass_int32_t page_size_data = static_cast<cass_int32_t>(page_size.page_size_);
+    data.add(&page_size_data);
+
+    // Get the data.
+    Lease4Collection result;
+    std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
+    exchange4->getLeaseCollection(lower_bound_address.isV4Zero() ?
+                                  CqlLease4Exchange::GET_LEASE4_LIMIT :
+                                  CqlLease4Exchange::GET_LEASE4_PAGE,
+                                  data, result);
+
+    return (result);
+}
+
+Lease4Collection
+CqlLeaseMgr::getLeases4(const IOAddress& lower_bound_address,
+                        const IOAddress& upper_bound_address) const {
+    if (upper_bound_address < lower_bound_address) {
+        isc_throw(InvalidRange, "upper bound address " << upper_bound_address
+                  << " is lower than lower bound address " << lower_bound_address);
+    }
+
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_CQL_GET_ADDR_RANGE4)
+        .arg(lower_bound_address.toText())
+        .arg(upper_bound_address.toText());
+
+    // Set up the WHERE clause value
+    AnyArray data;
+
+    cass_int32_t lb_address_data = static_cast<cass_int32_t>(lower_bound_address.toUint32());
+    data.add(&lb_address_data);
+
+    cass_int32_t ub_address_data = static_cast<cass_int32_t>(upper_bound_address.toUint32());
+    data.add(&ub_address_data);
+
+    // Get the data.
+    Lease4Collection result;
+    std::unique_ptr<CqlLease4Exchange> exchange4(new CqlLease4Exchange(dbconn_));
+    exchange4->getLeaseCollection(CqlLease4Exchange::GET_LEASE4_RANGE, data, result);
+
+    return (result);
+}
+
 Lease6Ptr
 CqlLeaseMgr::getLease6(Lease::Type lease_type, const IOAddress &addr) const {
     std::string addr_data = addr.toText();
index 69adf64500a503f833b626bb86d714b8c8263895..6dc17f42655738e9bf7ec56d2020140be3f2f50d 100644 (file)
@@ -215,6 +215,50 @@ public:
     /// this backend.
     virtual Lease4Collection getLeases4() const override;
 
+    /// @brief Returns range of IPv4 leases using paging.
+    ///
+    /// This method implements paged browsing of the lease database. The first
+    /// parameter specifies a page size. The second parameter is optional and
+    /// specifies the starting address of the range. This address is excluded
+    /// from the returned range. The IPv4 zero address (default) denotes that
+    /// the first page should be returned. There is no guarantee about the
+    /// order of returned leases.
+    ///
+    /// The typical usage of this method is as follows:
+    /// - Get the first page of leases by specifying IPv4 zero address as the
+    ///   beginning of the range.
+    /// - Last address of the returned range should be used as a starting
+    ///   address for the next page in the subsequent call.
+    /// - If the number of leases returned is lower than the page size, it
+    ///   indicates that the last page has been retrieved.
+    /// - If there are no leases returned it indicates that the previous page
+    ///   was the last page.
+    ///
+    /// @param lower_bound_address IPv4 address used as lower bound for the
+    /// returned range.
+    /// @param page_size maximum size of the page returned.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& lower_bound_address,
+               const LeasePageSize& page_size) const override;
+
+    /// @brief Returns a range of IPv4 leases.
+    ///
+    /// Returned leases are ordered by IPv4 addresses.
+    ///
+    /// @param lower_bound_address IPv4 address used as a lower bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    /// @param upper_bound_address IPv4 address used as an upper bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& lower_bound_address,
+               const asiolink::IOAddress& upper_bound_address) const override;
+
     /// @brief Returns existing IPv6 lease for a given IPv6 address.
     ///
     /// For a given address, we assume that there will be only one lease.
index 46fc58bdd05c3be463bb0635c2300e780bd6065c..64e99f461223b4bf863aa4a39ab1a729dc7915ac 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2015-2017 Internet Systems Consortium, Inc. ("ISC")
+// Copyright (C) 2015-2018 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
@@ -59,6 +59,14 @@ public:
         isc::Exception(file, line, what) {}
 };
 
+/// @brief Upper bound address is lower than lower bound address while
+/// retrieving a range of leases.
+class InvalidRange : public Exception {
+public:
+    InvalidRange(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
 }  // namespace isc
 }  // namespace dhcp
 
index 8d6e4fa36e2cdda55968aeb004671e3eb527de9b..576be84cd15b05cd956cdd947dc1e6704d990427 100644 (file)
@@ -279,6 +279,14 @@ A debug message issued when the server is attempting to obtain an IPv6
 lease from the Cassandra database for a client with the specified IAID
 (Identity Association ID), Subnet ID and DUID (DHCP Unique Identifier).
 
+% DHCPSRV_CQL_GET_ADDR_RANGE4 obtaining all IPv4 leases with addresses in range from %1 to %2
+A debug message issued when the server is attempting to obtain leases
+with addresses in the specified range.
+
+% DHCPSRV_CQL_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.
+
 % DHCPSRV_CQL_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 Cassandra database.
@@ -477,6 +485,14 @@ in the message.
 A debug message issued when the server is attempting to obtain all IPv4
 leases from the memory file database.
 
+% DHCPSRV_MEMFILE_GET_ADDR_RANGE4 obtaining all IPv4 leases with addresses in range from %1 to %2
+A debug message issued when the server is attempting to obtain leases
+with addresses in the specified range.
+
+% 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.
+
 % DHCPSRV_MEMFILE_GET6 obtaining all IPv6 leases
 A debug message issued when the server is attempting to obtain all IPv6
 leases from the memory file database.
@@ -729,6 +745,14 @@ leases from the MySQL database.
 A debug message issued when the server is attempting to obtain an IPv4
 lease from the MySQL database for the specified address.
 
+% DHCPSRV_MYSQL_GET_ADDR_RANGE4 obtaining all IPv4 leases with addresses in range from %1 to %2
+A debug message issued when the server is attempting to obtain leases
+with addresses in the specified range.
+
+% 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.
+
 % DHCPSRV_MYSQL_GET_ADDR6 obtaining IPv6 lease for address %1, lease type %2
 A debug message issued when the server is attempting to obtain an IPv6
 lease from the MySQL database for the specified address.
@@ -905,6 +929,10 @@ lease from the PostgreSQL database for the specified address.
 A debug message issued when the server is attempting to obtain an IPv6
 lease from the PostgreSQL database for the specified address.
 
+% DHCPSRV_PGSQL_GET_ADDR_RANGE4 obtaining all IPv4 leases with addresses in range from %1 to %2
+A debug message issued when the server is attempting to obtain leases
+with addresses in the specified range.
+
 % DHCPSRV_PGSQL_GET_CLIENTID obtaining IPv4 leases for client ID %1
 A debug message issued when the server is attempting to obtain a set
 of IPv4 leases from the PostgreSQL database for a client with the specified
@@ -935,6 +963,10 @@ A debug message issued when the server is attempting to obtain an IPv6
 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_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.
+
 % DHCPSRV_PGSQL_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 PostgreSQL database.
index 1defefc259b66e0664532af617d1d5a42d23534a..235b3495e32ffe60a3673051bb95efbf4ce05e2c 100644 (file)
@@ -30,6 +30,19 @@ using namespace std;
 namespace isc {
 namespace dhcp {
 
+LeasePageSize::LeasePageSize(const size_t page_size)
+    : page_size_(page_size) {
+
+    if (page_size_ == 0) {
+        isc_throw(OutOfRange, "page size of retrieved leases must not be 0");
+    }
+
+    if (page_size_ > std::numeric_limits<uint32_t>::max()) {
+        isc_throw(OutOfRange, "page size of retrieved leases must not be greater than "
+                  << std::numeric_limits<uint32_t>::max());
+    }
+}
+
 Lease6Ptr
 LeaseMgr::getLease6(Lease::Type type, const DUID& duid,
                     uint32_t iaid, SubnetID subnet_id) const {
index a820304ae28fa04c417803e264ecb9ee3624a951..0e5ca9c256209979e20858fe6a7cd2fe08125795 100644 (file)
@@ -64,6 +64,20 @@ namespace dhcp {
 /// @brief Pair containing major and minor versions
 typedef std::pair<uint32_t, uint32_t> VersionPair;
 
+/// @brief Wraps value holding size of the page with leases.
+class LeasePageSize {
+public:
+
+    /// @brief Constructor.
+    ///
+    /// @param page_size page size value.
+    /// @throw OutOfRange if page size is 0 or greater than uint32_t numeric
+    /// limit.
+    explicit LeasePageSize(const size_t page_size);
+
+    const size_t page_size_; ///< Holds page size.
+};
+
 /// @brief Contains a single row of lease statistical data
 ///
 /// The contents of the row consist of a subnet ID, a lease
@@ -350,6 +364,50 @@ public:
     /// @return Lease collection (may be empty if no IPv4 lease found).
     virtual Lease4Collection getLeases4() const = 0;
 
+    /// @brief Returns range of IPv4 leases using paging.
+    ///
+    /// This method implements paged browsing of the lease database. The first
+    /// parameter specifies a page size. The second parameter is optional and
+    /// specifies the starting address of the range. This address is excluded
+    /// from the returned range. The IPv4 zero address (default) denotes that
+    /// the first page should be returned. There is no guarantee about the
+    /// order of returned leases.
+    ///
+    /// The typical usage of this method is as follows:
+    /// - Get the first page of leases by specifying IPv4 zero address as the
+    ///   beginning of the range.
+    /// - Last address of the returned range should be used as a starting
+    ///   address for the next page in the subsequent call.
+    /// - If the number of leases returned is lower than the page size, it
+    ///   indicates that the last page has been retrieved.
+    /// - If there are no leases returned it indicates that the previous page
+    ///   was the last page.
+    ///
+    /// @param lower_bound_address IPv4 address used as lower bound for the
+    /// returned range.
+    /// @param page_size maximum size of the page returned.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& lower_bound_address,
+               const LeasePageSize& page_size) const = 0;
+
+    /// @brief Returns a range of IPv4 leases.
+    ///
+    /// Returned leases are ordered by IPv4 addresses.
+    ///
+    /// @param lower_bound_address IPv4 address used as a lower bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    /// @param upper_bound_address IPv4 address used as an upper bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& lower_bound_address,
+               const asiolink::IOAddress& upper_bound_address) const = 0;
+
     /// @brief Returns existing IPv6 lease for a given IPv6 address.
     ///
     /// For a given address, we assume that there will be only one lease.
index 449dae4564711ceea61440a09043bab57fcf4acc..5fb3c239a513b1324a6a2d611cf53cb02ba9532a 100644 (file)
@@ -38,6 +38,7 @@ const char* KEA_LFC_EXECUTABLE_ENV_NAME = "KEA_LFC_EXECUTABLE";
 
 } // end of anonymous namespace
 
+using namespace isc::asiolink;
 using namespace isc::util;
 
 namespace isc {
@@ -883,6 +884,59 @@ Memfile_LeaseMgr::getLeases4() const {
    return (collection);
 }
 
+Lease4Collection
+Memfile_LeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address,
+                             const LeasePageSize& page_size) const {
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_PAGE4)
+        .arg(page_size.page_size_)
+        .arg(lower_bound_address.toText());
+
+    Lease4Collection collection;
+    const Lease4StorageAddressIndex& idx = storage4_.get<AddressIndexTag>();
+    Lease4StorageAddressIndex::const_iterator lb = idx.lower_bound(lower_bound_address);
+
+    // Exclude the lower bound address specified by the caller.
+    if ((lb != idx.end()) && ((*lb)->addr_ == lower_bound_address)) {
+        ++lb;
+    }
+
+    // Return all other leases being within the page size.
+    for (auto lease = lb;
+         (lease != idx.end()) && (std::distance(lb, lease) < page_size.page_size_);
+         ++lease) {
+        collection.push_back(Lease4Ptr(new Lease4(**lease)));
+    }
+
+    return (collection);
+}
+
+Lease4Collection
+Memfile_LeaseMgr::getLeases4(const IOAddress& lower_bound_address,
+                             const IOAddress& upper_bound_address) const {
+    // Check if the range boundaries aren't swapped.
+    if (upper_bound_address < lower_bound_address) {
+        isc_throw(InvalidRange, "upper bound address " << upper_bound_address
+                  << " is lower than lower bound address " << lower_bound_address);
+    }
+
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MEMFILE_GET_ADDR_RANGE4)
+        .arg(lower_bound_address.toText())
+        .arg(upper_bound_address.toText());
+
+    Lease4Collection collection;
+    const Lease4StorageAddressIndex& idx = storage4_.get<AddressIndexTag>();
+    std::pair<Lease4StorageAddressIndex::const_iterator,
+              Lease4StorageAddressIndex::const_iterator> l =
+        std::make_pair(idx.lower_bound(lower_bound_address),
+                       idx.upper_bound(upper_bound_address));
+
+    for (auto lease = l.first; lease != l.second; ++lease) {
+        collection.push_back(Lease4Ptr(new Lease4(**lease)));
+    }
+
+    return (collection);
+}
+
 Lease6Ptr
 Memfile_LeaseMgr::getLease6(Lease::Type type,
                             const isc::asiolink::IOAddress& addr) const {
index 3af59246a823197be8450036e07f3a46f2776737..efb69175890b4492a5dd25913307b08f8c62c705 100644 (file)
@@ -232,6 +232,50 @@ public:
     /// @return Lease collection (may be empty if no IPv4 lease found).
     virtual Lease4Collection getLeases4() const;
 
+    /// @brief Returns range of IPv4 leases using paging.
+    ///
+    /// This method implements paged browsing of the lease database. The first
+    /// parameter specifies a page size. The second parameter is optional and
+    /// specifies the starting address of the range. This address is excluded
+    /// from the returned range. The IPv4 zero address (default) denotes that
+    /// the first page should be returned. There is no guarantee about the
+    /// order of returned leases.
+    ///
+    /// The typical usage of this method is as follows:
+    /// - Get the first page of leases by specifying IPv4 zero address as the
+    ///   beginning of the range.
+    /// - Last address of the returned range should be used as a starting
+    ///   address for the next page in the subsequent call.
+    /// - If the number of leases returned is lower than the page size, it
+    ///   indicates that the last page has been retrieved.
+    /// - If there are no leases returned it indicates that the previous page
+    ///   was the last page.
+    ///
+    /// @param lower_bound_address IPv4 address used as lower bound for the
+    /// returned range.
+    /// @param page_size maximum size of the page returned.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& lower_bound_address,
+               const LeasePageSize& page_size) const;
+
+    /// @brief Returns a range of IPv4 leases.
+    ///
+    /// Returned leases are ordered by IPv4 addresses.
+    ///
+    /// @param lower_bound_address IPv4 address used as a lower bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    /// @param upper_bound_address IPv4 address used as an upper bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& lower_bound_address,
+               const asiolink::IOAddress& upper_bound_address) const;
+
     /// @brief Returns existing IPv6 lease for a given IPv6 address.
     ///
     /// This function returns a copy of the lease. The modification in the
index 93593e9054cf64bb05423cbec4101b81293eca6e..76ae230aefabc5e87ee31b08cfe67a9bdb6d3b74 100644 (file)
@@ -25,6 +25,7 @@
 #include <time.h>
 
 using namespace isc;
+using namespace isc::asiolink;
 using namespace isc::dhcp;
 using namespace std;
 
@@ -137,6 +138,22 @@ tagged_statements = { {
                         "state "
                             "FROM lease4 "
                             "WHERE hwaddr = ? AND subnet_id = ?"},
+    {MySqlLeaseMgr::GET_LEASE4_PAGE,
+                    "SELECT address, hwaddr, client_id, "
+                        "valid_lifetime, expire, subnet_id, "
+                        "fqdn_fwd, fqdn_rev, hostname, "
+                        "state "
+                            "FROM lease4 "
+                            "WHERE address > ? "
+                            "ORDER BY address "
+                            "LIMIT ?"},
+    {MySqlLeaseMgr::GET_LEASE4_RANGE,
+                    "SELECT address, hwaddr, client_id, "
+                        "valid_lifetime, expire, subnet_id, "
+                        "fqdn_fwd, fqdn_rev, hostname, "
+                        "state "
+                            "FROM lease4 "
+                            "WHERE address >= ? AND address <= ?"},
     {MySqlLeaseMgr::GET_LEASE4_SUBID,
                     "SELECT address, hwaddr, client_id, "
                         "valid_lifetime, expire, subnet_id, "
@@ -1902,6 +1919,71 @@ MySqlLeaseMgr::getLeases4() const {
     return (result);
 }
 
+Lease4Collection
+MySqlLeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address,
+                          const LeasePageSize& page_size) const {
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_GET_PAGE4)
+        .arg(page_size.page_size_)
+        .arg(lower_bound_address.toText());
+
+    // Prepare WHERE clause
+    MYSQL_BIND inbind[2];
+    memset(inbind, 0, sizeof(inbind));
+
+    // Bind lower bound address
+    uint32_t lb_address_data = lower_bound_address.toUint32();
+    inbind[0].buffer_type = MYSQL_TYPE_LONG;
+    inbind[0].buffer = reinterpret_cast<char*>(&lb_address_data);
+    inbind[0].is_unsigned = MLM_TRUE;
+
+    // Bind page size value
+    size_t* ps = const_cast<size_t*>(&page_size.page_size_);
+    inbind[1].buffer_type = MYSQL_TYPE_LONG;
+    inbind[1].buffer = reinterpret_cast<char*>(ps);
+    inbind[1].is_unsigned = MLM_TRUE;
+
+    // Get the leases
+    Lease4Collection result;
+    getLeaseCollection(GET_LEASE4_PAGE, inbind, result);
+
+    return (result);
+}
+
+Lease4Collection
+MySqlLeaseMgr::getLeases4(const IOAddress& lower_bound_address,
+                          const IOAddress& upper_bound_address) const {
+    if (upper_bound_address < lower_bound_address) {
+        isc_throw(InvalidRange, "upper bound address " << upper_bound_address
+                  << " is lower than lower bound address " << lower_bound_address);
+    }
+
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_MYSQL_GET_ADDR_RANGE4)
+        .arg(lower_bound_address.toText())
+        .arg(upper_bound_address.toText());
+
+    // Prepare WHERE clause
+    MYSQL_BIND inbind[2];
+    memset(inbind, 0, sizeof(inbind));
+
+    // Bind lower bound address as uint32 value
+    uint32_t lb_address_data = lower_bound_address.toUint32();
+    inbind[0].buffer_type = MYSQL_TYPE_LONG;
+    inbind[0].buffer = reinterpret_cast<char*>(&lb_address_data);
+    inbind[0].is_unsigned = MLM_TRUE;
+
+    // Bind upper bound address as uint32 value
+    uint32_t ub_address_data = upper_bound_address.toUint32();
+    inbind[1].buffer_type = MYSQL_TYPE_LONG;
+    inbind[1].buffer = reinterpret_cast<char*>(&ub_address_data);
+    inbind[1].is_unsigned = MLM_TRUE;
+
+    // Get the leases
+    Lease4Collection result;
+    getLeaseCollection(GET_LEASE4_RANGE, inbind, result);
+
+    return (result);
+}
+
 Lease6Ptr
 MySqlLeaseMgr::getLease6(Lease::Type lease_type,
                          const isc::asiolink::IOAddress& addr) const {
index 38615124c460a8e2e0b36f5f9a515dfa97c0a59e..5f320ad9228cad6a91b453af2091e76c02788432 100644 (file)
@@ -206,6 +206,50 @@ public:
     /// @return Lease collection (may be empty if no IPv4 lease found).
     virtual Lease4Collection getLeases4() const;
 
+    /// @brief Returns range of IPv4 leases using paging.
+    ///
+    /// This method implements paged browsing of the lease database. The first
+    /// parameter specifies a page size. The second parameter is optional and
+    /// specifies the starting address of the range. This address is excluded
+    /// from the returned range. The IPv4 zero address (default) denotes that
+    /// the first page should be returned. There is no guarantee about the
+    /// order of returned leases.
+    ///
+    /// The typical usage of this method is as follows:
+    /// - Get the first page of leases by specifying IPv4 zero address as the
+    ///   beginning of the range.
+    /// - Last address of the returned range should be used as a starting
+    ///   address for the next page in the subsequent call.
+    /// - If the number of leases returned is lower than the page size, it
+    ///   indicates that the last page has been retrieved.
+    /// - If there are no leases returned it indicates that the previous page
+    ///   was the last page.
+    ///
+    /// @param lower_bound_address IPv4 address used as lower bound for the
+    /// returned range.
+    /// @param page_size maximum size of the page returned.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& lower_bound_address,
+               const LeasePageSize& page_size) const;
+
+    /// @brief Returns a range of IPv4 leases.
+    ///
+    /// Returned leases are ordered by IPv4 addresses.
+    ///
+    /// @param lower_bound_address IPv4 address used as a lower bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    /// @param upper_bound_address IPv4 address used as an upper bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& lower_bound_address,
+               const asiolink::IOAddress& upper_bound_address) const;
+
     /// @brief Returns existing IPv6 lease for a given IPv6 address.
     ///
     /// For a given address, we assume that there will be only one lease.
@@ -516,6 +560,8 @@ public:
         GET_LEASE4_HWADDR,           // Get lease4 by HW address
         GET_LEASE4_HWADDR_SUBID,     // Get lease4 by HW address & subnet ID
         GET_LEASE4_SUBID,            // Get IPv4 leases by subnet ID
+        GET_LEASE4_PAGE,             // Get page of leases beginning with an address
+        GET_LEASE4_RANGE,            // Get range of leases between addresses
         GET_LEASE4_EXPIRE,           // Get lease4 by expiration.
         GET_LEASE6,                  // Get all IPv6 leases
         GET_LEASE6_ADDR,             // Get lease6 by address
index f6e2a1843400d07627130a60d4db885e063f8e37..84030634c07ab1701301d796637243c829320edc 100644 (file)
@@ -21,6 +21,7 @@
 #include <time.h>
 
 using namespace isc;
+using namespace isc::asiolink;
 using namespace isc::dhcp;
 using namespace std;
 
@@ -111,6 +112,28 @@ PgSqlTaggedStatement tagged_statements[] = {
       "FROM lease4 "
       "WHERE hwaddr = $1 AND subnet_id = $2"},
 
+    // GET_LEASE4_PAGE
+    { 2, { OID_INT8, OID_INT8 },
+      "get_lease4_page",
+      "SELECT address, hwaddr, client_id, "
+        "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
+        "fqdn_fwd, fqdn_rev, hostname, "
+        "state "
+      "FROM lease4 "
+      "WHERE address > $1 "
+      "ORDER BY address "
+      "LIMIT $2"},
+
+    // GET_LEASE4_RANGE
+    { 2, { OID_INT8, OID_INT8 },
+      "get_lease4_range",
+      "SELECT address, hwaddr, client_id, "
+        "valid_lifetime, extract(epoch from expire)::bigint, subnet_id, "
+        "fqdn_fwd, fqdn_rev, hostname, "
+        "state "
+      "FROM lease4 "
+      "WHERE address >= $1 AND address <= $2"},
+
     // GET_LEASE4_SUBID
     { 1, { OID_INT8 },
       "get_lease4_subid",
@@ -1294,6 +1317,64 @@ PgSqlLeaseMgr::getLeases4() const {
     return (result);
 }
 
+Lease4Collection
+PgSqlLeaseMgr::getLeases4(const asiolink::IOAddress& lower_bound_address,
+                             const LeasePageSize& page_size) const {
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_PAGE4)
+        .arg(page_size.page_size_)
+        .arg(lower_bound_address.toText());
+
+    // Prepare WHERE clause
+    PsqlBindArray bind_array;
+
+    // Bind lower bound address
+    std::string lb_address_data = boost::lexical_cast<std::string>
+        (lower_bound_address.toUint32());
+    bind_array.add(lb_address_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 the leases
+    Lease4Collection result;
+    getLeaseCollection(GET_LEASE4_PAGE, bind_array, result);
+
+    return (result);
+}
+
+Lease4Collection
+PgSqlLeaseMgr::getLeases4(const IOAddress& lower_bound_address,
+                          const IOAddress& upper_bound_address) const {
+    if (upper_bound_address < lower_bound_address) {
+        isc_throw(InvalidRange, "upper bound address " << upper_bound_address
+                  << " is lower than lower bound address " << lower_bound_address);
+    }
+
+    LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL, DHCPSRV_PGSQL_GET_ADDR_RANGE4)
+        .arg(lower_bound_address.toText())
+        .arg(upper_bound_address.toText());
+
+    // Prepare WHERE clause
+    PsqlBindArray bind_array;
+
+    // Bind lower bound address
+    std::string lb_address_data = boost::lexical_cast<std::string>
+        (lower_bound_address.toUint32());
+    bind_array.add(lb_address_data);
+
+    // Bind upper bound address
+    std::string ub_address_data = boost::lexical_cast<std::string>
+        (upper_bound_address.toUint32());
+    bind_array.add(ub_address_data);
+
+    // Get the leases
+    Lease4Collection result;
+    getLeaseCollection(GET_LEASE4_RANGE, bind_array, result);
+
+    return (result);
+}
+
 Lease6Ptr
 PgSqlLeaseMgr::getLease6(Lease::Type lease_type,
                          const isc::asiolink::IOAddress& addr) const {
index 79353dfcdc43369c278a78330660a525e74813a1..7ecf6fa8c1f2a866fbf42c90eb485ac6960ac8d0 100644 (file)
@@ -187,6 +187,50 @@ public:
     /// @return Lease collection (may be empty if no IPv4 lease found).
     virtual Lease4Collection getLeases4() const;
 
+    /// @brief Returns range of IPv4 leases using paging.
+    ///
+    /// This method implements paged browsing of the lease database. The first
+    /// parameter specifies a page size. The second parameter is optional and
+    /// specifies the starting address of the range. This address is excluded
+    /// from the returned range. The IPv4 zero address (default) denotes that
+    /// the first page should be returned. There is no guarantee about the
+    /// order of returned leases.
+    ///
+    /// The typical usage of this method is as follows:
+    /// - Get the first page of leases by specifying IPv4 zero address as the
+    ///   beginning of the range.
+    /// - Last address of the returned range should be used as a starting
+    ///   address for the next page in the subsequent call.
+    /// - If the number of leases returned is lower than the page size, it
+    ///   indicates that the last page has been retrieved.
+    /// - If there are no leases returned it indicates that the previous page
+    ///   was the last page.
+    ///
+    /// @param lower_bound_address IPv4 address used as lower bound for the
+    /// returned range.
+    /// @param page_size maximum size of the page returned.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& lower_bound_address,
+               const LeasePageSize& page_size) const;
+
+    /// @brief Returns a range of IPv4 leases.
+    ///
+    /// Returned leases are ordered by IPv4 addresses.
+    ///
+    /// @param lower_bound_address IPv4 address used as a lower bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    /// @param upper_bound_address IPv4 address used as an upper bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& lower_bound_address,
+               const asiolink::IOAddress& upper_bound_address) const;
+
     /// @brief Returns existing IPv6 lease for a given IPv6 address.
     ///
     /// For a given address, we assume that there will be only one lease.
@@ -483,6 +527,8 @@ public:
         GET_LEASE4_CLIENTID_SUBID,  // Get lease4 by client ID & subnet ID
         GET_LEASE4_HWADDR,          // Get lease4 by HW address
         GET_LEASE4_HWADDR_SUBID,    // Get lease4 by HW address & subnet ID
+        GET_LEASE4_PAGE,            // Get page of leases beginning with an address
+        GET_LEASE4_RANGE,           // Get range of leases between addresses
         GET_LEASE4_SUBID,           // Get IPv4 leases by subnet ID
         GET_LEASE4_EXPIRE,          // Get expired lease4
         GET_LEASE6,                 // Get all IPv6 leases
index 74beea413a98c46032db7da91131c22b717d4f0b..5fa8b47757b27e6d6d9cee19629ceafae5762973 100644 (file)
@@ -587,6 +587,16 @@ TEST_F(CqlLeaseMgrTest, getLeases4) {
     testGetLeases4();
 }
 
+// Test that a range of IPv4 leases is returned with paging.
+TEST_F(CqlLeaseMgrTest, getLeases4Paged) {
+    testGetLeases4Paged();
+}
+
+// Test that a range of IPv4 leases is returmed.
+TEST_F(CqlLeaseMgrTest, getLeases4Range) {
+    testGetLeases4Range();
+}
+
 /// @brief Basic Lease4 Checks
 ///
 /// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
index ed1208fe2149d8a46b89612fe8541312e2fea353..601938205b79b4a3be83314d47a282119e0fabce 100644 (file)
@@ -7,6 +7,7 @@
 #include <config.h>
 
 #include <asiolink/io_address.h>
+#include <exceptions/exceptions.h>
 #include <dhcpsrv/cfgmgr.h>
 #include <dhcpsrv/database_connection.h>
 #include <dhcpsrv/lease_mgr_factory.h>
 #include <stats/stats_mgr.h>
 
 #include <boost/foreach.hpp>
+#include <boost/scoped_ptr.hpp>
 
 #include <gtest/gtest.h>
 
+#include <limits>
 #include <sstream>
 
 using namespace std;
@@ -1245,6 +1248,102 @@ GenericLeaseMgrTest::testGetLeases4() {
     ASSERT_EQ(leases.size(), returned.size());
 }
 
+void
+GenericLeaseMgrTest::testGetLeases4Paged() {
+    // Get the leases to be used for the test and add to the database.
+    vector<Lease4Ptr> leases = createLeases4();
+    for (size_t i = 0; i < leases.size(); ++i) {
+        EXPECT_TRUE(lmptr_->addLease(leases[i]));
+    }
+
+    Lease4Collection all_leases;
+
+    IOAddress last_address = IOAddress("0.0.0.0");
+    for (auto i = 0; i < 1000; ++i) {
+        Lease4Collection page = lmptr_->getLeases4(last_address, LeasePageSize(3));
+
+        // Collect leases in a common structure. They may be out of order.
+        for (Lease4Ptr lease : page) {
+            all_leases.push_back(lease);
+        }
+
+        // Empty page means there are no more leases.
+        if (page.empty()) {
+            break;
+
+        } else {
+            // Record last returned address because it is going to be used
+            // as an argument for the next call.
+            last_address = page[page.size() - 1]->addr_;
+        }
+    }
+
+    // Make sure that we got exactly the number of leases that we earlier
+    // stored in the database.
+    EXPECT_EQ(leases.size(), all_leases.size());
+
+    // Make sure that all leases that we stored in the lease database
+    // have been retrieved.
+    for (Lease4Ptr lease : leases) {
+        bool found = false;
+        for (Lease4Ptr returned_lease : all_leases) {
+            if (lease->addr_ == returned_lease->addr_) {
+                found = true;
+                break;
+            }
+        }
+        EXPECT_TRUE(found) << "lease for address " << lease->addr_.toText()
+            << " was not returned in any of the pages";
+    }
+
+    boost::scoped_ptr<LeasePageSize> lease_page_size;
+
+    // The maximum allowed value for the limit is max for uint32_t.
+    size_t oor = static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 1;
+    EXPECT_THROW(lease_page_size.reset(new LeasePageSize(oor)), OutOfRange);
+
+    // Zero page size is illegal too.
+    EXPECT_THROW(lease_page_size.reset(new LeasePageSize(0)), OutOfRange);
+}
+
+void
+GenericLeaseMgrTest::testGetLeases4Range() {
+    // Get the leases to be used for the test and add to the database.
+    vector<Lease4Ptr> leases = createLeases4();
+    for (size_t i = 0; i < leases.size(); ++i) {
+        EXPECT_TRUE(lmptr_->addLease(leases[i]));
+    }
+
+    // All addresses in the specified range should be returned.
+    Lease4Collection returned = lmptr_->getLeases4(IOAddress("192.0.2.2"),
+                                                   IOAddress("192.0.2.6"));
+    EXPECT_EQ(5, returned.size());
+
+    // The lower bound address is below the range, so the first two addresses
+    // in the database should be returned.
+    returned = lmptr_->getLeases4(IOAddress("192.0.1.0"), IOAddress("192.0.2.1"));
+    EXPECT_EQ(2, returned.size());
+
+    // The lower bound address is the last address in the database, so only this
+    // address should be returned.
+    returned = lmptr_->getLeases4(IOAddress("192.0.2.7"), IOAddress("192.0.2.15"));
+    EXPECT_EQ(1, returned.size());
+
+    // The lower bound is below the range and the upper bound is above the range,
+    // so the whole range should be returned.
+    returned = lmptr_->getLeases4(IOAddress("192.0.1.7"), IOAddress("192.0.2.15"));
+    EXPECT_EQ(8, returned.size());
+
+    // No addresses should be returned because our desired range does not
+    // overlap with leases in the database.
+    returned = lmptr_->getLeases4(IOAddress("192.0.2.8"), IOAddress("192.0.2.15"));
+    EXPECT_TRUE(returned.empty());
+
+    // Swapping the lower bound and upper bound should cause an error.
+    EXPECT_THROW(lmptr_->getLeases4(IOAddress("192.0.2.8"), IOAddress("192.0.2.1")),
+                 InvalidRange);
+}
+
 void
 GenericLeaseMgrTest::testGetLeases6SubnetId() {
     // Get the leases to be used for the test and add to the database.
@@ -2860,6 +2959,17 @@ LeaseMgrDbLostCallbackTest::testDbLostCallback() {
     EXPECT_TRUE(callback_called_);
 }
 
+void
+GenericLeaseMgrTest::checkLeaseRange(const Lease4Collection& returned,
+                                     const std::vector<std::string>& expected_addresses) {
+    ASSERT_EQ(expected_addresses.size(), returned.size());
+
+    for (auto a = returned.cbegin(); a != returned.cend(); ++a) {
+        EXPECT_EQ(expected_addresses[std::distance(returned.cbegin(), a)],
+                  (*a)->addr_.toText());
+    }
+}
+
 void
 GenericLeaseMgrTest::checkQueryAgainstRowSet(const LeaseStatsQueryPtr& query,
                                              const RowSet& expected_rows) {
index 09b0be7520db0d41f9701aa18e278974c5e939da..c4112d6a23173074e95a034adf7b4afc940532dd 100644 (file)
@@ -203,6 +203,12 @@ public:
     /// @brief Test method which returns all IPv4 leases.
     void testGetLeases4();
 
+    /// @brief Test method which returns range of IPv4 leases with paging.
+    void testGetLeases4Paged();
+
+    /// @brief Test method which returns range of IPv4 leases.
+    void testGetLeases4Range();
+
     /// @brief Test method which returns all IPv6 leases for Subnet ID.
     void testGetLeases6SubnetId();
 
@@ -426,6 +432,13 @@ public:
     /// @param row_set - set of rows expected to be found in the query rows
     void checkQueryAgainstRowSet(const LeaseStatsQueryPtr& qry, const RowSet& row_set);
 
+    /// @brief Checks if specified range of leases was returned.
+    ///
+    /// @param returned collection of leases returned.
+    /// @param expected_addresses ordered collection of expected addresses.
+    void checkLeaseRange(const Lease4Collection& returned,
+                         const std::vector<std::string>& expected_addresses);
+
     /// @brief String forms of IPv4 addresses
     std::vector<std::string>  straddress4_;
 
index 28e5c97e9b66bf4899ae01e9ef956478ea095d99..63daded660413000ef6ea8cc5bc3e51c4c8f6e62 100644 (file)
@@ -145,6 +145,54 @@ public:
         return (Lease4Collection());
     }
 
+    /// @brief Returns range of IPv4 leases using paging.
+    ///
+    /// This method implements paged browsing of the lease database. The first
+    /// parameter specifies a page size. The second parameter is optional and
+    /// specifies the starting address of the range. This address is excluded
+    /// from the returned range. The IPv4 zero address (default) denotes that
+    /// the first page should be returned. There is no guarantee about the
+    /// order of returned leases.
+    ///
+    /// The typical usage of this method is as follows:
+    /// - Get the first page of leases by specifying IPv4 zero address as the
+    ///   beginning of the range.
+    /// - Last address of the returned range should be used as a starting
+    ///   address for the next page in the subsequent call.
+    /// - If the number of leases returned is lower than the page size, it
+    ///   indicates that the last page has been retrieved.
+    /// - If there are no leases returned it indicates that the previous page
+    ///   was the last page.
+    ///
+    /// @param lower_bound_address IPv4 address used as lower bound for the
+    /// returned range.
+    /// @param page_size maximum size of the page returned.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& /* lower_bound_address */,
+               const LeasePageSize& /* page_size */) const {
+        return (Lease4Collection());
+    }
+
+    /// @brief Returns a range of IPv4 leases.
+    ///
+    /// Returned leases are ordered by IPv4 addresses.
+    ///
+    /// @param lower_bound_address IPv4 address used as a lower bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    /// @param upper_bound_address IPv4 address used as an upper bound for the
+    /// returned range. The lease for this address is included in the returned
+    /// range if the lease exists.
+    ///
+    /// @return Lease collection (may be empty if no IPv4 lease found).
+    virtual Lease4Collection
+    getLeases4(const asiolink::IOAddress& /* lower_bound_address */,
+               const asiolink::IOAddress& /* upper_bound_address */) const {
+        return (Lease4Collection());
+    }
+
     /// @brief Returns existing IPv6 lease for a given IPv6 address.
     ///
     /// @param addr address of the searched lease
index 84735a9e116a9c7a9d84dad2afe2b906d82bdf5f..99632a7f61db414319f20e7b1dd4f7e9aeecbbce 100644 (file)
@@ -930,6 +930,18 @@ TEST_F(MemfileLeaseMgrTest, getLeases4) {
     testGetLeases4();
 }
 
+// Test that a range of IPv4 leases is returned with paging.
+TEST_F(MemfileLeaseMgrTest, getLeases4Paged) {
+    startBackend(V4);
+    testGetLeases4Paged();
+}
+
+// Test that a range of IPv4 leases is returmed.
+TEST_F(MemfileLeaseMgrTest, getLeases4Range) {
+    startBackend(V4);
+    testGetLeases4Range();
+}
+
 // This test checks that all IPv6 leases for a specified subnet id are returned.
 TEST_F(MemfileLeaseMgrTest, getLeases6SubnetId) {
     startBackend(V6);
index dcacbc403e40f86e72f8871fc60620339c3a9681..7cc21eec4a073c0c30f8188bcfdf8f189df86b01 100644 (file)
@@ -355,6 +355,16 @@ TEST_F(MySqlLeaseMgrTest, getLeases4) {
     testGetLeases4();
 }
 
+// Test that a range of IPv4 leases is returned with paging.
+TEST_F(MySqlLeaseMgrTest, getLeases4Paged) {
+    testGetLeases4Paged();
+}
+
+// Test that a range of IPv4 leases is returmed.
+TEST_F(MySqlLeaseMgrTest, getLeases4Range) {
+    testGetLeases4Range();
+}
+
 // This test checks that all IPv6 leases for a specified subnet id are returned.
 TEST_F(MySqlLeaseMgrTest, getLeases6SubnetId) {
     testGetLeases6SubnetId();
index f0b3ec7b478750fccb318a362a948b89f17f7d6e..364c10638fbbaf5a15ba4bae314ec44c8f945e1f 100644 (file)
@@ -344,6 +344,16 @@ TEST_F(PgSqlLeaseMgrTest, getLeases4) {
     testGetLeases4();
 }
 
+// Test that a range of IPv4 leases is returned with paging.
+TEST_F(PgSqlLeaseMgrTest, getLeases4Paged) {
+    testGetLeases4Paged();
+}
+
+// Test that a range of IPv4 leases is returmed.
+TEST_F(PgSqlLeaseMgrTest, getLeases4Range) {
+    testGetLeases4Range();
+}
+
 // This test checks that all IPv6 leases for a specified subnet id are returned.
 TEST_F(PgSqlLeaseMgrTest, getLeases6SubnetId) {
     testGetLeases6SubnetId();