Skip to content

Commit 03316ff

Browse files
bill-scalesaainscow
authored andcommitted
test: ceph_test_rados_io_sequence support appends
1. Add append I/O to extend size of object 2. Allow write I/Os to extend size of object 3. Make interactive mode handle EOF gracefully Signed-off-by: Bill Scales <[email protected]>
1 parent f6b9454 commit 03316ff

File tree

7 files changed

+61
-10
lines changed

7 files changed

+61
-10
lines changed

src/common/io_exerciser/IoOp.cc

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ using TripleWriteOp = ceph::io_exerciser::TripleWriteOp;
1919
using SingleFailedWriteOp = ceph::io_exerciser::SingleFailedWriteOp;
2020
using DoubleFailedWriteOp = ceph::io_exerciser::DoubleFailedWriteOp;
2121
using TripleFailedWriteOp = ceph::io_exerciser::TripleFailedWriteOp;
22+
using SingleAppendOp = ceph::io_exerciser::SingleAppendOp;
2223

2324
namespace {
2425
std::string value_to_string(uint64_t v) {
@@ -100,16 +101,21 @@ template <OpType opType, int numIOs>
100101
std::string ceph::io_exerciser::ReadWriteOp<opType, numIOs>::to_string(
101102
uint64_t block_size) const {
102103
std::string offset_length_desc;
104+
std::string length_desc;
103105
if (numIOs > 0) {
104106
offset_length_desc += fmt::format(
105107
"offset1={}", value_to_string(this->offset[0] * block_size));
106-
offset_length_desc += fmt::format(
107-
",length1={}", value_to_string(this->length[0] * block_size));
108+
length_desc += fmt::format("length1={}",
109+
value_to_string(this->length[0] * block_size));
110+
offset_length_desc += "," + length_desc;
108111
for (int i = 1; i < numIOs; i++) {
112+
std::string length;
109113
offset_length_desc += fmt::format(
110114
",offset{}={}", i + 1, value_to_string(this->offset[i] * block_size));
111-
offset_length_desc += fmt::format(
112-
",length{}={}", i + 1, value_to_string(this->length[i] * block_size));
115+
length += fmt::format(",length{}={}", i + 1,
116+
value_to_string(this->length[i] * block_size));
117+
length_desc += length;
118+
offset_length_desc += length;
113119
}
114120
}
115121
switch (opType) {
@@ -125,6 +131,8 @@ std::string ceph::io_exerciser::ReadWriteOp<opType, numIOs>::to_string(
125131
[[fallthrough]];
126132
case OpType::Write3:
127133
return fmt::format("Write{} ({})", numIOs, offset_length_desc);
134+
case OpType::Append:
135+
return fmt::format("Append{} ({})", numIOs, length_desc);
128136
case OpType::FailedWrite:
129137
[[fallthrough]];
130138
case OpType::FailedWrite2:
@@ -200,6 +208,13 @@ std::unique_ptr<TripleWriteOp> TripleWriteOp::generate(
200208
offset3, length3);
201209
}
202210

211+
SingleAppendOp::SingleAppendOp(uint64_t length)
212+
: ReadWriteOp<OpType::Append, 1>({0}, {length}) {}
213+
214+
std::unique_ptr<SingleAppendOp> SingleAppendOp::generate(uint64_t length) {
215+
return std::make_unique<SingleAppendOp>(length);
216+
}
217+
203218
SingleFailedWriteOp::SingleFailedWriteOp(uint64_t offset, uint64_t length)
204219
: ReadWriteOp<OpType::FailedWrite, 1>({offset}, {length}) {}
205220

@@ -313,4 +328,4 @@ std::unique_ptr<ceph::io_exerciser::ClearWriteErrorInjectOp>
313328
ceph::io_exerciser ::ClearWriteErrorInjectOp::generate(
314329
int shard, const std::optional<uint64_t>& type) {
315330
return std::make_unique<ClearWriteErrorInjectOp>(shard, type);
316-
}
331+
}

src/common/io_exerciser/IoOp.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,12 @@ class TripleWriteOp : public ReadWriteOp<OpType::Write3, 3> {
125125
uint64_t offset3, uint64_t length3);
126126
};
127127

128+
class SingleAppendOp : public ReadWriteOp<OpType::Append, 1> {
129+
public:
130+
SingleAppendOp(uint64_t length);
131+
static std::unique_ptr<SingleAppendOp> generate(uint64_t length);
132+
};
133+
128134
class SingleFailedWriteOp : public ReadWriteOp<OpType::FailedWrite, 1> {
129135
public:
130136
SingleFailedWriteOp(uint64_t offset, uint64_t length);

src/common/io_exerciser/ObjectModel.cc

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@ void ObjectModel::applyIoOp(IoOp& op) {
7171
ceph_assert(!reads.intersects(writeOp.offset[i], writeOp.length[i]));
7272
ceph_assert(!writes.intersects(writeOp.offset[i], writeOp.length[i]));
7373
writes.union_insert(writeOp.offset[i], writeOp.length[i]);
74-
ceph_assert(writeOp.offset[i] + writeOp.length[i] <= contents.size());
74+
if (writeOp.offset[i] + writeOp.length[i] > contents.size()) {
75+
contents.resize(writeOp.offset[i] + writeOp.length[i]);
76+
}
7577
std::generate(std::execution::seq,
7678
std::next(contents.begin(), writeOp.offset[i]),
7779
std::next(contents.begin(),
@@ -148,6 +150,14 @@ void ObjectModel::applyIoOp(IoOp& op) {
148150
TripleWriteOp& writeOp = static_cast<TripleWriteOp&>(op);
149151
verify_write_and_record_and_generate_seed(writeOp);
150152
} break;
153+
154+
case OpType::Append: {
155+
ceph_assert(created);
156+
SingleAppendOp& appendOp = static_cast<SingleAppendOp&>(op);
157+
appendOp.offset[0] = contents.size();
158+
verify_write_and_record_and_generate_seed(appendOp);
159+
} break;
160+
151161
case OpType::FailedWrite: {
152162
ceph_assert(created);
153163
SingleWriteOp& writeOp = static_cast<SingleWriteOp&>(op);
@@ -156,6 +166,7 @@ void ObjectModel::applyIoOp(IoOp& op) {
156166
case OpType::FailedWrite2: {
157167
DoubleWriteOp& writeOp = static_cast<DoubleWriteOp&>(op);
158168
verify_failed_write_and_record(writeOp);
169+
159170
} break;
160171
case OpType::FailedWrite3: {
161172
TripleWriteOp& writeOp = static_cast<TripleWriteOp&>(op);

src/common/io_exerciser/OpType.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ enum class OpType {
2323
Write, // Write
2424
Write2, // Two writes in a single op
2525
Write3, // Three writes in a single op
26+
Append, // Append
2627
FailedWrite, // A write which should fail
2728
FailedWrite2, // Two writes in one op which should fail
2829
FailedWrite3, // Three writes in one op which should fail
@@ -69,6 +70,8 @@ struct fmt::formatter<ceph::io_exerciser::OpType> {
6970
return fmt::format_to(ctx.out(), "Write2");
7071
case ceph::io_exerciser::OpType::Write3:
7172
return fmt::format_to(ctx.out(), "Write3");
73+
case ceph::io_exerciser::OpType::Append:
74+
return fmt::format_to(ctx.out(), "Append");
7275
case ceph::io_exerciser::OpType::FailedWrite:
7376
return fmt::format_to(ctx.out(), "FailedWrite");
7477
case ceph::io_exerciser::OpType::FailedWrite2:
@@ -88,4 +91,4 @@ struct fmt::formatter<ceph::io_exerciser::OpType> {
8891
return fmt::format_to(ctx.out(), "Unknown OpType");
8992
}
9093
}
91-
};
94+
};

src/common/io_exerciser/RadosIo.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ void RadosIo::applyIoOp(IoOp& op) {
171171
[[fallthrough]];
172172
case OpType::Write3:
173173
[[fallthrough]];
174+
case OpType::Append:
175+
[[fallthrough]];
174176
case OpType::FailedWrite:
175177
[[fallthrough]];
176178
case OpType::FailedWrite2:
@@ -298,6 +300,13 @@ void RadosIo::applyReadWriteOp(IoOp& op) {
298300
break;
299301
}
300302

303+
case OpType::Append: {
304+
start_io();
305+
SingleAppendOp& appendOp = static_cast<SingleAppendOp&>(op);
306+
applyWriteOp(appendOp);
307+
break;
308+
}
309+
301310
case OpType::FailedWrite: {
302311
start_io();
303312
SingleFailedWriteOp& writeOp = static_cast<SingleFailedWriteOp&>(op);

src/test/osd/ceph_test_rados_io_sequence.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ using TripleReadOp = ceph::io_exerciser::TripleReadOp;
4848
using SingleWriteOp = ceph::io_exerciser::SingleWriteOp;
4949
using DoubleWriteOp = ceph::io_exerciser::DoubleWriteOp;
5050
using TripleWriteOp = ceph::io_exerciser::TripleWriteOp;
51+
using SingleAppendOp = ceph::io_exerciser::SingleAppendOp;
5152
using SingleFailedWriteOp = ceph::io_exerciser::SingleFailedWriteOp;
5253
using DoubleFailedWriteOp = ceph::io_exerciser::DoubleFailedWriteOp;
5354
using TripleFailedWriteOp = ceph::io_exerciser::TripleFailedWriteOp;
@@ -667,9 +668,12 @@ void ceph::io_sequence::tester::TestRunner::clear_tokens() {
667668
tokens = split.end();
668669
}
669670

670-
std::string ceph::io_sequence::tester::TestRunner::get_token() {
671+
std::string ceph::io_sequence::tester::TestRunner::get_token(bool allow_eof) {
671672
while (line.empty() || tokens == split.end()) {
672673
if (!std::getline(std::cin, line)) {
674+
if (allow_eof) {
675+
return "done";
676+
}
673677
throw std::runtime_error("End of input");
674678
}
675679
split = ceph::split(line);
@@ -759,7 +763,7 @@ bool ceph::io_sequence::tester::TestRunner::run_interactive_test() {
759763
}
760764

761765
while (!done) {
762-
const std::string op = get_token();
766+
const std::string op = get_token(true);
763767
if (op == "done" || op == "q" || op == "quit") {
764768
ioop = ceph::io_exerciser::DoneOp::generate();
765769
} else if (op == "create") {
@@ -804,6 +808,9 @@ bool ceph::io_sequence::tester::TestRunner::run_interactive_test() {
804808
uint64_t length3 = get_numeric_token();
805809
ioop = TripleWriteOp::generate(offset1, length1, offset2, length2,
806810
offset3, length3);
811+
} else if (op == "append") {
812+
uint64_t length = get_numeric_token();
813+
ioop = SingleAppendOp::generate(length);
807814
} else if (op == "failedwrite") {
808815
uint64_t offset = get_numeric_token();
809816
uint64_t length = get_numeric_token();

src/test/osd/ceph_test_rados_io_sequence.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ class TestRunner {
322322
ceph::spliterator tokens;
323323

324324
void clear_tokens();
325-
std::string get_token();
325+
std::string get_token(bool allow_eof = false);
326326
std::optional<std::string> get_optional_token();
327327
uint64_t get_numeric_token();
328328
std::optional<uint64_t> get_optional_numeric_token();

0 commit comments

Comments
 (0)