]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#2346] PgSql CB V6 globals,option defs, and options
authorThomas Markwalder <tmark@isc.org>
Wed, 9 Mar 2022 16:07:05 +0000 (11:07 -0500)
committerThomas Markwalder <tmark@isc.org>
Wed, 9 Mar 2022 16:07:05 +0000 (11:07 -0500)
src/hooks/dhcp/pgsql_cb/pgsql_cb_dhcp6.cc
    PgSqlConfigBackendDHCPv6Impl::
        getGlobalParameter6()
        createUpdateGlobalParameter6()
        deleteTransactional()
        insertOption6()
        createUpdateOption6()
        createUpdateOptionDef6()
        deleteOptionDef6()
        deleteOption6() - implemented

src/hooks/dhcp/pgsql_cb/pgsql_cb_impl.cc
    PgSqlConfigBackendImpl::createUpdateOptionDef()
    - added universe parameter

src/hooks/dhcp/pgsql_cb/tests/pgsql_cb_dhcp4_mgr_unittest.cc
src/hooks/dhcp/pgsql_cb/tests/pgsql_cb_dhcp6_mgr_unittest.cc
    - new files

src/hooks/dhcp/pgsql_cb/tests/Makefile.am
    Added pgsql_cb_dhcp4_mgr_unittest.cc, pgsql_cb_dhcp6_mgr_unittest.cc,

src/hooks/dhcp/pgsql_cb/tests/pgsql_cb_dhcp6_unittest.cc
    New tests:
    TEST_F(PgSqlConfigBackendDHCPv6Test, createUpdateDeleteGlobalParameter6Test)
    TEST_F(PgSqlConfigBackendDHCPv6Test, globalParameters6WithServerTagsTest)
    TEST_F(PgSqlConfigBackendDHCPv6Test, getAllGlobalParameters6Test)
    TEST_F(PgSqlConfigBackendDHCPv6Test, getModifiedGlobalParameters6Test)
    TEST_F(PgSqlConfigBackendDHCPv6Test, nullKeyErrorTest)
    TEST_F(PgSqlConfigBackendDHCPv6Test, getOptionDef6Test)
    TEST_F(PgSqlConfigBackendDHCPv6Test, optionDefs6WithServerTagsTest)
    TEST_F(PgSqlConfigBackendDHCPv6Test, getAllOptionDefs6Test)
    TEST_F(PgSqlConfigBackendDHCPv6Test, getModifiedOptionDefs6Test)
    TEST_F(PgSqlConfigBackendDHCPv6Test, createUpdateDeleteOption6Test)
    TEST_F(PgSqlConfigBackendDHCPv6Test, globalOptions6WithServerTagsTest)
    TEST_F(PgSqlConfigBackendDHCPv6Test, getAllOptions6Test)
    TEST_F(PgSqlConfigBackendDHCPv6Test, getModifiedOptions6Test)

src/hooks/dhcp/pgsql_cb/pgsql_cb_dhcp6.cc
src/hooks/dhcp/pgsql_cb/pgsql_cb_impl.cc
src/hooks/dhcp/pgsql_cb/tests/Makefile.am
src/hooks/dhcp/pgsql_cb/tests/pgsql_cb_dhcp4_mgr_unittest.cc [new file with mode: 0644]
src/hooks/dhcp/pgsql_cb/tests/pgsql_cb_dhcp6_mgr_unittest.cc [new file with mode: 0644]
src/hooks/dhcp/pgsql_cb/tests/pgsql_cb_dhcp6_unittest.cc

index dfe796278725ef3f90e60d0bd428d91b9ad8cb56..3860ac49958326b2cecc48e0a4a594649c5079ee 100644 (file)
@@ -199,9 +199,20 @@ public:
     ///
     /// @return Pointer to the retrieved value or null if such parameter
     /// doesn't exist.
-    StampedValuePtr getGlobalParameter6(const ServerSelector& /* server_selector */,
-                                        const std::string& /* name */) {
-        isc_throw(NotImplemented, NOT_IMPL_STR);
+    StampedValuePtr getGlobalParameter6(const ServerSelector& server_selector,
+                                        const std::string& name) {
+       StampedValueCollection parameters;
+
+        auto const& tags = server_selector.getTags();
+        for (auto const& tag : tags) {
+            PsqlBindArray in_bindings;
+            in_bindings.addTempString(tag.get());
+            in_bindings.add(name);
+
+            getGlobalParameters(GET_GLOBAL_PARAMETER6, in_bindings, parameters);
+        }
+
+        return (parameters.empty() ? StampedValuePtr() : *parameters.begin());
     }
 
     /// @brief Sends query to insert or update global parameter.
@@ -209,9 +220,56 @@ public:
     /// @param server_selector Server selector.
     /// @param name Name of the global parameter.
     /// @param value Value of the global parameter.
-    void createUpdateGlobalParameter6(const db::ServerSelector& /* server_selector */,
-                                      const StampedValuePtr& /* value */) {
-        isc_throw(NotImplemented, NOT_IMPL_STR);
+    void createUpdateGlobalParameter6(const db::ServerSelector& server_selector,
+                                      const StampedValuePtr& value) {
+        if (server_selector.amUnassigned()) {
+            isc_throw(NotImplemented, "managing configuration for no particular server"
+                      " (unassigned) is unsupported at the moment");
+        }
+
+        auto tag = getServerTag(server_selector, "creating or updating global parameter");
+
+        PsqlBindArray in_bindings;
+        in_bindings.addTempString(value->getName());
+        in_bindings.addTempString(value->getValue());
+        in_bindings.add(value->getType()),
+        in_bindings.addTimestamp(value->getModificationTime()),
+        in_bindings.addTempString(tag);
+        in_bindings.addTempString(value->getName());
+
+        PgSqlTransaction transaction(conn_);
+
+        // Create scoped audit revision. As long as this instance exists
+        // no new audit revisions are created in any subsequent calls.
+        ScopedAuditRevision audit_revision(this,
+                                           PgSqlConfigBackendDHCPv6Impl::CREATE_AUDIT_REVISION,
+                                           server_selector, "global parameter set",
+                                           false);
+
+        // Try to update the existing row.
+        if (updateDeleteQuery(PgSqlConfigBackendDHCPv6Impl::UPDATE_GLOBAL_PARAMETER6,
+                              in_bindings) == 0) {
+
+            // No such parameter found, so let's insert it. We have to adjust the
+            // bindings collection to match the prepared statement for insert.
+            in_bindings.popBack();
+            in_bindings.popBack();
+
+            insertQuery(PgSqlConfigBackendDHCPv6Impl::INSERT_GLOBAL_PARAMETER6,
+                        in_bindings);
+
+            // Successfully inserted global parameter. Now, we have to associate it
+            // with the server tag.
+            PsqlBindArray attach_bindings;
+            uint64_t pid = getLastInsertId("dhcp6_global_parameter", "id");
+            attach_bindings.add(pid);   // id of newly inserted global.
+            attach_bindings.addTimestamp(value->getModificationTime());
+            attachElementToServers(PgSqlConfigBackendDHCPv6Impl::INSERT_GLOBAL_PARAMETER6_SERVER,
+                                   server_selector, attach_bindings);
+        }
+
+        transaction.commit();
+
     }
 
     /// @brief Sends query to the database to retrieve multiple subnets.
@@ -412,13 +470,28 @@ public:
     ///
     /// @return Number of deleted entries.
     template<typename... Args>
-    uint64_t deleteTransactional(const int /* index */,
-                                 const db::ServerSelector& /* server_selector */,
-                                 const std::string& /* operation */,
-                                 const std::string& /* log_message */,
-                                 const bool /* cascade_delete */,
-                                 Args&&... /* keys */) {
-        isc_throw(NotImplemented, NOT_IMPL_STR);
+    uint64_t deleteTransactional(const int index,
+                                 const db::ServerSelector& server_selector,
+                                 const std::string& operation,
+                                 const std::string& log_message,
+                                 const bool cascade_delete,
+                                 Args&&... keys) {
+
+        PgSqlTransaction transaction(conn_);
+
+        // Create scoped audit revision. As long as this instance exists
+        // no new audit revisions are created in any subsequent calls.
+        ScopedAuditRevision
+            audit_revision(this,
+                           PgSqlConfigBackendDHCPv6Impl::CREATE_AUDIT_REVISION,
+                           server_selector, log_message, cascade_delete);
+
+        auto count = deleteFromTable(index, server_selector, operation, keys...);
+
+        transaction.commit();
+
+        return (count);
+
     }
 
     /// @brief Sends query to delete subnet by id.
@@ -533,18 +606,89 @@ public:
     ///
     /// @param server_selector Server selector.
     /// @param in_bindings Collection of bindings representing an option.
-    void insertOption6(const ServerSelector& /* server_selector */,
-                       const PsqlBindArray& /* in_bindings */) {
-        isc_throw(NotImplemented, NOT_IMPL_STR);
+    /// @param modification_ts option's modification timestamp
+    void insertOption6(const ServerSelector& server_selector,
+                       const PsqlBindArray& in_bindings,
+                       const boost::posix_time::ptime& modification_ts) {
+        // Attempt the insert.
+        insertQuery(PgSqlConfigBackendDHCPv6Impl::INSERT_OPTION6, in_bindings);
+
+        // Fetch primary key value of the inserted option. We will use it in the
+        // next INSERT statement to associate this option with the server.
+        auto option_id = getLastInsertId("dhcp6_options", "option_id");
+
+        PsqlBindArray attach_bindings;
+        attach_bindings.add(option_id);   // id of newly inserted global.
+        attach_bindings.addTimestamp(modification_ts);
+
+        // Associate the option with the servers.
+        attachElementToServers(PgSqlConfigBackendDHCPv6Impl::INSERT_OPTION6_SERVER,
+                               server_selector, attach_bindings);
     }
 
     /// @brief Sends query to insert or update global DHCP option.
     ///
     /// @param server_selector Server selector.
     /// @param option Pointer to the option descriptor encapsulating the option.
-    void createUpdateOption6(const ServerSelector& /* server_selector */,
-                             const OptionDescriptorPtr& /* option */) {
-        isc_throw(NotImplemented, NOT_IMPL_STR);
+    void createUpdateOption6(const ServerSelector& server_selector,
+                             const OptionDescriptorPtr& option) {
+
+        if (server_selector.amUnassigned()) {
+            isc_throw(NotImplemented, "managing configuration for no particular server"
+                      " (unassigned) is unsupported at the moment");
+        }
+
+        auto tag = getServerTag(server_selector, "creating or updating global option");
+
+        // Create the input parameter bindings.
+        PsqlBindArray in_bindings;
+        in_bindings.add(option->option_->getType());
+        addOptionValueBinding(in_bindings, option);
+        in_bindings.addOptional(option->formatted_value_);
+        in_bindings.addOptional(option->space_name_);
+        in_bindings.add(option->persistent_);
+        in_bindings.addNull();
+        in_bindings.addNull();
+        in_bindings.add(0);
+        in_bindings.add(option->getContext());
+        in_bindings.addNull();
+        in_bindings.addNull();
+        in_bindings.addTimestamp(option->getModificationTime());
+        in_bindings.addNull();
+
+        // Remember the size before we added where clause arguments.
+        size_t pre_where_size = in_bindings.size();
+
+        // Now the add the update where clause parameters
+        in_bindings.add(tag);
+        in_bindings.add(option->option_->getType());
+        in_bindings.addOptional(option->space_name_);
+
+        // Start transaction.
+        PgSqlTransaction transaction(conn_);
+
+        // Create scoped audit revision. As long as this instance exists
+        // no new audit revisions are created in any subsequent calls.
+        ScopedAuditRevision
+            audit_revision(this,
+                           PgSqlConfigBackendDHCPv6Impl::CREATE_AUDIT_REVISION,
+                           server_selector, "global option set", false);
+
+        // Try to update the option.
+        if (updateDeleteQuery(PgSqlConfigBackendDHCPv6Impl::UPDATE_OPTION6,
+                              in_bindings) == 0) {
+            // The option doesn't exist, so we'll try to insert it.
+            // Remove the update where clause bindings.
+            while (in_bindings.size() > pre_where_size) {
+                in_bindings.popBack();
+            }
+
+            // Try to insert the option.
+            insertOption6(server_selector, in_bindings, option->getModificationTime());
+        }
+
+        // Commit the work.
+        transaction.commit();
     }
 
     /// @brief Sends query to insert or update DHCP option in a subnet.
@@ -637,9 +781,15 @@ public:
     ///
     /// @param server_selector Server selector.
     /// @param option_def Pointer to the option definition to be inserted or updated.
-    void createUpdateOptionDef6(const ServerSelector& /* server_selector */,
-                                const OptionDefinitionPtr& /* option_def */) {
-        isc_throw(NotImplemented, NOT_IMPL_STR);
+    void createUpdateOptionDef6(const ServerSelector& server_selector,
+                                const OptionDefinitionPtr& option_def) {
+
+        createUpdateOptionDef(server_selector, option_def, DHCP6_OPTION_SPACE,
+                              PgSqlConfigBackendDHCPv6Impl::GET_OPTION_DEF6_CODE_SPACE,
+                              PgSqlConfigBackendDHCPv6Impl::INSERT_OPTION_DEF6,
+                              PgSqlConfigBackendDHCPv6Impl::UPDATE_OPTION_DEF6,
+                              PgSqlConfigBackendDHCPv6Impl::CREATE_AUDIT_REVISION,
+                              PgSqlConfigBackendDHCPv6Impl::INSERT_OPTION_DEF6_SERVER);
     }
 
     /// @brief Sends query to insert or update option definition
@@ -661,10 +811,21 @@ public:
     /// @param code Option code.
     /// @param name Option name.
     /// @return Number of deleted option definitions.
-    uint64_t deleteOptionDef6(const ServerSelector& /* server_selector */,
-                              const uint16_t /* code */,
-                              const std::string& /* space */) {
-        isc_throw(NotImplemented, NOT_IMPL_STR);
+    uint64_t deleteOptionDef6(const ServerSelector& server_selector,
+                              const uint16_t code,
+                              const std::string& space) {
+
+        PsqlBindArray in_bindings;
+        in_bindings.add(code);
+        in_bindings.add(space);
+
+        // Run DELETE.
+        return (deleteTransactional(PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION_DEF6_CODE_NAME,
+                                    server_selector,
+                                    "deleting option definition",
+                                    "option definition deleted",
+                                    false,
+                                    in_bindings));
     }
 
     /// @brief Sends query to delete option definitions for a client class.
@@ -684,10 +845,20 @@ public:
     /// @param code Code of the deleted option.
     /// @param space Option space of the deleted option.
     /// @return Number of deleted options.
-    uint64_t deleteOption6(const ServerSelector& /* server_selector */,
-                           const uint16_t /* code */,
-                           const std::string& /* space */) {
-        isc_throw(NotImplemented, NOT_IMPL_STR);
+    uint64_t deleteOption6(const ServerSelector& server_selector,
+                           const uint16_t code,
+                           const std::string& space) {
+        PsqlBindArray in_bindings;
+        in_bindings.add(code);
+        in_bindings.add(space);
+
+        // Run DELETE.
+        return (deleteTransactional(PgSqlConfigBackendDHCPv6Impl::DELETE_OPTION6,
+                                    server_selector,
+                                    "deleting global option",
+                                    "global option deleted",
+                                    false,
+                                    in_bindings));
     }
 
     /// @brief Deletes subnet level option.
index fe9c87c600d97d7c24b4fc718f9f6725990b750a..7069723c7215a811eb26c92d6be0fa2bbf4c91e5 100644 (file)
@@ -468,7 +468,7 @@ PgSqlConfigBackendImpl::getOptionDefs(const int index,
 void
 PgSqlConfigBackendImpl::createUpdateOptionDef(const db::ServerSelector& server_selector,
                                               const OptionDefinitionPtr& option_def,
-                                              const std::string& /*space*/,
+                                              const std::string& space,
                                               const int& /*get_option_def_code_space*/,
                                               const int& insert_option_def,
                                               const int& update_option_def,
@@ -545,7 +545,8 @@ PgSqlConfigBackendImpl::createUpdateOptionDef(const db::ServerSelector& server_s
         // Successfully inserted the definition. Now, we have to associate it
         // with the server tag.
         PsqlBindArray attach_bindings;
-        uint64_t id = getLastInsertId("dhcp4_option_def", "id");
+        uint64_t id = getLastInsertId((space == DHCP4_OPTION_SPACE ?
+                                       "dhcp4_option_def" : "dhcp6_option_def"), "id");
         attach_bindings.add(id);
         attach_bindings.addTimestamp(option_def->getModificationTime());
 
index 32c9805f97c875f51bba2f9fee8397399e3ed328..288980c6faa37536cceb6876684fa013f04d8b0e 100644 (file)
@@ -27,11 +27,11 @@ pgsql_cb_unittests_SOURCES  = pgsql_cb_impl_unittest.cc
 
 # disabled for now, to be added in #95
 pgsql_cb_unittests_SOURCES  += pgsql_cb_dhcp4_unittest.cc
-#pgsql_cb_unittests_SOURCES += pgsql_cb_dhcp4_mgr_unittest.cc
+pgsql_cb_unittests_SOURCES += pgsql_cb_dhcp4_mgr_unittest.cc
 
 # disabled for now, to be added in #96
 pgsql_cb_unittests_SOURCES += pgsql_cb_dhcp6_unittest.cc
-#pgsql_cb_unittests_SOURCES += pgsql_cb_dhcp6_mgr_unittest.cc
+pgsql_cb_unittests_SOURCES += pgsql_cb_dhcp6_mgr_unittest.cc
 
 pgsql_cb_unittests_SOURCES += run_unittests.cc
 
diff --git a/src/hooks/dhcp/pgsql_cb/tests/pgsql_cb_dhcp4_mgr_unittest.cc b/src/hooks/dhcp/pgsql_cb/tests/pgsql_cb_dhcp4_mgr_unittest.cc
new file mode 100644 (file)
index 0000000..5eb0df5
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2022 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 <config.h>
+#include <cc/stamped_value.h>
+#include <dhcpsrv/config_backend_dhcp4_mgr.h>
+#include <pgsql_cb_dhcp4.h>
+#include <pgsql/testutils/pgsql_schema.h>
+#include <dhcpsrv/testutils/generic_backend_unittest.h>
+#include <boost/shared_ptr.hpp>
+#include <gtest/gtest.h>
+
+using namespace isc::data;
+using namespace isc::dhcp;
+using namespace isc::dhcp::test;
+using namespace isc::db;
+using namespace isc::db::test;
+
+namespace {
+
+/// @brief Test fixture class for @c PgSqlConfigBackendDHCPv4Mgr.
+class PgSqlConfigBackendDHCPv4MgrTest : public GenericBackendTest {
+public:
+    /// @brief Constructor.
+    PgSqlConfigBackendDHCPv4MgrTest() {
+        // Recreate a fresh mgr.
+        ConfigBackendDHCPv4Mgr::create();
+
+        // Ensure we have the proper schema with no transient data.
+        createPgSQLSchema();
+    }
+
+    /// @brief Destructor.
+    virtual ~PgSqlConfigBackendDHCPv4MgrTest() {
+        // Destroy the mgr.
+        ConfigBackendDHCPv4Mgr::destroy();
+
+        // If data wipe enabled, delete transient data otherwise destroy the schema.
+        destroyPgSQLSchema();
+    }
+};
+
+// This test verifies that PgSQL backend can be registered with and
+// unregistered from the Config Backend Manager.
+TEST_F(PgSqlConfigBackendDHCPv4MgrTest, factoryRegistration) {
+
+    // Get the mgr singleton.
+    ConfigBackendDHCPv4Mgr& mgr = ConfigBackendDHCPv4Mgr::instance();
+
+    // With no factory registered, attempting to add a PgSQL db should fail.
+    ASSERT_THROW(mgr.addBackend(validPgSQLConnectionString()), InvalidType);
+
+    // Now we'll register the PgSQL factory.
+    ASSERT_NO_THROW(PgSqlConfigBackendDHCPv4::registerBackendType());
+
+    // With the factory registered, attempting to add a PgSQL db should succeed.
+    ASSERT_NO_THROW(mgr.addBackend(validPgSQLConnectionString()));
+
+    // Create a PgSQL backend selector for convenience.
+    BackendSelector pgsql(BackendSelector::Type::POSTGRESQL);
+
+    // Should be able to create a global parameter.
+    StampedValuePtr server_tag = StampedValue::create("server-tag", "whale");
+    ASSERT_NO_THROW(mgr.getPool()->createUpdateGlobalParameter4(pgsql, ServerSelector::ALL(),
+                                                                server_tag));
+    // Verify parameter can be fetched.
+    server_tag.reset();
+    ASSERT_NO_THROW(server_tag = mgr.getPool()->getGlobalParameter4(pgsql, ServerSelector::ALL(),
+                                                                    "server-tag"));
+    ASSERT_TRUE(server_tag);
+    EXPECT_EQ("server-tag", server_tag->getName());
+    EXPECT_EQ("whale", server_tag->getValue());
+
+    // Now we'll unregister PgSQL.
+    ASSERT_NO_THROW(PgSqlConfigBackendDHCPv4::unregisterBackendType());
+
+    // With no factory registered, attempting to add a PgSQL db should fail.
+    ASSERT_THROW(mgr.addBackend(validPgSQLConnectionString()), InvalidType);
+
+    // Attempting to read the global parameter should fail.
+    ASSERT_THROW(mgr.getPool()->getGlobalParameter4(pgsql, ServerSelector::ALL(), "server-tag"),
+                 NoSuchDatabase);
+}
+
+}
diff --git a/src/hooks/dhcp/pgsql_cb/tests/pgsql_cb_dhcp6_mgr_unittest.cc b/src/hooks/dhcp/pgsql_cb/tests/pgsql_cb_dhcp6_mgr_unittest.cc
new file mode 100644 (file)
index 0000000..ca4a97b
--- /dev/null
@@ -0,0 +1,88 @@
+// Copyright (C) 2022 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 <config.h>
+#include <cc/stamped_value.h>
+#include <dhcpsrv/config_backend_dhcp6_mgr.h>
+#include <pgsql_cb_dhcp6.h>
+#include <pgsql/testutils/pgsql_schema.h>
+#include <dhcpsrv/testutils/generic_backend_unittest.h>
+#include <boost/shared_ptr.hpp>
+#include <gtest/gtest.h>
+
+using namespace isc::data;
+using namespace isc::dhcp;
+using namespace isc::dhcp::test;
+using namespace isc::db;
+using namespace isc::db::test;
+
+namespace {
+
+/// @brief Test fixture class for @c PgSqlConfigBackendDHCPv6Mgr.
+class PgSqlConfigBackendDHCPv6MgrTest : public GenericBackendTest {
+public:
+    /// @brief Constructor.
+    PgSqlConfigBackendDHCPv6MgrTest() {
+        // Recreate a fresh mgr.
+        ConfigBackendDHCPv6Mgr::create();
+
+        // Ensure we have the proper schema with no transient data.
+        createPgSQLSchema();
+    }
+
+    /// @brief Destructor.
+    virtual ~PgSqlConfigBackendDHCPv6MgrTest() {
+        // Destroy the mgr.
+        ConfigBackendDHCPv6Mgr::destroy();
+
+        // If data wipe enabled, delete transient data otherwise destroy the schema.
+        destroyPgSQLSchema();
+    }
+};
+
+// This test verifies that PgSQL backend can be registered with and
+// unregistered from the Config Backend Manager.
+TEST_F(PgSqlConfigBackendDHCPv6MgrTest, factoryRegistration) {
+
+    // Get the mgr singleton.
+    ConfigBackendDHCPv6Mgr& mgr = ConfigBackendDHCPv6Mgr::instance();
+
+    // With no factory registered, attempting to add a PgSQL db should fail.
+    ASSERT_THROW(mgr.addBackend(validPgSQLConnectionString()), InvalidType);
+
+    // Now we'll register the PgSQL factory.
+    ASSERT_NO_THROW(PgSqlConfigBackendDHCPv6::registerBackendType());
+
+    // With the factory registered, attempting to add a PgSQL db should succeed.
+    ASSERT_NO_THROW(mgr.addBackend(validPgSQLConnectionString()));
+
+    // Create a PgSQL backend selector for convenience.
+    BackendSelector mysql(BackendSelector::Type::POSTGRESQL);
+
+    // Should be able to create a global parameter.
+    StampedValuePtr server_tag = StampedValue::create("server-tag", "whale");
+    ASSERT_NO_THROW(mgr.getPool()->createUpdateGlobalParameter6(mysql, ServerSelector::ALL(),
+                                                                server_tag));
+    // Verify parameter can be fetched.
+    server_tag.reset();
+    ASSERT_NO_THROW(server_tag = mgr.getPool()->getGlobalParameter6(mysql, ServerSelector::ALL(),
+                                                                    "server-tag"));
+    ASSERT_TRUE(server_tag);
+    EXPECT_EQ("server-tag", server_tag->getName());
+    EXPECT_EQ("whale", server_tag->getValue());
+
+    // Now we'll unregister PgSQL.
+    ASSERT_NO_THROW(PgSqlConfigBackendDHCPv6::unregisterBackendType());
+
+    // With no factory registered, attempting to add a PgSQL db should fail.
+    ASSERT_THROW(mgr.addBackend(validPgSQLConnectionString()), InvalidType);
+
+    // Attempting to read the global parameter should fail.
+    ASSERT_THROW(mgr.getPool()->getGlobalParameter6(mysql, ServerSelector::ALL(), "server-tag"),
+                 NoSuchDatabase);
+}
+
+}
index 853c066de57e9415a0d656401333e28638227eff..0a44d23dcf95a7a394397ef2f07046193c436918 100644 (file)
@@ -137,6 +137,60 @@ TEST_F(PgSqlConfigBackendDHCPv6Test, getAndDeleteAllServersTest) {
     getAndDeleteAllServersTest();
 }
 
+TEST_F(PgSqlConfigBackendDHCPv6Test, createUpdateDeleteGlobalParameter6Test) {
+    createUpdateDeleteGlobalParameter6Test();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, globalParameters6WithServerTagsTest) {
+    globalParameters6WithServerTagsTest();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, getAllGlobalParameters6Test) {
+    getAllGlobalParameters6Test();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, getModifiedGlobalParameters6Test) {
+    getModifiedGlobalParameters6Test();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, nullKeyErrorTest) {
+    nullKeyErrorTest();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, getOptionDef6Test) {
+    getOptionDef6Test();
+}
+
+// skipping shared-network and subnet tests for now
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, optionDefs6WithServerTagsTest) {
+    optionDefs6WithServerTagsTest();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, getAllOptionDefs6Test) {
+    getAllOptionDefs6Test();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, getModifiedOptionDefs6Test) {
+    getModifiedOptionDefs6Test();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, createUpdateDeleteOption6Test) {
+    createUpdateDeleteOption6Test();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, globalOptions6WithServerTagsTest) {
+    globalOptions6WithServerTagsTest();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, getAllOptions6Test) {
+    getAllOptions6Test();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv6Test, getModifiedOptions6Test) {
+    getModifiedOptions6Test();
+}
+
 /// @brief Test fixture for verifying database connection loss-recovery
 /// behavior.
 class PgSqlConfigBackendDHCPv6DbLostCallbackTest : public GenericConfigBackendDbLostCallbackTest {