]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#3770] v4 global options work
authorThomas Markwalder <tmark@isc.org>
Thu, 10 Jul 2025 18:11:31 +0000 (14:11 -0400)
committerThomas Markwalder <tmark@isc.org>
Tue, 15 Jul 2025 14:02:03 +0000 (14:02 +0000)
Fixed fetch of global options added UT tests

/src/hooks/dhcp/mysql/mysql_cb_impl.cc
    MySqlConfigBackendImpl::getOptions() - take client-classes into account
    MySqlConfigBackendImpl::createInputClientClassesBinding() - use ClientClasses::toElement()

/src/hooks/dhcp/mysql/tests/mysql_cb_dhcp4_unittest.cc
    TEST_F(MySqlConfigBackendDHCPv4Test, globalOption4WithClientClassesTest)
    TEST_F(MySqlConfigBackendDHCPv4Test, getAllOptions4WithClientClassesTest)
    - new tests

/src/hooks/dhcp/pgsql/pgsql_cb_impl.cc
    PgSqlConfigBackendImpl::getOptions() - take client-classes into account

/src/hooks/dhcp/pgsql/tests/pgsql_cb_dhcp4_unittest.cc
    TEST_F(PgSqlConfigBackendDHCPv4Test, globalOption4WithClientClassesTest)
    TEST_F(PgSqlConfigBackendDHCPv4Test, getAllOptions4WithClientClassesTest)
    - new tests

/src/lib/dhcpsrv/parsers/option_data_parser.cc
    OptionDataParser::createOption() - use ClientClasses::fromElement()

/src/lib/dhcpsrv/testutils/generic_cb_dhcp4_unittest.*
    GenericConfigBackendDHCPv4Test::TearDown() - skip schema destroy
    if env variable KEA_UNIT_TEST_KEEP_SCHEMA is defined

    GenericConfigBackendDHCPv4Test::makeClassTaggedOptions()
    GenericConfigBackendDHCPv4Test::updateClassTaggedOptions()
    GenericConfigBackendDHCPv4Test::globalOption4WithClientClassesTest()
    GenericConfigBackendDHCPv4Test::getAllOptions4WithClientClassesTest()
    - new tests

src/hooks/dhcp/mysql/mysql_cb_impl.cc
src/hooks/dhcp/mysql/tests/mysql_cb_dhcp4_unittest.cc
src/hooks/dhcp/pgsql/pgsql_cb_impl.cc
src/hooks/dhcp/pgsql/tests/pgsql_cb_dhcp4_unittest.cc
src/lib/dhcpsrv/parsers/option_data_parser.cc
src/lib/dhcpsrv/testutils/generic_cb_dhcp4_unittest.cc
src/lib/dhcpsrv/testutils/generic_cb_dhcp4_unittest.h

index 47b1bc75ab1498e042866416d3505898fded6cde..0b01dc677b18bc63f809e89cad9d0e1ebdd8f527 100644 (file)
@@ -802,7 +802,8 @@ MySqlConfigBackendImpl::getOptions(const int index,
                 auto existing_it = existing_it_pair.first;
                 bool found = false;
                 for ( ; existing_it != existing_it_pair.second; ++existing_it) {
-                    if (existing_it->space_name_ == desc->space_name_) {
+                    if ((existing_it->space_name_ == desc->space_name_) &&
+                        (existing_it->client_classes_ == desc->client_classes_)) {
                         found = true;
                         // This option was already fetched. Let's check if we should
                         // replace it or not.
@@ -818,8 +819,9 @@ MySqlConfigBackendImpl::getOptions(const int index,
                 // belongs to a different server and the inserted option is not
                 // for all servers.
                 if (!found ||
-                    (!existing_it->hasServerTag(last_option_server_tag) &&
-                     !last_option_server_tag.amAll())) {
+                    ((!existing_it->hasServerTag(last_option_server_tag) &&
+                      !last_option_server_tag.amAll()) ||
+                     (desc->client_classes_ != existing_it->client_classes_))) {
                     static_cast<void>(local_options.push_back(*desc));
                 }
             }
@@ -1130,11 +1132,7 @@ MySqlConfigBackendImpl::createClientClassesForWhereClause(const ClientClassesPtr
 db::MySqlBindingPtr
 MySqlConfigBackendImpl::createInputClientClassesBinding(const ClientClasses& client_classes) {
     // Create JSON list of client classes.
-    data::ElementPtr client_classes_element = data::Element::createList();
-    for (auto const& client_class : client_classes) {
-        client_classes_element->add(data::Element::create(client_class));
-    }
-
+    auto client_classes_element = client_classes.toElement();
     return (db::MySqlBinding::createString(client_classes_element->str()));
 }
 
index e4f366d5971a3d2929ba1a648a8c7f03140f7a89..3e28d98c7b06f17c9e1f3e1a52a88339057bb4b5 100644 (file)
@@ -351,6 +351,14 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedOptions4Test) {
     getModifiedOptions4Test();
 }
 
+TEST_F(MySqlConfigBackendDHCPv4Test, globalOption4WithClientClassesTest) {
+    globalOption4WithClientClassesTest();
+}
+
+TEST_F(MySqlConfigBackendDHCPv4Test, getAllOptions4WithClientClassesTest) {
+    getAllOptions4WithClientClassesTest();
+}
+
 TEST_F(MySqlConfigBackendDHCPv4Test, createUpdateDeleteSubnetOption4Test) {
     createUpdateDeleteSubnetOption4Test();
 }
@@ -403,10 +411,6 @@ TEST_F(MySqlConfigBackendDHCPv4Test, multipleAuditEntriesTest) {
     multipleAuditEntriesTest();
 }
 
-TEST_F(MySqlConfigBackendDHCPv4Test, globalOption4WithClientClassesTest) {
-    globalOption4WithClientClassesTest();
-}
-
 TEST_F(MySqlConfigBackendDHCPv4Test, sharedNetworkOption4WithClientClassesTest) {
     sharedNetworkOption4WithClientClassesTest();
 }
index 87cd19f68858e853fe0806291340396a7fd8e5f0..b386cf40e478250a14db8df35e30ffb754f2550b 100644 (file)
@@ -732,7 +732,8 @@ PgSqlConfigBackendImpl::getOptions(const int index,
                 auto existing_it = existing_it_pair.first;
                 bool found = false;
                 for ( ; existing_it != existing_it_pair.second; ++existing_it) {
-                    if (existing_it->space_name_ == desc->space_name_) {
+                    if ((existing_it->space_name_ == desc->space_name_) &&
+                        (existing_it->client_classes_ == desc->client_classes_)) {
                         found = true;
                         // This option was already fetched. Let's check if we should
                         // replace it or not.
@@ -748,8 +749,9 @@ PgSqlConfigBackendImpl::getOptions(const int index,
                 // belongs to a different server and the inserted option is not
                 // for all servers.
                 if (!found ||
-                    (!existing_it->hasServerTag(last_option_server_tag) &&
-                     !last_option_server_tag.amAll())) {
+                    ((!existing_it->hasServerTag(last_option_server_tag) &&
+                      !last_option_server_tag.amAll()) ||
+                     (desc->client_classes_ != existing_it->client_classes_))) {
                     static_cast<void>(local_options.push_back(*desc));
                 }
             }
index 8787aee0d51c08f9552d6bbcd7d0a35934941870..29b231266f2b58a36f3a46f0ccda171ac8deca88 100644 (file)
@@ -349,6 +349,14 @@ TEST_F(PgSqlConfigBackendDHCPv4Test, getModifiedOptions4Test) {
     getModifiedOptions4Test();
 }
 
+TEST_F(PgSqlConfigBackendDHCPv4Test, globalOption4WithClientClassesTest) {
+    globalOption4WithClientClassesTest();
+}
+
+TEST_F(PgSqlConfigBackendDHCPv4Test, getAllOptions4WithClientClassesTest) {
+    getAllOptions4WithClientClassesTest();
+}
+
 TEST_F(PgSqlConfigBackendDHCPv4Test, createUpdateDeleteSubnetOption4Test) {
     createUpdateDeleteSubnetOption4Test();
 }
@@ -401,10 +409,6 @@ TEST_F(PgSqlConfigBackendDHCPv4Test, multipleAuditEntriesTest) {
     multipleAuditEntriesTest();
 }
 
-TEST_F(PgSqlConfigBackendDHCPv4Test, globalOption4WithClientClassesTest) {
-    globalOption4WithClientClassesTest();
-}
-
 TEST_F(PgSqlConfigBackendDHCPv4Test, sharedNetworkOption4WithClientClassesTest) {
     sharedNetworkOption4WithClientClassesTest();
 }
index e75b524674dc8240e4a17d6522cd1e0d7ea48125..5be8fe78acd5c0938d790467982cf2a000764224 100644 (file)
@@ -441,15 +441,7 @@ OptionDataParser::createOption(ConstElementPtr option_data) {
         desc.setContext(user_context);
     }
 
-#if 1
     desc.client_classes_.fromElement(client_classes);
-#else
-    if (client_classes) {
-        for (auto const& class_element : client_classes->listValue()) {
-            desc.addClientClass(class_element->stringValue());
-        }
-    }
-#endif
 
     // All went good, so we can set the option space name.
     return (make_pair(desc, space_param));
index cbbe1f1e1b18d3b31bfafc8290ef0bd4f67306f3..03ae354f1fc3049aebf1727354e49e418d850a44 100644 (file)
@@ -73,7 +73,11 @@ void
 GenericConfigBackendDHCPv4Test::TearDown() {
     cbptr_.reset();
     // If data wipe enabled, delete transient data otherwise destroy the schema.
-    destroySchema();
+    if (getenv("KEA_UNIT_TEST_KEEP_SCHEMA")) {
+        std::cout << "KEA_UNIT_TEST_KEEP_SCHEMA set, avoid schema destruction" << std::endl;
+    } else {
+        destroySchema();
+    }
 }
 
 db::AuditEntryCollection
@@ -3362,9 +3366,13 @@ GenericConfigBackendDHCPv4Test::createUpdateDeleteOption4Test() {
 
 void
 GenericConfigBackendDHCPv4Test::globalOptions4WithServerTagsTest() {
-    OptionDescriptorPtr opt_boot_file_name1 = test_options_[0];
-    OptionDescriptorPtr opt_boot_file_name2 = test_options_[6];
-    OptionDescriptorPtr opt_boot_file_name3 = test_options_[7];
+    // Create test options without any client classes.
+    OptionDescriptorPtr opt_boot_file_name1(new OptionDescriptor(*test_options_[0]));
+    opt_boot_file_name1->client_classes_.clear();
+    OptionDescriptorPtr opt_boot_file_name2(new OptionDescriptor(*test_options_[6]));
+    opt_boot_file_name2->client_classes_.clear();
+    OptionDescriptorPtr opt_boot_file_name3(new OptionDescriptor(*test_options_[7]));
+    opt_boot_file_name3->client_classes_.clear();
 
     ASSERT_THROW(cbptr_->createUpdateOption4(ServerSelector::ONE("server1"),
                                              opt_boot_file_name1),
@@ -3636,6 +3644,215 @@ GenericConfigBackendDHCPv4Test::getModifiedOptions4Test() {
     }
 }
 
+std::list<OptionDescriptorPtr>
+GenericConfigBackendDHCPv4Test::makeClassTaggedOptions() {
+    // Describes an option to create.
+    struct OptData {
+        uint16_t code_;
+        std::string value_;
+        std::string cclass_;
+    };
+
+    // List of options to create.
+    std::list<OptData> opts_to_make = {
+        { DHO_TCODE,  "T100", "cc-one"   },
+        { DHO_PCODE,  "P100", "cc-one"   },
+        { DHO_PCODE,  "P300", ""         },
+        { DHO_TCODE,  "T200", ""         },
+        { DHO_PCODE,  "P200", "cc-two"   }
+    };
+
+    std::list<OptionDescriptorPtr> tagged_options;
+    for ( auto const& opt_to_make : opts_to_make) {
+        OptionDescriptor desc = createOption<OptionString>(Option::V4, opt_to_make.code_,
+                                                           true, false, false, opt_to_make.value_);
+        desc.space_name_ = DHCP4_OPTION_SPACE;
+        if (!opt_to_make.cclass_.empty()) {
+            desc.addClientClass(opt_to_make.cclass_);
+        }
+
+        tagged_options.push_back(OptionDescriptorPtr(new OptionDescriptor(desc)));
+    }
+
+    return (tagged_options);
+}
+
+void
+GenericConfigBackendDHCPv4Test::updateClassTaggedOptions(
+    std::list<OptionDescriptorPtr>& options) {
+    for ( auto& desc : options) {
+        OptionStringPtr opt = boost::dynamic_pointer_cast<OptionString>(desc->option_);
+        ASSERT_TRUE(opt);
+        std::string new_value(opt->getValue() + std::string(".") + opt->getValue());
+        opt->setValue(new_value);
+    }
+}
+
+// Macro the make SCOPED_TRACE around equivalance functon more compact and helpful.
+#define SCOPED_OPT_COMPARE(exp_opt,test_opt)\
+{\
+    std::stringstream oss;\
+    oss << "Options not equal:\n"\
+        << "  exp_opt: " << exp_opt.option_->toText() << "\n"\
+        << " test_opt: " << (test_opt.option_ ? test_opt.option_->toText() : "<null>") << "\n";\
+    SCOPED_TRACE(oss.str());\
+    testOptionsEquivalent(exp_opt,test_opt);\
+}
+
+// Verify that one can add multiple global instances of the same option code
+// and that they can be distinguished via their client_classes.
+void
+GenericConfigBackendDHCPv4Test::globalOption4WithClientClassesTest() {
+    // Add the options to global scope.
+    auto ref_options = makeClassTaggedOptions();
+    for (auto const& ref_option : ref_options) {
+        // Add option to the config back end.
+        cbptr_->createUpdateOption4(ServerSelector::ALL(), ref_option);
+    }
+
+    // Make sure that we can find each option.
+    OptionDescriptorPtr found_option;
+    for (auto const& ref_option : ref_options) {
+        // Find the option by code and client_classes.
+        ClientClassesPtr cclasses(new ClientClasses(ref_option->client_classes_));
+        found_option = cbptr_->getOption4(ServerSelector::ALL(),
+                                          ref_option->option_->getType(),
+                                          DHCP4_OPTION_SPACE,
+                                          cclasses);
+        ASSERT_TRUE(found_option);
+        SCOPED_OPT_COMPARE((*ref_option), (*found_option));
+    }
+
+    // Update the option values.
+    updateClassTaggedOptions(ref_options);
+
+    // Update each option in the backend.
+    for (auto const& ref_option : ref_options) {
+        ClientClassesPtr cclasses(new ClientClasses(ref_option->client_classes_));
+
+        // Update option in the config back end.
+        cbptr_->createUpdateOption4(ServerSelector::ALL(), ref_option);
+
+        // Fetch and verify the updated option.
+        found_option = cbptr_->getOption4(ServerSelector::ALL(),
+                                          ref_option->option_->getType(),
+                                          DHCP4_OPTION_SPACE,
+                                          cclasses);
+        ASSERT_TRUE(found_option);
+        SCOPED_OPT_COMPARE((*ref_option), (*found_option));
+    }
+
+    // Delete each option from the backend.
+    for (auto const& ref_option : ref_options) {
+        ClientClassesPtr cclasses(new ClientClasses(ref_option->client_classes_));
+
+        // Delete the option by code and client_classes.
+        ASSERT_EQ(1, cbptr_->deleteOption4(ServerSelector::ALL(),
+                                           ref_option->option_->getType(),
+                                           DHCP4_OPTION_SPACE,
+                                           cclasses));
+
+        // Finding the option by code and client_classes should fail.
+        found_option = cbptr_->getOption4(ServerSelector::ALL(),
+                                          ref_option->option_->getType(),
+                                          DHCP4_OPTION_SPACE,
+                                          cclasses);
+        ASSERT_FALSE(found_option);
+    }
+}
+
+
+void
+GenericConfigBackendDHCPv4Test::getAllOptions4WithClientClassesTest() {
+    // Describes an option to create.
+    struct OptData {
+        uint16_t code_;
+        uint32_t value_;
+        std::string cclass_;
+        ServerSelector server_;
+    };
+
+    auto server1 = ServerSelector::ONE("server1");
+    auto server2 = ServerSelector::ONE("server2");
+    auto all = ServerSelector::ALL();
+    // List of options to create.
+    std::list<OptData> opts_to_make = {
+        { 231,  1, "cc-1", server1 },
+        { 231,  2, "cc-2", server1 },
+        { 232,  3, "cc-3", server1 },
+        { 232,  4, "cc-3", server2 },
+        { 233,  5, "cc-4", server1 },
+        { 233,  6, "cc-4", all },
+        { 234,  7, "cc-5", all }
+    };
+
+    // Create two servers.
+    ASSERT_NO_THROW_LOG(cbptr_->createUpdateServer4(test_servers_[1]));
+    ASSERT_NO_THROW_LOG(cbptr_->createUpdateServer4(test_servers_[2]));
+
+    // Add all of the global options.
+    std::vector<OptionDescriptorPtr> ref_options;
+    for ( auto const& opt_to_make : opts_to_make) {
+        OptionDescriptor desc = createOption<OptionInt<uint32_t>>(Option::V4, opt_to_make.code_,
+                                                           true, false, false, opt_to_make.value_);
+        desc.space_name_ = DHCP4_OPTION_SPACE;
+        if (!opt_to_make.cclass_.empty()) {
+            desc.addClientClass(opt_to_make.cclass_);
+        }
+
+        ref_options.push_back(OptionDescriptorPtr(new OptionDescriptor(desc)));
+        ASSERT_NO_THROW_LOG(cbptr_->createUpdateOption4(opt_to_make.server_, ref_options.back()));
+    }
+
+    // Try to fetch the collection of global options for the server1.
+    // Build list of options we expect to get back.
+    std::vector<OptionDescriptorPtr> exp_options;
+    exp_options.push_back(ref_options[0]);
+    exp_options.push_back(ref_options[1]);
+    exp_options.push_back(ref_options[2]);
+    exp_options.push_back(ref_options[4]);
+    exp_options.push_back(ref_options[6]);
+
+    OptionContainer returned_options;
+    ASSERT_NO_THROW_LOG(returned_options = cbptr_->getAllOptions4(server1));
+    ASSERT_EQ(returned_options.size(), exp_options.size());
+    auto exp_option = exp_options.begin();
+    for (auto returned_option : returned_options) {
+        testOptionsEquivalent(*(*exp_option), returned_option);
+        ++exp_option;
+    }
+
+    // Try to fetch the collection of global options for the server1.
+    // Build list of options we expect to get back.
+    exp_options.clear();
+    exp_options.push_back(ref_options[3]);
+    exp_options.push_back(ref_options[5]);
+    exp_options.push_back(ref_options[6]);
+
+    ASSERT_NO_THROW_LOG(returned_options = cbptr_->getAllOptions4(server2));
+    ASSERT_EQ(returned_options.size(), exp_options.size());
+    exp_option = exp_options.begin();
+    for (auto returned_option : returned_options) {
+        testOptionsEquivalent(*(*exp_option), returned_option);
+        ++exp_option;
+    }
+
+    // Try to fetch the collection of global options for the server1.
+    // Build list of options we expect to get back.
+    exp_options.clear();
+    exp_options.push_back(ref_options[5]);
+    exp_options.push_back(ref_options[6]);
+
+    ASSERT_NO_THROW_LOG(returned_options = cbptr_->getAllOptions4(all));
+    ASSERT_EQ(returned_options.size(), exp_options.size());
+    exp_option = exp_options.begin();
+    for (auto returned_option : returned_options) {
+        testOptionsEquivalent(*(*exp_option), returned_option);
+        ++exp_option;
+    }
+}
+
+
 void
 GenericConfigBackendDHCPv4Test::createUpdateDeleteSubnetOption4Test() {
     // Insert new subnet.
@@ -4718,123 +4935,6 @@ GenericConfigBackendDHCPv4Test::multipleAuditEntriesTest() {
     }
 }
 
-std::list<OptionDescriptorPtr>
-GenericConfigBackendDHCPv4Test::makeClassTaggedOptions() {
-    // Describes an option to create.
-    struct OptData {
-        uint16_t code_;
-        std::string value_;
-        std::string cclass_;
-    };
-
-    // List of options to create.
-    std::list<OptData> opts_to_make = {
-        { DHO_TCODE,  "T100", "cc-one"   },
-        { DHO_PCODE,  "P100", "cc-one"   },
-        { DHO_PCODE,  "P300", ""         },
-        { DHO_TCODE,  "T200", ""         },
-        { DHO_PCODE,  "P200", "cc-two"   }
-    };
-
-    std::list<OptionDescriptorPtr> tagged_options;
-    for ( auto const& opt_to_make : opts_to_make) {
-        OptionDescriptor desc = createOption<OptionString>(Option::V4, opt_to_make.code_,
-                                                           true, false, false, opt_to_make.value_);
-        desc.space_name_ = DHCP4_OPTION_SPACE;
-        if (!opt_to_make.cclass_.empty()) {
-            desc.addClientClass(opt_to_make.cclass_);
-        }
-
-        tagged_options.push_back(OptionDescriptorPtr(new OptionDescriptor(desc)));
-    }
-
-    return (tagged_options);
-}
-
-void
-GenericConfigBackendDHCPv4Test::updateClassTaggedOptions(
-    std::list<OptionDescriptorPtr>& options) {
-    for ( auto& desc : options) {
-        OptionStringPtr opt = boost::dynamic_pointer_cast<OptionString>(desc->option_);
-        ASSERT_TRUE(opt);
-        std::string new_value(opt->getValue() + std::string(".") + opt->getValue());
-        opt->setValue(new_value);
-    }
-}
-
-// Macro the make SCOPED_TRACE around equivalance functon more compact and helpful.
-#define SCOPED_OPT_COMPARE(exp_opt,test_opt)\
-{\
-    std::stringstream oss;\
-    oss << "Options not equal:\n"\
-        << "  exp_opt: " << exp_opt.option_->toText() << "\n"\
-        << " test_opt: " << (test_opt.option_ ? test_opt.option_->toText() : "<null>") << "\n";\
-    SCOPED_TRACE(oss.str());\
-    testOptionsEquivalent(exp_opt,test_opt);\
-}
-
-// Verify that one can add multiple global instances of the same option code
-// and that they can be distinguished via their client_classes.
-void
-GenericConfigBackendDHCPv4Test::globalOption4WithClientClassesTest() {
-    // Add the options to global scope.
-    auto ref_options = makeClassTaggedOptions();
-    for (auto const& ref_option : ref_options) {
-        // Add option to the config back end.
-        cbptr_->createUpdateOption4(ServerSelector::ALL(), ref_option);
-    }
-
-    // Make sure that we can find each option.
-    OptionDescriptorPtr found_option;
-    for (auto const& ref_option : ref_options) {
-        // Find the option by code and client_classes.
-        ClientClassesPtr cclasses(new ClientClasses(ref_option->client_classes_));
-        found_option = cbptr_->getOption4(ServerSelector::ALL(),
-                                          ref_option->option_->getType(),
-                                          DHCP4_OPTION_SPACE,
-                                          cclasses);
-        ASSERT_TRUE(found_option);
-        SCOPED_OPT_COMPARE((*ref_option), (*found_option));
-    }
-
-    // Update the option values.
-    updateClassTaggedOptions(ref_options);
-
-    // Update each option in the backend.
-    for (auto const& ref_option : ref_options) {
-        ClientClassesPtr cclasses(new ClientClasses(ref_option->client_classes_));
-
-        // Update option in the config back end.
-        cbptr_->createUpdateOption4(ServerSelector::ALL(), ref_option);
-
-        // Fetch and verify the updated option.
-        found_option = cbptr_->getOption4(ServerSelector::ALL(),
-                                          ref_option->option_->getType(),
-                                          DHCP4_OPTION_SPACE,
-                                          cclasses);
-        ASSERT_TRUE(found_option);
-        SCOPED_OPT_COMPARE((*ref_option), (*found_option));
-    }
-
-    // Delete each option from the backend.
-    for (auto const& ref_option : ref_options) {
-        ClientClassesPtr cclasses(new ClientClasses(ref_option->client_classes_));
-
-        // Delete the option by code and client_classes.
-        ASSERT_EQ(1, cbptr_->deleteOption4(ServerSelector::ALL(),
-                                           ref_option->option_->getType(),
-                                           DHCP4_OPTION_SPACE,
-                                           cclasses));
-
-        // Finding the option by code and client_classes should fail.
-        found_option = cbptr_->getOption4(ServerSelector::ALL(),
-                                          ref_option->option_->getType(),
-                                          DHCP4_OPTION_SPACE,
-                                          cclasses);
-        ASSERT_FALSE(found_option);
-    }
-}
-
 // Verify that one can add multiple instances of the same option code
 // to a shared-network and that they can be distinguished via their client_classes.
 void
index 64fa80156103557f9ccc22410a22a255fc435ccd..71a2ccfa56591ae5d1be9a6e3164e3b8b8ca9ed4 100644 (file)
@@ -315,6 +315,22 @@ public:
     /// @brief This test verifies that modified global options can be retrieved.
     void getModifiedOptions4Test();
 
+    /// @brief Creates a list of string options with and without client_class tags.
+    /// It creates 3 DHO_TCODE options and 2 DHO_PCODE options.
+    std::list<OptionDescriptorPtr> makeClassTaggedOptions();
+
+    /// @brief Updates the value of each string option in the list.
+    void updateClassTaggedOptions(std::list<OptionDescriptorPtr>& options);
+
+    /// @brief This test verifies that multiple instances of an option can
+    /// be added to global scope and be distinguished from one another
+    /// by their client-classes content.
+    void globalOption4WithClientClassesTest();
+
+    /// @brief This test verifies that global options with varying client-classes
+    /// and varying server tags are handled properly.
+    void getAllOptions4WithClientClassesTest();
+
     /// @brief This test verifies that subnet level option can be added, updated and
     /// deleted.
     void createUpdateDeleteSubnetOption4Test();
@@ -369,18 +385,6 @@ public:
     /// event and it does not matter).
     void multipleAuditEntriesTest();
 
-    /// @brief Creates a list of string options with and without client_class tags.
-    /// It creates 3 DHO_TCODE options and 2 DHO_PCODE options.
-    std::list<OptionDescriptorPtr> makeClassTaggedOptions();
-
-    /// @brief Updates the value of each string option in the list.
-    void updateClassTaggedOptions(std::list<OptionDescriptorPtr>& options);
-
-    /// @brief This test verifies that multiple instances of an option can
-    /// be added to global scope and be distinguished from one another
-    /// by their client-classes content.
-    void globalOption4WithClientClassesTest();
-
     /// @brief This test verifies that multiple instances of an option can
     /// be added to a shared-network and be distinguished from one another
     /// by their client-classes content.