From: Thomas Markwalder Date: Mon, 11 Apr 2016 15:51:15 +0000 (-0400) Subject: [4239] MySQL and Postgresql unit tests use production schema create scripts X-Git-Tag: trac4106_update_base~38^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b45da89536223294e3b1b2e9cf0d71a0b73e75bb;p=thirdparty%2Fkea.git [4239] MySQL and Postgresql unit tests use production schema create scripts src/lib/dhcpsrv/testutils/schema.h src/lib/dhcpsrv/testutils/schema.cc New files that contain constants and functions common to RDBMS testing src/lib/dhcpsrv/testutils/pgsql_schema.h src/lib/dhcpsrv/testutils/pgsql_schema.cc New files that contain constants and functions needed for Posgresql testing src/lib/dhcpsrv/testutils/mysql_schema.cc src/lib/dhcpsrv/testutils/mysql_schema.h Removed common constants and functions Added MYSQL_VALID_TYPE runMySQLScript() - new function to submit a script to MySQL src/lib/dhcpsrv/pgsql_lease_mgr.cc PgSqlLease6Exchange - replaced uint32_t iaid member with Uiaid union instance. This permits the value to be safely stored in the database as an INT (signed 4-byte value) getColumnValue()- added int32_t variant of this method src/lib/dhcpsrv/tests/Makefile.am Removed schema_pgsql_copy.h src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc Altered tests to use MYSQL_VALID_TYPE src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc Moved constants and functions testutils/pgsl_schema.h & cc --- diff --git a/src/lib/dhcpsrv/pgsql_lease_mgr.cc b/src/lib/dhcpsrv/pgsql_lease_mgr.cc index ce83103bce..2691a619d3 100644 --- a/src/lib/dhcpsrv/pgsql_lease_mgr.cc +++ b/src/lib/dhcpsrv/pgsql_lease_mgr.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -461,6 +461,27 @@ public: } } + /// @brief Converts a column in a row in a result set to a int32_t. + /// + /// @param r the result set containing the query results + /// @param row the row number within the result set + /// @param col the column number within the row + /// @param[out] value parameter to receive the converted value + /// + /// @throw DbOperationError if the value cannot be fetched or is + /// invalid. + void getColumnValue(PGresult*& r, const int row, const size_t col, + int32_t &value) const { + const char* data = getRawColumnValue(r, row, col); + try { + value = boost::lexical_cast(data); + } catch (const std::exception& ex) { + isc_throw(DbOperationError, "Invalid int32_t data: " << data + << " for: " << getColumnLabel(col) << " row:" << row + << " : " << ex.what()); + } + } + /// @brief Converts a column in a row in a result set to a uint8_t. /// /// @param r the result set containing the query results @@ -807,7 +828,7 @@ private: public: PgSqlLease6Exchange() - : lease_(), duid_length_(0), duid_(), iaid_(0), iaid_str_(""), + : lease_(), duid_length_(0), duid_(), iaid_u_(0), iaid_str_(""), lease_type_(Lease6::TYPE_NA), lease_type_str_(""), prefix_len_(0), prefix_len_str_(""), pref_lifetime_(0), preferred_lft_str_("") { @@ -878,7 +899,11 @@ public: lease_type_str_ = boost::lexical_cast(lease_->type_); bind_array.add(lease_type_str_); - iaid_str_ = boost::lexical_cast(lease_->iaid_); + // The iaid is stored as an INT in lease6 table, so we must + // lexically cast from an integer version to avoid out of range + // exception failure upon insert. + iaid_u_.uval_ = lease_->iaid_; + iaid_str_ = boost::lexical_cast(iaid_u_.ival_); bind_array.add(iaid_str_); prefix_len_str_ = boost::lexical_cast @@ -930,7 +955,7 @@ public: getColumnValue(r, row, LEASE_TYPE_COL, lease_type_); - getColumnValue(r, row , IAID_COL, iaid_); + getColumnValue(r, row , IAID_COL, iaid_u_.ival_); getColumnValue(r, row , PREFIX_LEN_COL, prefix_len_); @@ -942,8 +967,9 @@ public: /// @todo: implement this in #3557. HWAddrPtr hwaddr; - Lease6Ptr result(new Lease6(lease_type_, addr, duid_ptr, iaid_, - pref_lifetime_, valid_lifetime_, 0, 0, + Lease6Ptr result(new Lease6(lease_type_, addr, duid_ptr, + iaid_u_.uval_, pref_lifetime_, + valid_lifetime_, 0, 0, subnet_id_, fqdn_fwd_, fqdn_rev_, hostname_, hwaddr, prefix_len_)); result->cltt_ = cltt_; @@ -987,7 +1013,14 @@ private: size_t duid_length_; vector duid_; uint8_t duid_buffer_[DUID::MAX_DUID_LEN]; - uint32_t iaid_; + + union Uiaid { + Uiaid(uint32_t val) : uval_(val){}; + Uiaid(int32_t val) : ival_(val){}; + uint32_t uval_; + int32_t ival_; + } iaid_u_; + std::string iaid_str_; Lease6::Type lease_type_; std::string lease_type_str_; diff --git a/src/lib/dhcpsrv/tests/Makefile.am b/src/lib/dhcpsrv/tests/Makefile.am index 86890aa6d4..2d88848c83 100755 --- a/src/lib/dhcpsrv/tests/Makefile.am +++ b/src/lib/dhcpsrv/tests/Makefile.am @@ -115,7 +115,6 @@ if HAVE_PGSQL libdhcpsrv_unittests_SOURCES += pgsql_lease_mgr_unittest.cc endif libdhcpsrv_unittests_SOURCES += pool_unittest.cc -libdhcpsrv_unittests_SOURCES += schema_pgsql_copy.h libdhcpsrv_unittests_SOURCES += srv_config_unittest.cc libdhcpsrv_unittests_SOURCES += subnet_unittest.cc libdhcpsrv_unittests_SOURCES += test_get_callout_handle.cc test_get_callout_handle.h diff --git a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc b/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc index ced78e34a0..7ec4e4e3b3 100644 --- a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc +++ b/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc @@ -125,21 +125,21 @@ TEST(MySqlHostDataSource, OpenDatabase) { // Check that invalid login data causes an exception. EXPECT_THROW(HostDataSourceFactory::create(connectionString( - VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)), + MYSQL_VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)), DbOpenError); EXPECT_THROW(HostDataSourceFactory::create(connectionString( - VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)), + MYSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)), DbOpenError); EXPECT_THROW(HostDataSourceFactory::create(connectionString( - VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)), + MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)), DbOpenError); EXPECT_THROW(HostDataSourceFactory::create(connectionString( - VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)), + MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)), DbOpenError); // Check for missing parameters EXPECT_THROW(HostDataSourceFactory::create(connectionString( - VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)), + MYSQL_VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)), NoDatabaseName); // Tidy up after the test diff --git a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc index ec9865789e..8f1f42b3d6 100755 --- a/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/mysql_lease_mgr_unittest.cc @@ -129,21 +129,21 @@ TEST(MySqlOpenTest, OpenDatabase) { // Check that invalid login data causes an exception. EXPECT_THROW(LeaseMgrFactory::create(connectionString( - VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)), + MYSQL_VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)), DbOpenError); EXPECT_THROW(LeaseMgrFactory::create(connectionString( - VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)), + MYSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)), DbOpenError); EXPECT_THROW(LeaseMgrFactory::create(connectionString( - VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)), + MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)), DbOpenError); EXPECT_THROW(LeaseMgrFactory::create(connectionString( - VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)), + MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)), DbOpenError); // Check for missing parameters EXPECT_THROW(LeaseMgrFactory::create(connectionString( - VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)), + MYSQL_VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)), NoDatabaseName); // Tidy up after the test diff --git a/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc b/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc index 958552cdbc..58370daa67 100755 --- a/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/pgsql_lease_mgr_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2014-2016 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -11,9 +11,9 @@ #include #include #include +#include #include - #include #include @@ -22,6 +22,8 @@ #include #include +#include + using namespace isc; using namespace isc::asiolink; using namespace isc::dhcp; @@ -30,112 +32,6 @@ using namespace std; namespace { -// This holds statements to create and destroy the schema. -#include "schema_pgsql_copy.h" - -// Connection strings. -// Database: keatest -// Host: localhost -// Username: keatest -// Password: keatest -const char* VALID_TYPE = "type=postgresql"; -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() { - // Open database - PGconn* conn = 0; - conn = PQconnectdb("host = 'localhost' user = 'keatest'" - " password = 'keatest' dbname = 'keatest'"); - - // Get rid of everything in it. - for (int i = 0; destroy_statement[i] != NULL; ++i) { - PGresult* r = PQexec(conn, destroy_statement[i]); - PQclear(r); - } - - PQfinish(conn); -} - -// @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() { - // Open database - PGconn* conn = 0; - conn = PQconnectdb("host = 'localhost' user = 'keatest'" - " password = 'keatest' dbname = 'keatest'"); - - // Get rid of everything in it. - for (int i = 0; create_statement[i] != NULL; ++i) { - PGresult* r = PQexec(conn, create_statement[i]); - PQclear(r); - } - - PQfinish(conn); -} - /// @brief Test fixture class for testing PostgreSQL Lease Manager /// /// Opens the database prior to each test and closes it afterwards. @@ -149,12 +45,12 @@ public: PgSqlLeaseMgrTest() { // Ensure schema is the correct one. - destroySchema(); - createSchema(); + destroyPgSQLSchema(); + createPgSQLSchema(); // Connect to the database try { - LeaseMgrFactory::create(validConnectionString()); + LeaseMgrFactory::create(validPgSQLConnectionString()); } catch (...) { std::cerr << "*** ERROR: unable to open database. The test\n" "*** environment is broken and must be fixed before\n" @@ -173,7 +69,7 @@ public: virtual ~PgSqlLeaseMgrTest() { lmptr_->rollback(); LeaseMgrFactory::destroy(); - destroySchema(); + destroyPgSQLSchema(); } /// @brief Reopen the database @@ -185,7 +81,7 @@ public: /// the same database. void reopen(Universe) { LeaseMgrFactory::destroy(); - LeaseMgrFactory::create(validConnectionString()); + LeaseMgrFactory::create(validPgSQLConnectionString()); lmptr_ = &(LeaseMgrFactory::instance()); } @@ -201,13 +97,13 @@ public: TEST(PgSqlOpenTest, OpenDatabase) { // Schema needs to be created for the test to work. - destroySchema(); - createSchema(); + destroyPgSQLSchema(); + createPgSQLSchema(); // 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(validPgSQLConnectionString()); EXPECT_NO_THROW((void) LeaseMgrFactory::instance()); LeaseMgrFactory::destroy(); } catch (const isc::Exception& ex) { @@ -233,31 +129,31 @@ TEST(PgSqlOpenTest, OpenDatabase) { // Check that invalid login data causes an exception. EXPECT_THROW(LeaseMgrFactory::create(connectionString( - VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)), + PGSQL_VALID_TYPE, INVALID_NAME, VALID_HOST, VALID_USER, VALID_PASSWORD)), DbOpenError); EXPECT_THROW(LeaseMgrFactory::create(connectionString( - VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)), + PGSQL_VALID_TYPE, VALID_NAME, INVALID_HOST, VALID_USER, VALID_PASSWORD)), DbOpenError); EXPECT_THROW(LeaseMgrFactory::create(connectionString( - VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)), + PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, INVALID_USER, VALID_PASSWORD)), DbOpenError); // This test might fail if 'auth-method' in PostgresSQL host-based authentication // file (/var/lib/pgsql/9.4/data/pg_hba.conf) is set to 'trust', // which allows logging without password. 'Auth-method' should be changed to 'password'. EXPECT_THROW(LeaseMgrFactory::create(connectionString( - VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)), + PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, VALID_USER, INVALID_PASSWORD)), DbOpenError); // Check for missing parameters EXPECT_THROW(LeaseMgrFactory::create(connectionString( - VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)), + PGSQL_VALID_TYPE, NULL, VALID_HOST, INVALID_USER, VALID_PASSWORD)), NoDatabaseName); // Tidy up after the test - destroySchema(); + destroyPgSQLSchema(); } /// @brief Check the getType() method @@ -490,9 +386,4 @@ TEST_F(PgSqlLeaseMgrTest, getExpiredLeases6) { testGetExpiredLeases6(); } -/// @brief Check that expired reclaimed DHCPv6 leases are removed. -TEST_F(PgSqlLeaseMgrTest, deleteExpiredReclaimedLeases6) { - testDeleteExpiredReclaimedLeases6(); -} - }; diff --git a/src/lib/dhcpsrv/tests/schema_pgsql_copy.h b/src/lib/dhcpsrv/tests/schema_pgsql_copy.h deleted file mode 100644 index 481101a456..0000000000 --- a/src/lib/dhcpsrv/tests/schema_pgsql_copy.h +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright (C) 2014-2015 Internet Systems Consortium, Inc. ("ISC") -// -// This Source Code Form is subject to the terms of the Mozilla Public -// License, v. 2.0. If a copy of the MPL was not distributed with this -// file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef SCHEMA_COPY_H -#define SCHEMA_COPY_H - -namespace { - -// What follows is a set of statements that creates a copy of the schema -// in the test database. It is used by the PostgreSQL unit test prior to each -// test. -// -// Each SQL statement is a single string. The statements are not terminated -// by semicolons, and the strings must end with a comma. The final line -// statement must be NULL (not in quotes) - -// NOTE: This file mirrors the schema in src/lib/dhcpsrv/dhcpdb_create.pgsql. -// If this file is altered, please ensure that any change is compatible -// with the schema in dhcpdb_create.pgsql. - -// Deletion of existing tables. - -const char* destroy_statement[] = { - "DROP TABLE lease4", - "DROP TABLE lease6", - "DROP TABLE lease6_types", - "DROP TABLE schema_version", - NULL -}; - -// Creation of the new tables. - -const char* create_statement[] = { - "START TRANSACTION", - "CREATE TABLE lease4 (" - "address BIGINT PRIMARY KEY NOT NULL," - "hwaddr BYTEA," - "client_id BYTEA," - "valid_lifetime BIGINT," - "expire TIMESTAMP WITH TIME ZONE," - "subnet_id BIGINT," - "fqdn_fwd BOOLEAN," - "fqdn_rev BOOLEAN," - "hostname VARCHAR(255)" - ")", - - "CREATE TABLE lease6 (" - "address VARCHAR(39) PRIMARY KEY NOT NULL," - "duid BYTEA," - "valid_lifetime BIGINT," - "expire TIMESTAMP WITH TIME ZONE," - "subnet_id BIGINT," - "pref_lifetime BIGINT," - "lease_type SMALLINT," - "iaid BIGINT," - "prefix_len SMALLINT," - "fqdn_fwd BOOLEAN," - "fqdn_rev BOOLEAN," - "hostname VARCHAR(255)" - ")", - - "CREATE TABLE lease6_types (" - "lease_type SMALLINT PRIMARY KEY NOT NULL," - "name VARCHAR(5)" - ")", - - "INSERT INTO lease6_types VALUES (0, 'IA_NA')", - "INSERT INTO lease6_types VALUES (1, 'IA_TA')", - "INSERT INTO lease6_types VALUES (2, 'IA_PD')", - - "CREATE TABLE schema_version (" - "version INT PRIMARY KEY NOT NULL," - "minor INT" - ")", - - "INSERT INTO schema_version VALUES (1, 0)", - "COMMIT", - - // This line concludes creation of database version 1.0. - - // Schema upgrade to 2.0 starts here. - - "ALTER TABLE lease4 " - "ADD COLUMN state INT8 DEFAULT 0", - - "ALTER TABLE lease6 " - "ADD COLUMN state INT8 DEFAULT 0", - - "CREATE INDEX lease4_by_state_expire ON lease4 (state ASC, expire ASC)", - "CREATE INDEX lease6_by_state_expire ON lease6 (state ASC, expire ASC)", - - // Production schema includes the lease_state table which maps - // the lease states to their names. This is not used in the unit tests - // so it is commented out. - - /*"CREATE TABLE lease_state (", - "state INT8 PRIMARY KEY NOT NULL," - "name VARCHAR(64) NOT NULL);", - - "ALTER TABLE lease4 " - "ADD CONSTRAINT fk_lease4_state FOREIGN KEY (state) " - "REFERENCES lease_state (state)", - - "ALTER TABLE lease6 " - "ADD CONSTRAINT fk_lease6_state FOREIGN KEY (state) " - "REFERENCES lease_state (state)", - - "ALTER TABLE lease6 " - "ADD CONSTRAINT fk_lease6_type FOREIGN KEY (lease_type) " - "REFERENCES lease6_types (lease_type)", - - "INSERT INTO lease_state VALUES (0, \"default\");", - "INSERT INTO lease_state VALUES (1, \"declined\");", - "INSERT INTO lease_state VALUES (2, \"expired-reclaimed\");",*/ - - "UPDATE schema_version SET version = '2', minor = '0';", - "COMMIT", - - // Schema upgrade to 2.0 ends here. - - NULL -}; - -}; // Anonymous namespace - -#endif // SCHEMA_COPY_H diff --git a/src/lib/dhcpsrv/testutils/Makefile.am b/src/lib/dhcpsrv/testutils/Makefile.am index a01e9e4020..f1a3c96fa5 100644 --- a/src/lib/dhcpsrv/testutils/Makefile.am +++ b/src/lib/dhcpsrv/testutils/Makefile.am @@ -12,20 +12,40 @@ if HAVE_GTEST noinst_LTLIBRARIES = libdhcpsrvtest.la -libdhcpsrvtest_la_SOURCES = config_result_check.cc config_result_check.h +libdhcpsrvtest_la_SOURCES = config_result_check.cc config_result_check.h + +if HAVE_MYSQL +libdhcpsrvtest_la_SOURCES += schema.cc schema.h +else +if HAVE_PGSQL +libdhcpsrvtest_la_SOURCES += schema.cc schema.h +endif +endif + if HAVE_MYSQL libdhcpsrvtest_la_SOURCES += mysql_schema.cc mysql_schema.h endif +if HAVE_PGSQL +libdhcpsrvtest_la_SOURCES += pgsql_schema.cc pgsql_schema.h +endif libdhcpsrvtest_la_CXXFLAGS = $(AM_CXXFLAGS) libdhcpsrvtest_la_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) if HAVE_MYSQL libdhcpsrvtest_la_CPPFLAGS += $(MYSQL_CPPFLAGS) endif +if HAVE_PGSQL +libdhcpsrvtest_la_CPPFLAGS += $(PGSQL_CPPFLAGS) +endif + libdhcpsrvtest_la_LDFLAGS = $(AM_LDFLAGS) if HAVE_MYSQL libdhcpsrvtest_la_LDFLAGS += $(MYSQL_LIBS) endif +if HAVE_PGSQL +libdhcpsrvtest_la_LDFLAGS += $(PGSQL_LIBS) +endif + libdhcpsrvtest_la_LIBADD = $(top_builddir)/src/lib/cc/libkea-cc.la libdhcpsrvtest_la_LIBADD += $(top_builddir)/src/lib/log/libkea-log.la diff --git a/src/lib/dhcpsrv/testutils/mysql_schema.cc b/src/lib/dhcpsrv/testutils/mysql_schema.cc index fda566617b..7bf2928056 100644 --- a/src/lib/dhcpsrv/testutils/mysql_schema.cc +++ b/src/lib/dhcpsrv/testutils/mysql_schema.cc @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -20,75 +21,17 @@ 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); -} +const char* MYSQL_VALID_TYPE = "type=mysql"; -// Return valid connection string string validMySQLConnectionString() { - return (connectionString(VALID_TYPE, VALID_NAME, VALID_HOST, + return (connectionString(MYSQL_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; - // @todo - replace this with list gleaned from create script + // @todo - replace this with call to drop script once it exists const char* destroy_statement[] = { // Turning off referential integrity checks ensures tables get dropped "SET SESSION FOREIGN_KEY_CHECKS = 0", @@ -121,27 +64,30 @@ void destroyMySQLSchema() { } } -// @brief Create the Schema -// -// Creates all the tables in what is assumed to be an empty database. If the -// script fails, the invoking test will fail. The output of stderr is -// suppressed unless the parameter, show_err is true. The is done to -// suppress the mysql warning about passing the password in on the command -// line, which otherwise mkes test output rather noisy. -// -// @param show_err flag which governs whether or not stderr is suppressed. void createMySQLSchema(bool show_err) { + runMySQLScript(TEST_ADMIN_SCRIPTS_DIR, "mysql/dhcpdb_create.mysql", + show_err); +} + +void runMySQLScript(const std::string& path, const std::string& script_name, + bool show_err) { std::ostringstream cmd; cmd << "mysql -N -B --user=keatest --password=keatest keatest"; if (!show_err) { cmd << " 2>/dev/null "; } - cmd << " < " << TEST_ADMIN_SCRIPTS_DIR << "/mysql/dhcpdb_create.mysql"; + + if (!path.empty()) { + cmd << " < " << path << "/"; + } + + cmd << script_name; int retval = std::system(cmd.str().c_str()); - ASSERT_EQ(0, retval) << "createMySQLSchema failed"; + ASSERT_EQ(0, retval) << "runMySQLSchema failed:" << cmd.str(); } + }; }; }; diff --git a/src/lib/dhcpsrv/testutils/mysql_schema.h b/src/lib/dhcpsrv/testutils/mysql_schema.h index c1352a7830..e493fdd637 100644 --- a/src/lib/dhcpsrv/testutils/mysql_schema.h +++ b/src/lib/dhcpsrv/testutils/mysql_schema.h @@ -1,4 +1,4 @@ -// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") +// Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC") // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this @@ -8,30 +8,19 @@ #define TEST_MYSQL_SCHEMA_H #include +#include #include 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. +extern const char* MYSQL_VALID_TYPE; + +/// Return valid connection string /// -/// There is no error checking in this code: if it fails, one of the tests -/// will fall over. -void createMySQLSchema(bool show_err=false); +/// @return valid MySQL connection string. +std::string validMySQLConnectionString(); /// @brief Clear everything from the database /// @@ -39,21 +28,32 @@ void createMySQLSchema(bool show_err=false); /// tests will (should) fall over. void destroyMySQLSchema(); -/// Return valid connection string -/// -/// @return valid MySQL connection string. -std::string validMySQLConnectionString(); +// @brief Run a MySQL SQL script against the Postgresql unit test database +// +// Submits the given SQL script to MySQL via mysql CLI. The output of +// stderr is suppressed unless the parameter, show_err is true. The is done +// to suppress warnings that might otherwise make test output needlessly +// noisy. A gtest assertion occurs if the script fails to execute. +// +// @param path - path (if not blank) of the script to execute +// @param script_name - file name of the path to execute +// @param show_err flag which governs whether or not stderr is suppressed. +void runMySQLScript(const std::string& path, const std::string& script_name, + bool show_err); + +// @brief Create the MySQL Schema +// +// Submits the current schema creation script: +// +// /mysql/dhcpdb_create.mysql +// +// to the unit test MySQL database. If the script fails, the invoking test +// will fail. The output of stderr is suppressed unless the parameter, +// show_err is true. +// +// @param show_err flag which governs whether or not stderr is suppressed. +void createMySQLSchema(bool show_err = false); -/// @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); }; }; }; diff --git a/src/lib/dhcpsrv/testutils/pgsql_schema.cc b/src/lib/dhcpsrv/testutils/pgsql_schema.cc new file mode 100644 index 0000000000..b275d944ef --- /dev/null +++ b/src/lib/dhcpsrv/testutils/pgsql_schema.cc @@ -0,0 +1,89 @@ +// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +using namespace std; + +namespace isc { +namespace dhcp { +namespace test { + +const char* PGSQL_VALID_TYPE = "type=postgresql"; + +string +validPgSQLConnectionString() { + return (connectionString(PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST, + VALID_USER, VALID_PASSWORD)); +} + +void destroyPgSQLSchema() { + // @todo - replace this call to run drop script once the script exists + const char* destroy_statement[] = { + "DROP TABLE lease4 CASCADE", + "DROP TABLE LEASE6 CASCADE", + "DROP TABLE lease6_types CASCADE", + "DROP TABLE schema_version CASCADE", + "DROP TABLE lease_state CASCADE", + "DROP FUNCTION lease4DumpHeader()", + "DROP FUNCTION lease4DumpData()", + "DROP FUNCTION lease6DumpHeader()", + "DROP FUNCTION lease6DumpData()", + NULL + }; + + // Open database + PGconn* conn = 0; + conn = PQconnectdb("host = 'localhost' user = 'keatest'" + " password = 'keatest' dbname = 'keatest'"); + + // Get rid of everything in it. + for (int i = 0; destroy_statement[i] != NULL; ++i) { + PGresult* r = PQexec(conn, destroy_statement[i]); + PQclear(r); + } + + PQfinish(conn); +} + +void createPgSQLSchema(bool show_err) { + runPgSQLScript(TEST_ADMIN_SCRIPTS_DIR, "pgsql/dhcpdb_create.pgsql", + show_err); +} + +void runPgSQLScript(const std::string& path, const std::string& script_name, + bool show_err) { + std::ostringstream cmd; + + cmd << "export PGPASSWORD=keatest; cat "; + if (!path.empty()) { + cmd << " < " << path << "/"; + } + + cmd << script_name + << " | psql --set ON_ERROR_STOP=1 -A -t -q -U keatest -d keatest"; + + if (!show_err) { + cmd << " 2>/dev/null "; + } + + int retval = std::system(cmd.str().c_str()); + ASSERT_EQ(0, retval) << "runPgSQLSchema failed:" << cmd.str(); +} + +}; +}; +}; diff --git a/src/lib/dhcpsrv/testutils/pgsql_schema.h b/src/lib/dhcpsrv/testutils/pgsql_schema.h new file mode 100644 index 0000000000..a679da163d --- /dev/null +++ b/src/lib/dhcpsrv/testutils/pgsql_schema.h @@ -0,0 +1,61 @@ +// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef TEST_PGSQL_SCHEMA_H +#define TEST_PGSQL_SCHEMA_H + +#include +#include +#include + +namespace isc { +namespace dhcp { +namespace test { + +extern const char* PGSQL_VALID_TYPE; + +/// Return valid connection string +/// +/// @return valid PgSQL connection string. +std::string validPgSQLConnectionString(); + +/// @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 destroyPgSQLSchema(); + +// @brief Create the Postgresql Schema +// +// Submits the current schema creation script: +// +// /pgsql/dhcpdb_create.pgsql +// +// to the unit test Postgresql database. If the script fails, the invoking +// test will fail. The output of stderr is suppressed unless the parameter, +// show_err is true. +// +// @param show_err flag which governs whether or not stderr is suppressed. +void createPgSQLSchema(bool show_err = false); + +// @brief Run a PgSQL SQL script against the Postgresql unit test database +// +// Submits the given SQL script to Postgresql via psql CLI. The output of +// stderr is suppressed unless the parameter, show_err is true. The is done +// to suppress warnings that might otherwise make test output needlessly +// noisy. A gtest assertion occurs if the script fails to execute. +// +// @param path - path (if not blank) of the script to execute +// @param script_name - file name of the path to execute +// @param show_err flag which governs whether or not stderr is suppressed. +void runPgSQLScript(const std::string& path, const std::string& script_name, + bool show_err); + +}; +}; +}; + +#endif diff --git a/src/lib/dhcpsrv/testutils/schema.cc b/src/lib/dhcpsrv/testutils/schema.cc new file mode 100644 index 0000000000..9dc5bab5c4 --- /dev/null +++ b/src/lib/dhcpsrv/testutils/schema.cc @@ -0,0 +1,73 @@ +// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include +#include + +using namespace std; + +namespace isc { +namespace dhcp { +namespace test { + +// Connection strings. +// Database: keatest +// Host: localhost +// Username: keatest +// Password: keatest + +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); +} + +}; +}; +}; diff --git a/src/lib/dhcpsrv/testutils/schema.h b/src/lib/dhcpsrv/testutils/schema.h new file mode 100644 index 0000000000..b6aa96410f --- /dev/null +++ b/src/lib/dhcpsrv/testutils/schema.h @@ -0,0 +1,41 @@ +// Copyright (C) 2016 Internet Systems Consortium, Inc. ("ISC") +// +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#ifndef SCHEMA_H +#define SCHEMA_H + +#include +#include + +namespace isc { +namespace dhcp { +namespace test { + +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 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