From acf9f8e0caeba850e65bfe796119ad9ba306d4b7 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Wed, 27 Mar 2024 14:21:51 +0000 Subject: [PATCH] test/ceph_test_rados: bring non-0 offset reads support. Signed-off-by: Radoslaw Zarzynski --- src/test/osd/Object.cc | 14 ++++++++---- src/test/osd/Object.h | 6 +++-- src/test/osd/RadosModel.h | 47 ++++++++++++++++++++++++++++++--------- src/test/osd/TestRados.cc | 9 +++++++- 4 files changed, 59 insertions(+), 17 deletions(-) diff --git a/src/test/osd/Object.cc b/src/test/osd/Object.cc index 9d914abd7944d..e9c36efd06713 100644 --- a/src/test/osd/Object.cc +++ b/src/test/osd/Object.cc @@ -125,15 +125,18 @@ void ObjectDesc::update(ContentsGenerator *gen, const ContDesc &next) { return; } -bool ObjectDesc::check(bufferlist &to_check) { +bool ObjectDesc::check(bufferlist &to_check, + const std::pair& offlen) { iterator objiter = begin(); + const auto [offset, size] = offlen; + objiter.seek(offset); + std::cout << "seeking to " << offset << std::endl; uint64_t error_at = 0; if (!objiter.check_bl_advance(to_check, &error_at)) { std::cout << "incorrect buffer at pos " << error_at << std::endl; return false; } - uint64_t size = layers.begin()->first->get_length(layers.begin()->second); if (to_check.length() < size) { std::cout << "only read " << to_check.length() << " out of size " << size << std::endl; @@ -143,11 +146,14 @@ bool ObjectDesc::check(bufferlist &to_check) { } bool ObjectDesc::check_sparse(const std::map& extents, - bufferlist &to_check) + bufferlist &to_check, + const std::pair& offlen) { + const auto [offset_to_skip, _] = offlen; + uint64_t pos = offset_to_skip; uint64_t off = 0; - uint64_t pos = 0; auto objiter = begin(); + objiter.seek(pos); for (auto &&extiter : extents) { // verify hole { diff --git a/src/test/osd/Object.h b/src/test/osd/Object.h index 76ce2d2a2fc8c..29338e814e1fc 100644 --- a/src/test/osd/Object.h +++ b/src/test/osd/Object.h @@ -517,9 +517,11 @@ public: // takes ownership of gen void update(ContentsGenerator *gen, const ContDesc &next); - bool check(bufferlist &to_check); + bool check(bufferlist &to_check, + const std::pair& offlen); bool check_sparse(const std::map& extends, - bufferlist &to_check); + bufferlist &to_check, + const std::pair& offlen); const ContDesc &most_recent(); ContentsGenerator *most_recent_gen() { return layers.begin()->first.get(); diff --git a/src/test/osd/RadosModel.h b/src/test/osd/RadosModel.h index 8bb94e7f3a049..49b7d605d3663 100644 --- a/src/test/osd/RadosModel.h +++ b/src/test/osd/RadosModel.h @@ -1355,10 +1355,12 @@ public: int snap; bool balance_reads; bool localize_reads; + uint8_t offlen_randomization_ratio; std::shared_ptr in_use; std::vector results; + std::vector> offlens; std::vector retvals; std::vector> extent_results; std::vector is_sparse_read; @@ -1382,6 +1384,7 @@ public: const std::string &oid, bool balance_reads, bool localize_reads, + uint8_t offlen_randomization_ratio, TestOpStat *stat = 0) : TestOp(n, context, stat), completions(3), @@ -1389,7 +1392,9 @@ public: snap(0), balance_reads(balance_reads), localize_reads(localize_reads), + offlen_randomization_ratio(offlen_randomization_ratio), results(3), + offlens(3), retvals(3), extent_results(3), is_sparse_read(3, false), @@ -1399,24 +1404,45 @@ public: attrretval(0) {} + static std::pair maybe_randomize_offlen( + uint8_t offlen_randomization_ratio, + uint64_t max_len) + { + if ((rand() % 100) < offlen_randomization_ratio && max_len > 0) { + // the random offset here is de dacto "first n bytes to skip in + // a chhunk" -- it doesn't care about good distrubution across + // entire object. imperfect but should be good enough for parital + // read testing. + const auto off = rand() % max_len; + return {off, max_len - off}; + } else { + return {0, max_len}; + } + } + void _do_read(librados::ObjectReadOperation& read_op, int index) { - uint64_t len = 0; - if (old_value.has_contents()) - len = old_value.most_recent_gen()->get_length(old_value.most_recent()); + uint64_t max_len = 0; + if (old_value.has_contents()) { + max_len = + old_value.most_recent_gen()->get_length(old_value.most_recent()); + } + offlens[index] = + maybe_randomize_offlen(offlen_randomization_ratio, max_len); + const auto [offset, length] = offlens[index]; if (context->no_sparse || rand() % 2) { is_sparse_read[index] = false; - read_op.read(0, - len, + read_op.read(offset, + length, &results[index], &retvals[index]); bufferlist init_value_bl; encode(static_cast(-1), init_value_bl); - read_op.checksum(LIBRADOS_CHECKSUM_TYPE_CRC32C, init_value_bl, 0, len, + read_op.checksum(LIBRADOS_CHECKSUM_TYPE_CRC32C, init_value_bl, offset, length, 0, &checksums[index], &checksum_retvals[index]); } else { is_sparse_read[index] = true; - read_op.sparse_read(0, - len, + read_op.sparse_read(offset, + length, &extent_results[index], &results[index], &retvals[index]); @@ -1576,12 +1602,12 @@ public: } for (unsigned i = 0; i < results.size(); i++) { if (is_sparse_read[i]) { - if (!old_value.check_sparse(extent_results[i], results[i])) { + if (!old_value.check_sparse(extent_results[i], results[i], offlens[i])) { std::cerr << num << ": oid " << oid << " contents " << to_check << " corrupt" << std::endl; context->errors++; } } else { - if (!old_value.check(results[i])) { + if (!old_value.check(results[i], offlens[i])) { std::cerr << num << ": oid " << oid << " contents " << to_check << " corrupt" << std::endl; context->errors++; } @@ -2176,6 +2202,7 @@ public: {} void _do_read(librados::ObjectReadOperation& read_op, uint32_t offset, uint32_t length, int index) { + std::cout << __func__ << ":" << __LINE__ << std::endl; read_op.read(offset, length, &results[index], diff --git a/src/test/osd/TestRados.cc b/src/test/osd/TestRados.cc index 876b5eb8dd744..f0acb24a3de7b 100644 --- a/src/test/osd/TestRados.cc +++ b/src/test/osd/TestRados.cc @@ -29,6 +29,7 @@ public: bool ec_pool, bool balance_reads, bool localize_reads, + uint8_t offlen_randomization_ratio, bool set_redirect, bool set_chunk, bool enable_dedup) : @@ -38,6 +39,7 @@ public: m_ec_pool(ec_pool), m_balance_reads(balance_reads), m_localize_reads(localize_reads), + m_offlen_randomization_ratio(offlen_randomization_ratio), m_set_redirect(set_redirect), m_set_chunk(set_chunk), m_enable_dedup(enable_dedup) @@ -264,7 +266,7 @@ private: case TEST_OP_READ: oid = *(rand_choose(context.oid_not_in_use)); return new ReadOp(m_op, &context, oid, m_balance_reads, m_localize_reads, - m_stats); + m_offlen_randomization_ratio, m_stats); case TEST_OP_WRITE: oid = *(rand_choose(context.oid_not_in_use)); @@ -452,6 +454,7 @@ private: bool m_ec_pool; bool m_balance_reads; bool m_localize_reads; + uint8_t m_offlen_randomization_ratio; bool m_set_redirect; bool m_set_chunk; bool m_enable_dedup; @@ -518,6 +521,7 @@ int main(int argc, char **argv) bool no_sparse = false; bool balance_reads = false; bool localize_reads = false; + uint8_t offlen_randomization_ratio = 50; bool set_redirect = false; bool set_chunk = false; bool enable_dedup = false; @@ -551,6 +555,8 @@ int main(int argc, char **argv) balance_reads = true; else if (strcmp(argv[i], "--localize-reads") == 0) localize_reads = true; + else if (strcmp(argv[i], "--offlen_randomization_ratio") == 0) + offlen_randomization_ratio = atoi(argv[++i]); else if (strcmp(argv[i], "--pool-snaps") == 0) pool_snaps = true; else if (strcmp(argv[i], "--write-fadvise-dontneed") == 0) @@ -711,6 +717,7 @@ int main(int argc, char **argv) ops, objects, op_weights, &stats, max_seconds, ec_pool, balance_reads, localize_reads, + offlen_randomization_ratio, set_redirect, set_chunk, enable_dedup); int r = context.init(); if (r < 0) { -- 2.39.5