From fff72a05b65d30c69fba9c83a38606497723ac1c Mon Sep 17 00:00:00 2001 From: Bill Scales Date: Fri, 29 Nov 2024 11:12:40 +0000 Subject: [PATCH] test: ceph_test_rados_io_sequence - add append with gaps sequence New I/O sequence - appends to objects by writing past the old object length so there is a gap before the new written data. Tests permutations of write length and gap length. Signed-off-by: Bill Scales --- src/common/io_exerciser/DataGenerator.cc | 52 +++++++++++++----------- src/common/io_exerciser/DataGenerator.h | 2 + src/common/io_exerciser/EcIoSequence.cc | 2 + src/common/io_exerciser/IoSequence.cc | 42 +++++++++++++++++++ src/common/io_exerciser/IoSequence.h | 16 ++++++++ src/common/io_exerciser/ObjectModel.cc | 4 +- 6 files changed, 94 insertions(+), 24 deletions(-) diff --git a/src/common/io_exerciser/DataGenerator.cc b/src/common/io_exerciser/DataGenerator.cc index 701c32fa9ec..20acb03bb1b 100644 --- a/src/common/io_exerciser/DataGenerator.cc +++ b/src/common/io_exerciser/DataGenerator.cc @@ -56,28 +56,32 @@ bool DataGenerator::validate(bufferlist& bufferlist, uint64_t offset, ceph::bufferptr SeededRandomGenerator::generate_block(uint64_t block_offset) { uint64_t block_size = m_model.get_block_size(); char buffer[block_size]; + SeedBytes seed = m_model.get_seed(block_offset); + if (seed != 0) { + std::mt19937_64 random_generator(seed); + uint64_t rand1 = random_generator(); + uint64_t rand2 = random_generator(); - std::mt19937_64 random_generator(m_model.get_seed(block_offset)); - uint64_t rand1 = random_generator(); - uint64_t rand2 = random_generator(); - - constexpr size_t generation_length = sizeof(uint64_t); + constexpr size_t generation_length = sizeof(uint64_t); - for (uint64_t i = 0; i < block_size; - i += (2 * generation_length), rand1++, rand2--) { - std::memcpy(buffer + i, &rand1, generation_length); - std::memcpy(buffer + i + generation_length, &rand2, generation_length); - } + for (uint64_t i = 0; i < block_size; + i += (2 * generation_length), rand1++, rand2--) { + std::memcpy(buffer + i, &rand1, generation_length); + std::memcpy(buffer + i + generation_length, &rand2, generation_length); + } - size_t remainingBytes = block_size % (generation_length * 2); - if (remainingBytes > generation_length) { - size_t remainingBytes2 = remainingBytes - generation_length; - std::memcpy(buffer + block_size - remainingBytes, &rand1, remainingBytes); - std::memcpy(buffer + block_size - remainingBytes2, &rand2, remainingBytes2); - } else if (remainingBytes > 0) { - std::memcpy(buffer + block_size - remainingBytes, &rand1, remainingBytes); + size_t remainingBytes = block_size % (generation_length * 2); + if (remainingBytes > generation_length) { + size_t remainingBytes2 = remainingBytes - generation_length; + std::memcpy(buffer + block_size - remainingBytes, &rand1, remainingBytes); + std::memcpy(buffer + block_size - remainingBytes2, &rand2, + remainingBytes2); + } else if (remainingBytes > 0) { + std::memcpy(buffer + block_size - remainingBytes, &rand1, remainingBytes); + } + } else { + std::memset(buffer, 0, block_size); } - return ceph::bufferptr(buffer, block_size); } @@ -159,10 +163,12 @@ ceph::bufferptr HeaderedSeededRandomGenerator::generate_block( ceph::bufferptr bufferptr = SeededRandomGenerator::generate_block(block_offset); - std::memcpy(bufferptr.c_str() + uniqueIdStart(), &unique_run_id, - uniqueIdLength()); - std::memcpy(bufferptr.c_str() + seedStart(), &seed, seedLength()); - std::memcpy(bufferptr.c_str() + timeStart(), ¤t_time, timeLength()); + if (seed != 0) { + std::memcpy(bufferptr.c_str() + uniqueIdStart(), &unique_run_id, + uniqueIdLength()); + std::memcpy(bufferptr.c_str() + seedStart(), &seed, seedLength()); + std::memcpy(bufferptr.c_str() + timeStart(), ¤t_time, timeLength()); + } return bufferptr; } @@ -650,4 +656,4 @@ void HeaderedSeededRandomGenerator ::printDebugInformationForOffsets( printDebugInformationForRange(read_offset, range_start, range_length, rangeError, bufferlist); } -} \ No newline at end of file +} diff --git a/src/common/io_exerciser/DataGenerator.h b/src/common/io_exerciser/DataGenerator.h index c497c78ed61..dd99c23fe04 100644 --- a/src/common/io_exerciser/DataGenerator.h +++ b/src/common/io_exerciser/DataGenerator.h @@ -51,6 +51,8 @@ class DataGenerator { // Used for testing debug outputs from data generation virtual bufferlist generate_wrong_data(uint64_t offset, uint64_t length); + using SeedBytes = int; + protected: const ObjectModel& m_model; diff --git a/src/common/io_exerciser/EcIoSequence.cc b/src/common/io_exerciser/EcIoSequence.cc index f2e5804dc02..8eb5e4defcb 100644 --- a/src/common/io_exerciser/EcIoSequence.cc +++ b/src/common/io_exerciser/EcIoSequence.cc @@ -37,6 +37,8 @@ std::unique_ptr EcIoSequence::generate_sequence( case Sequence::SEQUENCE_SEQ11: [[fallthrough]]; case Sequence::SEQUENCE_SEQ12: + [[fallthrough]]; + case Sequence::SEQUENCE_SEQ13: return std::make_unique(obj_size_range, seed, sequence, k, m); case Sequence::SEQUENCE_SEQ10: diff --git a/src/common/io_exerciser/IoSequence.cc b/src/common/io_exerciser/IoSequence.cc index b49d31b6e1c..a5d316f5d0c 100644 --- a/src/common/io_exerciser/IoSequence.cc +++ b/src/common/io_exerciser/IoSequence.cc @@ -46,6 +46,9 @@ std::ostream& ceph::io_exerciser::operator<<(std::ostream& os, case Sequence::SEQUENCE_SEQ12: os << "SEQUENCE_SEQ12"; break; + case Sequence::SEQUENCE_SEQ13: + os << "SEQUENCE_SEQ13"; + break; case Sequence::SEQUENCE_END: os << "SEQUENCE_END"; break; @@ -89,6 +92,8 @@ std::unique_ptr IoSequence::generate_sequence( return std::make_unique(obj_size_range, seed); case Sequence::SEQUENCE_SEQ12: return std::make_unique(obj_size_range, seed); + case Sequence::SEQUENCE_SEQ13: + return std::make_unique(obj_size_range, seed); default: break; } @@ -594,3 +599,40 @@ std::unique_ptr ceph::io_exerciser::Seq12::_next() { return SingleWriteOp::generate((count * obj_size) - overlap, obj_size + overlap); } + +ceph::io_exerciser::Seq13::Seq13(std::pair obj_size_range, int seed) + : IoSequence(obj_size_range, seed), count(0), gap(1), doneread(false) { + set_min_object_size(2); +} + +Sequence ceph::io_exerciser::Seq13::get_id() const { + return Sequence::SEQUENCE_SEQ13; +} + +std::string ceph::io_exerciser::Seq13::get_name() const { + return "Permutations of length sequential gap+append I/O"; +} + +std::unique_ptr ceph::io_exerciser::Seq13::_next() { + if (count >= 16) { + if (!doneread) { + doneread = true; + return SingleReadOp::generate(0, obj_size * (count + 1)); + } + doneread = false; + count = 0; + gap++; + if (gap >= obj_size) { + gap = 1; + return increment_object_size(); + } else { + create = true; + barrier = true; + remove = true; + return BarrierOp::generate(); + } + } + count++; + barrier = true; + return SingleWriteOp::generate((count * obj_size) + gap, obj_size - gap); +} diff --git a/src/common/io_exerciser/IoSequence.h b/src/common/io_exerciser/IoSequence.h index 001468736e2..28b1618da2b 100644 --- a/src/common/io_exerciser/IoSequence.h +++ b/src/common/io_exerciser/IoSequence.h @@ -44,6 +44,7 @@ enum class Sequence { SEQUENCE_SEQ10, SEQUENCE_SEQ11, SEQUENCE_SEQ12, + SEQUENCE_SEQ13, SEQUENCE_END, SEQUENCE_BEGIN = SEQUENCE_SEQ0 @@ -263,5 +264,20 @@ class Seq12 : public IoSequence { std::string get_name() const override; std::unique_ptr _next() override; }; + +class Seq13 : public IoSequence { + private: + uint64_t count; + uint64_t gap; + bool doneread = true; + bool donebarrier = false; + + public: + Seq13(std::pair obj_size_range, int seed); + + Sequence get_id() const override; + std::string get_name() const override; + std::unique_ptr _next() override; +}; } // namespace io_exerciser } // namespace ceph diff --git a/src/common/io_exerciser/ObjectModel.cc b/src/common/io_exerciser/ObjectModel.cc index edb7f9367f9..95708e33cae 100644 --- a/src/common/io_exerciser/ObjectModel.cc +++ b/src/common/io_exerciser/ObjectModel.cc @@ -45,7 +45,9 @@ std::string ObjectModel::to_string(int mask) const { bool ObjectModel::readyForIoOp(IoOp& op) { return true; } void ObjectModel::applyIoOp(IoOp& op) { - auto generate_random = [&rng = rng]() { return rng(); }; + auto generate_random = [&rng = rng]() { + return rng(1, std::numeric_limits::max()); + }; auto verify_and_record_read_op = [&contents = contents, &created = created, &num_io = num_io, -- 2.39.5