Browse Source

[3569_rebase] MySQL host data source is now indeed created and stored.

Tomek Mrugalski 9 years ago
parent
commit
3be59fccd1

+ 4 - 2
src/lib/dhcpsrv/host_data_source_factory.cc

@@ -39,9 +39,9 @@ namespace isc {
 namespace dhcp {
 
 
-boost::scoped_ptr<BaseHostDataSource>&
+HostDataSourcePtr&
 HostDataSourceFactory::getHostDataSourcePtr() {
-    static boost::scoped_ptr<BaseHostDataSource> hostDataSourcePtr;
+    static HostDataSourcePtr hostDataSourcePtr;
     return (hostDataSourcePtr);
 }
 
@@ -99,6 +99,7 @@ HostDataSourceFactory::destroy() {
     getHostDataSourcePtr().reset();
 }
 
+#if 0
 BaseHostDataSource&
 HostDataSourceFactory::instance() {
     BaseHostDataSource* hdsptr = getHostDataSourcePtr().get();
@@ -108,6 +109,7 @@ HostDataSourceFactory::instance() {
     }
     return (*hdsptr);
 }
+#endif
 
 }; // namespace dhcp
 }; // namespace isc

+ 1 - 12
src/lib/dhcpsrv/host_data_source_factory.h

@@ -88,23 +88,12 @@ public:
     /// 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();
 };
 
 

+ 3 - 2
src/lib/dhcpsrv/host_mgr.cc

@@ -51,9 +51,10 @@ HostMgr::create(const std::string& access) {
     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&

+ 1 - 0
src/lib/dhcpsrv/mysql_connection.h

@@ -19,6 +19,7 @@
 #include <boost/scoped_ptr.hpp>
 #include <mysql.h>
 #include <vector>
+#include <stdint.h>
 
 namespace isc {
 namespace dhcp {

+ 1 - 0
src/lib/dhcpsrv/tests/Makefile.am

@@ -104,6 +104,7 @@ libdhcpsrv_unittests_SOURCES += generic_host_data_source_unittest.cc generic_hos
 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

+ 20 - 7
src/lib/dhcpsrv/tests/dbaccess_parser_unittest.cc

@@ -17,6 +17,7 @@
 #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>
 
@@ -28,6 +29,7 @@
 using namespace std;
 using namespace isc;
 using namespace isc::dhcp;
+using namespace isc::dhcp::test;
 using namespace isc::data;
 using namespace isc::config;
 
@@ -536,6 +538,8 @@ TEST_F(DbAccessParserTest, getDbAccessString) {
 // 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();
@@ -566,8 +570,11 @@ TEST_F(DbAccessParserTest, commitLeaseDb) {
     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
@@ -577,7 +584,8 @@ TEST_F(DbAccessParserTest, commitHostsDb) {
             }, 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);
@@ -588,24 +596,29 @@ TEST_F(DbAccessParserTest, commitHostsDb) {
     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

+ 1 - 1
src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc

@@ -27,7 +27,7 @@ namespace dhcp {
 namespace test {
 
 GenericHostDataSourceTest::GenericHostDataSourceTest()
-    :hdsptr_(NULL) {
+    :hdsptr_() {
 
 }
 

+ 1 - 1
src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h

@@ -125,7 +125,7 @@ public:
                               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.

+ 4 - 4
src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc

@@ -166,7 +166,7 @@ public:
             throw;
         }
 
-        hdsptr_ = &(HostDataSourceFactory::instance());
+        hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
     }
 
     /// @brief Destructor
@@ -189,7 +189,7 @@ public:
     void reopen(Universe) {
         HostDataSourceFactory::destroy();
         HostDataSourceFactory::create(validConnectionString());
-        hdsptr_ = &(HostDataSourceFactory::instance());
+        hdsptr_ = HostDataSourceFactory::getHostDataSourcePtr();
     }
 
 };
@@ -211,7 +211,7 @@ TEST(MySqlHostDataSource, OpenDatabase) {
     //  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"
@@ -222,7 +222,7 @@ TEST(MySqlHostDataSource, OpenDatabase) {
 
     // 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

+ 10 - 111
src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc

@@ -20,6 +20,7 @@
 #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>
@@ -38,108 +39,6 @@ using namespace std;
 
 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
 ///
@@ -154,12 +53,12 @@ public:
     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"
@@ -178,7 +77,7 @@ public:
     virtual ~MySqlLeaseMgrTest() {
         lmptr_->rollback();
         LeaseMgrFactory::destroy();
-        destroySchema();
+        destroyMySQLSchema();
     }
 
     /// @brief Reopen the database
@@ -190,7 +89,7 @@ public:
     /// the same database.
     void reopen(Universe) {
         LeaseMgrFactory::destroy();
-        LeaseMgrFactory::create(validConnectionString());
+        LeaseMgrFactory::create(validMySQLConnectionString());
         lmptr_ = &(LeaseMgrFactory::instance());
     }
 
@@ -206,13 +105,13 @@ public:
 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) {
@@ -256,7 +155,7 @@ TEST(MySqlOpenTest, OpenDatabase) {
         NoDatabaseName);
 
     // Tidy up after the test
-    destroySchema();
+    destroyMySQLSchema();
 }
 
 /// @brief Check the getType() method

+ 131 - 0
src/lib/dhcpsrv/tests/mysql_schema.cc

@@ -0,0 +1,131 @@
+// 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];
+    }
+}
+
+};
+};
+};

+ 69 - 0
src/lib/dhcpsrv/tests/mysql_schema.h

@@ -0,0 +1,69 @@
+// 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