/// @brief Destructor (closes database)
virtual ~MySqlLeaseMgr();
- /// #brief Create a new context.
+ /// @brief Create a new context.
///
/// The database is opened with all the SQL commands pre-compiled.
///
#include <dhcpsrv/dhcpsrv_log.h>
#include <dhcpsrv/dhcpsrv_exceptions.h>
#include <dhcpsrv/pgsql_lease_mgr.h>
+#include <util/multi_threading_mgr.h>
#include <boost/static_assert.hpp>
using namespace isc::db;
using namespace isc::dhcp;
using namespace isc::data;
+using namespace isc::util;
using namespace std;
namespace {
bool fetch_type_;
};
+// PgSqlLeaseContext Constructor
+
+PgSqlLeaseContext::PgSqlLeaseContext(
+ const DatabaseConnection::ParameterMap& parameters) : conn_(parameters) {
+}
+
+// PgSqlLeaseContextAlloc Constructor and Destructor
+
+PgSqlLeaseMgr::PgSqlLeaseContextAlloc::PgSqlLeaseContextAlloc(
+ const PgSqlLeaseMgr& mgr) : ctx_(), mgr_(mgr) {
+
+ if (MultiThreadingMgr::instance().getMode()) {
+ {
+ lock_guard<mutex> lock(mgr_.pool_->mutex_);
+ if (!mgr_.pool_->pool_.empty()) {
+ ctx_ = mgr_.pool_->pool_.back();
+ mgr_.pool_->pool_.pop_back();
+ }
+ }
+ if (!ctx_) {
+ ctx_ = mgr_.createContext();
+ }
+ } else {
+ if (mgr_.pool_->pool_.empty()) {
+ isc_throw(Unexpected, "No available PgSql lease context?!");
+ }
+ ctx_ = mgr_.pool_->pool_.back();
+ }
+}
+
+PgSqlLeaseMgr::PgSqlLeaseContextAlloc::~PgSqlLeaseContextAlloc() {
+ if (MultiThreadingMgr::instance().getMode()) {
+ lock_guard<mutex> lock(mgr_.pool_->mutex_);
+ mgr_.pool_->pool_.push_back(ctx_);
+ }
+}
+
+// PgSqlLeaseMgr Constructor and Destructor
+
PgSqlLeaseMgr::PgSqlLeaseMgr(const DatabaseConnection::ParameterMap& parameters)
- : LeaseMgr(), exchange4_(new PgSqlLease4Exchange()),
- exchange6_(new PgSqlLease6Exchange()), parameters_(parameters),
- conn_(parameters) {
+ : LeaseMgr(), parameters_(parameters) {
+
// Validate schema version first.
std::pair<uint32_t, uint32_t> code_version(PG_SCHEMA_VERSION_MAJOR,
PG_SCHEMA_VERSION_MINOR);
<< db_version.second);
}
+ // Create an initial context.
+ pool_.reset(new PgSqlLeaseContextPool());
+ pool_->pool_.push_back(createContext());
+}
+
+PgSqlLeaseMgr::~PgSqlLeaseMgr() {
+}
+
+// Create context.
+
+PgSqlLeaseContextPtr
+PgSqlLeaseMgr::createContext() const {
+
+ PgSqlLeaseContextPtr ctx(new PgSqlLeaseContext(parameters_));
+
// Open the database.
- conn_.openDatabase();
+ ctx->conn_.openDatabase();
// Now prepare the SQL statements.
- int i = 0;
- for( ; tagged_statements[i].text != NULL ; ++i) {
- conn_.prepareStatement(tagged_statements[i]);
+ unsigned i = 0;
+ for ( ; tagged_statements[i].text != NULL ; ++i) {
+ ctx->conn_.prepareStatement(tagged_statements[i]);
}
// Just in case somebody foo-barred things
isc_throw(DbOpenError, "Number of statements prepared: " << i
<< " does not match expected count:" << NUM_STATEMENTS);
}
-}
-PgSqlLeaseMgr::~PgSqlLeaseMgr() {
+ // Create the exchange objects for use for transfer of data to/from
+ // the database.
+ ctx->exchange4_.reset(new PgSqlLease4Exchange());
+ ctx->exchange6_.reset(new PgSqlLease6Exchange());
+
+ return (ctx);
}
std::string
}
bool
-PgSqlLeaseMgr::addLeaseCommon(StatementIndex stindex,
+PgSqlLeaseMgr::addLeaseCommon(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex,
PsqlBindArray& bind_array) {
- PgSqlResult r(PQexecPrepared(conn_, tagged_statements[stindex].name,
+ PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
tagged_statements[stindex].nbparams,
&bind_array.values_[0],
&bind_array.lengths_[0],
// Failure: check for the special case of duplicate entry. If this is
// the case, we return false to indicate that the row was not added.
// Otherwise we throw an exception.
- if (conn_.compareError(r, PgSqlConnection::DUPLICATE_KEY)) {
+ if (ctx->conn_.compareError(r, PgSqlConnection::DUPLICATE_KEY)) {
return (false);
}
- conn_.checkStatementError(r, tagged_statements[stindex]);
+ ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
}
return (true);
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_ADD_ADDR4).arg(lease->addr_.toText());
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
PsqlBindArray bind_array;
- exchange4_->createBindForSend(lease, bind_array);
- return (addLeaseCommon(INSERT_LEASE4, bind_array));
+ ctx->exchange4_->createBindForSend(lease, bind_array);
+ return (addLeaseCommon(ctx, INSERT_LEASE4, bind_array));
}
bool
PgSqlLeaseMgr::addLease(const Lease6Ptr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_ADD_ADDR6).arg(lease->addr_.toText());
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
PsqlBindArray bind_array;
- exchange6_->createBindForSend(lease, bind_array);
+ ctx->exchange6_->createBindForSend(lease, bind_array);
- return (addLeaseCommon(INSERT_LEASE6, bind_array));
+ return (addLeaseCommon(ctx, INSERT_LEASE6, bind_array));
}
template <typename Exchange, typename LeaseCollection>
-void PgSqlLeaseMgr::getLeaseCollection(StatementIndex stindex,
+void PgSqlLeaseMgr::getLeaseCollection(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex,
PsqlBindArray& bind_array,
Exchange& exchange,
LeaseCollection& result,
bool single) const {
const int n = tagged_statements[stindex].nbparams;
- PgSqlResult r(PQexecPrepared(conn_, tagged_statements[stindex].name, n,
+ PgSqlResult r(PQexecPrepared(ctx->conn_,
+ tagged_statements[stindex].name, n,
n > 0 ? &bind_array.values_[0] : NULL,
n > 0 ? &bind_array.lengths_[0] : NULL,
n > 0 ? &bind_array.formats_[0] : NULL, 0));
- conn_.checkStatementError(r, tagged_statements[stindex]);
+ ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
int rows = PQntuples(r);
if (single && rows > 1) {
}
void
-PgSqlLeaseMgr::getLease(StatementIndex stindex, PsqlBindArray& bind_array,
- Lease4Ptr& result) const {
+PgSqlLeaseMgr::getLease(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex, PsqlBindArray& bind_array,
+ Lease4Ptr& result) const {
// Create appropriate collection object and get all leases matching
// the selection criteria. The "single" parameter is true to indicate
// that the called method should throw an exception if multiple
// matching records are found: this particular method is called when only
// one or zero matches is expected.
Lease4Collection collection;
- getLeaseCollection(stindex, bind_array, exchange4_, collection, true);
+ getLeaseCollection(ctx, stindex, bind_array, ctx->exchange4_,
+ collection, true);
// Return single record if present, else clear the lease.
if (collection.empty()) {
}
void
-PgSqlLeaseMgr::getLease(StatementIndex stindex, PsqlBindArray& bind_array,
- Lease6Ptr& result) const {
+PgSqlLeaseMgr::getLease(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex, PsqlBindArray& bind_array,
+ Lease6Ptr& result) const {
// Create appropriate collection object and get all leases matching
// the selection criteria. The "single" parameter is true to indicate
// that the called method should throw an exception if multiple
// matching records are found: this particular method is called when only
// one or zero matches is expected.
Lease6Collection collection;
- getLeaseCollection(stindex, bind_array, exchange6_, collection, true);
+ getLeaseCollection(ctx, stindex, bind_array, ctx->exchange6_,
+ collection, true);
// Return single record if present, else clear the lease.
if (collection.empty()) {
// Get the data
Lease4Ptr result;
- getLease(GET_LEASE4_ADDR, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLease(ctx, GET_LEASE4_ADDR, bind_array, result);
return (result);
}
// Get the data
Lease4Collection result;
- getLeaseCollection(GET_LEASE4_HWADDR, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE4_HWADDR, bind_array, result);
return (result);
}
// Get the data
Lease4Ptr result;
- getLease(GET_LEASE4_HWADDR_SUBID, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLease(ctx, GET_LEASE4_HWADDR_SUBID, bind_array, result);
return (result);
}
// Get the data
Lease4Collection result;
- getLeaseCollection(GET_LEASE4_CLIENTID, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE4_CLIENTID, bind_array, result);
return (result);
}
// Get the data
Lease4Ptr result;
- getLease(GET_LEASE4_CLIENTID_SUBID, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLease(ctx, GET_LEASE4_CLIENTID_SUBID, bind_array, result);
return (result);
}
// ... and get the data
Lease4Collection result;
- getLeaseCollection(GET_LEASE4_SUBID, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE4_SUBID, bind_array, result);
return (result);
}
// ... and get the data
Lease4Collection result;
- getLeaseCollection(GET_LEASE4_HOSTNAME, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE4_HOSTNAME, bind_array, result);
return (result);
}
// WHERE clause.
PsqlBindArray bind_array;
Lease4Collection result;
- getLeaseCollection(GET_LEASE4, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE4, bind_array, result);
return (result);
}
// Get the leases
Lease4Collection result;
- getLeaseCollection(GET_LEASE4_PAGE, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE4_PAGE, bind_array, result);
return (result);
}
// ... and get the data
Lease6Ptr result;
- getLease(GET_LEASE6_ADDR, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLease(ctx, GET_LEASE6_ADDR, bind_array, result);
return (result);
}
// ... and get the data
Lease6Collection result;
- getLeaseCollection(GET_LEASE6_DUID_IAID, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE6_DUID_IAID, bind_array, result);
return (result);
}
// ... and get the data
Lease6Collection result;
- getLeaseCollection(GET_LEASE6_DUID_IAID_SUBID, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE6_DUID_IAID_SUBID, bind_array, result);
return (result);
}
// ... and get the data
Lease6Collection result;
- getLeaseCollection(GET_LEASE6_SUBID, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE6_SUBID, bind_array, result);
return (result);
}
bind_array.add(duid.getDuid());
Lease6Collection result;
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
// query to fetch the data
- getLeaseCollection(GET_LEASE6_DUID, bind_array, result);
+ getLeaseCollection(ctx, GET_LEASE6_DUID, bind_array, result);
return (result);
}
// ... and get the data
Lease6Collection result;
- getLeaseCollection(GET_LEASE6_HOSTNAME, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE6_HOSTNAME, bind_array, result);
return (result);
}
// WHERE clause.
PsqlBindArray bind_array;
Lease6Collection result;
- getLeaseCollection(GET_LEASE6, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE6, bind_array, result);
return (result);
}
// Get the leases
Lease6Collection result;
- getLeaseCollection(GET_LEASE6_PAGE, bind_array, result);
+
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ getLeaseCollection(ctx, GET_LEASE6_PAGE, bind_array, result);
return (result);
}
std::string limit_str = boost::lexical_cast<std::string>(limit);
bind_array.add(limit_str);
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
// Retrieve leases from the database.
- getLeaseCollection(statement_index, bind_array, expired_leases);
+ getLeaseCollection(ctx, statement_index, bind_array, expired_leases);
}
template<typename LeasePtr>
void
-PgSqlLeaseMgr::updateLeaseCommon(StatementIndex stindex,
+PgSqlLeaseMgr::updateLeaseCommon(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex,
PsqlBindArray& bind_array,
const LeasePtr& lease) {
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_ADD_ADDR4).arg(tagged_statements[stindex].name);
- PgSqlResult r(PQexecPrepared(conn_, tagged_statements[stindex].name,
+ PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
tagged_statements[stindex].nbparams,
&bind_array.values_[0],
&bind_array.lengths_[0],
&bind_array.formats_[0], 0));
- conn_.checkStatementError(r, tagged_statements[stindex]);
+ ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
// Check success case first as it is the most likely outcome.
if (affected_rows == 1) {
- return;
+ return;
}
// If no rows affected, lease doesn't exist.
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_UPDATE_ADDR4).arg(lease->addr_.toText());
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
// Create the BIND array for the data being updated
PsqlBindArray bind_array;
- exchange4_->createBindForSend(lease, bind_array);
+ ctx->exchange4_->createBindForSend(lease, bind_array);
// Set up the WHERE clause and append it to the SQL_BIND array
std::string addr4_ = boost::lexical_cast<std::string>
bind_array.add(addr4_);
// Drop to common update code
- updateLeaseCommon(stindex, bind_array, lease);
+ updateLeaseCommon(ctx, stindex, bind_array, lease);
}
void
LOG_DEBUG(dhcpsrv_logger, DHCPSRV_DBG_TRACE_DETAIL,
DHCPSRV_PGSQL_UPDATE_ADDR6).arg(lease->addr_.toText());
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
// Create the BIND array for the data being updated
PsqlBindArray bind_array;
- exchange6_->createBindForSend(lease, bind_array);
+ ctx->exchange6_->createBindForSend(lease, bind_array);
// Set up the WHERE clause and append it to the BIND array
std::string addr_str = lease->addr_.toText();
bind_array.add(addr_str);
// Drop to common update code
- updateLeaseCommon(stindex, bind_array, lease);
+ updateLeaseCommon(ctx, stindex, bind_array, lease);
}
uint64_t
PgSqlLeaseMgr::deleteLeaseCommon(StatementIndex stindex,
PsqlBindArray& bind_array) {
- PgSqlResult r(PQexecPrepared(conn_, tagged_statements[stindex].name,
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
+ PgSqlResult r(PQexecPrepared(ctx->conn_, tagged_statements[stindex].name,
tagged_statements[stindex].nbparams,
&bind_array.values_[0],
&bind_array.lengths_[0],
&bind_array.formats_[0], 0));
- conn_.checkStatementError(r, tagged_statements[stindex]);
+ ctx->conn_.checkStatementError(r, tagged_statements[stindex]);
int affected_rows = boost::lexical_cast<int>(PQcmdTuples(r));
return (affected_rows);
LeaseStatsQueryPtr
PgSqlLeaseMgr::startLeaseStatsQuery4() {
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
LeaseStatsQueryPtr query(
- new PgSqlLeaseStatsQuery(conn_, tagged_statements[ALL_LEASE4_STATS], false));
+ new PgSqlLeaseStatsQuery(ctx->conn_,
+ tagged_statements[ALL_LEASE4_STATS],
+ false));
query->start();
return(query);
}
LeaseStatsQueryPtr
PgSqlLeaseMgr::startSubnetLeaseStatsQuery4(const SubnetID& subnet_id) {
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
LeaseStatsQueryPtr query(
- new PgSqlLeaseStatsQuery(conn_, tagged_statements[SUBNET_LEASE4_STATS],
+ new PgSqlLeaseStatsQuery(ctx->conn_,
+ tagged_statements[SUBNET_LEASE4_STATS],
false, subnet_id));
query->start();
return(query);
LeaseStatsQueryPtr
PgSqlLeaseMgr::startSubnetRangeLeaseStatsQuery4(const SubnetID& first_subnet_id,
- const SubnetID& last_subnet_id) {
+ const SubnetID& last_subnet_id) {
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
LeaseStatsQueryPtr query(
- new PgSqlLeaseStatsQuery(conn_, tagged_statements[SUBNET_RANGE_LEASE4_STATS],
+ new PgSqlLeaseStatsQuery(ctx->conn_,
+ tagged_statements[SUBNET_RANGE_LEASE4_STATS],
false, first_subnet_id, last_subnet_id));
query->start();
return(query);
LeaseStatsQueryPtr
PgSqlLeaseMgr::startLeaseStatsQuery6() {
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
LeaseStatsQueryPtr query(
- new PgSqlLeaseStatsQuery(conn_, tagged_statements[ALL_LEASE6_STATS], true));
+ new PgSqlLeaseStatsQuery(ctx->conn_,
+ tagged_statements[ALL_LEASE6_STATS],
+ true));
query->start();
return(query);
}
LeaseStatsQueryPtr
PgSqlLeaseMgr::startSubnetLeaseStatsQuery6(const SubnetID& subnet_id) {
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
LeaseStatsQueryPtr query(
- new PgSqlLeaseStatsQuery(conn_, tagged_statements[SUBNET_LEASE6_STATS],
+ new PgSqlLeaseStatsQuery(ctx->conn_,
+ tagged_statements[SUBNET_LEASE6_STATS],
true, subnet_id));
query->start();
return(query);
LeaseStatsQueryPtr
PgSqlLeaseMgr::startSubnetRangeLeaseStatsQuery6(const SubnetID& first_subnet_id,
const SubnetID& last_subnet_id) {
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
LeaseStatsQueryPtr query(
- new PgSqlLeaseStatsQuery(conn_, tagged_statements[SUBNET_RANGE_LEASE6_STATS],
+ new PgSqlLeaseStatsQuery(ctx->conn_,
+ tagged_statements[SUBNET_RANGE_LEASE6_STATS],
true, first_subnet_id, last_subnet_id));
query->start();
return(query);
string
PgSqlLeaseMgr::getName() const {
+ // Get a context
+ PgSqlLeaseContextAlloc get_context(*this);
+ PgSqlLeaseContextPtr ctx = get_context.ctx_;
+
string name = "";
try {
- name = conn_.getParameter("name");
+ name = ctx->conn_.getParameter("name");
} catch (...) {
// Return an empty name
}
void
PgSqlLeaseMgr::commit() {
- conn_.commit();
}
void
PgSqlLeaseMgr::rollback() {
- conn_.rollback();
}
}; // end of isc::dhcp namespace
#include <boost/utility.hpp>
#include <vector>
+#include <mutex>
namespace isc {
namespace dhcp {
class PgSqlLease4Exchange;
class PgSqlLease6Exchange;
+/// @brief PostgreSQL Lease Context
+class PgSqlLeaseContext {
+public:
+
+ /// @brief Constructor
+ ///
+ /// @param parameters See PgSqlLeaseMgr constructor.
+ PgSqlLeaseContext(const db::DatabaseConnection::ParameterMap& parameters);
+
+ /// The exchange objects are used for transfer of data to/from the database.
+ /// They are pointed-to objects as the contents may change in "const" calls,
+ /// while the rest of this object does not. (At alternative would be to
+ /// declare them as "mutable".)
+ boost::scoped_ptr<PgSqlLease4Exchange> exchange4_; ///< Exchange object
+ boost::scoped_ptr<PgSqlLease6Exchange> exchange6_; ///< Exchange object
+
+ /// PostgreSQL connection handle
+ db::PgSqlConnection conn_;
+};
+
+/// @brief Type of pointers to contexts.
+typedef boost::shared_ptr<PgSqlLeaseContext> PgSqlLeaseContextPtr;
+
+/// @brief PostgreSQL Lease Context Pool
+///
+/// This class provides a pool of contexts.
+class PgSqlLeaseContextPool {
+public:
+
+ /// @brief The vector of available contexts.
+ std::vector<PgSqlLeaseContextPtr> pool_;
+
+ /// @brief The mutex to protect pool access.
+ std::mutex mutex_;
+};
+
+/// @brief Type of pointers to context pools.
+typedef boost::shared_ptr<PgSqlLeaseContextPool> PgSqlLeaseContextPoolPtr;
+
/// @brief PostgreSQL Lease Manager
///
/// This class provides the \ref isc::dhcp::LeaseMgr interface to the PostgreSQL
/// - user - Username under which to connect (optional)
/// - password - Password for "user" on the database (optional)
///
- /// If the database is successfully opened, the version number in the
- /// schema_version table will be checked against hard-coded value in
- /// the implementation file.
- ///
- /// Finally, all the SQL commands are pre-compiled.
+ /// Check the schema version and create an initial context.
///
/// @param parameters A data structure relating keywords and values
/// concerned with the database.
/// @brief Destructor (closes database)
virtual ~PgSqlLeaseMgr();
+ /// @brief Create a new context.
+ ///
+ /// The database is opened with all the SQL commands pre-compiled.
+ ///
+ /// @return A new (never null) context.
+ /// @throw isc::dhcp::NoDatabaseName Mandatory database name not given.
+ /// @throw isc::db::DbOperationError An operation on the open database has
+ /// failed.
+ PgSqlLeaseContextPtr createContext() const;
+
/// @brief Local version of getDBVersion() class method
static std::string getDBVersion();
/// of the addLease method. It binds the contents of the lease object to
/// the prepared statement and adds it to the database.
///
+ /// @param ctx Context
/// @param stindex Index of statement being executed
/// @param bind_array array that has been created for the type
/// of lease in question.
///
/// @throw isc::db::DbOperationError An operation on the open database has
/// failed.
- bool addLeaseCommon(StatementIndex stindex, db::PsqlBindArray& bind_array);
+ bool addLeaseCommon(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex, db::PsqlBindArray& bind_array);
/// @brief Get Lease Collection Common Code
///
/// This method performs the common actions for obtaining multiple leases
/// from the database.
///
+ /// @param ctx Context
/// @param stindex Index of statement being executed
/// @param bind_array array containing the where clause input parameters
/// @param exchange Exchange object to use
/// @throw isc::db::MultipleRecords Multiple records were retrieved
/// from the database where only one was expected.
template <typename Exchange, typename LeaseCollection>
- void getLeaseCollection(StatementIndex stindex, db::PsqlBindArray& bind_array,
+ void getLeaseCollection(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex,
+ db::PsqlBindArray& bind_array,
Exchange& exchange, LeaseCollection& result,
bool single = false) const;
/// Gets a collection of Lease4 objects. This is just an interface to
/// the get lease collection common code.
///
+ /// @param ctx Context
/// @param stindex Index of statement being executed
/// @param bind_array array containing the where clause input parameters
/// @param lease LeaseCollection object returned. Note that any leases in
/// failed.
/// @throw isc::db::MultipleRecords Multiple records were retrieved
/// from the database where only one was expected.
- void getLeaseCollection(StatementIndex stindex, db::PsqlBindArray& bind_array,
+ void getLeaseCollection(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex,
+ db::PsqlBindArray& bind_array,
Lease4Collection& result) const {
- getLeaseCollection(stindex, bind_array, exchange4_, result);
+ getLeaseCollection(ctx, stindex, bind_array, ctx->exchange4_, result);
}
/// @brief Get Lease6 Collection
/// Gets a collection of Lease6 objects. This is just an interface to
/// the get lease collection common code.
///
+ /// @param ctx Context
/// @param stindex Index of statement being executed
/// @param bind_array array containing input parameters for the query
/// @param lease LeaseCollection object returned. Note that any existing
/// failed.
/// @throw isc::db::MultipleRecords Multiple records were retrieved
/// from the database where only one was expected.
- void getLeaseCollection(StatementIndex stindex, db::PsqlBindArray& bind_array,
+ void getLeaseCollection(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex,
+ db::PsqlBindArray& bind_array,
Lease6Collection& result) const {
- getLeaseCollection(stindex, bind_array, exchange6_, result);
+ getLeaseCollection(ctx, stindex, bind_array, ctx->exchange6_, result);
}
/// @brief Get Lease4 Common Code
/// methods. It acts as an interface to the getLeaseCollection() method,
/// but retrieving only a single lease.
///
+ /// @param ctx Context
/// @param stindex Index of statement being executed
/// @param bind_array array containing input parameters for the query
/// @param lease Lease4 object returned
- void getLease(StatementIndex stindex, db::PsqlBindArray& bind_array,
+ void getLease(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex, db::PsqlBindArray& bind_array,
Lease4Ptr& result) const;
/// @brief Get Lease6 Common Code
/// methods. It acts as an interface to the getLeaseCollection() method,
/// but retrieving only a single lease.
///
+ /// @param ctx Context
/// @param stindex Index of statement being executed
/// @param bind_array array containing input parameters for the query
/// @param lease Lease6 object returned
- void getLease(StatementIndex stindex, db::PsqlBindArray& bind_array,
+ void getLease(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex, db::PsqlBindArray& bind_array,
Lease6Ptr& result) const;
/// @brief Get expired leases common code.
/// to the prepared statement, executes it, then checks how many rows
/// were affected.
///
+ /// @param ctx Context
/// @param stindex Index of prepared statement to be executed
/// @param bind_array array containing lease values and where clause
/// parameters for the update.
/// @throw isc::db::DbOperationError An operation on the open database has
/// failed.
template <typename LeasePtr>
- void updateLeaseCommon(StatementIndex stindex, db::PsqlBindArray& bind_array,
+ void updateLeaseCommon(PgSqlLeaseContextPtr ctx,
+ StatementIndex stindex,
+ db::PsqlBindArray& bind_array,
const LeasePtr& lease);
/// @brief Delete lease common code
uint64_t deleteExpiredReclaimedLeasesCommon(const uint32_t secs,
StatementIndex statement_index);
- /// The exchange objects are used for transfer of data to/from the database.
- /// They are pointed-to objects as the contents may change in "const" calls,
- /// while the rest of this object does not. (At alternative would be to
- /// declare them as "mutable".)
- boost::scoped_ptr<PgSqlLease4Exchange> exchange4_; ///< Exchange object
- boost::scoped_ptr<PgSqlLease6Exchange> exchange6_; ///< Exchange object
+ /// @brief Context RAII Allocator.
+ class PgSqlLeaseContextAlloc {
+ public:
+
+ /// @brief Constructor
+ ///
+ /// This constructor takes a context of the pool if one is available
+ /// or creates a new one.
+ ///
+ /// @param mgr A parent instance
+ PgSqlLeaseContextAlloc(const PgSqlLeaseMgr& mgr);
+
+ /// @brief Destructor
+ ///
+ /// This destructor puts back the context in the pool.
+ ~PgSqlLeaseContextAlloc();
+
+ /// @brief The context
+ PgSqlLeaseContextPtr ctx_;
+
+ private:
+ /// @brief The manager
+ const PgSqlLeaseMgr& mgr_;
+ };
+
+ // Members
/// The parameters.
db::DatabaseConnection::ParameterMap parameters_;
- /// PostgreSQL connection handle
- db::PgSqlConnection conn_;
+ /// @brief The pool of contexts
+ PgSqlLeaseContextPoolPtr pool_;
};
} // namespace dhcp
#include <dhcpsrv/tests/generic_lease_mgr_unittest.h>
#include <pgsql/pgsql_connection.h>
#include <pgsql/testutils/pgsql_schema.h>
+#include <util/multi_threading_mgr.h>
#include <gtest/gtest.h>
using namespace isc::db::test;
using namespace isc::dhcp;
using namespace isc::dhcp::test;
+using namespace isc::util;
using namespace std;
namespace {
}
lmptr_ = &(LeaseMgrFactory::instance());
+
+ MultiThreadingMgr::instance().setMode(false);
}
/// @brief Destroys the LM and the schema.
LeaseMgrFactory::destroy();
// If data wipe enabled, delete transient data otherwise destroy the schema
destroyPgSQLSchema();
+
+ // Disable Multi-Threading.
+ MultiThreadingMgr::instance().setMode(false);
}
/// @brief Constructor
/// opened: the fixtures assume that and check basic operations.
TEST(PgSqlOpenTest, OpenDatabase) {
+ // Explicitely disable Multi-Threading.
+ MultiThreadingMgr::instance().setMode(false);
+
// Schema needs to be created for the test to work.
createPgSQLSchema();
destroyPgSQLSchema();
}
+/// @brief Check that database can be opened with Multi-Threading
+TEST(PgSqlOpenTest, OpenDatabaseMultiThreading) {
+ // Enable Multi-Threading.
+ MultiThreadingMgr::instance().setMode(true);
+
+ // Schema needs to be created for the test to work.
+ createPgSQLSchema();
+
+ // Check that lease manager open the database opens correctly and tidy up.
+ // If it fails, print the error message.
+ try {
+ LeaseMgrFactory::create(validPgSQLConnectionString());
+ EXPECT_NO_THROW((void)LeaseMgrFactory::instance());
+ LeaseMgrFactory::destroy();
+ } catch (const isc::Exception& ex) {
+ FAIL() << "*** ERROR: unable to open database, reason:\n"
+ << " " << ex.what() << "\n"
+ << "*** The test environment is broken and must be fixed\n"
+ << "*** before the PostgreSQL tests will run correctly.\n";
+ }
+
+ // Tidy up after the test
+ destroyPgSQLSchema();
+
+ // Disable Multi-Threading.
+ MultiThreadingMgr::instance().setMode(false);
+}
+
/// @brief Test fixture class for validating @c LeaseMgr using
/// PostgreSQL as back end and PostgreSQL connectivity loss.
class PgSqlLeaseMgrDbLostCallbackTest : public LeaseMgrDbLostCallbackTest {
// Verifies that db lost callback is not invoked on an open failure
TEST_F(PgSqlLeaseMgrDbLostCallbackTest, testNoCallbackOnOpenFailure) {
+ MultiThreadingMgr::instance().setMode(false);
+ testDbLostCallback();
+}
+
+// Verifies that db lost callback is not invoked on an open failure
+TEST_F(PgSqlLeaseMgrDbLostCallbackTest, testNoCallbackOnOpenFailureMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
testDbLostCallback();
}
// Verifies that loss of connectivity to PostgreSQL is handled correctly.
TEST_F(PgSqlLeaseMgrDbLostCallbackTest, testDbLostCallback) {
+ MultiThreadingMgr::instance().setMode(false);
+ testDbLostCallback();
+}
+
+// Verifies that loss of connectivity to PostgreSQL is handled correctly.
+TEST_F(PgSqlLeaseMgrDbLostCallbackTest, testDbLostCallbackMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
testDbLostCallback();
}
testBasicLease4();
}
+/// @brief Basic Lease4 Checks
+TEST_F(PgSqlLeaseMgrTest, basicLease4MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testBasicLease4();
+}
+
/// @brief Check that Lease4 code safely handles invalid dates.
TEST_F(PgSqlLeaseMgrTest, maxDate4) {
testMaxDate4();
}
+/// @brief Check that Lease4 code safely handles invalid dates.
+TEST_F(PgSqlLeaseMgrTest, maxDate4MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testMaxDate4();
+}
+
/// @brief Lease4 update tests
///
/// Checks that we are able to update a lease in the database.
testUpdateLease4();
}
+/// @brief Lease4 update tests
+TEST_F(PgSqlLeaseMgrTest, updateLease4MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testUpdateLease4();
+}
+
/// @brief Check GetLease4 methods - access by Hardware Address
TEST_F(PgSqlLeaseMgrTest, getLease4HWAddr1) {
testGetLease4HWAddr1();
}
+/// @brief Check GetLease4 methods - access by Hardware Address
+TEST_F(PgSqlLeaseMgrTest, getLease4HWAddr1MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease4HWAddr1();
+}
+
/// @brief Check GetLease4 methods - access by Hardware Address
TEST_F(PgSqlLeaseMgrTest, getLease4HWAddr2) {
testGetLease4HWAddr2();
}
+/// @brief Check GetLease4 methods - access by Hardware Address
+TEST_F(PgSqlLeaseMgrTest, getLease4HWAddr2MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease4HWAddr2();
+}
+
// @brief Get lease4 by hardware address (2)
//
// Check that the system can cope with getting a hardware address of
testGetLease4HWAddrSize();
}
+// @brief Get lease4 by hardware address (2)
+TEST_F(PgSqlLeaseMgrTest, getLease4HWAddrSizeMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease4HWAddrSize();
+}
+
/// @brief Check GetLease4 methods - access by Hardware Address & Subnet ID
///
/// Adds leases to the database and checks that they can be accessed via
testGetLease4HWAddrSubnetId();
}
+/// @brief Check GetLease4 methods - access by Hardware Address & Subnet ID
+TEST_F(PgSqlLeaseMgrTest, getLease4HwaddrSubnetIdMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease4HWAddrSubnetId();
+}
+
// @brief Get lease4 by hardware address and subnet ID (2)
//
// Check that the system can cope with getting a hardware address of
testGetLease4HWAddrSubnetIdSize();
}
+// @brief Get lease4 by hardware address and subnet ID (2)
+TEST_F(PgSqlLeaseMgrTest, getLease4HWAddrSubnetIdSizeMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease4HWAddrSubnetIdSize();
+}
+
// This test was derived from memfile.
TEST_F(PgSqlLeaseMgrTest, getLease4ClientId) {
testGetLease4ClientId();
}
+// This test was derived from memfile.
+TEST_F(PgSqlLeaseMgrTest, getLease4ClientIdMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease4ClientId();
+}
+
/// @brief Check GetLease4 methods - access by Client ID
///
/// Adds leases to the database and checks that they can be accessed via
testGetLease4ClientId2();
}
+/// @brief Check GetLease4 methods - access by Client ID
+TEST_F(PgSqlLeaseMgrTest, getLease4ClientId2MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease4ClientId2();
+}
+
// @brief Get Lease4 by client ID (2)
//
// Check that the system can cope with a client ID of any size.
testGetLease4ClientIdSize();
}
+// @brief Get Lease4 by client ID (2)
+TEST_F(PgSqlLeaseMgrTest, getLease4ClientIdSizeMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease4ClientIdSize();
+}
+
/// @brief Check GetLease4 methods - access by Client ID & Subnet ID
///
/// Adds leases to the database and checks that they can be accessed via
testGetLease4ClientIdSubnetId();
}
+/// @brief Check GetLease4 methods - access by Client ID & Subnet ID
+TEST_F(PgSqlLeaseMgrTest, getLease4ClientIdSubnetIdMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease4ClientIdSubnetId();
+}
+
// This test checks that all IPv4 leases for a specified subnet id are returned.
TEST_F(PgSqlLeaseMgrTest, getLeases4SubnetId) {
testGetLeases4SubnetId();
}
+// This test checks that all IPv4 leases for a specified subnet id are returned.
+TEST_F(PgSqlLeaseMgrTest, getLeases4SubnetIdMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLeases4SubnetId();
+}
+
// This test checks that all IPv4 leases with a specified hostname are returned.
TEST_F(PgSqlLeaseMgrTest, getLeases4Hostname) {
testGetLeases4Hostname();
}
+// This test checks that all IPv4 leases with a specified hostname are returned.
+TEST_F(PgSqlLeaseMgrTest, getLeases4HostnameMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLeases4Hostname();
+}
+
// This test checks that all IPv4 leases are returned.
TEST_F(PgSqlLeaseMgrTest, getLeases4) {
testGetLeases4();
}
+// This test checks that all IPv4 leases are returned.
+TEST_F(PgSqlLeaseMgrTest, getLeases4MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ 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 returned with paging.
+TEST_F(PgSqlLeaseMgrTest, getLeases4PagedMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLeases4Paged();
+}
+
// This test checks that all IPv6 leases for a specified subnet id are returned.
TEST_F(PgSqlLeaseMgrTest, getLeases6SubnetId) {
testGetLeases6SubnetId();
}
+// This test checks that all IPv6 leases for a specified subnet id are returned.
+TEST_F(PgSqlLeaseMgrTest, getLeases6SubnetIdMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLeases6SubnetId();
+}
+
// This test checks that all IPv6 leases with a specified hostname are returned.
TEST_F(PgSqlLeaseMgrTest, getLeases6Hostname) {
testGetLeases6Hostname();
}
+// This test checks that all IPv6 leases with a specified hostname are returned.
+TEST_F(PgSqlLeaseMgrTest, getLeases6HostnameMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLeases6Hostname();
+}
+
// This test checks that all IPv6 leases are returned.
TEST_F(PgSqlLeaseMgrTest, getLeases6) {
testGetLeases6();
}
+// This test checks that all IPv6 leases are returned.
+TEST_F(PgSqlLeaseMgrTest, getLeases6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLeases6();
+}
+
// Test that a range of IPv6 leases is returned with paging.
TEST_F(PgSqlLeaseMgrTest, getLeases6Paged) {
testGetLeases6Paged();
}
+// Test that a range of IPv6 leases is returned with paging.
+TEST_F(PgSqlLeaseMgrTest, getLeases6PagedMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLeases6Paged();
+}
+
/// @brief Basic Lease4 Checks
///
/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
testLease4NullClientId();
}
+/// @brief Basic Lease4 Checks
+TEST_F(PgSqlLeaseMgrTest, lease4NullClientIdMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testLease4NullClientId();
+}
+
/// @brief Verify that too long hostname for Lease4 is not accepted.
///
/// Checks that the it is not possible to create a lease when the hostname
testLease4InvalidHostname();
}
+/// @brief Verify that too long hostname for Lease4 is not accepted.
+TEST_F(PgSqlLeaseMgrTest, lease4InvalidHostnameMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testLease4InvalidHostname();
+}
+
/// @brief Check that the expired DHCPv4 leases can be retrieved.
///
/// This test adds a number of leases to the lease database and marks
testGetExpiredLeases4();
}
+/// @brief Check that the expired DHCPv4 leases can be retrieved.
+TEST_F(PgSqlLeaseMgrTest, getExpiredLeases4MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetExpiredLeases4();
+}
+
/// @brief Check that expired reclaimed DHCPv4 leases are removed.
TEST_F(PgSqlLeaseMgrTest, deleteExpiredReclaimedLeases4) {
testDeleteExpiredReclaimedLeases4();
}
+/// @brief Check that expired reclaimed DHCPv4 leases are removed.
+TEST_F(PgSqlLeaseMgrTest, deleteExpiredReclaimedLeases4MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testDeleteExpiredReclaimedLeases4();
+}
+
////////////////////////////////////////////////////////////////////////////////
/// LEASE6 /////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
testAddGetDelete6();
}
+// Test checks whether simple add, get and delete operations are possible
+// on Lease6
+TEST_F(PgSqlLeaseMgrTest, testAddGetDelete6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testAddGetDelete6();
+}
+
/// @brief Basic Lease6 Checks
///
/// Checks that the addLease, getLease6 (by address) and deleteLease (with an
testBasicLease6();
}
+/// @brief Basic Lease6 Checks
+TEST_F(PgSqlLeaseMgrTest, basicLease6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testBasicLease6();
+}
+
/// @brief Check that Lease6 code safely handles invalid dates.
TEST_F(PgSqlLeaseMgrTest, maxDate6) {
testMaxDate6();
}
+/// @brief Check that Lease6 code safely handles invalid dates.
+TEST_F(PgSqlLeaseMgrTest, maxDate6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testMaxDate6();
+}
+
/// @brief Verify that too long hostname for Lease6 is not accepted.
///
/// Checks that the it is not possible to create a lease when the hostname
testLease6InvalidHostname();
}
+/// @brief Verify that too long hostname for Lease6 is not accepted.
+TEST_F(PgSqlLeaseMgrTest, lease6InvalidHostnameMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testLease6InvalidHostname();
+}
+
/// @brief Verify that large IAID values work correctly.
///
/// Adds lease with a large IAID to the database and verifies it can
testLease6LargeIaidCheck();
}
+/// @brief Verify that large IAID values work correctly.
+TEST_F(PgSqlLeaseMgrTest, leases6LargeIaidCheckMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testLease6LargeIaidCheck();
+}
+
/// @brief Check GetLease6 methods - access by DUID/IAID
///
/// Adds leases to the database and checks that they can be accessed via
testGetLeases6DuidIaid();
}
+/// @brief Check GetLease6 methods - access by DUID/IAID
+TEST_F(PgSqlLeaseMgrTest, getLeases6DuidIaidMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLeases6DuidIaid();
+}
+
// Check that the system can cope with a DUID of allowed size.
TEST_F(PgSqlLeaseMgrTest, getLeases6DuidSize) {
testGetLeases6DuidSize();
}
+// Check that the system can cope with a DUID of allowed size.
+TEST_F(PgSqlLeaseMgrTest, getLeases6DuidSizeMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLeases6DuidSize();
+}
+
/// @brief Check that getLease6 methods discriminate by lease type.
///
/// Adds six leases, two per lease type all with the same duid and iad but
testLease6LeaseTypeCheck();
}
+/// @brief Check that getLease6 methods discriminate by lease type.
+TEST_F(PgSqlLeaseMgrTest, lease6LeaseTypeCheckMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testLease6LeaseTypeCheck();
+}
+
/// @brief Verifies the getLeases6(DUID) method
///
/// Adds 3 lease and verifies fetch by DUID.
testGetLeases6Duid();
}
+/// @brief Verifies the getLeases6(DUID) method
+TEST_F(PgSqlLeaseMgrTest, getLeases6DuidMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLeases6Duid();
+}
+
/// @brief Check GetLease6 methods - access by DUID/IAID/SubnetID
///
/// Adds leases to the database and checks that they can be accessed via
testGetLease6DuidIaidSubnetId();
}
+/// @brief Check GetLease6 methods - access by DUID/IAID/SubnetID
+TEST_F(PgSqlLeaseMgrTest, getLease6DuidIaidSubnetIdMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease6DuidIaidSubnetId();
+}
+
// Test checks that getLease6() works with different DUID sizes
TEST_F(PgSqlLeaseMgrTest, getLease6DuidIaidSubnetIdSize) {
testGetLease6DuidIaidSubnetIdSize();
}
+// Test checks that getLease6() works with different DUID sizes
+TEST_F(PgSqlLeaseMgrTest, getLease6DuidIaidSubnetIdSizeMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetLease6DuidIaidSubnetIdSize();
+}
+
/// @brief Lease6 update tests
///
/// Checks that we are able to update a lease in the database.
testUpdateLease6();
}
+/// @brief Lease6 update tests
+TEST_F(PgSqlLeaseMgrTest, updateLease6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testUpdateLease6();
+}
+
/// @brief DHCPv4 Lease recreation tests
///
/// Checks that the lease can be created, deleted and recreated with
testRecreateLease4();
}
+/// @brief DHCPv4 Lease recreation tests
+TEST_F(PgSqlLeaseMgrTest, testRecreateLease4MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testRecreateLease4();
+}
+
/// @brief DHCPv6 Lease recreation tests
///
/// Checks that the lease can be created, deleted and recreated with
testRecreateLease6();
}
+/// @brief DHCPv6 Lease recreation tests
+TEST_F(PgSqlLeaseMgrTest, testRecreateLease6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testRecreateLease6();
+}
+
/// @brief Checks that null DUID is not allowed.
TEST_F(PgSqlLeaseMgrTest, nullDuid) {
testNullDuid();
}
+/// @brief Checks that null DUID is not allowed.
+TEST_F(PgSqlLeaseMgrTest, nullDuidMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testNullDuid();
+}
+
/// @brief Tests whether PostgreSQL can store and retrieve hardware addresses
TEST_F(PgSqlLeaseMgrTest, testLease6Mac) {
testLease6MAC();
}
+/// @brief Tests whether PostgreSQL can store and retrieve hardware addresses
+TEST_F(PgSqlLeaseMgrTest, testLease6MacMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testLease6MAC();
+}
+
/// @brief Tests whether PostgreSQL can store and retrieve hardware addresses
TEST_F(PgSqlLeaseMgrTest, testLease6HWTypeAndSource) {
testLease6HWTypeAndSource();
}
+/// @brief Tests whether PostgreSQL can store and retrieve hardware addresses
+TEST_F(PgSqlLeaseMgrTest, testLease6HWTypeAndSourceMultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testLease6HWTypeAndSource();
+}
+
/// @brief Check that the expired DHCPv6 leases can be retrieved.
///
/// This test adds a number of leases to the lease database and marks
testGetExpiredLeases6();
}
+/// @brief Check that the expired DHCPv6 leases can be retrieved.
+TEST_F(PgSqlLeaseMgrTest, getExpiredLeases6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testGetExpiredLeases6();
+}
+
/// @brief Check that expired reclaimed DHCPv6 leases are removed.
TEST_F(PgSqlLeaseMgrTest, deleteExpiredReclaimedLeases6) {
testDeleteExpiredReclaimedLeases6();
}
+/// @brief Check that expired reclaimed DHCPv6 leases are removed.
+TEST_F(PgSqlLeaseMgrTest, deleteExpiredReclaimedLeases6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testDeleteExpiredReclaimedLeases6();
+}
+
/// @brief Verifies that IPv4 lease statistics can be recalculated.
TEST_F(PgSqlLeaseMgrTest, recountLeaseStats4) {
testRecountLeaseStats4();
}
+/// @brief Verifies that IPv4 lease statistics can be recalculated.
+TEST_F(PgSqlLeaseMgrTest, recountLeaseStats4MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testRecountLeaseStats4();
+}
+
/// @brief Verifies that IPv6 lease statistics can be recalculated.
TEST_F(PgSqlLeaseMgrTest, recountLeaseStats6) {
testRecountLeaseStats6();
}
+/// @brief Verifies that IPv6 lease statistics can be recalculated.
+TEST_F(PgSqlLeaseMgrTest, recountLeaseStats6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testRecountLeaseStats6();
+}
+
/// @brief Tests that leases from specific subnet can be removed.
TEST_F(PgSqlLeaseMgrTest, DISABLED_wipeLeases4) {
testWipeLeases4();
}
+/// @brief Tests that leases from specific subnet can be removed.
+TEST_F(PgSqlLeaseMgrTest, DISABLED_wipeLeases4MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testWipeLeases4();
+}
+
/// @brief Tests that leases from specific subnet can be removed.
TEST_F(PgSqlLeaseMgrTest, DISABLED_wipeLeases6) {
testWipeLeases6();
}
+/// @brief Tests that leases from specific subnet can be removed.
+TEST_F(PgSqlLeaseMgrTest, DISABLED_wipeLeases6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testWipeLeases6();
+}
+
// Tests v4 lease stats query variants.
TEST_F(PgSqlLeaseMgrTest, leaseStatsQuery4) {
testLeaseStatsQuery4();
}
+// Tests v4 lease stats query variants.
+TEST_F(PgSqlLeaseMgrTest, leaseStatsQuery4MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testLeaseStatsQuery4();
+}
+
// Tests v6 lease stats query variants.
TEST_F(PgSqlLeaseMgrTest, leaseStatsQuery6) {
testLeaseStatsQuery6();
}
+// Tests v6 lease stats query variants.
+TEST_F(PgSqlLeaseMgrTest, leaseStatsQuery6MultiThreading) {
+ MultiThreadingMgr::instance().setMode(true);
+ testLeaseStatsQuery6();
+}
+
} // namespace