aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorserg-belyakov <serg-belyakov@yandex-team.com>2022-09-06 14:31:39 +0300
committerserg-belyakov <serg-belyakov@yandex-team.com>2022-09-06 14:31:39 +0300
commit1cca4fc87bc31952e10b45b79ae70d821df1b185 (patch)
tree8676c3a56134109e58d35a6c60acc3007bf1f636
parent846bbb03aafcaab7494cdd305cf3a75f1f58ff4d (diff)
downloadydb-1cca4fc87bc31952e10b45b79ae70d821df1b185.tar.gz
Fix pdisk mock in race tests,
Fix pdisk mock in race tests,
-rw-r--r--ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_races.cpp33
-rw-r--r--ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp54
2 files changed, 67 insertions, 20 deletions
diff --git a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_races.cpp b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_races.cpp
index 024d54ebe0c..3e609b28ded 100644
--- a/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_races.cpp
+++ b/ydb/core/blobstorage/pdisk/blobstorage_pdisk_ut_races.cpp
@@ -16,6 +16,7 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
THPTimer timer;
while (timer.Passed() < timeLimit) {
TActorTestContext testCtx(false, usePDiskMock);
+ const TString data = PrepareData(4096);
auto logNoTest = [&](TVDiskMock& mock, NPDisk::TCommitRecord rec) {
auto evLog = MakeHolder<NPDisk::TEvLog>(mock.PDiskParams->Owner, mock.PDiskParams->OwnerRound, 0, PrepareData(1),
@@ -39,13 +40,13 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
}
mock.CommitReservedChunks();
TVector<TChunkIdx> chunkIds(mock.Chunks[EChunkState::COMMITTED].begin(), mock.Chunks[EChunkState::COMMITTED].end());
-
+
while (mock.Chunks[EChunkState::COMMITTED].size() > 0) {
auto it = mock.Chunks[EChunkState::COMMITTED].begin();
for (ui32 i = 0; i < inflight; ++i) {
- TString data = "HATE. LET ME TELL YOU HOW MUCH I'VE COME TO HATE YOU SINCE I BEGAN TO LIVE...";
+ TString dataCopy = data;
testCtx.Send(new NPDisk::TEvChunkWrite(mock.PDiskParams->Owner, mock.PDiskParams->OwnerRound,
- *it, 0, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(data), nullptr, false, 0));
+ *it, 0, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(dataCopy), nullptr, false, 0));
}
NPDisk::TCommitRecord rec;
rec.DeleteChunks.push_back(*it);
@@ -56,7 +57,7 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
testCtx.Send(new NPDisk::TEvHarakiri(mock.PDiskParams->Owner, mock.PDiskParams->OwnerRound));
- for (ui32 c = 0; ; c = (c + 1) % mocks.size()) {
+ for (ui32 c = 0, i = 0; i < 300; c = (c + 1) % mocks.size(), ++i) {
testCtx.Send(new NPDisk::TEvChunkReserve(mocks[c].PDiskParams->Owner, mocks[c].PDiskParams->OwnerRound, 1));
THolder<NPDisk::TEvChunkReserveResult> evRes = testCtx.Recv<NPDisk::TEvChunkReserveResult>();
if (!evRes || evRes->Status != NKikimrProto::OK) {
@@ -70,7 +71,7 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
rec.CommitChunks.push_back(*reservedChunks.begin());
logNoTest(mocks[c], rec);
reservedChunks.clear();
- }
+ }
testCtx.Recv<NPDisk::TEvHarakiriResult>();
}
}
@@ -91,7 +92,7 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
THPTimer timer;
while (timer.Passed() < timeLimit) {
TActorTestContext testCtx(false, usePDiskMock);
- ui32 dataSize = 1024;
+ const TString data = PrepareData(4096);
auto logNoTest = [&](TVDiskMock& mock, NPDisk::TCommitRecord rec) {
auto evLog = MakeHolder<NPDisk::TEvLog>(mock.PDiskParams->Owner, mock.PDiskParams->OwnerRound, 0, PrepareData(1),
@@ -104,15 +105,15 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
auto sendManyReads = [&](TVDiskMock& mock, TChunkIdx chunk, ui32 number, ui64& cookie) {
for (ui32 i = 0; i < number; ++i) {
testCtx.Send(new NPDisk::TEvChunkRead(mock.PDiskParams->Owner, mock.PDiskParams->OwnerRound,
- chunk, 0, dataSize, 0, (void*)(cookie++)));
+ chunk, 0, data.size(), 0, (void*)(cookie++)));
}
};
auto sendManyWrites = [&](TVDiskMock& mock, TChunkIdx chunk, ui32 number, ui64& cookie) {
for (ui32 i = 0; i < number; ++i) {
- TString data = PrepareData(dataSize);
+ TString dataCopy = data;
testCtx.Send(new NPDisk::TEvChunkWrite(mock.PDiskParams->Owner, mock.PDiskParams->OwnerRound,
- chunk, 0, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(data), (void*)(cookie++), false, 0));
+ chunk, 0, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(dataCopy), (void*)(cookie++), false, 0));
}
};
@@ -126,9 +127,9 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
{
auto& chunkIds = mock.Chunks[EChunkState::COMMITTED];
for (auto it = chunkIds.begin(); it != chunkIds.end(); ++it) {
- TString data = PrepareData(dataSize);
+ TString dataCopy = data;
testCtx.TestResponce<NPDisk::TEvChunkWriteResult>(new NPDisk::TEvChunkWrite(mock.PDiskParams->Owner, mock.PDiskParams->OwnerRound,
- *it, 0, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(data), (void*)10, false, 0),
+ *it, 0, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(dataCopy), (void*)10, false, 0),
NKikimrProto::OK);
}
}
@@ -154,6 +155,9 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
{
auto res = testCtx.Recv<NPDisk::TEvChunkReadResult>();
UNIT_ASSERT_VALUES_EQUAL_C(res->Status, NKikimrProto::OK, res->ToString());
+ if (res->Data.IsReadable()) {
+ UNIT_ASSERT_VALUES_EQUAL(res->Data.ToString(), data);
+ }
}
{
auto res = testCtx.Recv<NPDisk::TEvChunkWriteResult>();
@@ -183,6 +187,7 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
THPTimer timer;
while (timer.Passed() < timeLimit) {
TActorTestContext testCtx(false, usePDiskMock);
+ const TString data = PrepareData(4096);
auto logNoTest = [&](TVDiskMock& mock, NPDisk::TCommitRecord rec) {
auto evLog = MakeHolder<NPDisk::TEvLog>(mock.PDiskParams->Owner, mock.PDiskParams->OwnerRound, 0, PrepareData(1),
@@ -210,9 +215,9 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
while (mock.Chunks[EChunkState::COMMITTED].size() > 0) {
auto it = mock.Chunks[EChunkState::COMMITTED].begin();
for (ui32 i = 0; i < inflight; ++i) {
- TString data = "HATE. LET ME TELL YOU HOW MUCH I'VE COME TO HATE YOU SINCE I BEGAN TO LIVE...";
+ TString dataCopy = data;
testCtx.Send(new NPDisk::TEvChunkWrite(mock.PDiskParams->Owner, mock.PDiskParams->OwnerRound,
- *it, 0, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(data), nullptr, false, 0));
+ *it, 0, new NPDisk::TEvChunkWrite::TStrokaBackedUpParts(dataCopy), nullptr, false, 0));
}
NPDisk::TCommitRecord rec;
rec.DeleteChunks.push_back(*it);
@@ -224,7 +229,7 @@ Y_UNIT_TEST_SUITE(TPDiskRaces) {
testCtx.Send(new NPDisk::TEvHarakiri(mock.PDiskParams->Owner, mock.PDiskParams->OwnerRound));
- for (ui32 c = 0; ; c = (c + 1) % mocks.size()) {
+ for (ui32 c = 0, i = 0; i < 300; c = (c + 1) % mocks.size(), ++i) {
testCtx.Send(new NPDisk::TEvChunkReserve(mocks[c].PDiskParams->Owner, mocks[c].PDiskParams->OwnerRound, 1));
THolder<NPDisk::TEvChunkReserveResult> evRes = testCtx.Recv<NPDisk::TEvChunkReserveResult>();
if (!evRes || evRes->Status != NKikimrProto::OK) {
diff --git a/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp b/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp
index 866dea43dd3..2eb9d3af4cd 100644
--- a/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp
+++ b/ydb/core/blobstorage/pdisk/mock/pdisk_mock.cpp
@@ -114,13 +114,22 @@ struct TPDiskMockState::TImpl {
}
std::tuple<ui8, TOwner*> FindOrCreateOwner(const TVDiskID& vdiskId, ui32 slotId, bool *created) {
+ bool slotIsValid = (slotId != Max<ui32>());
for (auto& [ownerId, owner] : Owners) {
- if (slotId == owner.SlotId) {
- Y_VERIFY(owner.VDiskId.SameExceptGeneration(vdiskId));
- *created = false;
- return std::make_tuple(ownerId, &owner);
+ if (slotIsValid) {
+ if (slotId == owner.SlotId) {
+ Y_VERIFY(owner.VDiskId.SameExceptGeneration(vdiskId));
+ *created = false;
+ return std::make_tuple(ownerId, &owner);
+ }
+ } else {
+ if (owner.VDiskId.SameExceptGeneration(vdiskId)) {
+ *created = false;
+ return std::make_tuple(ownerId, &owner);
+ }
}
}
+
ui8 ownerId = 1;
std::map<ui8, TOwner>::iterator it;
for (it = Owners.begin(); it != Owners.end() && it->first == ownerId; ++it, ++ownerId)
@@ -707,8 +716,41 @@ public:
Send(ev->Sender, res.release());
}
- void Handle(NPDisk::TEvHarakiri::TPtr /*ev*/) {
- Y_FAIL();
+ void Handle(NPDisk::TEvHarakiri::TPtr ev) {
+ auto *msg = ev->Get();
+ PDISK_MOCK_LOG(INFO, PDM18, "received TEvHarakiri", (Msg, msg->ToString()));
+
+ TString errorReason = "";
+ auto res = std::make_unique<NPDisk::TEvHarakiriResult>(NKikimrProto::OK, GetStatusFlags(), errorReason);
+ auto it = Impl.Owners.find(msg->Owner);
+
+ if (it == Impl.Owners.end()) {
+ res->Status = NKikimrProto::ALREADY;
+ res->ErrorReason = "not found";
+ }
+
+ auto owner = it->second;
+
+ if (owner.Slain) {
+ res->Status = NKikimrProto::ALREADY; // already slain or not found
+ res->ErrorReason = "already slain or not found";
+ } else if (msg->OwnerRound <= owner.OwnerRound) {
+ res->Status = NKikimrProto::RACE;
+ res->ErrorReason = TStringBuilder() << "Message OwnerRound# " << msg->OwnerRound << " actual OwnerRound# "
+ << owner.OwnerRound << " race detected";
+ } else {
+ owner.Slain = true;
+ Impl.FreeChunks.merge(owner.ReservedChunks);
+ Impl.FreeChunks.merge(owner.CommittedChunks);
+ Impl.AdjustFreeChunks();
+ owner.ChunkData.clear();
+ owner.Log.clear();
+ owner.LogDataSize = 0;
+ owner.LastLsn = 0;
+ owner.StartingPoints.clear();
+ }
+
+ Send(ev->Sender, res.release());
}
void Handle(NPDisk::TEvCheckSpace::TPtr ev) {