namespace dhcp {
-boost::scoped_ptr<BaseHostDataSource>&
+HostDataSourcePtr&
HostDataSourceFactory::getHostDataSourcePtr() {
- static boost::scoped_ptr<BaseHostDataSource> hostDataSourcePtr;
+ static HostDataSourcePtr hostDataSourcePtr;
return (hostDataSourcePtr);
}
getHostDataSourcePtr().reset();
}
+#if 0
BaseHostDataSource&
HostDataSourceFactory::instance() {
BaseHostDataSource* hdsptr = getHostDataSourcePtr().get();
}
return (*hdsptr);
}
+#endif
}; // namespace dhcp
}; // namespace isc
/// host data source is available.
static void destroy();
- /// @brief Return current host data source
- ///
- /// @returns An instance of the "current" host data source. An exception
- /// will be thrown if none is available.
- ///
- /// @throw NoHostDataSourceManager No host data source is available: use
- /// create() to create one before calling this method.
- static BaseHostDataSource& instance();
-
-private:
/// @brief Hold pointer to host data source instance
///
/// Holds a pointer to the singleton host data source. The singleton
/// is encapsulated in this method to avoid a "static initialization
/// fiasco" if defined in an external static variable.
- static boost::scoped_ptr<BaseHostDataSource>& getHostDataSourcePtr();
-
+ static HostDataSourcePtr& getHostDataSourcePtr();
};
if (!access.empty()) {
HostDataSourceFactory::create(access);
- /// @todo Initialize alternate_source here.
- //alternate_source = HostDataSourceFactory::getHostDataSourcePtr();
}
+
+ // Now store the host data source pointer.
+ getHostMgrPtr()->alternate_source = HostDataSourceFactory::getHostDataSourcePtr();
}
HostMgr&
#include <boost/scoped_ptr.hpp>
#include <mysql.h>
#include <vector>
+#include <stdint.h>
namespace isc {
namespace dhcp {
libdhcpsrv_unittests_SOURCES += memfile_lease_mgr_unittest.cc
libdhcpsrv_unittests_SOURCES += dhcp_parsers_unittest.cc
if HAVE_MYSQL
+libdhcpsrv_unittests_SOURCES += mysql_schema.cc mysql_schema.h
libdhcpsrv_unittests_SOURCES += mysql_lease_mgr_unittest.cc
libdhcpsrv_unittests_SOURCES += mysql_host_data_source_unittest.cc
endif
#include <cc/command_interpreter.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcpsrv/parsers/dbaccess_parser.h>
+#include <dhcpsrv/tests/mysql_schema.h>
#include <dhcpsrv/host_mgr.h>
#include <log/logger_support.h>
using namespace std;
using namespace isc;
using namespace isc::dhcp;
+using namespace isc::dhcp::test;
using namespace isc::data;
using namespace isc::config;
// that does not assume that the test has been built with MySQL support.
TEST_F(DbAccessParserTest, commitLeaseDb) {
+ EXPECT_NO_THROW(createMySQLSchema());
+
// Verify that no lease database is open
EXPECT_THROW({
LeaseMgr& manager = LeaseMgrFactory::instance();
EXPECT_EQ(std::string("memfile"), dbtype);
}
+#ifdef HAVE_MYSQL
// Check that the "commit" function actually opens the database, when type
-// is set to HOSTS_DB.
+// is set to HOSTS_DB. We're using MySQL here. Since the only currently supported
+// host data source is the one that uses MySQL, we have no other choice, but to
+// depend this test on MYSQL availability.
TEST_F(DbAccessParserTest, commitHostsDb) {
// Verify that no lease database is open
}, isc::dhcp::NoLeaseManager);
// Set up the parser to open the memfile database.
- const char* config[] = {"type", "memfile", "persist", "false", NULL};
+ const char* config[] = {"type", "mysql", "user", "keatest",
+ "password", "keatest", "name", "keatest", NULL};
string json_config = toJson(config);
ConstElementPtr json_elements = Element::fromJSON(json_config);
EXPECT_NO_THROW(parser.build(json_elements));
// Ensure that the access string is as expected.
- EXPECT_EQ("persist=false type=memfile universe=4",
+ EXPECT_EQ("name=keatest password=keatest type=mysql universe=4 user=keatest",
parser.getDbAccessString());
// Destroy lease mgr (if there's any)
LeaseMgrFactory::destroy();
+ EXPECT_NO_THROW(createMySQLSchema());
+
// Committal of the parser changes should not create LeaseMgr.
// It should create HostDataSource instead.
EXPECT_NO_THROW(parser.commit());
- // Check that LeaseMgr was NOT created (it shouldn't, this is for HOSTS_DB.
+ // Check that LeaseMgr was NOT created (it shouldn't, this is for HOSTS_DB).
EXPECT_THROW(LeaseMgrFactory::instance(), NoLeaseManager);
+ // Verify that HostDataSource has been created.
HostDataSourcePtr hds = HostMgr::instance().getHostDataSource();
+ ASSERT_TRUE(hds);
+
+ EXPECT_EQ("mysql", hds->getType());
- /// @todo: Uncomment this once 3682 is merged. The whole unit-test
- /// should create MySQL database and be ifdefed appropriately.
- // ASSERT_TRUE(hds);
+ EXPECT_NO_THROW(destroyMySQLSchema());
}
+#endif
}; // Anonymous namespace
namespace test {
GenericHostDataSourceTest::GenericHostDataSourceTest()
- :hdsptr_(NULL) {
+ :hdsptr_() {
}
const ClientClasses& classes2);
/// @brief Pointer to the host data source
- BaseHostDataSource* hdsptr_;
+ HostDataSourcePtr hdsptr_;
/// @brief Test that checks that simple host with IPv4 reservation
/// can be inserted and later retrieved.
throw;
}
- hdsptr_ = &(HostDataSourceFactory::instance());
+ hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
}
/// @brief Destructor
void reopen(Universe) {
HostDataSourceFactory::destroy();
HostDataSourceFactory::create(validConnectionString());
- hdsptr_ = &(HostDataSourceFactory::instance());
+ hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
}
};
// If it fails, print the error message.
try {
HostDataSourceFactory::create(validConnectionString());
- EXPECT_NO_THROW((void) HostDataSourceFactory::instance());
+ EXPECT_NO_THROW((void) HostDataSourceFactory::getHostDataSourcePtr());
HostDataSourceFactory::destroy();
} catch (const isc::Exception& ex) {
FAIL() << "*** ERROR: unable to open database, reason:\n"
// Check that attempting to get an instance of the lease manager when
// none is set throws an exception.
- EXPECT_THROW(HostDataSourceFactory::instance(), NoHostDataSourceManager);
+ EXPECT_FALSE(HostDataSourceFactory::getHostDataSourcePtr());
// Check that wrong specification of backend throws an exception.
// (This is really a check on LeaseMgrFactory, but is convenient to
#include <dhcpsrv/mysql_lease_mgr.h>
#include <dhcpsrv/tests/test_utils.h>
#include <dhcpsrv/tests/generic_lease_mgr_unittest.h>
+#include <dhcpsrv/tests/mysql_schema.h>
#include <exceptions/exceptions.h>
#include <gtest/gtest.h>
namespace {
-// This holds statements to create and destroy the schema.
-#include "schema_mysql_copy.h"
-
-// Connection strings.
-// Database: keatest
-// Host: localhost
-// Username: keatest
-// Password: keatest
-const char* VALID_TYPE = "type=mysql";
-const char* INVALID_TYPE = "type=unknown";
-const char* VALID_NAME = "name=keatest";
-const char* INVALID_NAME = "name=invalidname";
-const char* VALID_HOST = "host=localhost";
-const char* INVALID_HOST = "host=invalidhost";
-const char* VALID_USER = "user=keatest";
-const char* INVALID_USER = "user=invaliduser";
-const char* VALID_PASSWORD = "password=keatest";
-const char* INVALID_PASSWORD = "password=invalid";
-
-// Given a combination of strings above, produce a connection string.
-string connectionString(const char* type, const char* name, const char* host,
- const char* user, const char* password) {
- const string space = " ";
- string result = "";
-
- if (type != NULL) {
- result += string(type);
- }
- if (name != NULL) {
- if (! result.empty()) {
- result += space;
- }
- result += string(name);
- }
-
- if (host != NULL) {
- if (! result.empty()) {
- result += space;
- }
- result += string(host);
- }
-
- if (user != NULL) {
- if (! result.empty()) {
- result += space;
- }
- result += string(user);
- }
-
- if (password != NULL) {
- if (! result.empty()) {
- result += space;
- }
- result += string(password);
- }
-
- return (result);
-}
-
-// Return valid connection string
-string
-validConnectionString() {
- return (connectionString(VALID_TYPE, VALID_NAME, VALID_HOST,
- VALID_USER, VALID_PASSWORD));
-}
-
-// @brief Clear everything from the database
-//
-// There is no error checking in this code: if something fails, one of the
-// tests will (should) fall over.
-void destroySchema() {
- MySqlHolder mysql;
-
- // Open database
- (void) mysql_real_connect(mysql, "localhost", "keatest",
- "keatest", "keatest", 0, NULL, 0);
-
- // Get rid of everything in it.
- for (int i = 0; destroy_statement[i] != NULL; ++i) {
- (void) mysql_query(mysql, destroy_statement[i]);
- }
-}
-
-// @brief Create the Schema
-//
-// Creates all the tables in what is assumed to be an empty database.
-//
-// There is no error checking in this code: if it fails, one of the tests
-// will fall over.
-void createSchema() {
- MySqlHolder mysql;
-
- // Open database
- (void) mysql_real_connect(mysql, "localhost", "keatest",
- "keatest", "keatest", 0, NULL, 0);
-
- // Execute creation statements.
- for (int i = 0; create_statement[i] != NULL; ++i) {
- ASSERT_EQ(0, mysql_query(mysql, create_statement[i]))
- << "Failed on statement " << i << ": " << create_statement[i];
- }
-}
/// @brief Test fixture class for testing MySQL Lease Manager
///
MySqlLeaseMgrTest() {
// Ensure schema is the correct one.
- destroySchema();
- createSchema();
+ destroyMySQLSchema();
+ createMySQLSchema();
// Connect to the database
try {
- LeaseMgrFactory::create(validConnectionString());
+ LeaseMgrFactory::create(validMySQLConnectionString());
} catch (...) {
std::cerr << "*** ERROR: unable to open database. The test\n"
"*** environment is broken and must be fixed before\n"
virtual ~MySqlLeaseMgrTest() {
lmptr_->rollback();
LeaseMgrFactory::destroy();
- destroySchema();
+ destroyMySQLSchema();
}
/// @brief Reopen the database
/// the same database.
void reopen(Universe) {
LeaseMgrFactory::destroy();
- LeaseMgrFactory::create(validConnectionString());
+ LeaseMgrFactory::create(validMySQLConnectionString());
lmptr_ = &(LeaseMgrFactory::instance());
}
TEST(MySqlOpenTest, OpenDatabase) {
// Schema needs to be created for the test to work.
- destroySchema();
- createSchema();
+ destroyMySQLSchema();
+ createMySQLSchema();
// Check that lease manager open the database opens correctly and tidy up.
// If it fails, print the error message.
try {
- LeaseMgrFactory::create(validConnectionString());
+ LeaseMgrFactory::create(validMySQLConnectionString());
EXPECT_NO_THROW((void) LeaseMgrFactory::instance());
LeaseMgrFactory::destroy();
} catch (const isc::Exception& ex) {
NoDatabaseName);
// Tidy up after the test
- destroySchema();
+ destroyMySQLSchema();
}
/// @brief Check the getType() method
--- /dev/null
+// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#include <config.h>
+#include <string>
+#include <mysql.h>
+#include <dhcpsrv/mysql_connection.h>
+#include <gtest/gtest.h>
+
+// This holds statements to create and destroy the schema.
+#include "schema_mysql_copy.h"
+
+using namespace std;
+
+namespace isc {
+namespace dhcp {
+namespace test {
+
+// Connection strings.
+// Database: keatest
+// Host: localhost
+// Username: keatest
+// Password: keatest
+const char* VALID_TYPE = "type=mysql";
+const char* INVALID_TYPE = "type=unknown";
+const char* VALID_NAME = "name=keatest";
+const char* INVALID_NAME = "name=invalidname";
+const char* VALID_HOST = "host=localhost";
+const char* INVALID_HOST = "host=invalidhost";
+const char* VALID_USER = "user=keatest";
+const char* INVALID_USER = "user=invaliduser";
+const char* VALID_PASSWORD = "password=keatest";
+const char* INVALID_PASSWORD = "password=invalid";
+
+string connectionString(const char* type, const char* name, const char* host,
+ const char* user, const char* password) {
+ const string space = " ";
+ string result = "";
+
+ if (type != NULL) {
+ result += string(type);
+ }
+ if (name != NULL) {
+ if (! result.empty()) {
+ result += space;
+ }
+ result += string(name);
+ }
+
+ if (host != NULL) {
+ if (! result.empty()) {
+ result += space;
+ }
+ result += string(host);
+ }
+
+ if (user != NULL) {
+ if (! result.empty()) {
+ result += space;
+ }
+ result += string(user);
+ }
+
+ if (password != NULL) {
+ if (! result.empty()) {
+ result += space;
+ }
+ result += string(password);
+ }
+
+ return (result);
+}
+
+// Return valid connection string
+string
+validMySQLConnectionString() {
+ return (connectionString(VALID_TYPE, VALID_NAME, VALID_HOST,
+ VALID_USER, VALID_PASSWORD));
+}
+
+// @brief Clear everything from the database
+//
+// There is no error checking in this code: if something fails, one of the
+// tests will (should) fall over.
+void destroyMySQLSchema() {
+ MySqlHolder mysql;
+
+ // Open database
+ (void) mysql_real_connect(mysql, "localhost", "keatest",
+ "keatest", "keatest", 0, NULL, 0);
+
+ // Get rid of everything in it.
+ for (int i = 0; destroy_statement[i] != NULL; ++i) {
+ (void) mysql_query(mysql, destroy_statement[i]);
+ }
+}
+
+// @brief Create the Schema
+//
+// Creates all the tables in what is assumed to be an empty database.
+//
+// There is no error checking in this code: if it fails, one of the tests
+// will fall over.
+void createMySQLSchema() {
+ MySqlHolder mysql;
+
+ // Open database
+ (void) mysql_real_connect(mysql, "localhost", "keatest",
+ "keatest", "keatest", 0, NULL, 0);
+
+ // Execute creation statements.
+ for (int i = 0; create_statement[i] != NULL; ++i) {
+ ASSERT_EQ(0, mysql_query(mysql, create_statement[i]))
+ << "Failed on statement " << i << ": " << create_statement[i];
+ }
+}
+
+};
+};
+};
--- /dev/null
+// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+// PERFORMANCE OF THIS SOFTWARE.
+
+#ifndef TEST_MYSQL_SCHEMA_H
+#define TEST_MYSQL_SCHEMA_H
+
+#include <config.h>
+#include <string>
+
+namespace isc {
+namespace dhcp {
+namespace test {
+
+extern const char* VALID_TYPE;
+extern const char* INVALID_TYPE;
+extern const char* VALID_NAME;
+extern const char* INVALID_NAME;
+extern const char* VALID_HOST;
+extern const char* INVALID_HOST;
+extern const char* VALID_USER;
+extern const char* INVALID_USER;
+extern const char* VALID_PASSWORD;
+extern const char* INVALID_PASSWORD;
+
+/// @brief Create the Schema
+///
+/// Creates all the tables in what is assumed to be an empty database.
+///
+/// There is no error checking in this code: if it fails, one of the tests
+/// will fall over.
+void createMySQLSchema();
+
+/// @brief Clear everything from the database
+///
+/// There is no error checking in this code: if something fails, one of the
+/// tests will (should) fall over.
+void destroyMySQLSchema();
+
+/// Return valid connection string
+///
+/// @return valid MySQL connection string.
+std::string validMySQLConnectionString();
+
+/// @brief Given a combination of strings above, produce a connection string.
+///
+/// @param type type of the database
+/// @param name name of the database to connect to
+/// @param host hostname
+/// @param user username used to authendicate during connection attempt
+/// @param password password used to authendicate during connection attempt
+/// @return string containing all specified parameters
+std::string connectionString(const char* type, const char* name, const char* host,
+ const char* user, const char* password);
+};
+};
+};
+
+#endif