This is an automated email from the ASF dual-hosted git repository.

wangdan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pegasus.git


The following commit(s) were added to refs/heads/master by this push:
     new 18e8aeb74 test: enable validation logic in debug-only code to run 
during unit tests (#2262)
18e8aeb74 is described below

commit 18e8aeb744228a01247fe3970e375785ddcda4db
Author: Dan Wang <wang...@apache.org>
AuthorDate: Tue Jul 1 19:01:07 2025 +0800

    test: enable validation logic in debug-only code to run during unit tests 
(#2262)
    
    In Pegasus, unit tests are not necessarily executed in debug mode (i.e., 
with the
    `NDEBUG` macro undefined). For example, the GitHub CI workflow builds and
    runs unit tests in release mode. As a result, certain test-related code 
paths that
    are only enabled in debug builds are not actually executed during CI 
testing.
    
    To address this, we now allow such debug-only validation logic to be 
compiled
    and executed when building test code (i.e., executing `./run.sh build 
--test` where
    `--test` defines the `MOCK_TEST` macro). This ensures that debug-mode test
    logic is included and exercised during unit test runs, improving test 
coverage in
    CI and other environments.
---
 src/meta/server_state.cpp      |  7 ++--
 src/rpc/dsn_message_parser.cpp | 79 ++++++++++++++++++++++--------------------
 src/server/result_writer.cpp   |  1 -
 src/task/task_worker.cpp       | 10 +++---
 src/utils/alloc.h              |  9 +++--
 src/utils/blob.h               |  8 +++--
 src/utils/errors.h             |  2 +-
 src/utils/fmt_logging.h        |  5 +++
 src/utils/test/blob_test.cpp   |  4 ---
 9 files changed, 70 insertions(+), 55 deletions(-)

diff --git a/src/meta/server_state.cpp b/src/meta/server_state.cpp
index 1b1257a88..4e504ff24 100644
--- a/src/meta/server_state.cpp
+++ b/src/meta/server_state.cpp
@@ -1829,9 +1829,11 @@ void server_state::update_configuration_locally(
             ns = get_node_state(_nodes, node, false);
             CHECK_NOTNULL(ns, "invalid node: {}", node);
         }
-#ifndef NDEBUG
+
+#if defined(MOCK_TEST) || !defined(NDEBUG)
         request_check(old_pc, *config_request);
 #endif
+
         switch (config_request->type) {
         case config_type::CT_ASSIGN_PRIMARY:
         case config_type::CT_UPGRADE_TO_PRIMARY:
@@ -1940,9 +1942,10 @@ void server_state::update_configuration_locally(
                  boost::lexical_cast<std::string>(*config_request));
     }
 
-#ifndef NDEBUG
+#if defined(MOCK_TEST) || !defined(NDEBUG)
     check_consistency(gpid);
 #endif
+
     if (_config_change_subscriber) {
         _config_change_subscriber(_all_apps);
     }
diff --git a/src/rpc/dsn_message_parser.cpp b/src/rpc/dsn_message_parser.cpp
index 178a60273..d475318b5 100644
--- a/src/rpc/dsn_message_parser.cpp
+++ b/src/rpc/dsn_message_parser.cpp
@@ -26,9 +26,10 @@
 
 #include "dsn_message_parser.h"
 
-#include <stddef.h>
-#include <stdint.h>
+#include <cstddef>
+#include <cstdint>
 #include <memory>
+#include <numeric>
 #include <vector>
 
 #include "rpc/rpc_message.h"
@@ -102,50 +103,52 @@ message_ex 
*dsn_message_parser::get_message_on_receive(message_reader *reader,
 void dsn_message_parser::prepare_on_send(message_ex *msg)
 {
     auto &header = msg->header;
-    auto &buffers = msg->buffers;
-
-#ifndef NDEBUG
-    int i_max = (int)buffers.size() - 1;
-    size_t len = 0;
-    for (int i = 0; i <= i_max; i++) {
-        len += (size_t)buffers[i].length();
+    const auto &buffers = msg->buffers;
+
+#if defined(MOCK_TEST) || !defined(NDEBUG)
+    {
+        const size_t len =
+            std::accumulate(buffers.begin(), buffers.end(), 0UL, [](size_t 
sum, const auto &buf) {
+                return sum + buf.length();
+            });
+        CHECK_EQ(len, header->body_length + sizeof(message_header));
     }
-    CHECK_EQ(len, header->body_length + sizeof(message_header));
 #endif
 
-    if (task_spec::get(msg->local_rpc_code)->rpc_message_crc_required) {
-        // compute data crc if necessary (only once for the first time)
-        if (header->body_crc32 == CRC_INVALID) {
-            int i_max = (int)buffers.size() - 1;
-            uint32_t crc32 = 0;
-            size_t len = 0;
-            for (int i = 0; i <= i_max; i++) {
-                uint32_t lcrc;
-                const void *ptr;
-                size_t sz;
-
-                if (i == 0) {
-                    ptr = (const void *)(buffers[i].data() + 
sizeof(message_header));
-                    sz = (size_t)buffers[i].length() - sizeof(message_header);
-                } else {
-                    ptr = (const void *)buffers[i].data();
-                    sz = (size_t)buffers[i].length();
-                }
-
-                lcrc = dsn::utils::crc32_calc(ptr, sz, crc32);
-                crc32 = dsn::utils::crc32_concat(0, 0, crc32, len, crc32, 
lcrc, sz);
-
-                len += sz;
+    if (!task_spec::get(msg->local_rpc_code)->rpc_message_crc_required) {
+        return;
+    }
+
+    // compute data crc if necessary (only once for the first time)
+    if (header->body_crc32 == CRC_INVALID) {
+        uint32_t crc32 = 0;
+        size_t len = 0;
+
+        for (size_t i = 0; i < buffers.size(); ++i) {
+            const auto &buf = buffers[i];
+            const char *ptr = buf.data();
+            size_t sz = buf.length();
+
+            if (i == 0) {
+                ptr += sizeof(message_header);
+
+                // TODO(wangdan): CHECK_GE(sz, sizeof(message_header)) ?
+                sz -= sizeof(message_header);
             }
 
-            CHECK_EQ(len, header->body_length);
-            header->body_crc32 = crc32;
+            const auto lcrc = dsn::utils::crc32_calc(ptr, sz, crc32);
+            crc32 = dsn::utils::crc32_concat(0, 0, crc32, len, crc32, lcrc, 
sz);
+
+            len += sz;
         }
 
-        // always compute header crc
-        header->hdr_crc32 = CRC_INVALID;
-        header->hdr_crc32 = dsn::utils::crc32_calc(header, 
sizeof(message_header), 0);
+        CHECK_EQ(len, header->body_length);
+        header->body_crc32 = crc32;
     }
+
+    // always compute header crc
+    header->hdr_crc32 = CRC_INVALID;
+    header->hdr_crc32 = dsn::utils::crc32_calc(header, sizeof(message_header), 
0);
 }
 
 int dsn_message_parser::get_buffers_on_send(message_ex *msg, /*out*/ send_buf 
*buffers)
diff --git a/src/server/result_writer.cpp b/src/server/result_writer.cpp
index df78172e9..4d3a9160e 100644
--- a/src/server/result_writer.cpp
+++ b/src/server/result_writer.cpp
@@ -21,7 +21,6 @@
 
 #include <pegasus/error.h>
 #include <chrono>
-#include <type_traits>
 #include <utility>
 
 #include "pegasus/client.h"
diff --git a/src/task/task_worker.cpp b/src/task/task_worker.cpp
index 01fec9887..d5606d2a8 100644
--- a/src/task/task_worker.cpp
+++ b/src/task/task_worker.cpp
@@ -236,20 +236,22 @@ void task_worker::loop()
 
         q->decrease_count(batch_size);
 
-#ifndef NDEBUG
+#if defined(MOCK_TEST) || !defined(NDEBUG)
         int count = 0;
 #endif
+
         while (task != nullptr) {
             next = task->next;
             task->next = nullptr;
             task->exec_internal();
             task = next;
-#ifndef NDEBUG
-            count++;
+
+#if defined(MOCK_TEST) || !defined(NDEBUG)
+            ++count;
 #endif
         }
 
-#ifndef NDEBUG
+#if defined(MOCK_TEST) || !defined(NDEBUG)
         CHECK_EQ_MSG(count, batch_size, "returned task count and batch size do 
not match");
 #endif
 
diff --git a/src/utils/alloc.h b/src/utils/alloc.h
index fdb799117..fa078cd8c 100644
--- a/src/utils/alloc.h
+++ b/src/utils/alloc.h
@@ -30,8 +30,13 @@
 // where CACHELINE_SIZE is defined.
 #ifdef CACHELINE_SIZE
 
-#ifndef NDEBUG
+#if defined(MOCK_TEST) || !defined(NDEBUG)
+
+#include <cstdint>
+#include <fmt/format.h>
+
 #include "utils/fmt_logging.h"
+
 #endif
 
 namespace dsn {
@@ -53,7 +58,7 @@ cacheline_aligned_ptr<T> cacheline_aligned_alloc_array(size_t 
len)
 
     T *array = new (buffer) T[len];
 
-#ifndef NDEBUG
+#if defined(MOCK_TEST) || !defined(NDEBUG)
     if (sizeof(T) <= CACHELINE_SIZE && (sizeof(T) & (sizeof(T) - 1)) == 0) {
         for (size_t i = 0; i < len; ++i) {
             T *elem = &(array[i]);
diff --git a/src/utils/blob.h b/src/utils/blob.h
index c1212afb4..d07ac7df5 100644
--- a/src/utils/blob.h
+++ b/src/utils/blob.h
@@ -114,9 +114,11 @@ public:
     /// NOTE: this operation is not efficient since it involves a memory copy.
     [[nodiscard]] static blob create_from_bytes(const char *s, size_t len)
     {
-        DCHECK(s != nullptr || len == 0,
-               "null source pointer with non-zero length would lead to "
-               "undefined behaviour");
+#if defined(MOCK_TEST) || !defined(NDEBUG)
+        CHECK(s != nullptr || len == 0,
+              "null source pointer with non-zero length would lead to "
+              "undefined behaviour");
+#endif
 
         std::shared_ptr<char> s_arr(new char[len], 
std::default_delete<char[]>());
         memcpy(s_arr.get(), s, len);
diff --git a/src/utils/errors.h b/src/utils/errors.h
index d262f2241..36b99d070 100644
--- a/src/utils/errors.h
+++ b/src/utils/errors.h
@@ -294,7 +294,7 @@ USER_DEFINED_STRUCTURE_FORMATTER(::dsn::error_s);
         }                                                                      
                    \
     } while (false)
 
-#ifndef NDEBUG
+#if defined(MOCK_TEST) || !defined(NDEBUG)
 #define DCHECK_OK CHECK_OK
 #else
 #define DCHECK_OK(s, ...)
diff --git a/src/utils/fmt_logging.h b/src/utils/fmt_logging.h
index 97e751a48..6360bbfb9 100644
--- a/src/utils/fmt_logging.h
+++ b/src/utils/fmt_logging.h
@@ -324,6 +324,11 @@ inline const char *null_str_printer(const char *s) { 
return s == nullptr ? "(nul
         }                                                                      
                    \
     } while (0)
 
+// TODO(wangdan): currently enable `DCHECK` for test code (via `MOCK_TEST`) 
causes many unit
+// tests to fail; it will be enabled after the issues are resolved.
+//
+// After resolved, enable `DCHECK` for test code by:
+// #if defined(MOCK_TEST) || !defined(NDEBUG)
 #ifndef NDEBUG
 #define DCHECK CHECK
 #define DCHECK_NOTNULL CHECK_NOTNULL
diff --git a/src/utils/test/blob_test.cpp b/src/utils/test/blob_test.cpp
index 586a7d68d..37a7f502d 100644
--- a/src/utils/test/blob_test.cpp
+++ b/src/utils/test/blob_test.cpp
@@ -32,8 +32,6 @@ TEST(BlobTest, CreateFromZeroLengthNullptr)
     EXPECT_EQ(0, obj.size());
 }
 
-#ifndef NDEBUG
-
 TEST(BlobTest, CreateFromNonZeroLengthNullptr)
 {
     ASSERT_DEATH({ const auto &obj = blob::create_from_bytes(nullptr, 1); },
@@ -41,8 +39,6 @@ TEST(BlobTest, CreateFromNonZeroLengthNullptr)
                  "undefined behaviour");
 }
 
-#endif
-
 struct blob_base_case
 {
     std::string expected_str;


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@pegasus.apache.org
For additional commands, e-mail: commits-h...@pegasus.apache.org

Reply via email to