Skip to content

Commit 008e57f

Browse files
committed
DS proxy mirror-3-dc restoration strategy test
1 parent f7af241 commit 008e57f

File tree

2 files changed

+149
-4
lines changed

2 files changed

+149
-4
lines changed

ydb/core/blobstorage/dsproxy/dsproxy_blackboard.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ struct TBlobState {
108108
};
109109

110110
struct TDiskGetRequest {
111-
const TLogoBlobID Id;
112-
const ui32 Shift;
113-
const ui32 Size;
111+
TLogoBlobID Id;
112+
ui32 Shift;
113+
ui32 Size;
114114
ssize_t PartMapIndex = -1;
115115

116116
TDiskGetRequest(const TLogoBlobID &id, const ui32 shift, const ui32 size)
@@ -127,7 +127,7 @@ struct TDiskPutRequest {
127127
ReasonInitial,
128128
ReasonAccelerate
129129
};
130-
const TLogoBlobID Id;
130+
TLogoBlobID Id;
131131
TRope Buffer;
132132
EPutReason Reason;
133133
bool IsHandoff;

ydb/core/blobstorage/dsproxy/ut_strategy/strategy_ut.cpp

+145
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#include <ydb/core/blobstorage/dsproxy/dsproxy_blackboard.h>
22
#include <ydb/core/blobstorage/dsproxy/dsproxy_strategy_restore.h>
3+
#include <ydb/core/blobstorage/dsproxy/dsproxy_strategy_get_m3dc_restore.h>
34
#include <library/cpp/testing/unittest/registar.h>
45
#include <util/stream/null.h>
6+
#include <util/generic/overloaded.h>
57

68
using namespace NActors;
79
using namespace NKikimr;
@@ -193,10 +195,153 @@ void RunStrategyTest(TBlobStorageGroupType type) {
193195
}
194196
}
195197

198+
struct TGetQuery {
199+
ui32 OrderNumber;
200+
TLogoBlobID Id;
201+
ui32 Shift;
202+
ui32 Size;
203+
204+
friend bool operator ==(const TGetQuery& x, const TGetQuery& y) {
205+
return x.OrderNumber == y.OrderNumber && x.Id == y.Id && x.Shift == y.Shift && x.Size == y.Size;
206+
}
207+
};
208+
209+
struct TPutQuery {
210+
ui32 OrderNumber;
211+
TLogoBlobID Id;
212+
213+
friend bool operator ==(const TPutQuery& x, const TPutQuery& y) {
214+
return x.OrderNumber == y.OrderNumber && x.Id == y.Id;
215+
}
216+
};
217+
218+
using TOperation = std::variant<TGetQuery, TPutQuery>;
219+
220+
void RunTestLevel(const TBlobStorageGroupInfo& info, TBlackboard& blackboard,
221+
const std::function<EStrategyOutcome(TBlackboard&)>& runStrategies, const TLogoBlobID& id,
222+
std::vector<TOperation>& stock, TSubgroupPartLayout presenceMask, bool nonWorkingDomain) {
223+
// see which operations we can add to the stock
224+
const size_t stockSizeOnEntry = stock.size();
225+
auto& requests = blackboard.GroupDiskRequests.DiskRequestsForOrderNumber;
226+
for (ui32 i = 0; i < info.GetTotalVDisksNum(); ++i) {
227+
for (const auto& get : requests[i].GetsToSend) {
228+
stock.push_back(TGetQuery{i, get.Id, get.Shift, get.Size});
229+
}
230+
requests[i].GetsToSend.clear();
231+
for (const auto& put : requests[i].PutsToSend) {
232+
stock.push_back(TPutQuery{i, put.Id});
233+
}
234+
requests[i].PutsToSend.clear();
235+
}
236+
237+
// try every single operation in stock
238+
for (size_t i = 0; i < stock.size(); ++i) {
239+
std::swap(stock[i], stock.back());
240+
TOperation operation = std::move(stock.back());
241+
stock.pop_back();
242+
243+
TBlackboard branch(blackboard);
244+
TSubgroupPartLayout myPresenceMask(presenceMask);
245+
246+
std::visit(TOverloaded{
247+
[&](const TGetQuery& op) {
248+
const ui32 idxInSubgroup = info.GetTopology().GetIdxInSubgroup(info.GetVDiskId(op.OrderNumber), id.Hash());
249+
if (nonWorkingDomain && idxInSubgroup % 3 == 2) {
250+
branch.AddErrorResponse(op.Id, op.OrderNumber);
251+
} else if (myPresenceMask.GetDisksWithPart(op.Id.PartId() - 1) >> idxInSubgroup & 1) {
252+
const ui32 blobSize = op.Id.BlobSize();
253+
const ui32 shift = Min(op.Shift, blobSize);
254+
const ui32 size = Min(op.Size ? op.Size : Max<ui32>(), blobSize - shift);
255+
branch.AddResponseData(op.Id, op.OrderNumber, shift, TRope(TString(size, 'X')));
256+
} else {
257+
branch.AddNoDataResponse(op.Id, op.OrderNumber);
258+
}
259+
},
260+
[&](const TPutQuery& op) {
261+
const ui32 idxInSubgroup = info.GetTopology().GetIdxInSubgroup(info.GetVDiskId(op.OrderNumber), id.Hash());
262+
if (nonWorkingDomain && idxInSubgroup % 3 == 2) {
263+
branch.AddErrorResponse(op.Id, op.OrderNumber);
264+
} else {
265+
myPresenceMask.AddItem(idxInSubgroup, op.Id.PartId() - 1, info.Type);
266+
branch.AddPutOkResponse(op.Id, op.OrderNumber);
267+
}
268+
}
269+
}, operation);
270+
271+
auto outcome = runStrategies(branch);
272+
UNIT_ASSERT(outcome != EStrategyOutcome::ERROR);
273+
if (outcome == EStrategyOutcome::DONE) {
274+
TBlobStorageGroupInfo::TOrderNums nums;
275+
info.GetTopology().PickSubgroup(id.Hash(), nums);
276+
UNIT_ASSERT(info.GetQuorumChecker().GetBlobState(myPresenceMask, {&info.GetTopology()}) == TBlobStorageGroupInfo::EBS_FULL);
277+
} else {
278+
RunTestLevel(info, branch, runStrategies, id, stock, myPresenceMask, nonWorkingDomain);
279+
}
280+
281+
stock.push_back(std::move(operation));
282+
std::swap(stock[i], stock.back());
283+
}
284+
285+
// revert stock
286+
stock.resize(stockSizeOnEntry);
287+
}
288+
196289
Y_UNIT_TEST_SUITE(DSProxyStrategyTest) {
197290

198291
Y_UNIT_TEST(Restore_block42) {
199292
RunStrategyTest<TRestoreStrategy>(TBlobStorageGroupType::Erasure4Plus2Block);
200293
}
201294

295+
Y_UNIT_TEST(Restore_mirror3dc) {
296+
THPTimer timer;
297+
const TBlobStorageGroupType type(TBlobStorageGroupType::ErasureMirror3dc);
298+
299+
TBlobStorageGroupInfo info(type, 1, 3, 3);
300+
info.Ref();
301+
TGroupQueues groupQueues(info.GetTopology());
302+
groupQueues.Ref();
303+
304+
std::vector<TOperation> stock;
305+
306+
TLogContext logCtx(NKikimrServices::BS_PROXY, false);
307+
logCtx.SuppressLog = true;
308+
309+
auto runStrategies = [&](TBlackboard& blackboard) {
310+
return blackboard.RunStrategy(logCtx, TMirror3dcGetWithRestoreStrategy());
311+
};
312+
313+
const ui32 base = RandomNumber(512u);
314+
for (ui32 i = 0; i < 512; ++i) {
315+
const ui32 diskMask = (base + i) % 512;
316+
for (bool nonWorkingDomain : {false, true}) {
317+
Cerr << "diskMask# " << diskMask << " nonWorkingDomain# " << nonWorkingDomain << Endl;
318+
319+
TBlackboard blackboard(&info, &groupQueues, NKikimrBlobStorage::UserData, NKikimrBlobStorage::FastRead);
320+
321+
const TLogoBlobID id(1'000'000'000, 1, 1, 0, 1000, 0);
322+
TSubgroupPartLayout presenceMask;
323+
blackboard.AddNeeded(id, 0, id.BlobSize());
324+
bool partsAvailable = false;
325+
for (ui32 idxInSubgroup = 0; idxInSubgroup < 9; ++idxInSubgroup) {
326+
if (diskMask >> idxInSubgroup & 1 && (!nonWorkingDomain || idxInSubgroup % 3 != 2)) {
327+
presenceMask.AddItem(idxInSubgroup, idxInSubgroup % 3, info.Type);
328+
partsAvailable = true;
329+
}
330+
}
331+
if (!partsAvailable) {
332+
continue;
333+
}
334+
335+
auto outcome = runStrategies(blackboard);
336+
UNIT_ASSERT(outcome == EStrategyOutcome::IN_PROGRESS);
337+
338+
RunTestLevel(info, blackboard, runStrategies, id, stock, presenceMask, nonWorkingDomain);
339+
340+
if (TDuration::Seconds(timer.Passed()) >= TDuration::Minutes(5)) {
341+
break;
342+
}
343+
}
344+
}
345+
}
346+
202347
}

0 commit comments

Comments
 (0)