Commit 36a28182 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰

[2952] MySQL LeaseMgr unit-tests refactored

parent d038572f
......@@ -18,7 +18,7 @@
#include <dhcp/duid.h>
#include <dhcpsrv/lease_mgr.h>
#include <dhcpsrv/memfile_lease_mgr.h>
#include <dhcpsrv/tests/test_utils.h>
#include <gtest/gtest.h>
#include <iostream>
......@@ -28,10 +28,11 @@ using namespace std;
using namespace isc;
using namespace isc::asiolink;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
namespace {
// empty class for now, but may be extended once Addr6 becomes bigger
class MemfileLeaseMgrTest : public ::testing::Test {
class MemfileLeaseMgrTest : public GenericLeaseMgrTest {
public:
MemfileLeaseMgrTest() {
}
......
......@@ -20,6 +20,7 @@
#include <dhcpsrv/tests/test_utils.h>
#include <exceptions/exceptions.h>
#include <gtest/gtest.h>
#include <algorithm>
......@@ -39,18 +40,6 @@ namespace {
// This holds statements to create and destroy the schema.
#include "schema_copy.h"
// IPv4 and IPv6 addresses used in the tests
const char* 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",
NULL
};
const char* 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",
NULL
};
// Connection strings.
// Database: keatest
// Host: localhost
......@@ -155,26 +144,12 @@ void createSchema() {
/// Opens the database prior to each test and closes it afterwards.
/// All pending transactions are deleted prior to closure.
class MySqlLeaseMgrTest : public ::testing::Test {
class MySqlLeaseMgrTest : public GenericLeaseMgrTest {
public:
/// @brief Constructor
///
/// Deletes everything from the database and opens it.
MySqlLeaseMgrTest() {
// Initialize address strings and IOAddresses
for (int i = 0; ADDRESS4[i] != NULL; ++i) {
string addr(ADDRESS4[i]);
straddress4_.push_back(addr);
IOAddress ioaddr(addr);
ioaddress4_.push_back(ioaddr);
}
for (int i = 0; ADDRESS6[i] != NULL; ++i) {
string addr(ADDRESS6[i]);
straddress6_.push_back(addr);
IOAddress ioaddr(addr);
ioaddress6_.push_back(ioaddr);
}
// Ensure schema is the correct one.
destroySchema();
......@@ -214,319 +189,6 @@ public:
lmptr_ = &(LeaseMgrFactory::instance());
}
/// @brief Initialize Lease4 Fields
///
/// Returns a pointer to a Lease4 structure. Different values are put into
/// the lease according to the address passed.
///
/// This is just a convenience function for the test methods.
///
/// @param address Address to use for the initialization
///
/// @return Lease4Ptr. This will not point to anything if the
/// initialization failed (e.g. unknown address).
Lease4Ptr initializeLease4(std::string address) {
Lease4Ptr lease(new Lease4());
// Set the address of the lease
lease->addr_ = IOAddress(address);
// Initialize unused fields.
lease->ext_ = 0; // Not saved
lease->t1_ = 0; // Not saved
lease->t2_ = 0; // Not saved
lease->fixed_ = false; // Unused
lease->hostname_ = std::string(""); // Unused
lease->fqdn_fwd_ = false; // Unused
lease->fqdn_rev_ = false; // Unused
lease->comments_ = std::string(""); // Unused
// Set other parameters. For historical reasons, address 0 is not used.
if (address == straddress4_[0]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x08);
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x42)));
lease->valid_lft_ = 8677;
lease->cltt_ = 168256;
lease->subnet_id_ = 23;
} else if (address == straddress4_[1]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x19);
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53)));
lease->valid_lft_ = 3677;
lease->cltt_ = 123456;
lease->subnet_id_ = 73;
} else if (address == straddress4_[2]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x2a);
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x64)));
lease->valid_lft_ = 5412;
lease->cltt_ = 234567;
lease->subnet_id_ = 73; // Same as lease 1
} else if (address == straddress4_[3]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x19); // Same as lease 1
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x75)));
// The times used in the next tests are deliberately restricted - we
// should be able to cope with valid lifetimes up to 0xffffffff.
// However, this will lead to overflows.
// @TODO: test overflow conditions when code has been fixed
lease->valid_lft_ = 7000;
lease->cltt_ = 234567;
lease->subnet_id_ = 37;
} else if (address == straddress4_[4]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x4c);
// Same ClientId as straddr4_[1]
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 7736;
lease->cltt_ = 222456;
lease->subnet_id_ = 85;
} else if (address == straddress4_[5]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x19); // Same as lease 1
// Same ClientId and IAID as straddress4_1
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 7832;
lease->cltt_ = 227476;
lease->subnet_id_ = 175;
} else if (address == straddress4_[6]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x6e);
// Same ClientId as straddress4_1
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 1832;
lease->cltt_ = 627476;
lease->subnet_id_ = 112;
} else if (address == straddress4_[7]) {
lease->hwaddr_ = vector<uint8_t>(); // Empty
lease->client_id_ = ClientIdPtr(); // Empty
lease->valid_lft_ = 7975;
lease->cltt_ = 213876;
lease->subnet_id_ = 19;
} else {
// Unknown address, return an empty pointer.
lease.reset();
}
return (lease);
}
/// @brief Initialize Lease6 Fields
///
/// Returns a pointer to a Lease6 structure. Different values are put into
/// the lease according to the address passed.
///
/// This is just a convenience function for the test methods.
///
/// @param address Address to use for the initialization
///
/// @return Lease6Ptr. This will not point to anything if the initialization
/// failed (e.g. unknown address).
Lease6Ptr initializeLease6(std::string address) {
Lease6Ptr lease(new Lease6());
// Set the address of the lease
lease->addr_ = IOAddress(address);
// Initialize unused fields.
lease->t1_ = 0; // Not saved
lease->t2_ = 0; // Not saved
lease->fixed_ = false; // Unused
lease->hostname_ = std::string(""); // Unused
lease->fqdn_fwd_ = false; // Unused
lease->fqdn_rev_ = false; // Unused
lease->comments_ = std::string(""); // Unused
// Set other parameters. For historical reasons, address 0 is not used.
if (address == straddress6_[0]) {
lease->type_ = Lease6::LEASE_IA_TA;
lease->prefixlen_ = 4;
lease->iaid_ = 142;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x77)));
lease->preferred_lft_ = 900;
lease->valid_lft_ = 8677;
lease->cltt_ = 168256;
lease->subnet_id_ = 23;
} else if (address == straddress6_[1]) {
lease->type_ = Lease6::LEASE_IA_TA;
lease->prefixlen_ = 0;
lease->iaid_ = 42;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
lease->preferred_lft_ = 3600;
lease->valid_lft_ = 3677;
lease->cltt_ = 123456;
lease->subnet_id_ = 73;
} else if (address == straddress6_[2]) {
lease->type_ = Lease6::LEASE_IA_PD;
lease->prefixlen_ = 7;
lease->iaid_ = 89;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x3a)));
lease->preferred_lft_ = 1800;
lease->valid_lft_ = 5412;
lease->cltt_ = 234567;
lease->subnet_id_ = 73; // Same as lease 1
} else if (address == straddress6_[3]) {
lease->type_ = Lease6::LEASE_IA_NA;
lease->prefixlen_ = 28;
lease->iaid_ = 0xfffffffe;
vector<uint8_t> duid;
for (uint8_t i = 31; i < 126; ++i) {
duid.push_back(i);
}
lease->duid_ = DuidPtr(new DUID(duid));
// The times used in the next tests are deliberately restricted - we
// should be able to cope with valid lifetimes up to 0xffffffff.
// However, this will lead to overflows.
// @TODO: test overflow conditions when code has been fixed
lease->preferred_lft_ = 7200;
lease->valid_lft_ = 7000;
lease->cltt_ = 234567;
lease->subnet_id_ = 37;
} else if (address == straddress6_[4]) {
// Same DUID and IAID as straddress6_1
lease->type_ = Lease6::LEASE_IA_PD;
lease->prefixlen_ = 15;
lease->iaid_ = 42;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
lease->preferred_lft_ = 4800;
lease->valid_lft_ = 7736;
lease->cltt_ = 222456;
lease->subnet_id_ = 671;
} else if (address == straddress6_[5]) {
// Same DUID and IAID as straddress6_1
lease->type_ = Lease6::LEASE_IA_PD;
lease->prefixlen_ = 24;
lease->iaid_ = 42; // Same as lease 4
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
// Same as lease 4
lease->preferred_lft_ = 5400;
lease->valid_lft_ = 7832;
lease->cltt_ = 227476;
lease->subnet_id_ = 175;
} else if (address == straddress6_[6]) {
// Same DUID as straddress6_1
lease->type_ = Lease6::LEASE_IA_PD;
lease->prefixlen_ = 24;
lease->iaid_ = 93;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0x42)));
// Same as lease 4
lease->preferred_lft_ = 5400;
lease->valid_lft_ = 1832;
lease->cltt_ = 627476;
lease->subnet_id_ = 112;
} else if (address == straddress6_[7]) {
// Same IAID as straddress6_1
lease->type_ = Lease6::LEASE_IA_PD;
lease->prefixlen_ = 24;
lease->iaid_ = 42;
lease->duid_ = DuidPtr(new DUID(vector<uint8_t>(8, 0xe5)));
lease->preferred_lft_ = 5600;
lease->valid_lft_ = 7975;
lease->cltt_ = 213876;
lease->subnet_id_ = 19;
} else {
// Unknown address, return an empty pointer.
lease.reset();
}
return (lease);
}
/// @brief Check Leases present and different
///
/// Checks a vector of lease pointers and ensures that all the leases
/// they point to are present and different. If not, a GTest assertion
/// will fail.
///
/// @param leases Vector of pointers to leases
template <typename T>
void checkLeasesDifferent(const std::vector<T>& leases) const {
// Check they were created
for (int i = 0; i < leases.size(); ++i) {
ASSERT_TRUE(leases[i]);
}
// Check they are different
for (int i = 0; i < (leases.size() - 1); ++i) {
for (int j = (i + 1); j < leases.size(); ++j) {
stringstream s;
s << "Comparing leases " << i << " & " << j << " for equality";
SCOPED_TRACE(s.str());
EXPECT_TRUE(*leases[i] != *leases[j]);
}
}
}
/// @brief Creates leases for the test
///
/// Creates all leases for the test and checks that they are different.
///
/// @return vector<Lease4Ptr> Vector of pointers to leases
vector<Lease4Ptr> createLeases4() {
// Create leases for each address
vector<Lease4Ptr> leases;
for (int i = 0; i < straddress4_.size(); ++i) {
leases.push_back(initializeLease4(straddress4_[i]));
}
EXPECT_EQ(8, leases.size());
// Check all were created and that they are different.
checkLeasesDifferent(leases);
return (leases);
}
/// @brief Creates leases for the test
///
/// Creates all leases for the test and checks that they are different.
///
/// @return vector<Lease6Ptr> Vector of pointers to leases
vector<Lease6Ptr> createLeases6() {
// Create leases for each address
vector<Lease6Ptr> leases;
for (int i = 0; i < straddress6_.size(); ++i) {
leases.push_back(initializeLease6(straddress6_[i]));
}
EXPECT_EQ(8, leases.size());
// Check all were created and that they are different.
checkLeasesDifferent(leases);
return (leases);
}
// Member variables
LeaseMgr* lmptr_; ///< Pointer to the lease manager
vector<string> straddress4_; ///< String forms of IPv4 addresses
vector<IOAddress> ioaddress4_; ///< IOAddress forms of IPv4 addresses
vector<string> straddress6_; ///< String forms of IPv6 addresses
vector<IOAddress> ioaddress6_; ///< IOAddress forms of IPv6 addresses
};
/// @brief Check that database can be opened
......@@ -888,7 +550,7 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSize) {
leases[1]->hwaddr_.resize(i, i);
EXPECT_TRUE(lmptr_->addLease(leases[1]));
// @todo: Simply use HWAddr directly once 2589 is implemented
Lease4Collection returned =
Lease4Collection returned =
lmptr_->getLease4(HWAddr(leases[1]->hwaddr_, HTYPE_ETHER));
ASSERT_EQ(1, returned.size());
......@@ -917,7 +579,7 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetId) {
// Get the leases matching the hardware address of lease 1 and
// subnet ID of lease 1. Result should be a single lease - lease 1.
// @todo: Simply use HWAddr directly once 2589 is implemented
Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
HTYPE_ETHER), leases[1]->subnet_id_);
ASSERT_TRUE(returned);
......@@ -954,16 +616,11 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetId) {
leases[1]->addr_ = leases[2]->addr_;
EXPECT_TRUE(lmptr_->addLease(leases[1]));
// @todo: Simply use HWAddr directly once 2589 is implemented
EXPECT_THROW(returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
HTYPE_ETHER),
leases[1]->subnet_id_),
EXPECT_THROW(returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
HTYPE_ETHER),
leases[1]->subnet_id_),
isc::dhcp::MultipleRecords);
// Delete all leases in the database
for (int i = 0; ADDRESS4[i] != NULL; ++i) {
IOAddress addr(ADDRESS4[i]);
(void) lmptr_->deleteLease(addr);
}
}
// @brief Get lease4 by hardware address and subnet ID (2)
......@@ -981,8 +638,8 @@ TEST_F(MySqlLeaseMgrTest, getLease4HwaddrSubnetIdSize) {
leases[1]->hwaddr_.resize(i, i);
EXPECT_TRUE(lmptr_->addLease(leases[1]));
// @todo: Simply use HWAddr directly once 2589 is implemented
Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
HTYPE_ETHER),
Lease4Ptr returned = lmptr_->getLease4(HWAddr(leases[1]->hwaddr_,
HTYPE_ETHER),
leases[1]->subnet_id_);
ASSERT_TRUE(returned);
detailCompareLease(leases[1], returned);
......
......@@ -13,12 +13,29 @@
// PERFORMANCE OF THIS SOFTWARE.
#include "test_utils.h"
#include <asiolink/io_address.h>
#include <gtest/gtest.h>
#include <sstream>
using namespace std;
using namespace isc::asiolink;
namespace isc {
namespace dhcp {
namespace test {
// IPv4 and IPv6 addresses used in the tests
const char* 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",
NULL
};
const char* 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",
NULL
};
void
detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
// Compare address strings. Comparison of address objects is not used, as
......@@ -69,6 +86,293 @@ detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second) {
EXPECT_EQ(first->subnet_id_, second->subnet_id_);
}
GenericLeaseMgrTest::GenericLeaseMgrTest() {
// Initialize address strings and IOAddresses
for (int i = 0; ADDRESS4[i] != NULL; ++i) {
string addr(ADDRESS4[i]);
straddress4_.push_back(addr);
IOAddress ioaddr(addr);
ioaddress4_.push_back(ioaddr);
}
for (int i = 0; ADDRESS6[i] != NULL; ++i) {
string addr(ADDRESS6[i]);
straddress6_.push_back(addr);
IOAddress ioaddr(addr);
ioaddress6_.push_back(ioaddr);
}
}
Lease4Ptr
GenericLeaseMgrTest::initializeLease4(std::string address) {
Lease4Ptr lease(new Lease4());
// Set the address of the lease
lease->addr_ = IOAddress(address);
// Initialize unused fields.
lease->ext_ = 0; // Not saved
lease->t1_ = 0; // Not saved
lease->t2_ = 0; // Not saved
lease->fixed_ = false; // Unused
lease->hostname_ = std::string(""); // Unused
lease->fqdn_fwd_ = false; // Unused
lease->fqdn_rev_ = false; // Unused
lease->comments_ = std::string(""); // Unused
// Set other parameters. For historical reasons, address 0 is not used.
if (address == straddress4_[0]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x08);
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x42)));
lease->valid_lft_ = 8677;
lease->cltt_ = 168256;
lease->subnet_id_ = 23;
} else if (address == straddress4_[1]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x19);
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53)));
lease->valid_lft_ = 3677;
lease->cltt_ = 123456;
lease->subnet_id_ = 73;
} else if (address == straddress4_[2]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x2a);
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x64)));
lease->valid_lft_ = 5412;
lease->cltt_ = 234567;
lease->subnet_id_ = 73; // Same as lease 1
} else if (address == straddress4_[3]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x19); // Same as lease 1
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x75)));
// The times used in the next tests are deliberately restricted - we
// should be able to cope with valid lifetimes up to 0xffffffff.
// However, this will lead to overflows.
// @TODO: test overflow conditions when code has been fixed
lease->valid_lft_ = 7000;
lease->cltt_ = 234567;
lease->subnet_id_ = 37;
} else if (address == straddress4_[4]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x4c);
// Same ClientId as straddr4_[1]
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 7736;
lease->cltt_ = 222456;
lease->subnet_id_ = 85;
} else if (address == straddress4_[5]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x19); // Same as lease 1
// Same ClientId and IAID as straddress4_1
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 7832;
lease->cltt_ = 227476;
lease->subnet_id_ = 175;
} else if (address == straddress4_[6]) {
lease->hwaddr_ = vector<uint8_t>(6, 0x6e);
// Same ClientId as straddress4_1
lease->client_id_ = ClientIdPtr(
new ClientId(vector<uint8_t>(8, 0x53))); // Same as lease 1
lease->valid_lft_ = 1832;
lease->cltt_ = 627476;
lease->subnet_id_ = 112;
} else if (address == straddress4_[7]) {
lease->hwaddr_ = vector<uint8_t>(); // Empty
lease->client_id_ = ClientIdPtr(); // Empty
lease->valid_lft_ = 7975;
lease->cltt_ = 213876;
lease->subnet_id_ = 19;
} else {
// Unknown address, return an empty pointer.
lease.reset();
}
return (lease);
}
Lease6Ptr
GenericLeaseMgrTest::initializeLease6(std::string address) {
Lease6Ptr lease(new Lease6());