]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
test: ceph_test_rados_io_sequence - add append with gaps sequence
authorBill Scales <bill_scales@uk.ibm.com>
Fri, 29 Nov 2024 11:12:40 +0000 (11:12 +0000)
committerAlex Ainscow <aainscow@uk.ibm.com>
Wed, 5 Mar 2025 08:59:17 +0000 (08:59 +0000)
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 <bill_scales@uk.ibm.com>
src/common/io_exerciser/DataGenerator.cc
src/common/io_exerciser/DataGenerator.h
src/common/io_exerciser/EcIoSequence.cc
src/common/io_exerciser/IoSequence.cc
src/common/io_exerciser/IoSequence.h
src/common/io_exerciser/ObjectModel.cc

index 701c32fa9ec21bace5348f25d3ed34be3ba19bd6..20acb03bb1bbc3cd97b62ebb7880d6401ce610f0 100644 (file)
@@ -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(), &current_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(), &current_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
+}
index c497c78ed614a0367ac688676838358aceaabe12..dd99c23fe042f767613cc2f97874fb2c44bd3ca6 100644 (file)
@@ -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;
 
index f2e5804dc02199f614e2574698b94a025483060c..8eb5e4defcb6f421911c58989e707830c1b51665 100644 (file)
@@ -37,6 +37,8 @@ std::unique_ptr<IoSequence> EcIoSequence::generate_sequence(
     case Sequence::SEQUENCE_SEQ11:
       [[fallthrough]];
     case Sequence::SEQUENCE_SEQ12:
+      [[fallthrough]];
+    case Sequence::SEQUENCE_SEQ13:
       return std::make_unique<ReadInjectSequence>(obj_size_range, seed,
                                                   sequence, k, m);
     case Sequence::SEQUENCE_SEQ10:
index b49d31b6e1cd187a081ef2c43ed18ac36ba43654..a5d316f5d0c677615e2bc9b8f8d71aaaf3579985 100644 (file)
@@ -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> IoSequence::generate_sequence(
       return std::make_unique<Seq11>(obj_size_range, seed);
     case Sequence::SEQUENCE_SEQ12:
       return std::make_unique<Seq12>(obj_size_range, seed);
+    case Sequence::SEQUENCE_SEQ13:
+      return std::make_unique<Seq13>(obj_size_range, seed);
     default:
       break;
   }
@@ -594,3 +599,40 @@ std::unique_ptr<ceph::io_exerciser::IoOp> ceph::io_exerciser::Seq12::_next() {
   return SingleWriteOp::generate((count * obj_size) - overlap,
                                  obj_size + overlap);
 }
+
+ceph::io_exerciser::Seq13::Seq13(std::pair<int, int> 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::IoOp> 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);
+}
index 001468736e2028cb381272b7c72c69be888eef42..28b1618da2bb88c36db481fbb8c0082a8781fe46 100644 (file)
@@ -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<IoOp> _next() override;
 };
+
+class Seq13 : public IoSequence {
+ private:
+  uint64_t count;
+  uint64_t gap;
+  bool doneread = true;
+  bool donebarrier = false;
+
+ public:
+  Seq13(std::pair<int, int> obj_size_range, int seed);
+
+  Sequence get_id() const override;
+  std::string get_name() const override;
+  std::unique_ptr<IoOp> _next() override;
+};
 }  // namespace io_exerciser
 }  // namespace ceph
index edb7f9367f9b847615b0e53380366934dadaf429..95708e33cae8d11ce1f4bed57d03e41d83937df1 100644 (file)
@@ -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<int>::max());
+  };
 
   auto verify_and_record_read_op =
       [&contents = contents, &created = created, &num_io = num_io,