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