auto db_reconnect_ctl = pool_->pool_[0]->conn_.reconnectCtl();
- std::string manager = "MySqlLeaseMgr[";
+ std::string manager = "MySqlHostMgr[";
manager += boost::lexical_cast<std::string>(reinterpret_cast<uint64_t>(this));
std::string timer_name = manager + "]DbReconnectTimer";
auto db_reconnect_ctl = pool_->pool_[0]->conn_.reconnectCtl();
- std::string manager = "PgSqlLeaseMgr[";
+ std::string manager = "PgSqlHostMgr[";
manager += boost::lexical_cast<std::string>(reinterpret_cast<uint64_t>(this));
std::string timer_name = manager + "]DbReconnectTimer";
ASSERT_THROW(LeaseMgrFactory::create(invalidConnectString()),
DbOpenError);
+ io_service_->run_one();
+
EXPECT_FALSE(callback_called_);
}
ASSERT_THROW(lease = lm.getLease4(IOAddress("192.0.1.0")),
DbConnectionUnusable);
+ io_service_->run_one();
+
// Our lost connectivity callback should have been invoked.
EXPECT_TRUE(callback_called_);
}
#ifndef GENERIC_LEASE_MGR_UNITTEST_H
#define GENERIC_LEASE_MGR_UNITTEST_H
+#include <asiolink/io_service.h>
#include <dhcpsrv/lease_mgr.h>
+
#include <gtest/gtest.h>
+
+#include <boost/make_shared.hpp>
#include <vector>
#include <set>
class LeaseMgrDbLostCallbackTest : public ::testing::Test {
public:
- LeaseMgrDbLostCallbackTest() {
+ LeaseMgrDbLostCallbackTest()
+ : callback_called_(false),
+ io_service_(boost::make_shared<isc::asiolink::IOService>()) {
db::DatabaseConnection::db_lost_callback_ = 0;
+ LeaseMgr::setIOService(io_service_);
}
virtual ~LeaseMgrDbLostCallbackTest() {
db::DatabaseConnection::db_lost_callback_ = 0;
+ LeaseMgr::setIOService(isc::asiolink::IOServicePtr());
}
/// @brief Prepares the class for a test.
/// @brief Flag used to detect calls to db_lost_callback function
bool callback_called_;
+ /// The IOService object, used for all ASIO operations.
+ isc::asiolink::IOServicePtr io_service_;
};
} // namespace test
class HostMgrDbLostCallbackTest : public ::testing::Test {
public:
- HostMgrDbLostCallbackTest() : callback_called_(false) {};
+ HostMgrDbLostCallbackTest()
+ : callback_called_(false),
+ io_service_(boost::make_shared<isc::asiolink::IOService>()) {
+ }
/// @brief Prepares the class for a test.
///
/// appropriate schema and create a basic host manager to
/// wipe out any prior instance
virtual void SetUp() {
+ HostMgr::setIOService(io_service_);
DatabaseConnection::db_lost_callback_ = 0;
// Ensure we have the proper schema with no transient data.
createSchema();
/// Invoked by gtest upon test exit, we destroy the schema
/// we created.
virtual void TearDown() {
+ HostMgr::setIOService(isc::asiolink::IOServicePtr());
DatabaseConnection::db_lost_callback_ = 0;
// If data wipe enabled, delete transient data otherwise destroy the schema
destroySchema();
/// @brief Flag used to detect calls to db_lost_callback function
bool callback_called_;
+
+ /// The IOService object, used for all ASIO operations.
+ isc::asiolink::IOServicePtr io_service_;
};
#if defined(HAVE_MYSQL) || defined(HAVE_PGSQL)
ASSERT_THROW(hosts = HostMgr::instance().getAll4(IOAddress("192.0.2.5")),
DbConnectionUnusable);
+ io_service_->run_one();
+
// Our lost connectivity callback should have been invoked.
EXPECT_TRUE(callback_called_);
}
destroyMySQLSchema();
}
+/// @brief Flag used to detect calls to db_lost_callback function
+bool callback_called = false;
+
+/// @brief Callback function used in open database testing
+bool db_lost_callback(ReconnectCtlPtr /* db_conn_retry */) {
+ return (callback_called = true);
+}
+
+/// @brief Make sure open failures do NOT invoke db lost callback
+/// The db lost callback should only be invoked after successfully
+/// opening the DB and then subsequently losing it. Failing to
+/// open should be handled directly by the application layer.
+/// There is simply no good way to break the connection in a
+/// unit test environment. So testing the callback invocation
+/// in a unit test is next to impossible. That has to be done
+/// as a system test.
+TEST(MySqlHostDataSource, NoCallbackOnOpenFail) {
+ // Schema needs to be created for the test to work.
+ destroyMySQLSchema();
+ createMySQLSchema();
+
+ callback_called = false;
+ DatabaseConnection::db_lost_callback_ = db_lost_callback;
+ HostMgr::create();
+ EXPECT_THROW(HostMgr::addBackend(connectionString(
+ MYSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)),
+ DbOpenError);
+
+ EXPECT_FALSE(callback_called);
+ destroyMySQLSchema();
+}
+
+/// @brief Make sure open failures do NOT invoke db lost callback
+/// The db lost callback should only be invoked after successfully
+/// opening the DB and then subsequently losing it. Failing to
+/// open should be handled directly by the application layer.
+/// There is simply no good way to break the connection in a
+/// unit test environment. So testing the callback invocation
+/// in a unit test is next to impossible. That has to be done
+/// as a system test.
+TEST(MySqlHostDataSource, NoCallbackOnOpenFailMultiThreading) {
+ // Enable Multi-Threading.
+ MultiThreadingTest mt(true);
+
+ // Schema needs to be created for the test to work.
+ destroyMySQLSchema();
+ createMySQLSchema();
+
+ callback_called = false;
+ DatabaseConnection::db_lost_callback_ = db_lost_callback;
+ HostMgr::create();
+ EXPECT_THROW(HostMgr::addBackend(connectionString(
+ MYSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)),
+ DbOpenError);
+
+ EXPECT_FALSE(callback_called);
+ destroyMySQLSchema();
+}
/// @brief Check conversion functions
///
#include <dhcpsrv/host_data_source_factory.h>
#include <pgsql/pgsql_connection.h>
#include <pgsql/testutils/pgsql_schema.h>
-#include <util/multi_threading_mgr.h>
#include <testutils/multi_threading_utils.h>
+#include <util/multi_threading_mgr.h>
#include <gtest/gtest.h>
EXPECT_THROW(HostMgr::addBackend(connectionString(
PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_2)),
DbInvalidTimeout);
+ EXPECT_THROW(HostMgr::addBackend(connectionString(
+ PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD,
+ VALID_TIMEOUT, INVALID_READONLY_DB)), DbInvalidReadOnly);
// Check for missing parameters
EXPECT_THROW(HostMgr::addBackend(connectionString(
EXPECT_THROW(HostMgr::addBackend(connectionString(
PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_2)),
DbInvalidTimeout);
+ EXPECT_THROW(HostMgr::addBackend(connectionString(
+ PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD,
+ VALID_TIMEOUT, INVALID_READONLY_DB)), DbInvalidReadOnly);
// Check for missing parameters
EXPECT_THROW(HostMgr::addBackend(connectionString(