]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1247] Half done: updated MySQL code, to do databaseConfigApply
authorFrancis Dupont <fdupont@isc.org>
Sat, 20 Jun 2020 17:24:50 +0000 (19:24 +0200)
committerFrancis Dupont <fdupont@isc.org>
Mon, 6 Jul 2020 13:05:13 +0000 (15:05 +0200)
src/hooks/dhcp/mysql_cb/mysql_cb_dhcp4.cc
src/hooks/dhcp/mysql_cb/mysql_cb_dhcp6.cc
src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp4_unittest.cc
src/hooks/dhcp/mysql_cb/tests/mysql_cb_dhcp6_unittest.cc

index 436770195b0f9a5d420b8c73c4a323e81280444c..ac3f24abd71d06f7f82a5abf397c5131f9a54462 100644 (file)
@@ -2256,7 +2256,7 @@ TaggedStatementArray tagged_statements = { {
 
     // Select modified global parameters.
     { MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_GLOBAL_PARAMETERS4,
-      MYSQL_GET_GLOBAL_PARAMETER(dhcp4, AND g.modification_ts > ?)
+      MYSQL_GET_GLOBAL_PARAMETER(dhcp4, AND g.modification_ts >= ?)
     },
 
     // Select subnet by id.
@@ -2301,12 +2301,12 @@ TaggedStatementArray tagged_statements = { {
 
     // Select subnets having modification time later than X.
     { MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_SUBNETS4,
-      MYSQL_GET_SUBNET4_NO_TAG(WHERE s.modification_ts > ?)
+      MYSQL_GET_SUBNET4_NO_TAG(WHERE s.modification_ts >= ?)
     },
 
     // Select modified and unassigned subnets.
     { MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_SUBNETS4_UNASSIGNED,
-      MYSQL_GET_SUBNET4_UNASSIGNED(AND s.modification_ts > ?)
+      MYSQL_GET_SUBNET4_UNASSIGNED(AND s.modification_ts >= ?)
     },
 
     // Select subnets belonging to a shared network.
@@ -2352,12 +2352,12 @@ TaggedStatementArray tagged_statements = { {
 
     // Select modified shared networks.
     { MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_SHARED_NETWORKS4,
-      MYSQL_GET_SHARED_NETWORK4_NO_TAG(WHERE n.modification_ts > ?)
+      MYSQL_GET_SHARED_NETWORK4_NO_TAG(WHERE n.modification_ts >= ?)
     },
 
     // Select modified and unassigned shared networks.
     { MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_SHARED_NETWORKS4_UNASSIGNED,
-      MYSQL_GET_SHARED_NETWORK4_UNASSIGNED(AND n.modification_ts > ?)
+      MYSQL_GET_SHARED_NETWORK4_UNASSIGNED(AND n.modification_ts >= ?)
     },
 
     // Retrieves option definition by code and space.
@@ -2372,7 +2372,7 @@ TaggedStatementArray tagged_statements = { {
 
     // Retrieves modified option definitions.
     { MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_OPTION_DEFS4,
-      MYSQL_GET_OPTION_DEF(dhcp4, AND d.modification_ts > ?)
+      MYSQL_GET_OPTION_DEF(dhcp4, AND d.modification_ts >= ?)
     },
 
     // Retrieves global option by code and space.
@@ -2387,7 +2387,7 @@ TaggedStatementArray tagged_statements = { {
 
     // Retrieves modified options.
     { MySqlConfigBackendDHCPv4Impl::GET_MODIFIED_OPTIONS4,
-      MYSQL_GET_OPTION4(AND o.scope_id = 0 AND o.modification_ts > ?)
+      MYSQL_GET_OPTION4(AND o.scope_id = 0 AND o.modification_ts >= ?)
     },
 
     // Retrieves an option for a given subnet, option code and space.
index d66bf1072561e44ffb5359f03108ce506e0ac1fd..db5f56d89f8185f5b6ef53fa301ddaf9667388e9 100644 (file)
@@ -2700,7 +2700,7 @@ TaggedStatementArray tagged_statements = { {
 
     // Select modified global parameters.
     { MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_GLOBAL_PARAMETERS6,
-      MYSQL_GET_GLOBAL_PARAMETER(dhcp6, AND g.modification_ts > ?)
+      MYSQL_GET_GLOBAL_PARAMETER(dhcp6, AND g.modification_ts >= ?)
     },
 
     // Delete all global parameters which are unassigned to any servers.
@@ -2750,12 +2750,12 @@ TaggedStatementArray tagged_statements = { {
 
     // Select subnets having modification time later than X.
     { MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_SUBNETS6,
-      MYSQL_GET_SUBNET6_NO_TAG(WHERE s.modification_ts > ?)
+      MYSQL_GET_SUBNET6_NO_TAG(WHERE s.modification_ts >= ?)
     },
 
     // Select modified and unassigned subnets.
     { MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_SUBNETS6_UNASSIGNED,
-      MYSQL_GET_SUBNET6_UNASSIGNED(AND s.modification_ts > ?)
+      MYSQL_GET_SUBNET6_UNASSIGNED(AND s.modification_ts >= ?)
     },
 
     // Select subnets belonging to a shared network.
@@ -2812,12 +2812,12 @@ TaggedStatementArray tagged_statements = { {
 
     // Select modified shared networks.
     { MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_SHARED_NETWORKS6,
-      MYSQL_GET_SHARED_NETWORK6_NO_TAG(WHERE n.modification_ts > ?)
+      MYSQL_GET_SHARED_NETWORK6_NO_TAG(WHERE n.modification_ts >= ?)
     },
 
     // Select modified and unassigned shared networks.
     { MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_SHARED_NETWORKS6_UNASSIGNED,
-      MYSQL_GET_SHARED_NETWORK6_UNASSIGNED(AND n.modification_ts > ?)
+      MYSQL_GET_SHARED_NETWORK6_UNASSIGNED(AND n.modification_ts >= ?)
     },
 
     // Retrieves option definition by code and space.
@@ -2832,7 +2832,7 @@ TaggedStatementArray tagged_statements = { {
 
     // Retrieves modified option definitions.
     { MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_OPTION_DEFS6,
-      MYSQL_GET_OPTION_DEF(dhcp6, AND d.modification_ts > ?)
+      MYSQL_GET_OPTION_DEF(dhcp6, AND d.modification_ts >= ?)
     },
 
     // Retrieves global option by code and space.
@@ -2847,7 +2847,7 @@ TaggedStatementArray tagged_statements = { {
 
     // Retrieves modified options.
     { MySqlConfigBackendDHCPv6Impl::GET_MODIFIED_OPTIONS6,
-      MYSQL_GET_OPTION6(AND o.scope_id = 0 AND o.modification_ts > ?)
+      MYSQL_GET_OPTION6(AND o.scope_id = 0 AND o.modification_ts >= ?)
     },
 
     // Retrieves an option for a given subnet, option code and space.
index 16d9577155703263b79a06e5694bea6f19073873..2a4a44d4b81f4bc189e43c50b834c02f0beaf15f 100644 (file)
@@ -416,12 +416,18 @@ public:
         // Current time minus 1 hour to make sure it is in the past.
         timestamps_["today"] = boost::posix_time::second_clock::local_time()
             - boost::posix_time::hours(1);
+        // One second after today.
+        timestamps_["after today"] = timestamps_["today"] + boost::posix_time::seconds(1);
         // Yesterday.
         timestamps_["yesterday"] = timestamps_["today"] - boost::posix_time::hours(24);
+        // One second after yesterday.
+        timestamps_["after yesterday"] = timestamps_["yesterday"] + boost::posix_time::seconds(1);
         // Two days ago.
         timestamps_["two days ago"] = timestamps_["today"] - boost::posix_time::hours(48);
         // Tomorrow.
         timestamps_["tomorrow"] = timestamps_["today"] + boost::posix_time::hours(24);
+        // One second after tomorrow.
+        timestamps_["after tomorrow"] = timestamps_["tomorrow"] + boost::posix_time::seconds(1);
     }
 
     /// @brief Logs audit entries in the @c audit_entries_ member.
@@ -1061,7 +1067,7 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedGlobalParameters4) {
 
     // Get parameters modified after "today".
     auto parameters = cbptr_->getModifiedGlobalParameters4(ServerSelector::ALL(),
-                                                           timestamps_["today"]);
+                                                           timestamps_["after today"]);
 
     const auto& parameters_index = parameters.get<StampedValueNameIndexTag>();
 
@@ -1077,7 +1083,7 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedGlobalParameters4) {
     // Should be able to fetct these parameters when explicitly providing
     // the server tag.
     parameters = cbptr_->getModifiedGlobalParameters4(ServerSelector::ONE("server1"),
-                                                      timestamps_["today"]);
+                                                      timestamps_["after today"]);
     EXPECT_EQ(1, parameters.size());
 }
 
@@ -1920,24 +1926,24 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedSubnets4) {
     // should be returned.
     Subnet4Collection
         subnets = cbptr_->getModifiedSubnets4(ServerSelector::ALL(),
-                                              timestamps_["today"]);
+                                              timestamps_["after today"]);
     ASSERT_EQ(1, subnets.size());
 
     // All subnets should also be returned for explicitly specified server tag.
     subnets = cbptr_->getModifiedSubnets4(ServerSelector::ONE("server1"),
-                                          timestamps_["today"]);
+                                          timestamps_["after today"]);
     ASSERT_EQ(1, subnets.size());
 
     // Fetch subnets with timestamp later than yesterday. We should get
     // two subnets.
     subnets = cbptr_->getModifiedSubnets4(ServerSelector::ALL(),
-                                          timestamps_["yesterday"]);
+                                          timestamps_["after yesterday"]);
     ASSERT_EQ(2, subnets.size());
 
     // Fetch subnets with timestamp later than tomorrow. Nothing should
     // be returned.
     subnets = cbptr_->getModifiedSubnets4(ServerSelector::ALL(),
-                                          timestamps_["tomorrow"]);
+                                          timestamps_["after tomorrow"]);
     ASSERT_TRUE(subnets.empty());
 }
 
@@ -2622,19 +2628,19 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedSharedNetworks4) {
     // shared network  should be returned.
     SharedNetwork4Collection
         networks = cbptr_->getModifiedSharedNetworks4(ServerSelector::ALL(),
-                                                      timestamps_["today"]);
+                                                      timestamps_["after today"]);
     ASSERT_EQ(1, networks.size());
 
     // Fetch shared networks with timestamp later than yesterday. We
     // should get two shared networks.
     networks = cbptr_->getModifiedSharedNetworks4(ServerSelector::ALL(),
-                                                 timestamps_["yesterday"]);
+                                                 timestamps_["after yesterday"]);
     ASSERT_EQ(2, networks.size());
 
     // Fetch shared networks with timestamp later than tomorrow. Nothing
     // should be returned.
     networks = cbptr_->getModifiedSharedNetworks4(ServerSelector::ALL(),
-                                                  timestamps_["tomorrow"]);
+                                                  timestamps_["after tomorrow"]);
     ASSERT_TRUE(networks.empty());
 }
 
@@ -3290,19 +3296,19 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedOptionDefs4) {
     // option definition should be returned.
     OptionDefContainer
         option_defs = cbptr_->getModifiedOptionDefs4(ServerSelector::ALL(),
-                                                     timestamps_["today"]);
+                                                     timestamps_["after today"]);
     ASSERT_EQ(1, option_defs.size());
 
     // Fetch option definitions with timestamp later than yesterday. We
     // should get two option definitions.
     option_defs = cbptr_->getModifiedOptionDefs4(ServerSelector::ALL(),
-                                                 timestamps_["yesterday"]);
+                                                 timestamps_["after yesterday"]);
     ASSERT_EQ(2, option_defs.size());
 
     // Fetch option definitions with timestamp later than tomorrow. Nothing
     // should be returned.
     option_defs = cbptr_->getModifiedOptionDefs4(ServerSelector::ALL(),
-                                              timestamps_["tomorrow"]);
+                                              timestamps_["after tomorrow"]);
     ASSERT_TRUE(option_defs.empty());
 }
 
@@ -3638,13 +3644,13 @@ TEST_F(MySqlConfigBackendDHCPv4Test, getModifiedOptions4) {
     // one option should be returned.
     OptionContainer returned_options =
         cbptr_->getModifiedOptions4(ServerSelector::ALL(),
-                                    timestamps_["today"]);
+                                    timestamps_["after today"]);
     ASSERT_EQ(1, returned_options.size());
 
     // Fetching modified options with explicitly specified server selector
     // should return the same result.
     returned_options = cbptr_->getModifiedOptions4(ServerSelector::ONE("server1"),
-                                                   timestamps_["today"]);
+                                                   timestamps_["after today"]);
     ASSERT_EQ(1, returned_options.size());
 
     // The returned option should be the one with the timestamp
@@ -4093,4 +4099,41 @@ TEST_F(MySqlConfigBackendDHCPv4Test, sharedNetworkOptionIdOrder) {
     }
 }
 
+/// This test verifies that audit entries can be retrieved from a given
+/// timestamp and id including when two entries can get the same timestamp.
+/// (either it is a common even and this should catch it, or it is a rare
+/// event and it does not matter).
+TEST_F(MySqlConfigBackendDHCPv4Test, multipleAuditEntries) {
+    // Get current time.
+    boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
+
+    // Create a server.
+    EXPECT_NO_THROW(cbptr_->createUpdateServer4(test_servers_[1]));
+
+    // Create a global parameter and update it many times.
+    const ServerSelector& server_selector = ServerSelector::ALL();
+    StampedValuePtr param;
+    ElementPtr value;
+    for (int i = 0; i < 100; ++i) {
+        value = Element::create(i);
+        param = StampedValue::create("my-parameter", value);
+        cbptr_->createUpdateGlobalParameter4(server_selector, param);
+    }
+
+    // Get all audit entries from now.
+    AuditEntryCollection audit_entries =
+        cbptr_->getRecentAuditEntries(server_selector, now, 0);
+
+    // Check that partial retrieves return the right count.
+    auto& mod_time_idx = audit_entries.get<AuditEntryModificationTimeIdTag>();
+    for (auto it = mod_time_idx.begin(); it != mod_time_idx.end(); ++it) {
+        size_t partial_size =
+            cbptr_->getRecentAuditEntries(server_selector,
+                                          (*it)->getModificationTime(),
+                                          (*it)->getModificationId()).size();
+        EXPECT_EQ(partial_size + 1,
+                  std::distance(it, mod_time_idx.end()));
+    }
+}
+
 }
index bf5948011ce76f970dcf9431fa9d421298c27a8f..a2a9a61b51d1fc59b6421613906d9810a69f6ed3 100644 (file)
@@ -464,12 +464,18 @@ public:
         // Current time minus 1 hour to make sure it is in the past.
         timestamps_["today"] = boost::posix_time::second_clock::local_time()
             - boost::posix_time::hours(1);
+        // One second after today.
+        timestamps_["after today"] = timestamps_["today"] + boost::posix_time::seconds(1);
         // Yesterday.
         timestamps_["yesterday"] = timestamps_["today"] - boost::posix_time::hours(24);
+        // One second after yesterday.
+        timestamps_["after yesterday"] = timestamps_["yesterday"] + boost::posix_time::seconds(1);
         // Two days ago.
         timestamps_["two days ago"] = timestamps_["today"] - boost::posix_time::hours(48);
         // Tomorrow.
         timestamps_["tomorrow"] = timestamps_["today"] + boost::posix_time::hours(24);
+        // One second after tomorrow.
+        timestamps_["after tomorrow"] = timestamps_["tomorrow"] + boost::posix_time::seconds(1);
     }
 
     /// @brief Logs audit entries in the @c audit_entries_ member.
@@ -1104,7 +1110,7 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getModifiedGlobalParameters6) {
 
     // Get parameters modified after "today".
     auto parameters = cbptr_->getModifiedGlobalParameters6(ServerSelector::ALL(),
-                                                           timestamps_["today"]);
+                                                           timestamps_["after today"]);
 
     const auto& parameters_index = parameters.get<StampedValueNameIndexTag>();
 
@@ -1120,7 +1126,7 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getModifiedGlobalParameters6) {
     // Should be able to fetct these parameters when explicitly providing
     // the server tag.
     parameters = cbptr_->getModifiedGlobalParameters6(ServerSelector::ONE("server1"),
-                                                      timestamps_["today"]);
+                                                      timestamps_["after today"]);
     EXPECT_EQ(1, parameters.size());
 }
 
@@ -1930,24 +1936,24 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getModifiedSubnets6) {
     // should be returned.
     Subnet6Collection
         subnets = cbptr_->getModifiedSubnets6(ServerSelector::ALL(),
-                                              timestamps_["today"]);
+                                              timestamps_["after today"]);
     ASSERT_EQ(1, subnets.size());
 
     // All subnets should also be returned for explicitly specified server tag.
     subnets = cbptr_->getModifiedSubnets6(ServerSelector::ONE("server1"),
-                                          timestamps_["today"]);
+                                          timestamps_["after today"]);
     ASSERT_EQ(1, subnets.size());
 
     // Fetch subnets with timestamp later than yesterday. We should get
     // two subnets.
     subnets = cbptr_->getModifiedSubnets6(ServerSelector::ALL(),
-                                          timestamps_["yesterday"]);
+                                          timestamps_["after yesterday"]);
     ASSERT_EQ(2, subnets.size());
 
     // Fetch subnets with timestamp later than tomorrow. Nothing should
     // be returned.
     subnets = cbptr_->getModifiedSubnets6(ServerSelector::ALL(),
-                                          timestamps_["tomorrow"]);
+                                          timestamps_["after tomorrow"]);
     ASSERT_TRUE(subnets.empty());
 }
 
@@ -2658,19 +2664,19 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getModifiedSharedNetworks6) {
     // shared network  should be returned.
     SharedNetwork6Collection
         networks = cbptr_->getModifiedSharedNetworks6(ServerSelector::ALL(),
-                                                      timestamps_["today"]);
+                                                      timestamps_["after today"]);
     ASSERT_EQ(1, networks.size());
 
     // Fetch shared networks with timestamp later than yesterday. We
     // should get two shared networks.
     networks = cbptr_->getModifiedSharedNetworks6(ServerSelector::ALL(),
-                                                 timestamps_["yesterday"]);
+                                                 timestamps_["after yesterday"]);
     ASSERT_EQ(2, networks.size());
 
     // Fetch shared networks with timestamp later than tomorrow. Nothing
     // should be returned.
     networks = cbptr_->getModifiedSharedNetworks6(ServerSelector::ALL(),
-                                                  timestamps_["tomorrow"]);
+                                                  timestamps_["after tomorrow"]);
     ASSERT_TRUE(networks.empty());
 }
 
@@ -3329,19 +3335,19 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getModifiedOptionDefs6) {
     // option definition should be returned.
     OptionDefContainer
         option_defs = cbptr_->getModifiedOptionDefs6(ServerSelector::ALL(),
-                                                     timestamps_["today"]);
+                                                     timestamps_["after today"]);
     ASSERT_EQ(1, option_defs.size());
 
     // Fetch option definitions with timestamp later than yesterday. We
     // should get two option definitions.
     option_defs = cbptr_->getModifiedOptionDefs6(ServerSelector::ALL(),
-                                                 timestamps_["yesterday"]);
+                                                 timestamps_["after yesterday"]);
     ASSERT_EQ(2, option_defs.size());
 
     // Fetch option definitions with timestamp later than tomorrow. Nothing
     // should be returned.
     option_defs = cbptr_->getModifiedOptionDefs6(ServerSelector::ALL(),
-                                              timestamps_["tomorrow"]);
+                                              timestamps_["after tomorrow"]);
     ASSERT_TRUE(option_defs.empty());
 }
 
@@ -3679,13 +3685,13 @@ TEST_F(MySqlConfigBackendDHCPv6Test, getModifiedOptions6) {
     // one option should be returned.
     OptionContainer returned_options =
         cbptr_->getModifiedOptions6(ServerSelector::ALL(),
-                                    timestamps_["today"]);
+                                    timestamps_["after today"]);
     ASSERT_EQ(1, returned_options.size());
 
     // Fetching modified options with explicitly specified server selector
     // should return the same result.
     returned_options = cbptr_->getModifiedOptions6(ServerSelector::ONE("server1"),
-                                                   timestamps_["today"]);
+                                                   timestamps_["after today"]);
     ASSERT_EQ(1, returned_options.size());
 
     // The returned option should be the one with the timestamp
@@ -4268,4 +4274,41 @@ TEST_F(MySqlConfigBackendDHCPv6Test, sharedNetworkOptionIdOrder) {
     }
 }
 
+/// This test verifies that audit entries can be retrieved from a given
+/// timestamp and id including when two entries can get the same timestamp.
+/// (either it is a common even and this should catch it, or it is a rare
+/// event and it does not matter).
+TEST_F(MySqlConfigBackendDHCPv6Test, multipleAuditEntries) {
+    // Get current time.
+    boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
+
+    // Create a server.
+    EXPECT_NO_THROW(cbptr_->createUpdateServer6(test_servers_[1]));
+
+    // Create a global parameter and update it many times.
+    const ServerSelector& server_selector = ServerSelector::ALL();
+    StampedValuePtr param;
+    ElementPtr value;
+    for (int i = 0; i < 100; ++i) {
+        value = Element::create(i);
+        param = StampedValue::create("my-parameter", value);
+        cbptr_->createUpdateGlobalParameter6(server_selector, param);
+    }
+
+    // Get all audit entries from now.
+    AuditEntryCollection audit_entries =
+        cbptr_->getRecentAuditEntries(server_selector, now, 0);
+
+    // Check that partial retrieves return the right count.
+    auto& mod_time_idx = audit_entries.get<AuditEntryModificationTimeIdTag>();
+    for (auto it = mod_time_idx.begin(); it != mod_time_idx.end(); ++it) {
+        size_t partial_size =
+            cbptr_->getRecentAuditEntries(server_selector,
+                                          (*it)->getModificationTime(),
+                                          (*it)->getModificationId()).size();
+        EXPECT_EQ(partial_size + 1,
+                  std::distance(it, mod_time_idx.end()));
+    }
+}
+
 }