From 132d0db633949a46766e16897834f68c30b3a139 Mon Sep 17 00:00:00 2001 From: Alex Ainscow Date: Tue, 21 Oct 2025 14:29:29 +0100 Subject: [PATCH] test/librados: Add testcase handlers to look at stats and check split_ops Signed-off-by: Alex Ainscow --- src/test/librados/testcase_cxx.cc | 45 ++++++++++++++++++++--- src/test/librados/testcase_cxx.h | 59 ++++++++++++++++++++++++++----- 2 files changed, 91 insertions(+), 13 deletions(-) diff --git a/src/test/librados/testcase_cxx.cc b/src/test/librados/testcase_cxx.cc index dc5163494a6..916aadefc26 100644 --- a/src/test/librados/testcase_cxx.cc +++ b/src/test/librados/testcase_cxx.cc @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -13,6 +14,9 @@ #include "crimson_utils.h" #include "include/scope_guard.h" +#include "common/ceph_context.h" +#include "common/perf_counters_collection.h" + using namespace librados; namespace { @@ -274,7 +278,6 @@ void RadosTestPPBase::cleanup_namespace(librados::IoCtx ioctx, std::string ns) std::string RadosTestParamPP::pool_name; std::string RadosTestParamPP::cache_pool_name; -Rados RadosTestParamPP::s_cluster; void RadosTestParamPP::SetUpTestCase() { @@ -370,7 +373,6 @@ void RadosTestParamPP::cleanup_namespace(librados::IoCtx ioctx, std::string ns) std::string RadosTestECPP::pool_name_default; std::string RadosTestECPP::pool_name_fast; std::string RadosTestECPP::pool_name_fast_split; -Rados RadosTestECPP::s_cluster; void RadosTestECPP::SetUpTestCase() { @@ -399,8 +401,8 @@ void RadosTestECPP::SetUp() { SKIP_IF_CRIMSON(); const auto& params = GetParam(); - bool fast_ec = std::get<0>(params); - bool split_ops = std::get<1>(params); + fast_ec = std::get<0>(params); + split_ops = std::get<1>(params); if (fast_ec && split_ops) { pool_name = pool_name_fast_split; } else if (fast_ec) { @@ -456,3 +458,38 @@ void RadosTestECPP::set_allow_ec_overwrites() std::this_thread::sleep_for(std::chrono::seconds(2)); } } + +uint64_t RadosTestPPBase::get_perf_counter_by_path(std::string_view path) { + CephContext* cct = (CephContext*)cluster.cct(); + PerfCountersCollection *coll = cct->get_perfcounters_collection(); + + std::stringstream ss; + bool found = false; + + uint64_t value = 0; + coll->with_counters([&](const auto& counter_map) { + auto it = counter_map.find(std::string(path)); + if (it != counter_map.end()) { + value = it->second.data->u64.load(); + found = true; + } + }); + + if (!found) { + ss << "Performance counter not found: '" << path << "'.\n"; + ss << "Available counters are:\n"; + coll->with_counters([&](const auto& counter_map) { + if (counter_map.empty()) { + ss << " (The collection is empty, check initialization timing)"; + } else { + for (const auto& pair : counter_map) { + ss << " - " << pair.first << "\n"; + } + } + }); + + throw(std::range_error(ss.str())); + } + + return value; +} \ No newline at end of file diff --git a/src/test/librados/testcase_cxx.h b/src/test/librados/testcase_cxx.h index ea3b42cc3fc..1fb16ff9a21 100644 --- a/src/test/librados/testcase_cxx.h +++ b/src/test/librados/testcase_cxx.h @@ -3,9 +3,13 @@ #pragma once +#include + #include "gtest/gtest.h" #include "include/rados/librados.hpp" +using namespace std::literals::string_view_literals; + class RadosTestPPNS : public ::testing::Test { public: RadosTestPPNS(bool c=false) : cluster(s_cluster), cleanup(c) {} @@ -76,8 +80,49 @@ public: protected: static librados::Rados s_cluster; librados::Rados &cluster; + librados::IoCtx ioctx; + bool split_ops = false; + static void cleanup_default_namespace(librados::IoCtx ioctx); static void cleanup_namespace(librados::IoCtx ioctx, std::string ns); + + uint64_t get_perf_counter_by_path(std::string_view path); + + template + ::testing::AssertionResult AssertOperateSplitOp(bool splits, int rc, Args... args) + { + auto split_op_stat = "objecter.split_op_reads"sv; + int64_t before_count = get_perf_counter_by_path(split_op_stat); + + // Perform the I/O operation + int ret = ioctx.operate(std::forward(args)...); + if (ret != rc) { + return ::testing::AssertionFailure() + << "ioctx.operate() Incorrect rc " << rc << " != " << ret; + } + + int64_t actual_count = get_perf_counter_by_path(split_op_stat); + int64_t expected_count = before_count + ((splits && split_ops) ? 1 : 0); + + if (actual_count == expected_count) { + return ::testing::AssertionSuccess(); + } + + return ::testing::AssertionFailure() + << "Perf counter '" << split_op_stat << "' has incorrect value after operate().\n" + << " Expected: " << expected_count + << " (before: " << before_count << ", split_ops: " << split_ops << ")\n" + << " Actual: " << actual_count; + } + + template + ::testing::AssertionResult AssertOperateWithSplitOp(int rc, Args... args) { + return AssertOperateSplitOp(true, rc, std::forward(args)...); + } + template + ::testing::AssertionResult AssertOperateWithoutSplitOp(int rc, Args... args) { + return AssertOperateSplitOp(false, rc, std::forward(args)...); + } }; class RadosTestPP : public RadosTestPPBase, public ::testing::Test { @@ -96,23 +141,21 @@ protected: std::string nspace; }; -class RadosTestParamPP : public ::testing::TestWithParam { +class RadosTestParamPP : public RadosTestPPBase, + public ::testing::TestWithParam { public: - RadosTestParamPP(bool c=false) : cluster(s_cluster), cleanup(c) {} + RadosTestParamPP(bool c=false) : cleanup(c) {} ~RadosTestParamPP() override {} static void SetUpTestCase(); static void TearDownTestCase(); protected: static void cleanup_default_namespace(librados::IoCtx ioctx); static void cleanup_namespace(librados::IoCtx ioctx, std::string ns); - static librados::Rados s_cluster; static std::string pool_name; static std::string cache_pool_name; void SetUp() override; void TearDown() override; - librados::Rados &cluster; - librados::IoCtx ioctx; bool cleanup; std::string nspace; }; @@ -121,13 +164,12 @@ class RadosTestECPP : public RadosTestPPBase, public ::testing::TestWithParam> { bool ec_overwrites_set = false; public: - RadosTestECPP(bool c=false) : cluster(s_cluster), cleanup(c) {} + RadosTestECPP(bool c=false) : cleanup(c) {} ~RadosTestECPP() override {} protected: static void SetUpTestCase(); static void TearDownTestCase(); void set_allow_ec_overwrites(); - static librados::Rados s_cluster; static std::string pool_name_default; static std::string pool_name_fast; static std::string pool_name_fast_split; @@ -135,9 +177,8 @@ protected: std::string pool_name; void SetUp() override; void TearDown() override; - librados::Rados &cluster; - librados::IoCtx ioctx; bool cleanup; std::string nspace; uint64_t alignment = 0; + bool fast_ec = false; }; -- 2.39.5