#ifdef HAVE_CQL
-/// @brief Test fixture class for the test utilizing Cassandra database backend.
+// Starting tests which require Cassandra backend availability. Those tests
+// will not be executed if Kea has been compiled without the
+// --with-cql.
class DORACQLTest : public DORATest {
public:
/// @brief Constructor.
// If there is no such option in the destination container,
// add one.
if (std::distance(range.first, range.second) == 0) {
- dest_container.addItem(OptionDescriptor(
- src_opt->option_, src_opt->persistent_,
- src_opt->formatted_value_), *it);
+ dest_container.addItem(OptionDescriptor(src_opt), *it);
}
}
}
/// @param formatted_value option value in the textual format. Default
/// value is empty indicating that the value is not set.
OptionDescriptor(const OptionPtr& opt, bool persist,
- const std::string& formatted_value = "")
+ const std::string& formatted_value = "",
+ data::ConstElementPtr user_context = data::ConstElementPtr())
: option_(opt), persistent_(persist),
- formatted_value_(formatted_value) {};
+ formatted_value_(formatted_value) {
+ setContext(user_context);
+ };
/// @brief Constructor
///
: option_(OptionPtr()), persistent_(persist),
formatted_value_() {};
+ /// @brief Constructor.
+ ///
+ /// @param desc descriptor
+ OptionDescriptor(const OptionDescriptor& desc)
+ : option_(desc.option_), persistent_(desc.persistent_),
+ formatted_value_(desc.formatted_value_) {
+ setContext(desc.user_context_);
+ };
+
/// @brief Checks if the one descriptor is equal to another.
///
/// @param other Other option descriptor to compare to.
#include <dhcpsrv/testutils/pgsql_schema.h>
#endif
+#if defined HAVE_CQL
+#include <dhcpsrv/testutils/cql_schema.h>
+#endif
+
#include <gtest/gtest.h>
#include <vector>
/// @brief Rollback and drop PostgreSQL schema after the test.
virtual void TearDown();
-
};
void
#endif
-} // end of anonymous namespace
+
+// The following tests require Cassandra enabled.
+#if defined HAVE_CQL
+
+/// @brief Test fixture class for validating @c HostMgr using
+/// CQL as alternate host data source.
+class CQLHostMgrTest : public HostMgrTest {
+protected:
+
+ /// @brief Build CQL schema for a test.
+ virtual void SetUp();
+
+ /// @brief Rollback and drop CQL schema after the test.
+ virtual void TearDown();
+};
+
+void
+CQLHostMgrTest::SetUp() {
+ HostMgrTest::SetUp();
+
+ // Ensure schema is the correct one.
+ test::destroyCqlSchema(false, true);
+ test::createCqlSchema(false, true);
+
+ // Connect to the database
+ try {
+ HostMgr::create(test::validCqlConnectionString());
+ } catch (...) {
+ std::cerr << "*** ERROR: unable to open database. The test\n"
+ "*** environment is broken and must be fixed before\n"
+ "*** the CQL tests will run correctly.\n"
+ "*** The reason for the problem is described in the\n"
+ "*** accompanying exception output.\n";
+ throw;
+ }
+}
+
+void
+CQLHostMgrTest::TearDown() {
+ HostDataSourceFactory::getHostDataSourcePtr()->rollback();
+ HostDataSourceFactory::destroy();
+ test::destroyCqlSchema(false, true);
+}
+
+// This test verifies that reservations for a particular client can
+// be retrieved from the configuration file and a database simultaneously.
+TEST_F(CQLHostMgrTest, getAll) {
+ testGetAll(*getCfgHosts(), HostMgr::instance());
+}
+
+// This test verifies that IPv4 reservations for a particular client can
+// be retrieved from the configuration file and a database simultaneously.
+TEST_F(CQLHostMgrTest, getAll4) {
+ testGetAll4(*getCfgHosts(), HostMgr::instance());
+}
+
+// This test verifies that the IPv4 reservation can be retrieved from a
+// database.
+TEST_F(CQLHostMgrTest, get4) {
+ testGet4(HostMgr::instance());
+}
+
+// This test verifies that the IPv6 reservation can be retrieved from a
+// database.
+TEST_F(CQLHostMgrTest, get6) {
+ testGet6(HostMgr::instance());
+}
+
+// This test verifies that the IPv6 prefix reservation can be retrieved
+// from a configuration file and a database.
+TEST_F(CQLHostMgrTest, get6ByPrefix) {
+ testGet6ByPrefix(*getCfgHosts(), HostMgr::instance());
+}
+
+#endif
+
+} // namespace
class MySqlHostDataSourceTest : public GenericHostDataSourceTest {
public:
- /// @brief Constructor
- ///
- /// Deletes everything from the database and opens it.
- MySqlHostDataSourceTest() {
-
+ /// @brief Clears the database and opens connection to it.
+ void initializeTest() {
// Ensure schema is the correct one.
destroyMySQLSchema();
createMySQLSchema();
hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
}
- /// @brief Destructor
- ///
- /// Rolls back all pending transactions. The deletion of myhdsptr_ will close
- /// the database. Then reopen it and delete everything created by the test.
- virtual ~MySqlHostDataSourceTest() {
+ /// @brief Destroys the HDS and the schema.
+ void destroyTest() {
try {
hdsptr_->rollback();
} catch (...) {
// Rollback may fail if backend is in read only mode. That's ok.
}
HostDataSourceFactory::destroy();
- hdsptr_.reset();
destroyMySQLSchema();
}
+ /// @brief Constructor
+ ///
+ /// Deletes everything from the database and opens it.
+ MySqlHostDataSourceTest() {
+ initializeTest();
+ }
+
+ /// @brief Destructor
+ ///
+ /// Rolls back all pending transactions. The deletion of myhdsptr_ will close
+ /// the database. Then reopen it and delete everything created by the test.
+ virtual ~MySqlHostDataSourceTest() {
+ destroyTest();
+ }
+
/// @brief Reopen the database
///
/// Closes the database and re-open it. Anything committed should be
params["name"] = "keatest";
params["user"] = "keatest";
params["password"] = "keatest";
+
MySqlConnection conn(params);
conn.openDatabase();
+
int status = mysql_query(conn.mysql_, query.c_str());
if (status !=0) {
isc_throw(DbOperationError, "Query failed: " << mysql_error(conn.mysql_));
<< "*** before the MySQL tests will run correctly.\n";
}
- // Check that attempting to get an instance of the lease manager when
+ // Check that attempting to get an instance of the host data source when
// none is set throws an exception.
EXPECT_FALSE(HostDataSourceFactory::getHostDataSourcePtr());
// Check that wrong specification of backend throws an exception.
- // (This is really a check on LeaseMgrFactory, but is convenient to
+ // (This is really a check on HostDataSourceFactory, but is convenient to
// perform here.)
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
NULL, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
destroyMySQLSchema();
}
-
-
/// @brief Check conversion functions
///
/// The server works using cltt and valid_filetime. In the database, the
EXPECT_EQ(cltt, converted_cltt);
}
+// This test verifies that database backend can operate in Read-Only mode.
TEST_F(MySqlHostDataSourceTest, testReadOnlyDatabase) {
testReadOnlyDatabase(MYSQL_VALID_TYPE);
}
params["password"] = "keatest";
MySqlConnection conn(params);
ASSERT_NO_THROW(conn.openDatabase());
+
int status = mysql_query(conn.mysql_,
"DROP TABLE IF EXISTS ipv6_reservations");
ASSERT_EQ(0, status) << mysql_error(conn.mysql_);
testMultipleHosts6();
}
-}; // Of anonymous namespace
+} // namespace
class MySqlLeaseMgrTest : public GenericLeaseMgrTest {
public:
- /// @brief Constructor
- ///
- /// Deletes everything from the database and opens it.
- MySqlLeaseMgrTest() {
-
+ /// @brief Clears the database and opens connection to it.
+ void initializeTest() {
// Ensure schema is the correct one.
destroyMySQLSchema();
createMySQLSchema();
"*** accompanying exception output.\n";
throw;
}
+
lmptr_ = &(LeaseMgrFactory::instance());
}
+ /// @brief Destroys the LM and the schema.
+ void destroyTest() {
+ try {
+ lmptr_->rollback();
+ } catch (...) {
+ // Rollback may fail if backend is in read only mode. That's ok.
+ }
+ LeaseMgrFactory::destroy();
+ destroyMySQLSchema();
+ }
+
+ /// @brief Constructor
+ ///
+ /// Deletes everything from the database and opens it.
+ MySqlLeaseMgrTest() {
+ initializeTest();
+ }
+
/// @brief Destructor
///
/// Rolls back all pending transactions. The deletion of lmptr_ will close
/// the database. Then reopen it and delete everything created by the test.
virtual ~MySqlLeaseMgrTest() {
- lmptr_->rollback();
- LeaseMgrFactory::destroy();
- destroyMySQLSchema();
+ destroyTest();
}
/// @brief Reopen the database
LeaseMgrFactory::create(validMySQLConnectionString());
lmptr_ = &(LeaseMgrFactory::instance());
}
-
};
/// @brief Check that database can be opened
// If it fails, print the error message.
try {
LeaseMgrFactory::create(validMySQLConnectionString());
- EXPECT_NO_THROW((void) LeaseMgrFactory::instance());
+ EXPECT_NO_THROW((void)LeaseMgrFactory::instance());
LeaseMgrFactory::destroy();
} catch (const isc::Exception& ex) {
FAIL() << "*** ERROR: unable to open database, reason:\n"
EXPECT_THROW(LeaseMgrFactory::create(connectionString(
NULL, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
InvalidParameter);
+
EXPECT_THROW(LeaseMgrFactory::create(connectionString(
INVALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
InvalidType);
EXPECT_THROW(LeaseMgrFactory::create(connectionString(
MYSQL_VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)),
DbOpenError);
+
EXPECT_THROW(LeaseMgrFactory::create(connectionString(
MYSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)),
DbOpenError);
+
EXPECT_THROW(LeaseMgrFactory::create(connectionString(
MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
DbOpenError);
+
EXPECT_THROW(LeaseMgrFactory::create(connectionString(
MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)),
DbOpenError);
+
+ // Check for invalid timeouts
EXPECT_THROW(LeaseMgrFactory::create(connectionString(
MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_1)),
DbInvalidTimeout);
+
EXPECT_THROW(LeaseMgrFactory::create(connectionString(
MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD, INVALID_TIMEOUT_2)),
DbInvalidTimeout);
EXPECT_EQ(cltt, converted_cltt);
}
-
/// @brief Check getName() returns correct database name
TEST_F(MySqlLeaseMgrTest, getName) {
EXPECT_EQ(std::string("keatest"), lmptr_->getName());
/// @brief Basic Lease4 Checks
///
/// Checks that the addLease, getLease4(by address), getLease4(hwaddr,subnet_id),
-/// updateLease4() and deleteLease (IPv4 address) can handle NULL client-id.
+/// updateLease4() and deleteLease can handle NULL client-id.
/// (client-id is optional and may not be present)
TEST_F(MySqlLeaseMgrTest, lease4NullClientId) {
testLease4NullClientId();
testLease4InvalidHostname();
}
+/// @brief Check that the expired DHCPv4 leases can be retrieved.
+///
+/// This test adds a number of leases to the lease database and marks
+/// some of them as expired. Then it queries for expired leases and checks
+/// whether only expired leases are returned, and that they are returned in
+/// the order from most to least expired. It also checks that the lease
+/// which is marked as 'reclaimed' is not returned.
+TEST_F(MySqlLeaseMgrTest, getExpiredLeases4) {
+ testGetExpiredLeases4();
+}
+
+/// @brief Check that expired reclaimed DHCPv4 leases are removed.
+TEST_F(MySqlLeaseMgrTest, deleteExpiredReclaimedLeases4) {
+ testDeleteExpiredReclaimedLeases4();
+}
+
////////////////////////////////////////////////////////////////////////////////
/// LEASE6 /////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
testLease6HWTypeAndSource();
}
-/// @brief Check that the expired DHCPv4 leases can be retrieved.
-///
-/// This test adds a number of leases to the lease database and marks
-/// some of them as expired. Then it queries for expired leases and checks
-/// whether only expired leases are returned, and that they are returned in
-/// the order from most to least expired. It also checks that the lease
-/// which is marked as 'reclaimed' is not returned.
-TEST_F(MySqlLeaseMgrTest, getExpiredLeases4) {
- testGetExpiredLeases4();
-}
-
/// @brief Check that the expired DHCPv6 leases can be retrieved.
///
/// This test adds a number of leases to the lease database and marks
testDeleteExpiredReclaimedLeases6();
}
-/// @brief Check that expired reclaimed DHCPv4 leases are removed.
-TEST_F(MySqlLeaseMgrTest, deleteExpiredReclaimedLeases4) {
- testDeleteExpiredReclaimedLeases4();
-}
-
// Verifies that IPv4 lease statistics can be recalculated.
TEST_F(MySqlLeaseMgrTest, recountLeaseStats4) {
testRecountLeaseStats4();
testWipeLeases6();
}
-}; // Of anonymous namespace
+} // namespace
class PgSqlHostDataSourceTest : public GenericHostDataSourceTest {
public:
- /// @brief Constructor
- ///
- /// Deletes everything from the database and opens it.
- PgSqlHostDataSourceTest() {
-
+ /// @brief Clears the database and opens connection to it.
+ void initializeTest() {
// Ensure schema is the correct one.
destroyPgSQLSchema();
createPgSQLSchema();
hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
}
- /// @brief Destructor
- ///
- /// Rolls back all pending transactions. The deletion of myhdsptr_ will
- /// close the database. Then reopen it and delete everything created by
- /// the test.
- virtual ~PgSqlHostDataSourceTest() {
+ /// @brief Destroys the HDS and the schema.
+ void destroyTest() {
try {
hdsptr_->rollback();
} catch (...) {
// Rollback may fail if backend is in read only mode. That's ok.
}
HostDataSourceFactory::destroy();
- hdsptr_.reset();
destroyPgSQLSchema();
}
+ /// @brief Constructor
+ ///
+ /// Deletes everything from the database and opens it.
+ PgSqlHostDataSourceTest() {
+ initializeTest();
+ }
+
+ /// @brief Destructor
+ ///
+ /// Rolls back all pending transactions. The deletion of myhdsptr_ will close
+ /// the database. Then reopen it and delete everything created by the test.
+ virtual ~PgSqlHostDataSourceTest() {
+ destroyTest();
+ }
+
/// @brief Reopen the database
///
/// Closes the database and re-open it. Anything committed should be
/// visible.
///
- /// Parameter is ignored for PostgreSQL backend as the v4 and v6 leases
- /// share the same database.
+ /// Parameter is ignored for PostgreSQL backend as the v4 and v6 leases share
+ /// the same database.
void reopen(Universe) {
HostDataSourceFactory::destroy();
HostDataSourceFactory::create(validPgSQLConnectionString());
}
int numrows = PQntuples(r);
+
return (numrows);
}
- /// @brief Returns number of IPv4 options in the DB table.
+ /// @brief Returns number of IPv4 options currently stored in DB.
virtual int countDBOptions4() {
return (countRowsInTable("dhcp4_options"));
}
- /// @brief Returns number of IPv4 options in the DB table.
+ /// @brief Returns number of IPv4 options currently stored in DB.
virtual int countDBOptions6() {
return (countRowsInTable("dhcp6_options"));
}
- /// @brief Returns number of IPv6 reservations in the DB table.
+ /// @brief Returns number of IPv6 reservations currently stored in DB.
virtual int countDBReservations6() {
return (countRowsInTable("ipv6_reservations"));
}
<< "*** before the PostgreSQL tests will run correctly.\n";
}
- // Check that attempting to get an instance of the lease manager when
+ // Check that attempting to get an instance of the host data source when
// none is set throws an exception.
EXPECT_FALSE(HostDataSourceFactory::getHostDataSourcePtr());
// Check that wrong specification of backend throws an exception.
- // (This is really a check on LeaseMgrFactory, but is convenient to
+ // (This is really a check on HostDataSourceFactory, but is convenient to
// perform here.)
EXPECT_THROW(HostDataSourceFactory::create(connectionString(
NULL, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)),
destroyPgSQLSchema();
}
-
// This test verifies that database backend can operate in Read-Only mode.
TEST_F(PgSqlHostDataSourceTest, testReadOnlyDatabase) {
testReadOnlyDatabase(PGSQL_VALID_TYPE);
testHostname("foo.example.org", 100);
}
-// Test verifies if a host without any hostname specified can be stored and
-// later retrieved.
+// Test verifies if a host without any hostname specified can be stored and later
+// retrieved.
TEST_F(PgSqlHostDataSourceTest, noHostname) {
testHostname("", 1);
}
testMultipleHosts6();
}
-}; // Of anonymous namespace
+} // namespace