Skip to content

Commit 6536467

Browse files
authored
Make fake io error tests in PDisk more robust (#10091)
1 parent 2c63185 commit 6536467

File tree

3 files changed

+41
-23
lines changed

3 files changed

+41
-23
lines changed

ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ Y_UNIT_TEST_SUITE(TPDiskTest) {
346346

347347
Y_UNIT_TEST(TestFakeErrorPDiskManyLogWrite) {
348348
TActorTestContext testCtx({ false });
349-
testCtx.TestCtx.SectorMap->ImitateIoErrorProbability = 1e-4;
349+
testCtx.TestCtx.SectorMap->IoErrorEveryNthRequests = 1000;
350350

351351
const TVDiskID vDiskID(0, 1, 0, 0, 0);
352352
const auto evInitRes = testCtx.TestResponse<NPDisk::TEvYardInitResult>(
@@ -355,7 +355,7 @@ Y_UNIT_TEST_SUITE(TPDiskTest) {
355355

356356
ui32 errors = 0;
357357
ui32 lsn = 2;
358-
for (ui32 i = 0; i < 100'000; ++i) {
358+
for (ui32 i = 0; i < 10'000; ++i) {
359359
testCtx.Send(new NPDisk::TEvLog(evInitRes->PDiskParams->Owner, evInitRes->PDiskParams->OwnerRound, 0,
360360
TRcBuf(TString("abc")), TLsnSeg(lsn, lsn), nullptr));
361361
++lsn;
@@ -384,7 +384,7 @@ Y_UNIT_TEST_SUITE(TPDiskTest) {
384384
vdisk.Init();
385385

386386
// Make sure there will be read error.
387-
testCtx.TestCtx.SectorMap->ImitateReadIoErrorProbability = 1;
387+
testCtx.TestCtx.SectorMap->ReadIoErrorEveryNthRequests = 1;
388388

389389
auto res = vdisk.ReadLog(true);
390390

@@ -404,7 +404,7 @@ Y_UNIT_TEST_SUITE(TPDiskTest) {
404404
vdisk.InitFull();
405405

406406
// Make sure there will be syslog read error.
407-
testCtx.TestCtx.SectorMap->ImitateReadIoErrorProbability = 1;
407+
testCtx.TestCtx.SectorMap->ReadIoErrorEveryNthRequests = 1;
408408

409409
testCtx.TestResponse<NPDisk::TEvYardControlResult>(
410410
new NPDisk::TEvYardControl(NPDisk::TEvYardControl::PDiskStop, nullptr),
@@ -417,7 +417,7 @@ Y_UNIT_TEST_SUITE(TPDiskTest) {
417417

418418
Y_UNIT_TEST(TestFakeErrorPDiskManyChunkRead) {
419419
TActorTestContext testCtx({ false });
420-
testCtx.TestCtx.SectorMap->ImitateReadIoErrorProbability = 1e-4;
420+
testCtx.TestCtx.SectorMap->ReadIoErrorEveryNthRequests = 100;
421421

422422
TVDiskMock vdisk(&testCtx);
423423
vdisk.InitFull();
@@ -434,7 +434,8 @@ Y_UNIT_TEST_SUITE(TPDiskTest) {
434434
NKikimrProto::OK);
435435

436436
bool printed = false;
437-
for (ui32 i = 0; i < 100'000; ++i) {
437+
ui32 errors = 0;
438+
for (ui32 i = 0; i < 10'000; ++i) {
438439
testCtx.Send(new NPDisk::TEvChunkRead(vdisk.PDiskParams->Owner, vdisk.PDiskParams->OwnerRound,
439440
reservedChunk, 0, 1024, 0, nullptr));
440441

@@ -445,30 +446,32 @@ Y_UNIT_TEST_SUITE(TPDiskTest) {
445446
printed = true;
446447
Ctest << res->ToString() << Endl;
447448
}
449+
++errors;
448450
}
449451
}
452+
UNIT_ASSERT(errors > 0);
450453
// Check that PDisk is in working state now
451454
vdisk.InitFull();
452455
}
453456

454457
Y_UNIT_TEST(TestFakeErrorPDiskManyChunkWrite) {
455458
TActorTestContext testCtx({ false });
456-
testCtx.TestCtx.SectorMap->ImitateIoErrorProbability = 1e-4;
459+
testCtx.TestCtx.SectorMap->IoErrorEveryNthRequests = 1000;
457460

458461
const TVDiskID vDiskID(0, 1, 0, 0, 0);
459462
const auto evInitRes = testCtx.TestResponse<NPDisk::TEvYardInitResult>(
460463
new NPDisk::TEvYardInit(2, vDiskID, testCtx.TestCtx.PDiskGuid),
461464
NKikimrProto::OK);
462465

463-
ui32 errors = 0;
464466
const auto evReserveRes = testCtx.TestResponse<NPDisk::TEvChunkReserveResult>(
465467
new NPDisk::TEvChunkReserve(evInitRes->PDiskParams->Owner, evInitRes->PDiskParams->OwnerRound, 1),
466468
NKikimrProto::OK);
467469
UNIT_ASSERT(evReserveRes->ChunkIds.size() == 1);
468470
const ui32 reservedChunk = evReserveRes->ChunkIds.front();
469471

472+
ui32 errors = 0;
470473
bool printed = false;
471-
for (ui32 i = 0; i < 100'000; ++i) {
474+
for (ui32 i = 0; i < 10'000; ++i) {
472475
TString data = PrepareData(1024);
473476
testCtx.Send(new NPDisk::TEvChunkWrite(evInitRes->PDiskParams->Owner, evInitRes->PDiskParams->OwnerRound,
474477
reservedChunk, 0, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(data), nullptr, false, 0));

ydb/library/pdisk_io/aio_map.cpp

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ class TAsyncIoContextMap : public IAsyncIoContext {
218218

219219
TSpinLock SpinLock;
220220
IAsyncIoOperation* LastOngoingAsyncIoOperation = nullptr;
221+
std::atomic<ui64> GlobalCounter = 0;
222+
221223
public:
222224

223225
TAsyncIoContextMap(const TString &path, ui32 pDiskId, TIntrusivePtr<TSectorMap> sectorMap)
@@ -248,6 +250,25 @@ class TAsyncIoContextMap : public IAsyncIoContext {
248250
return EIoResult::Ok;
249251
}
250252

253+
EIoResult GenerateResultForOperaion(IAsyncIoOperation::EType type) {
254+
auto result = EIoResult::Ok;
255+
256+
auto globalIdx = GlobalCounter++;
257+
if (auto everyNth = SectorMap->IoErrorEveryNthRequests.load()) {
258+
if (globalIdx % everyNth == everyNth - 1) {
259+
result = EIoResult::FakeError;
260+
}
261+
}
262+
if (type == IAsyncIoOperation::EType::PRead) {
263+
if (auto everyNth = SectorMap->ReadIoErrorEveryNthRequests.load()) {
264+
if (globalIdx % everyNth == everyNth - 1) {
265+
result = EIoResult::FakeError;
266+
}
267+
}
268+
}
269+
return result;
270+
}
271+
251272
i64 GetEvents(ui64 minEvents, ui64 maxEvents, TAsyncIoOperationResult *events, TDuration timeout) override {
252273
ui64 outputIdx = 0;
253274
TInstant startTime = TInstant::Now();
@@ -258,14 +279,8 @@ class TAsyncIoContextMap : public IAsyncIoContext {
258279
for (TAtomicBase idx = 0; idx < size; ++idx) {
259280
TAsyncIoOperationMap *op = static_cast<TAsyncIoOperationMap*>(CompleteQueue.Pop());
260281
events[outputIdx].Operation = op;
261-
events[outputIdx].Result = (RandomNumber<double>() <
262-
SectorMap->ImitateIoErrorProbability.load())
263-
? EIoResult::FakeError
264-
: EIoResult::Ok;
265-
if (op->GetType() == IAsyncIoOperation::EType::PRead &&
266-
RandomNumber<double>() < SectorMap->ImitateReadIoErrorProbability.load()) {
267-
events[outputIdx].Result = EIoResult::FakeError;
268-
}
282+
283+
events[outputIdx].Result = GenerateResultForOperaion(op->GetType());
269284
events[outputIdx].Operation->ExecCallback(&events[outputIdx]);
270285
++outputIdx;
271286
if (outputIdx == maxEvents) {

ydb/library/pdisk_io/sector_map.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,16 @@ class TSectorMap : public TThrRefBase {
191191
TTicketLock MapLock;
192192
std::atomic<bool> IsLocked;
193193
std::optional<std::pair<TDuration, TDuration>> ImitateRandomWait;
194-
std::atomic<double> ImitateIoErrorProbability;
195-
std::atomic<double> ImitateReadIoErrorProbability;
194+
std::atomic<ui64> IoErrorEveryNthRequests;
195+
std::atomic<ui64> ReadIoErrorEveryNthRequests;
196196

197197
std::atomic<ui64> AllocatedBytes;
198198

199199
TSectorMap(ui64 deviceSize = 0, NSectorMap::EDiskMode diskMode = NSectorMap::DM_NONE)
200200
: DeviceSize(deviceSize)
201201
, IsLocked(false)
202-
, ImitateIoErrorProbability(0.0)
203-
, ImitateReadIoErrorProbability(0.0)
202+
, IoErrorEveryNthRequests(0)
203+
, ReadIoErrorEveryNthRequests(0)
204204
, AllocatedBytes(0)
205205
, DiskMode(diskMode)
206206
{
@@ -327,8 +327,8 @@ class TSectorMap : public TThrRefBase {
327327
str << "ImitateRandomWait# [" << ImitateRandomWait->first << ", "
328328
<< ImitateRandomWait->first + ImitateRandomWait->second << ")" << "\n";
329329
}
330-
str << "ImitateReadIoErrorProbability# " << ImitateReadIoErrorProbability.load() << "\n";
331-
str << "ImitateIoErrorProbability# " << ImitateIoErrorProbability.load() << "\n";
330+
str << "ReadIoErrorEveryNthRequests# " << ReadIoErrorEveryNthRequests.load() << "\n";
331+
str << "IoErrorEveryNthRequests# " << IoErrorEveryNthRequests.load() << "\n";
332332
str << "AllocatedBytes (approx.)# " << HumanReadableSize(AllocatedBytes.load(), SF_QUANTITY) << "\n";
333333
str << "DataBytes# " << HumanReadableSize(DataBytes(), SF_QUANTITY) << "\n";
334334
str << "DiskMode# " << DiskModeToString(DiskMode) << "\n";

0 commit comments

Comments
 (0)