]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
test: Add option to select data generation type 65917/head
authorMatty Williams <Matty.Williams@ibm.com>
Mon, 13 Oct 2025 14:55:55 +0000 (15:55 +0100)
committerMatty Williams <Matty.Williams@ibm.com>
Tue, 31 Mar 2026 09:59:50 +0000 (10:59 +0100)
New command line argument for ceph_test_rados_io_sequence to specify the DataGenerator class that you wish to use to generate data for write IOs.

Fixes: https://tracker.ceph.com/issues/73525
Signed-off-by: Matty Williams <Matty.Williams@ibm.com>
src/common/io_exerciser/RadosIo.cc
src/common/io_exerciser/RadosIo.h
src/test/osd/ceph_test_rados_io_sequence/ceph_test_rados_io_sequence.cc
src/test/osd/ceph_test_rados_io_sequence/ceph_test_rados_io_sequence.h

index bd9e021beca43b5914704f664638a9a3c7ad5ef7..6881a4ccc3c3495236056acecf42fbd47eb03974 100644 (file)
@@ -17,6 +17,8 @@
 using RadosIo = ceph::io_exerciser::RadosIo;
 using ConsistencyChecker = ceph::consistency::ConsistencyChecker;
 
+using GenerationType = ceph::io_exerciser::data_generation::GenerationType;
+
 namespace {
 template <typename S>
 int send_osd_command(int osd, S& s, librados::Rados& rados, const char* name,
@@ -47,14 +49,14 @@ RadosIo::RadosIo(librados::Rados& rados, boost::asio::io_context& asio,
                  const std::string& pool, const std::string& primary_oid, const std::string& secondary_oid,
                  uint64_t block_size, int seed, int threads, ceph::mutex& lock,
                  ceph::condition_variable& cond, bool is_replicated_pool,
-                 bool ec_optimizations, std::shared_ptr<ceph::io_exerciser::IoSequence> seq,
-                 bool delete_objects)
+                 bool ec_optimizations, GenerationType data_generation_type,
+                 std::shared_ptr<ceph::io_exerciser::IoSequence> seq, bool delete_objects)
     : Model(primary_oid, secondary_oid, block_size, delete_objects),
       rados(rados),
       asio(asio),
       om(std::make_unique<ObjectModel>(primary_oid, secondary_oid, block_size, seed, delete_objects)),
       db(data_generation::DataGenerator::create_generator(
-          data_generation::GenerationType::HeaderedSeededRandom, *om)),
+          data_generation_type, *om)),
       pool(pool),
       threads(threads),
       lock(lock),
index c16187b518499e7b9058d2b07a4035d891752c3f..5ed082b593dd12d439a2236d4de18a31eaf63d7b 100644 (file)
@@ -23,6 +23,7 @@ namespace ceph {
 namespace io_exerciser {
 namespace data_generation {
 class DataGenerator;
+enum class GenerationType;
 }
 
 class RadosIo : public Model {
@@ -49,8 +50,8 @@ class RadosIo : public Model {
           const std::string& pool, const std::string& primary_oid, const std::string& secondary_oid,
           uint64_t block_size, int seed, int threads, ceph::mutex& lock,
           ceph::condition_variable& cond, bool is_replicated_pool,
-          bool ec_optimizations, std::shared_ptr<ceph::io_exerciser::IoSequence> seq = nullptr,
-          bool delete_objects = true);
+          bool ec_optimizations, ceph::io_exerciser::data_generation::GenerationType data_generation_type,
+          std::shared_ptr<ceph::io_exerciser::IoSequence> seq = nullptr, bool delete_objects = true);
 
   ~RadosIo();
 
index e9f86c4d769ce6a11f15218559ac4b1d3708c600..d7540919f3f70d4a51036bb6844a1c868a5cfdc7 100644 (file)
@@ -55,6 +55,8 @@ using SingleFailedWriteOp = ceph::io_exerciser::SingleFailedWriteOp;
 using DoubleFailedWriteOp = ceph::io_exerciser::DoubleFailedWriteOp;
 using TripleFailedWriteOp = ceph::io_exerciser::TripleFailedWriteOp;
 
+using GenerationType = ceph::io_exerciser::data_generation::GenerationType;
+
 namespace {
 struct Size {};
 void validate(boost::any& v, const std::vector<std::string>& values,
@@ -222,11 +224,30 @@ po::options_description get_options_description() {
       " may be removed. at a later date. Disabled by default if ec optimized")(
       "dont_delete_objects",
       "Stops the IO exerciser from deleting the object it was running the test "
-      "against once the test finishes. Does not affect interactive mode");
+      "against once the test finishes. Does not affect interactive mode")(
+      "data_generation_type", po::value<std::string>(),
+      "Data generation type to use for write IOs. Default is HeaderedSeededRandom");
 
   return desc;
 }
 
+GenerationType parse_data_generation_type(po::variables_map& vm) {
+  if (!vm.contains("data_generation_type")) {
+    // Default value
+    return GenerationType::HeaderedSeededRandom;
+  }
+
+  std::string data_generation_type = vm["data_generation_type"].as<std::string>();
+  if (data_generation_type == "HeaderedSeededRandom") {
+    return GenerationType::HeaderedSeededRandom;
+  } else if (data_generation_type == "SeededRandom") {
+    return GenerationType::SeededRandom;
+  } else {
+    throw std::invalid_argument(
+      fmt::format("Unrecognised data generation type: {}", data_generation_type));
+  }
+}
+
 int parse_io_seq_options(po::variables_map& vm, int argc, char** argv) {
   std::vector<std::string> unrecognized_options;
   try {
@@ -1039,9 +1060,11 @@ ceph::io_sequence::tester::TestObject::TestObject(
     SelectObjectSize& sos, SelectNumThreads& snt, SelectSeqRange& ssr,
     std::mt19937_64& rng, ceph::mutex& lock,
     ceph::condition_variable& cond, bool dryrun, bool verbose,
-    std::optional<int> seqseed, bool testrecovery, bool checkconsistency, bool delete_objects)
-    : rng(rng), verbose(verbose), seqseed(seqseed), testrecovery(testrecovery), checkconsistency(checkconsistency),
-      delete_objects(delete_objects) {
+    std::optional<int> seqseed, bool testrecovery, bool checkconsistency,
+    bool delete_objects, GenerationType data_generation_type)
+    : rng(rng), verbose(verbose), seqseed(seqseed), testrecovery(testrecovery),
+      checkconsistency(checkconsistency), delete_objects(delete_objects),
+      data_generation_type(data_generation_type) {
   if (dryrun) {
     int model_seed = rng();
     exerciser_model = std::make_unique<ceph::io_exerciser::ObjectModel>(
@@ -1067,7 +1090,7 @@ ceph::io_sequence::tester::TestObject::TestObject(
     exerciser_model = std::make_unique<ceph::io_exerciser::RadosIo>(
         rados, asio, pool, primary_oid, secondary_oid, sbs.select(), model_seed,
         threads, lock, cond, spo.is_replicated_pool(),
-        spo.get_allow_pool_ec_optimizations(), seq, delete_objects);
+        spo.get_allow_pool_ec_optimizations(), data_generation_type, seq, delete_objects);
     dout(0) << "= " << primary_oid << " pool=" << pool << " threads=" << threads
             << " blocksize=" << exerciser_model->get_block_size() << " ="
             << dendl;
@@ -1170,6 +1193,8 @@ ceph::io_sequence::tester::TestRunner::TestRunner(
   dryrun = vm.contains("dryrun");
   delete_objects = !vm.contains("dont_delete_objects");
 
+  data_generation_type = parse_data_generation_type(vm);
+
   seqseed = std::nullopt;
   if (vm.contains("seqseed")) {
     seqseed = vm["seqseed"].as<int>();
@@ -1337,7 +1362,8 @@ bool ceph::io_sequence::tester::TestRunner::run_interactive_test() {
         rados, asio, pool, primary_object_name, secondary_object_name, sbs.select(), model_seed,
         1,  // 1 thread
         lock, cond, spo.is_replicated_pool(),
-        spo.get_allow_pool_ec_optimizations());
+        spo.get_allow_pool_ec_optimizations(),
+        data_generation_type);
   }
 
   while (!done) {
@@ -1493,7 +1519,8 @@ bool ceph::io_sequence::tester::TestRunner::run_automated_test() {
       test_objects.push_back(
           std::make_shared<ceph::io_sequence::tester::TestObject>(
               primary_name, secondary_name, rados, asio, sbs, spo, sos, snt, ssr, rng, lock, cond,
-              dryrun, verbose, seqseed, testrecovery, checkconsistency, delete_objects));
+              dryrun, verbose, seqseed, testrecovery, checkconsistency,
+              delete_objects, data_generation_type));
     }
     catch (const std::runtime_error &e) {
       std::cerr << "Error: " << e.what() << std::endl;
index 02487b47c0e457e4bcdde68e018eea143d2ec128..b5a6a111dd68487c0c8c3e6ccbc50797a22d7685 100644 (file)
@@ -6,6 +6,7 @@
 #include <utility>
 
 #include "ProgramOptionReader.h"
+#include "common/io_exerciser/DataGenerator.h"
 #include "common/io_exerciser/IoOp.h"
 #include "common/io_exerciser/IoSequence.h"
 #include "common/io_exerciser/Model.h"
@@ -16,6 +17,8 @@
 #include "include/random.h"
 #include "librados/librados_asio.h"
 
+using GenerationType = ceph::io_exerciser::data_generation::GenerationType;
+
 /* Overview
  *
  * class SelectObjectSize
@@ -462,7 +465,8 @@ class TestObject {
              std::optional<int> seqseed,
              bool testRecovery,
              bool checkConsistency,
-             bool delete_objects);
+             bool delete_objects,
+             GenerationType data_generation_type);
 
   int get_num_io();
   bool readyForIo();
@@ -487,6 +491,7 @@ class TestObject {
   bool testrecovery;
   bool checkconsistency;
   bool delete_objects;
+  GenerationType data_generation_type;
 };
 
 class TestRunner {
@@ -540,6 +545,8 @@ class TestRunner {
   std::string primary_object_name;
   std::string secondary_object_name;
 
+  GenerationType data_generation_type;
+
   std::string line;
   ceph::split split = ceph::split("");
   ceph::spliterator tokens;