// {"read-timeout", "--net-read-timeout"}, // available in docs, but client says unknown variable?
// {"write-timeout", "--net-write-timeout"}, // available in docs, but client says unknown variable?
};
- bool extra_flag_added(false);
if (conversions.count(keyword)) {
- if (!extra_flag_added) {
- result.push_back("--extra");
- extra_flag_added = true;
- }
- result.push_back("--" + conversions.at(keyword));
- result.push_back(value);
+ result.push_back("--extra");
+ result.push_back("--" + conversions.at(keyword) + " " + value);
}
}
return result;
/// @brief Destructor
virtual ~MySqlConnection();
+ /// @brief Convert MySQL library parameters to kea-admin parameters.
+ ///
+ /// @param params input MySQL parameters
+ ///
+ /// @return vector of kea-admin parameters
static std::vector<std::string>
toKeaAdminParameters(ParameterMap const& params);
SUBDIRS = .
-AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS =
+AM_CPPFLAGS += -DABS_TOP_BUILDDIR="\"$(abs_top_builddir)\""
+AM_CPPFLAGS += -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES) $(MYSQL_CPPFLAGS)
AM_CXXFLAGS = $(KEA_CXXFLAGS)
using namespace isc::db;
using namespace isc::db::test;
+using namespace std;
+
namespace {
/// @brief RAII wrapper over MYSQL_RES obtained from MySQL library functions like
// Make sure that null values were returned for columns for which null
// was set.
ASSERT_EQ(in_bindings.size(), out_bindings.size());
- for (auto i = 0; i < in_bindings.size(); ++i) {
+ for (size_t i = 0; i < in_bindings.size(); ++i) {
EXPECT_EQ(in_bindings[i]->amNull(), out_bindings[i]->amNull())
<< "null value test failed for binding #" << i;
}
EXPECT_THROW(conn.openDatabase(), DbOpenError);
}
+/// @brief Check ensureSchemaVersion when schema is not created.
+TEST_F(MySqlConnectionTest, ensureSchemaVersionNoSchema) {
+ std::pair<uint32_t, uint32_t> version;
+ auto const parameters(DatabaseConnection::parse(validMySQLConnectionString()));
+
+ // Make sure schema is not created.
+ destroyMySQLSchema(/* show_err = */ false, /* force = */ true);
+ dropTestTable();
+ EXPECT_THROW_MSG(version = MySqlConnection::getVersion(parameters), DbOperationError,
+ "unable to prepare MySQL statement <SELECT version, minor FROM "
+ "schema_version>, reason: Table 'keatest.schema_version' doesn't exist");
+
+ EXPECT_NO_THROW_LOG(MySqlConnection::ensureSchemaVersion(parameters));
+
+ EXPECT_NO_THROW_LOG(version = MySqlConnection::getVersion(parameters));
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MINOR, version.second);
+}
+
+/// @brief Check ensureSchemaVersion when schema is created.
+TEST_F(MySqlConnectionTest, ensureSchemaVersion) {
+ std::pair<uint32_t, uint32_t> version;
+ auto const parameters(DatabaseConnection::parse(validMySQLConnectionString()));
+
+ // Make sure schema is created.
+ EXPECT_NO_THROW_LOG(version = MySqlConnection::getVersion(parameters));
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MINOR, version.second);
+
+ EXPECT_NO_THROW_LOG(MySqlConnection::ensureSchemaVersion(parameters));
+
+ EXPECT_NO_THROW_LOG(version = MySqlConnection::getVersion(parameters));
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MINOR, version.second);
+}
+
+/// @brief Check ensureSchemaVersion when schema is not created.
+TEST_F(MySqlConnectionTest, initializeSchemaNoSchema) {
+ pair<uint32_t, uint32_t> version;
+ auto const parameters(DatabaseConnection::parse(validMySQLConnectionString()));
+
+ // Make sure schema is not created.
+ destroyMySQLSchema(/* show_err = */ false, /* force = */ true);
+ dropTestTable();
+ EXPECT_THROW_MSG(version = MySqlConnection::getVersion(parameters), DbOperationError,
+ "unable to prepare MySQL statement <SELECT version, minor FROM "
+ "schema_version>, reason: Table 'keatest.schema_version' doesn't exist");
+
+ EXPECT_NO_THROW_LOG(MySqlConnection::initializeSchema(parameters));
+
+ EXPECT_NO_THROW_LOG(version = MySqlConnection::getVersion(parameters));
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MINOR, version.second);
+}
+
+/// @brief Check ensureSchemaVersion when schema is created.
+TEST_F(MySqlConnectionTest, initializeSchema) {
+ pair<uint32_t, uint32_t> version;
+ auto const parameters(DatabaseConnection::parse(validMySQLConnectionString()));
+
+ // Make sure schema is created.
+ EXPECT_NO_THROW_LOG(version = MySqlConnection::getVersion(parameters));
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MINOR, version.second);
+
+ EXPECT_THROW_MSG(MySqlConnection::initializeSchema(parameters), SchemaInitializationFailed,
+ "Expected exit code 0 for kea-admin. Got 1");
+
+ EXPECT_NO_THROW_LOG(version = MySqlConnection::getVersion(parameters));
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(MYSQL_SCHEMA_VERSION_MINOR, version.second);
+}
+
+/// @brief Check ensureSchemaVersion when schema is created.
+TEST_F(MySqlConnectionTest, toKeaAdminParameters) {
+ auto parameters(DatabaseConnection::parse(validMySQLConnectionString()));
+ vector<string> kea_admin_parameters(MySqlConnection::toKeaAdminParameters(parameters));
+ EXPECT_EQ(kea_admin_parameters,
+ vector<string>({"mysql", "--host", "localhost", "--name", "keatest", "--password",
+ "keatest", "--user", "keatest"}));
+
+ string const full_mysql_connection_string(
+ connectionString(MYSQL_VALID_TYPE, VALID_NAME, VALID_HOST_TCP, VALID_SECURE_USER,
+ VALID_PASSWORD, VALID_TIMEOUT, VALID_READONLY_DB, VALID_CERT, VALID_KEY,
+ VALID_CA, VALID_CIPHER));
+ parameters = DatabaseConnection::parse(full_mysql_connection_string);
+ kea_admin_parameters = MySqlConnection::toKeaAdminParameters(parameters);
+ EXPECT_EQ(kea_admin_parameters,
+ vector<string>(
+ {"mysql", "--extra",
+ "--ssl-cert " ABS_TOP_BUILDDIR "/src/lib/database/testutils/../../asiolink/"
+ "testutils/ca/kea-client.crt",
+ "--extra", "--ssl-cipher AES", "--extra", "--connect_timeout 10", "--host",
+ "127.0.0.1", "--extra",
+ "--ssl-key " ABS_TOP_BUILDDIR "/src/lib/database/testutils/../../asiolink/"
+ "testutils/ca/kea-client.key",
+ "--name", "keatest", "--password", "keatest", "--extra",
+ "--ssl-ca " ABS_TOP_BUILDDIR "/src/lib/database/testutils/../../asiolink/"
+ "testutils/ca/kea-ca.crt",
+ "--user", "keatest_secure"}));
+}
+
} // namespace
/// @brief Destructor
virtual ~PgSqlConnection();
+ /// @brief Convert MySQL library parameters to kea-admin parameters.
+ ///
+ /// @param params input MySQL parameters
+ ///
+ /// @return tuple of (vector of kea-admin parameters, vector of PostgreSQL
+ /// environment variables)
static std::tuple<std::vector<std::string>, std::vector<std::string>>
toKeaAdminParameters(ParameterMap const& params);
SUBDIRS = .
-AM_CPPFLAGS = -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
+AM_CPPFLAGS =
+AM_CPPFLAGS += -DABS_TOP_BUILDDIR="\"$(abs_top_builddir)\""
+AM_CPPFLAGS += -I$(top_builddir)/src/lib -I$(top_srcdir)/src/lib
AM_CPPFLAGS += $(BOOST_INCLUDES) $(PGSQL_CPPFLAGS)
AM_CXXFLAGS = $(KEA_CXXFLAGS)
using namespace isc::db::test;
using namespace isc::util;
+using namespace std;
+
namespace {
// A small extension of PgSqlBasicsTest that instantiates the actual Kea schema.
// Run the select. The row consumption lambda should populate
// fetched_rows based on the the result set returned by the select.
conn_->selectQuery(tagged_statements[GET_BY_INT_RANGE], in_bindings,
- [&](PgSqlResult& r, int row) {
+ [&](PgSqlResult& r, size_t row) {
TestRow fetched_row;
if (row >= expected_rows.size()) {
// We have too many rows.
EXPECT_THROW(conn.getConnParameters(), DbInvalidTimeout);
}
+/// @brief Check ensureSchemaVersion when schema is not created.
+TEST_F(PgSqlConnectionTest, ensureSchemaVersionNoSchema) {
+ std::pair<uint32_t, uint32_t> version;
+ auto const parameters(DatabaseConnection::parse(validPgSQLConnectionString()));
+
+ // Make sure schema is not created.
+ destroyPgSQLSchema(/* show_err = */ false, /* force = */ true);
+ destroySchema();
+ EXPECT_THROW_MSG(version = PgSqlConnection::getVersion(parameters), DbOperationError,
+ "unable to execute PostgreSQL statement <SELECT version, minor FROM "
+ "schema_version;, reason: ERROR: relation \"schema_version\" does not "
+ "exist\nLINE 1: SELECT version, minor FROM schema_version;\n "
+ " ^\n");
+
+ EXPECT_NO_THROW_LOG(PgSqlConnection::ensureSchemaVersion(parameters));
+
+ EXPECT_NO_THROW_LOG(version = PgSqlConnection::getVersion(parameters));
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MINOR, version.second);
+}
+
+/// @brief Check ensureSchemaVersion when schema is created.
+TEST_F(PgSqlConnectionTest, ensureSchemaVersion) {
+ std::pair<uint32_t, uint32_t> version;
+ auto const parameters(DatabaseConnection::parse(validPgSQLConnectionString()));
+
+ // Make sure schema is created.
+ EXPECT_NO_THROW_LOG(version = PgSqlConnection::getVersion(parameters));
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MINOR, version.second);
+
+ EXPECT_NO_THROW_LOG(PgSqlConnection::ensureSchemaVersion(parameters));
+
+ EXPECT_NO_THROW_LOG(version = PgSqlConnection::getVersion(parameters));
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MINOR, version.second);
+}
+
+/// @brief Check ensureSchemaVersion when schema is not created.
+TEST_F(PgSqlConnectionTest, initializeSchemaNoSchema) {
+ pair<uint32_t, uint32_t> version;
+ auto const parameters(DatabaseConnection::parse(validPgSQLConnectionString()));
+
+ // Make sure schema is not created.
+ destroyPgSQLSchema(/* show_err = */ false, /* force = */ true);
+ destroySchema();
+ EXPECT_THROW_MSG(version = PgSqlConnection::getVersion(parameters), DbOperationError,
+ "unable to execute PostgreSQL statement <SELECT version, minor FROM "
+ "schema_version;, reason: ERROR: relation \"schema_version\" does not "
+ "exist\nLINE 1: SELECT version, minor FROM schema_version;\n "
+ " ^\n");
+
+ EXPECT_NO_THROW_LOG(PgSqlConnection::initializeSchema(parameters));
+
+ EXPECT_NO_THROW_LOG(version = PgSqlConnection::getVersion(parameters));
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MINOR, version.second);
+}
+
+/// @brief Check ensureSchemaVersion when schema is created.
+TEST_F(PgSqlConnectionTest, initializeSchema) {
+ pair<uint32_t, uint32_t> version;
+ auto const parameters(DatabaseConnection::parse(validPgSQLConnectionString()));
+
+ // Make sure schema is created.
+ EXPECT_NO_THROW_LOG(version = PgSqlConnection::getVersion(parameters));
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MINOR, version.second);
+
+ EXPECT_THROW_MSG(PgSqlConnection::initializeSchema(parameters), SchemaInitializationFailed,
+ "Expected exit code 0 for kea-admin. Got 2");
+
+ EXPECT_NO_THROW_LOG(version = PgSqlConnection::getVersion(parameters));
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MAJOR, version.first);
+ EXPECT_EQ(PGSQL_SCHEMA_VERSION_MINOR, version.second);
+}
+
+/// @brief Check ensureSchemaVersion when schema is created.
+TEST_F(PgSqlConnectionTest, toKeaAdminParameters) {
+ auto parameters(DatabaseConnection::parse(validPgSQLConnectionString()));
+ auto tupl(PgSqlConnection::toKeaAdminParameters(parameters));
+ vector<string> kea_admin_parameters(get<0>(tupl));
+ vector<string> kea_admin_env_vars(get<1>(tupl));
+ EXPECT_EQ(kea_admin_parameters,
+ vector<string>({"pgsql", "--host", "localhost", "--name", "keatest", "--password",
+ "keatest", "--user", "keatest"}));
+ EXPECT_EQ(kea_admin_env_vars, vector<string>({}));
+
+ string const full_pgsql_connection_string(
+ connectionString(PGSQL_VALID_TYPE, VALID_NAME, VALID_HOST_TCP, VALID_SECURE_USER,
+ VALID_PASSWORD, VALID_TIMEOUT, VALID_READONLY_DB, VALID_CERT, VALID_KEY,
+ VALID_CA, VALID_CIPHER));
+ parameters = DatabaseConnection::parse(full_pgsql_connection_string);
+ tupl = PgSqlConnection::toKeaAdminParameters(parameters);
+ kea_admin_parameters = get<0>(tupl);
+ kea_admin_env_vars = get<1>(tupl);
+ EXPECT_EQ(kea_admin_parameters,
+ vector<string>({"pgsql", "--host", "127.0.0.1", "--name", "keatest", "--password",
+ "keatest", "--user", "keatest_secure"}));
+ EXPECT_EQ(kea_admin_env_vars, vector<string>({ "PGCONNECT_TIMEOUT=10" }));
+}
-}; // namespace
+} // namespace