]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1928] Copy assignment for class dictionary
authorMarcin Siodelski <marcin@isc.org>
Tue, 20 Jul 2021 18:19:45 +0000 (20:19 +0200)
committerMarcin Siodelski <marcin@isc.org>
Wed, 21 Jul 2021 10:49:50 +0000 (10:49 +0000)
src/lib/dhcpsrv/client_class_def.cc
src/lib/dhcpsrv/client_class_def.h
src/lib/dhcpsrv/tests/client_class_def_unittest.cc

index 51ed095ba5c51adda469b009f3b32717d6ffdf46..9b5a500e5465b99160f9689710890102fd3759af 100644 (file)
@@ -361,6 +361,19 @@ ClientClassDictionary::toElement() const {
     return (result);
 }
 
+ClientClassDictionary&
+ClientClassDictionary::operator=(const ClientClassDictionary& rhs) {
+    if (this != &rhs) {
+        list_->clear();
+        map_->clear();
+        for (auto cclass : *(rhs.list_)) {
+            ClientClassDefPtr copy(new ClientClassDef(*cclass));
+            addClass(copy);
+        }
+    }
+    return (*this);
+}
+
 std::list<std::string>
 builtinNames = {
     // DROP is not in this list because it is special but not built-in.
index 293e84ee8ec7b269cb5b800fe2acd6caa18c4441..aab8ddc186443f7c1a0cc9a5c68ac6044d9347b7 100644 (file)
@@ -391,6 +391,12 @@ public:
         return (!equals(other));
     }
 
+    /// @brief Copy assignment operator.
+    ///
+    /// @param rhs Client class dictionary to be copied from.
+    /// @return Instance copy.
+    ClientClassDictionary& operator=(const ClientClassDictionary& rhs);
+
     /// @brief Unparse a configuration object
     ///
     /// @return a pointer to unparsed configuration
index 68f1328d30a11700efccb1f2f505e3d70ae4e0eb..d33f01b8813c12acf99786f8f75ad263ad6b998f 100644 (file)
@@ -431,6 +431,45 @@ TEST(ClientClassDictionary, copyAndEquality) {
     EXPECT_TRUE(*dictionary != *dictionary2);
 }
 
+// Verify that client class dictionaries are deep-copied.
+TEST(ClientClassDictionary, copy) {
+    ClientClassDictionary dictionary;
+    ExpressionPtr expr;
+    CfgOptionPtr options;
+
+    // Get a client class dictionary and fill it.
+    ASSERT_NO_THROW(dictionary.addClass("one", expr, "", false,
+                                         false, options));
+    ASSERT_NO_THROW(dictionary.addClass("two", expr, "", false,
+                                         false, options));
+    ASSERT_NO_THROW(dictionary.addClass("three", expr, "", false,
+                                         false, options));
+
+    // Make a copy with a copy constructor. Expect it to be a deep copy.
+    ClientClassDictionary dictionary_copy(dictionary);
+    ASSERT_NO_THROW(dictionary.removeClass("one"));
+    ASSERT_NO_THROW(dictionary.removeClass("two"));
+    ASSERT_NO_THROW(dictionary.removeClass("three"));
+    EXPECT_TRUE(dictionary.empty());
+    EXPECT_FALSE(dictionary_copy.empty());
+
+    // Refill the client class dictionary.
+    ASSERT_NO_THROW(dictionary.addClass("one", expr, "", false,
+                                         false, options));
+    ASSERT_NO_THROW(dictionary.addClass("two", expr, "", false,
+                                         false, options));
+    ASSERT_NO_THROW(dictionary.addClass("three", expr, "", false,
+                                         false, options));
+
+    // Make a copy with operator=. Expect it to be a deep copy.
+    dictionary_copy = dictionary;
+    ASSERT_NO_THROW(dictionary.removeClass("one"));
+    ASSERT_NO_THROW(dictionary.removeClass("two"));
+    ASSERT_NO_THROW(dictionary.removeClass("three"));
+    EXPECT_TRUE(dictionary.empty());
+    EXPECT_FALSE(dictionary_copy.empty());
+}
+
 // Tests dependency.
 TEST(ClientClassDictionary, dependency) {
     ClientClassDictionaryPtr dictionary(new ClientClassDictionary());