Skip to content

Commit 29f2113

Browse files
Merge eca636e into 3a7aa37
2 parents 3a7aa37 + eca636e commit 29f2113

File tree

5 files changed

+209
-8
lines changed

5 files changed

+209
-8
lines changed

ydb/core/testlib/actors/test_runtime.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,10 @@ namespace NActors {
205205
return *node->GetAppData<NKikimr::TAppData>();
206206
}
207207

208+
ui32 TTestActorRuntime::GetFirstNodeId() {
209+
return FirstNodeId;
210+
}
211+
208212
bool TTestActorRuntime::DefaultScheduledFilterFunc(TTestActorRuntimeBase& runtime, TAutoPtr<IEventHandle>& event, TDuration delay, TInstant& deadline) {
209213
Y_UNUSED(delay);
210214
Y_UNUSED(deadline);

ydb/core/testlib/actors/test_runtime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ namespace NActors {
9696
void ClosePipe(TActorId clientId, const TActorId& sender, ui32 nodeIndex);
9797
void DisconnectNodes(ui32 fromNodeIndex, ui32 toNodeIndex, bool async = true);
9898
NKikimr::TAppData& GetAppData(ui32 nodeIndex = 0);
99+
ui32 GetFirstNodeId();
99100

100101
TPortManager& GetPortManager() {
101102
return *this;

ydb/core/viewer/json_storage.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ class TJsonStorage : public TJsonStorageBase {
250250
}
251251

252252
bool CheckGroupFilters(const TString& groupId, const TString& poolName, const TGroupRow& groupRow) {
253-
if (!EffectiveFilterGroupIds.empty() && !EffectiveFilterGroupIds.contains(groupId)) {
253+
if (!EffectiveGroupFilter.contains(groupId)) {
254254
return false;
255255
}
256256
switch (With) {
@@ -497,6 +497,7 @@ struct TJsonRequestParameters<TJsonStorage> {
497497
{"name":"tenant","in":"query","description":"tenant name","required":false,"type":"string"},
498498
{"name":"pool","in":"query","description":"storage pool name","required":false,"type":"string"},
499499
{"name":"node_id","in":"query","description":"node id","required":false,"type":"integer"},
500+
{"name":"pdisk_id","in":"query","description":"pdisk id","required":false,"type":"integer"},
500501
{"name":"group_id","in":"query","description":"group id","required":false,"type":"integer"},
501502
{"name":"need_groups","in":"query","description":"return groups information","required":false,"type":"boolean","default":true},
502503
{"name":"need_disks","in":"query","description":"return disks information","required":false,"type":"boolean","default":true},

ydb/core/viewer/json_storage_base.h

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,11 @@ class TJsonStorageBase : public TViewerPipeClient<TJsonStorageBase> {
7272
ui32 Timeout = 0;
7373
TString FilterTenant;
7474
THashSet<TString> FilterStoragePools;
75-
TVector<TString> FilterGroupIds;
7675
TString Filter;
76+
std::unordered_set<TString> FilterGroupIds;
7777
std::unordered_set<TNodeId> FilterNodeIds;
78-
THashSet<TString> EffectiveFilterGroupIds;
78+
std::unordered_set<ui32> FilterPDiskIds;
79+
THashSet<TString> EffectiveGroupFilter;
7980
std::unordered_set<TNodeId> NodeIds;
8081
bool NeedAdditionalNodesRequests;
8182

@@ -133,9 +134,9 @@ class TJsonStorageBase : public TViewerPipeClient<TJsonStorageBase> {
133134
FilterStoragePools.emplace(filterStoragePool);
134135
}
135136
SplitIds(params.Get("node_id"), ',', FilterNodeIds);
137+
SplitIds(params.Get("pdisk_id"), ',', FilterPDiskIds);
136138
NeedAdditionalNodesRequests = !FilterNodeIds.empty();
137139
SplitIds(params.Get("group_id"), ',', FilterGroupIds);
138-
Sort(FilterGroupIds);
139140
Filter = params.Get("filter");
140141
if (params.Get("with") == "missing") {
141142
With = EWith::MissingDisks;
@@ -356,6 +357,14 @@ class TJsonStorageBase : public TViewerPipeClient<TJsonStorageBase> {
356357
for (auto& vDiskStateInfo : *(vDiskInfo.MutableVDiskStateInfo())) {
357358
vDiskStateInfo.SetNodeId(nodeId);
358359
VDiskId2vDiskStateInfo[VDiskIDFromVDiskID(vDiskStateInfo.GetVDiskId())] = &vDiskStateInfo;
360+
361+
bool isNodeIdValid = FilterNodeIds.empty() || FilterNodeIds.contains(nodeId);
362+
bool isPDiskIdValid = FilterNodeIds.empty() || FilterPDiskIds.empty() || FilterPDiskIds.contains(vDiskStateInfo.GetPDiskId());
363+
bool isGroupIdValid = FilterGroupIds.empty() || FilterGroupIds.contains(ToString(vDiskStateInfo.GetVDiskId().GetGroupID()));
364+
365+
if (isNodeIdValid && isPDiskIdValid && isGroupIdValid) {
366+
EffectiveGroupFilter.insert(ToString(vDiskStateInfo.GetVDiskId().GetGroupID()));
367+
}
359368
}
360369
RequestDone();
361370
}
@@ -375,10 +384,6 @@ class TJsonStorageBase : public TViewerPipeClient<TJsonStorageBase> {
375384
}
376385
if (FilterNodeIds.empty() || FilterNodeIds.contains(info.GetNodeId())) {
377386
StoragePoolInfo[storagePoolName].Groups.emplace(ToString(info.GetGroupID()));
378-
TString groupId(ToString(info.GetGroupID()));
379-
if (FilterGroupIds.empty() || BinarySearch(FilterGroupIds.begin(), FilterGroupIds.end(), groupId)) {
380-
EffectiveFilterGroupIds.insert(groupId);
381-
}
382387
}
383388
for (const auto& vDiskNodeId : info.GetVDiskNodeIds()) {
384389
Group2NodeId[info.GetGroupID()].push_back(vDiskNodeId);

ydb/core/viewer/viewer_ut.cpp

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,4 +1325,194 @@ Y_UNIT_TEST_SUITE(Viewer) {
13251325
"description",
13261326
});
13271327
}
1328+
1329+
void ChangeBSGroupStateResponse(TEvWhiteboard::TEvBSGroupStateResponse::TPtr* ev) {
1330+
ui64 nodeId = (*ev)->Cookie;
1331+
auto& pbRecord = (*ev)->Get()->Record;
1332+
1333+
pbRecord.clear_bsgroupstateinfo();
1334+
1335+
for (ui64 groupId = 1; groupId <= 9; groupId++) {
1336+
if (groupId % 9 == nodeId % 9) {
1337+
continue;
1338+
}
1339+
auto state = pbRecord.add_bsgroupstateinfo();
1340+
state->set_groupid(groupId);
1341+
state->set_storagepoolname("/Root:test");
1342+
state->set_nodeid(nodeId);
1343+
for (int k = 1; k <= 8; k++) {
1344+
auto vdisk = groupId * 8 + k;
1345+
auto vdiskId = state->add_vdiskids();
1346+
vdiskId->set_groupid(groupId);
1347+
vdiskId->set_groupgeneration(1);
1348+
vdiskId->set_vdisk(vdisk);
1349+
}
1350+
}
1351+
}
1352+
1353+
void ChangePDiskStateResponse(TEvWhiteboard::TEvPDiskStateResponse::TPtr* ev) {
1354+
auto& pbRecord = (*ev)->Get()->Record;
1355+
pbRecord.clear_pdiskstateinfo();
1356+
for (int k = 0; k < 2; k++) {
1357+
auto state = pbRecord.add_pdiskstateinfo();
1358+
state->set_pdiskid(k);
1359+
}
1360+
}
1361+
1362+
void ChangeVDiskStateOn9NodeResponse(NNodeWhiteboard::TEvWhiteboard::TEvVDiskStateResponse::TPtr* ev) {
1363+
ui64 nodeId = (*ev)->Cookie;
1364+
auto& pbRecord = (*ev)->Get()->Record;
1365+
1366+
pbRecord.clear_vdiskstateinfo();
1367+
1368+
for (int k = 0; k < 8; k++) {
1369+
auto groupId = (nodeId + k) % 9 + 1;
1370+
auto vdisk = groupId * 8 + k + 1;
1371+
ui32 pdisk = k / 4;
1372+
ui32 slotid = k % 4;
1373+
auto state = pbRecord.add_vdiskstateinfo();
1374+
state->set_pdiskid(pdisk);
1375+
state->set_vdiskslotid(slotid);
1376+
state->mutable_vdiskid()->set_groupid(groupId);
1377+
state->mutable_vdiskid()->set_groupgeneration(1);
1378+
state->mutable_vdiskid()->set_vdisk(vdisk++);
1379+
state->set_vdiskstate(NKikimrWhiteboard::EVDiskState::OK);
1380+
state->set_nodeid(nodeId);
1381+
}
1382+
}
1383+
1384+
void AddGroupsInControllerSelectGroupsResult(TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr* ev, int groupCount) {
1385+
auto& pbRecord = (*ev)->Get()->Record;
1386+
auto pbMatchGroups = pbRecord.mutable_matchinggroups(0);
1387+
1388+
auto sample = pbMatchGroups->groups(0);
1389+
pbMatchGroups->ClearGroups();
1390+
1391+
for (int groupId = 1; groupId <= groupCount; groupId++) {
1392+
auto group = pbMatchGroups->add_groups();
1393+
group->CopyFrom(sample);
1394+
group->set_groupid(groupId++);
1395+
group->set_storagepoolname("/Root:test");
1396+
}
1397+
};
1398+
1399+
void JsonStorage9Nodes9GroupsListingTest(TString version, bool groupFilter, bool nodeFilter, bool pdiskFilter, ui32 expectedFoundGroups, ui32 expectedTotalGroups) {
1400+
TPortManager tp;
1401+
ui16 port = tp.GetPort(2134);
1402+
ui16 grpcPort = tp.GetPort(2135);
1403+
auto settings = TServerSettings(port);
1404+
settings.InitKikimrRunConfig()
1405+
.SetNodeCount(9)
1406+
.SetUseRealThreads(false)
1407+
.SetDomainName("Root");
1408+
TServer server(settings);
1409+
server.EnableGRpc(grpcPort);
1410+
TClient client(settings);
1411+
TTestActorRuntime& runtime = *server.GetRuntime();
1412+
1413+
TActorId sender = runtime.AllocateEdgeActor();
1414+
TAutoPtr<IEventHandle> handle;
1415+
1416+
THttpRequest httpReq(HTTP_METHOD_GET);
1417+
httpReq.CgiParameters.emplace("with", "all");
1418+
httpReq.CgiParameters.emplace("version", version);
1419+
if (groupFilter) {
1420+
httpReq.CgiParameters.emplace("group_id", "1");
1421+
}
1422+
if (nodeFilter) {
1423+
httpReq.CgiParameters.emplace("node_id", ToString(runtime.GetFirstNodeId()));
1424+
}
1425+
if (pdiskFilter) {
1426+
httpReq.CgiParameters.emplace("pdisk_id", "0");
1427+
}
1428+
auto page = MakeHolder<TMonPage>("viewer", "title");
1429+
TMonService2HttpRequest monReq(nullptr, &httpReq, nullptr, page.Get(), "/json/storage", nullptr);
1430+
auto request = MakeHolder<NMon::TEvHttpInfo>(monReq);
1431+
1432+
auto observerFunc = [&](TAutoPtr<IEventHandle>& ev) {
1433+
Y_UNUSED(ev);
1434+
switch (ev->GetTypeRewrite()) {
1435+
case NConsole::TEvConsole::EvListTenantsResponse: {
1436+
auto *x = reinterpret_cast<NConsole::TEvConsole::TEvListTenantsResponse::TPtr*>(&ev);
1437+
Ydb::Cms::ListDatabasesResult listTenantsResult;
1438+
(*x)->Get()->Record.GetResponse().operation().result().UnpackTo(&listTenantsResult);
1439+
listTenantsResult.Addpaths("/Root");
1440+
(*x)->Get()->Record.MutableResponse()->mutable_operation()->mutable_result()->PackFrom(listTenantsResult);
1441+
break;
1442+
}
1443+
case TEvWhiteboard::EvBSGroupStateResponse: {
1444+
auto *x = reinterpret_cast<TEvWhiteboard::TEvBSGroupStateResponse::TPtr*>(&ev);
1445+
ChangeBSGroupStateResponse(x);
1446+
break;
1447+
}
1448+
case TEvWhiteboard::EvVDiskStateResponse: {
1449+
auto *x = reinterpret_cast<TEvWhiteboard::TEvVDiskStateResponse::TPtr*>(&ev);
1450+
ChangeVDiskStateOn9NodeResponse(x);
1451+
break;
1452+
}
1453+
case TEvWhiteboard::EvPDiskStateResponse: {
1454+
auto *x = reinterpret_cast<TEvWhiteboard::TEvPDiskStateResponse::TPtr*>(&ev);
1455+
ChangePDiskStateResponse(x);
1456+
break;
1457+
}
1458+
case TEvBlobStorage::EvControllerSelectGroupsResult: {
1459+
auto *x = reinterpret_cast<TEvBlobStorage::TEvControllerSelectGroupsResult::TPtr*>(&ev);
1460+
AddGroupsInControllerSelectGroupsResult(x, 9);
1461+
break;
1462+
}
1463+
}
1464+
1465+
return TTestActorRuntime::EEventAction::PROCESS;
1466+
};
1467+
runtime.SetObserverFunc(observerFunc);
1468+
1469+
runtime.Send(new IEventHandle(NKikimr::NViewer::MakeViewerID(0), sender, request.Release(), 0));
1470+
NMon::TEvHttpInfoRes* result = runtime.GrabEdgeEvent<NMon::TEvHttpInfoRes>(handle);
1471+
1472+
size_t pos = result->Answer.find('{');
1473+
TString jsonResult = result->Answer.substr(pos);
1474+
NJson::TJsonValue json;
1475+
try {
1476+
NJson::ReadJsonTree(jsonResult, &json, true);
1477+
}
1478+
catch (yexception ex) {
1479+
Ctest << ex.what() << Endl;
1480+
}
1481+
1482+
UNIT_ASSERT_VALUES_EQUAL(json.GetMap().at("FoundGroups"), ToString(expectedFoundGroups));
1483+
UNIT_ASSERT_VALUES_EQUAL(json.GetMap().at("TotalGroups"), ToString(expectedTotalGroups));
1484+
}
1485+
1486+
Y_UNIT_TEST(JsonStorageListingV1) {
1487+
JsonStorage9Nodes9GroupsListingTest("v1", false, false, false, 9, 9);
1488+
}
1489+
1490+
Y_UNIT_TEST(JsonStorageListingV2) {
1491+
JsonStorage9Nodes9GroupsListingTest("v2", false, false, false, 9, 9);
1492+
}
1493+
1494+
Y_UNIT_TEST(JsonStorageListingV1GroupIdFilter) {
1495+
JsonStorage9Nodes9GroupsListingTest("v1", true, false, false, 1, 9);
1496+
}
1497+
1498+
Y_UNIT_TEST(JsonStorageListingV2GroupIdFilter) {
1499+
JsonStorage9Nodes9GroupsListingTest("v2", true, false, false, 1, 9);
1500+
}
1501+
1502+
Y_UNIT_TEST(JsonStorageListingV1NodeIdFilter) {
1503+
JsonStorage9Nodes9GroupsListingTest("v1", false, true, false, 8, 8);
1504+
}
1505+
1506+
Y_UNIT_TEST(JsonStorageListingV2NodeIdFilter) {
1507+
JsonStorage9Nodes9GroupsListingTest("v2", false, true, false, 8, 8);
1508+
}
1509+
1510+
Y_UNIT_TEST(JsonStorageListingV1PDiskIdFilter) {
1511+
JsonStorage9Nodes9GroupsListingTest("v1", false, true, true, 4, 8);
1512+
JsonStorage9Nodes9GroupsListingTest("v1", false, true, true, 4, 8);
1513+
}
1514+
1515+
Y_UNIT_TEST(JsonStorageListingV2PDiskIdFilter) {
1516+
JsonStorage9Nodes9GroupsListingTest("v2", false, true, true, 4, 8);
1517+
}
13281518
}

0 commit comments

Comments
 (0)