@@ -601,6 +601,89 @@ Y_UNIT_TEST_SUITE(Viewer) {
601601 StorageSpaceTest (" space" , NKikimrWhiteboard::EFlag::Green, 90 , 100 , true );
602602 }
603603
604+ const TPathId SHARED_DOMAIN_KEY = {7000000000 , 1 };
605+ const TPathId SERVERLESS_DOMAIN_KEY = {7000000000 , 2 };
606+ const TPathId SERVERLESS_TABLE = {7000000001 , 2 };
607+
608+ void ChangeNavigateKeySetResultServerless (TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr* ev,
609+ TTestActorRuntime& runtime) {
610+ TSchemeCacheNavigate::TEntry& entry ((*ev)->Get ()->Request ->ResultSet .front ());
611+ TString path = CanonizePath (entry.Path );
612+ if (path == " /Root/serverless" || entry.TableId .PathId == SERVERLESS_DOMAIN_KEY) {
613+ entry.Status = TSchemeCacheNavigate::EStatus::Ok;
614+ entry.Kind = TSchemeCacheNavigate::EKind::KindExtSubdomain;
615+ entry.DomainInfo = MakeIntrusive<TDomainInfo>(SERVERLESS_DOMAIN_KEY, SHARED_DOMAIN_KEY);
616+ } else if (path == " /Root/shared" || entry.TableId .PathId == SHARED_DOMAIN_KEY) {
617+ entry.Status = TSchemeCacheNavigate::EStatus::Ok;
618+ entry.Kind = TSchemeCacheNavigate::EKind::KindExtSubdomain;
619+ entry.DomainInfo = MakeIntrusive<TDomainInfo>(SHARED_DOMAIN_KEY, SHARED_DOMAIN_KEY);
620+ auto domains = runtime.GetAppData ().DomainsInfo ;
621+ auto domain = domains->Domains .begin ()->second ;
622+ ui64 hiveId = domains->GetHive (domain->DefaultHiveUid );
623+ entry.DomainInfo ->Params .SetHive (hiveId);
624+ } else if (path == " /Root/serverless/users" || entry.TableId .PathId == SERVERLESS_TABLE) {
625+ entry.Status = TSchemeCacheNavigate::EStatus::Ok;
626+ entry.Kind = TSchemeCacheNavigate::EKind::KindTable;
627+ entry.DomainInfo = MakeIntrusive<TDomainInfo>(SERVERLESS_DOMAIN_KEY, SHARED_DOMAIN_KEY);
628+ auto dirEntryInfo = MakeIntrusive<TSchemeCacheNavigate::TDirEntryInfo>();
629+ dirEntryInfo->Info .SetSchemeshardId (SERVERLESS_TABLE.OwnerId );
630+ dirEntryInfo->Info .SetPathId (SERVERLESS_TABLE.LocalPathId );
631+ entry.Self = dirEntryInfo;
632+ }
633+ }
634+
635+ void ChangeBoardInfoServerless (TEvStateStorage::TEvBoardInfo::TPtr* ev,
636+ const std::vector<size_t >& sharedDynNodes = {},
637+ const std::vector<size_t >& exclusiveDynNodes = {}) {
638+ auto *record = (*ev)->Get ();
639+ using EStatus = TEvStateStorage::TEvBoardInfo::EStatus;
640+ if (record->Path == " gpc+/Root/serverless" && !exclusiveDynNodes.empty ()) {
641+ const_cast <EStatus&>(record->Status ) = EStatus::Ok;
642+ for (auto exclusiveDynNodeId : exclusiveDynNodes) {
643+ TActorId actorOnExclusiveDynNode = TActorId (exclusiveDynNodeId, 0 , 0 , 0 );
644+ record->InfoEntries [actorOnExclusiveDynNode] = {};
645+ }
646+ } else if (record->Path == " gpc+/Root/shared" && !sharedDynNodes.empty ()) {
647+ const_cast <EStatus&>(record->Status ) = EStatus::Ok;
648+ for (auto sharedDynNodeId : sharedDynNodes) {
649+ TActorId actorOnSharedDynNode = TActorId (sharedDynNodeId, 0 , 0 , 0 );
650+ record->InfoEntries [actorOnSharedDynNode] = {};
651+ }
652+ }
653+ }
654+
655+ void ChangeResponseHiveNodeStatsServerless (TEvHive::TEvResponseHiveNodeStats::TPtr* ev,
656+ size_t sharedDynNode = 0 ,
657+ size_t exclusiveDynNode = 0 ,
658+ size_t exclusiveDynNodeWithTablet = 0 ) {
659+ auto &record = (*ev)->Get ()->Record ;
660+ if (sharedDynNode) {
661+ auto *sharedNodeStats = record.MutableNodeStats ()->Add ();
662+ sharedNodeStats->SetNodeId (sharedDynNode);
663+ sharedNodeStats->MutableNodeDomain ()->SetSchemeShard (SHARED_DOMAIN_KEY.OwnerId );
664+ sharedNodeStats->MutableNodeDomain ()->SetPathId (SHARED_DOMAIN_KEY.LocalPathId );
665+ }
666+
667+ if (exclusiveDynNode) {
668+ auto *exclusiveNodeStats = record.MutableNodeStats ()->Add ();
669+ exclusiveNodeStats->SetNodeId (exclusiveDynNode);
670+ exclusiveNodeStats->MutableNodeDomain ()->SetSchemeShard (SERVERLESS_DOMAIN_KEY.OwnerId );
671+ exclusiveNodeStats->MutableNodeDomain ()->SetPathId (SERVERLESS_DOMAIN_KEY.LocalPathId );
672+ }
673+
674+ if (exclusiveDynNodeWithTablet) {
675+ auto *exclusiveDynNodeWithTabletStats = record.MutableNodeStats ()->Add ();
676+ exclusiveDynNodeWithTabletStats->SetNodeId (exclusiveDynNodeWithTablet);
677+ exclusiveDynNodeWithTabletStats->MutableNodeDomain ()->SetSchemeShard (SERVERLESS_DOMAIN_KEY.OwnerId );
678+ exclusiveDynNodeWithTabletStats->MutableNodeDomain ()->SetPathId (SERVERLESS_DOMAIN_KEY.LocalPathId );
679+
680+ auto *stateStats = exclusiveDynNodeWithTabletStats->MutableStateStats ()->Add ();
681+ stateStats->SetTabletType (NKikimrTabletBase::TTabletTypes::DataShard);
682+ stateStats->SetVolatileState (NKikimrHive::TABLET_VOLATILE_STATE_RUNNING);
683+ stateStats->SetCount (1 );
684+ }
685+ }
686+
604687 Y_UNIT_TEST (ServerlessNodesPage)
605688 {
606689 TPortManager tp;
@@ -622,7 +705,7 @@ Y_UNIT_TEST_SUITE(Viewer) {
622705 TAutoPtr<IEventHandle> handle;
623706
624707 THttpRequest httpReq (HTTP_METHOD_GET);
625- httpReq.CgiParameters .emplace (" tenant " , " /Root/serverless" );
708+ httpReq.CgiParameters .emplace (" path " , " /Root/serverless" );
626709 httpReq.CgiParameters .emplace (" tablets" , " true" );
627710 httpReq.CgiParameters .emplace (" enums" , " true" );
628711 httpReq.CgiParameters .emplace (" sort" , " " );
@@ -631,6 +714,39 @@ Y_UNIT_TEST_SUITE(Viewer) {
631714 TMonService2HttpRequest monReq (nullptr , &httpReq, nullptr , page.Get (), " /json/nodes" , nullptr );
632715 auto request = MakeHolder<NMon::TEvHttpInfo>(monReq);
633716
717+ size_t staticNodeId = 0 ;
718+ size_t sharedDynNodeId = 0 ;
719+ auto observerFunc = [&](TAutoPtr<IEventHandle>& ev) {
720+ switch (ev->GetTypeRewrite ()) {
721+ case TEvTxProxySchemeCache::EvNavigateKeySetResult: {
722+ auto *x = reinterpret_cast <TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr*>(&ev);
723+ ChangeNavigateKeySetResultServerless (x, runtime);
724+ break ;
725+ }
726+ case TEvInterconnect::EvNodesInfo: {
727+ auto *x = reinterpret_cast <TEvInterconnect::TEvNodesInfo::TPtr*>(&ev);
728+ TVector<TEvInterconnect::TNodeInfo> &nodes = (*x)->Get ()->Nodes ;
729+ UNIT_ASSERT_EQUAL (nodes.size (), 2 );
730+ staticNodeId = nodes[0 ];
731+ sharedDynNodeId = nodes[1 ];
732+ break ;
733+ }
734+ case TEvStateStorage::EvBoardInfo: {
735+ auto *x = reinterpret_cast <TEvStateStorage::TEvBoardInfo::TPtr*>(&ev);
736+ ChangeBoardInfoServerless (x, { sharedDynNodeId });
737+ break ;
738+ }
739+ case TEvHive::EvResponseHiveNodeStats: {
740+ auto *x = reinterpret_cast <TEvHive::TEvResponseHiveNodeStats::TPtr*>(&ev);
741+ ChangeResponseHiveNodeStatsServerless (x, sharedDynNodeId);
742+ break ;
743+ }
744+ }
745+
746+ return TTestActorRuntime::EEventAction::PROCESS;
747+ };
748+ runtime.SetObserverFunc (observerFunc);
749+
634750 runtime.Send (new IEventHandle (NKikimr::NViewer::MakeViewerID (0 ), sender, request.Release (), 0 ));
635751 NMon::TEvHttpInfoRes* result = runtime.GrabEdgeEvent <NMon::TEvHttpInfoRes>(handle);
636752
@@ -669,7 +785,7 @@ Y_UNIT_TEST_SUITE(Viewer) {
669785 TAutoPtr<IEventHandle> handle;
670786
671787 THttpRequest httpReq (HTTP_METHOD_GET);
672- httpReq.CgiParameters .emplace (" tenant " , " /Root/serverless" );
788+ httpReq.CgiParameters .emplace (" path " , " /Root/serverless" );
673789 httpReq.CgiParameters .emplace (" tablets" , " true" );
674790 httpReq.CgiParameters .emplace (" enums" , " true" );
675791 httpReq.CgiParameters .emplace (" sort" , " " );
@@ -683,6 +799,11 @@ Y_UNIT_TEST_SUITE(Viewer) {
683799 size_t exclusiveDynNodeId = 0 ;
684800 auto observerFunc = [&](TAutoPtr<IEventHandle>& ev) {
685801 switch (ev->GetTypeRewrite ()) {
802+ case TEvTxProxySchemeCache::EvNavigateKeySetResult: {
803+ auto *x = reinterpret_cast <TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr*>(&ev);
804+ ChangeNavigateKeySetResultServerless (x, runtime);
805+ break ;
806+ }
686807 case TEvInterconnect::EvNodesInfo: {
687808 auto *x = reinterpret_cast <TEvInterconnect::TEvNodesInfo::TPtr*>(&ev);
688809 TVector<TEvInterconnect::TNodeInfo> &nodes = (*x)->Get ()->Nodes ;
@@ -694,11 +815,12 @@ Y_UNIT_TEST_SUITE(Viewer) {
694815 }
695816 case TEvStateStorage::EvBoardInfo: {
696817 auto *x = reinterpret_cast <TEvStateStorage::TEvBoardInfo::TPtr*>(&ev);
697- auto *record = (*x)->Get ();
698- using EStatus = TEvStateStorage::TEvBoardInfo::EStatus;
699- const_cast <EStatus&>(record->Status ) = EStatus::Ok;
700- TActorId actorOnExclusiveDynNode = TActorId (exclusiveDynNodeId, 0 , 0 , 0 );
701- record->InfoEntries [actorOnExclusiveDynNode] = {};
818+ ChangeBoardInfoServerless (x, { sharedDynNodeId }, { exclusiveDynNodeId });
819+ break ;
820+ }
821+ case TEvHive::EvResponseHiveNodeStats: {
822+ auto *x = reinterpret_cast <TEvHive::TEvResponseHiveNodeStats::TPtr*>(&ev);
823+ ChangeResponseHiveNodeStatsServerless (x, sharedDynNodeId, exclusiveDynNodeId);
702824 break ;
703825 }
704826 }
@@ -748,7 +870,7 @@ Y_UNIT_TEST_SUITE(Viewer) {
748870 TAutoPtr<IEventHandle> handle;
749871
750872 THttpRequest httpReq (HTTP_METHOD_GET);
751- httpReq.CgiParameters .emplace (" tenant " , " Root/shared" );
873+ httpReq.CgiParameters .emplace (" path " , " / Root/shared" );
752874 httpReq.CgiParameters .emplace (" tablets" , " true" );
753875 httpReq.CgiParameters .emplace (" enums" , " true" );
754876 httpReq.CgiParameters .emplace (" sort" , " " );
@@ -762,6 +884,11 @@ Y_UNIT_TEST_SUITE(Viewer) {
762884 size_t exclusiveDynNodeId = 0 ;
763885 auto observerFunc = [&](TAutoPtr<IEventHandle>& ev) {
764886 switch (ev->GetTypeRewrite ()) {
887+ case TEvTxProxySchemeCache::EvNavigateKeySetResult: {
888+ auto *x = reinterpret_cast <TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr*>(&ev);
889+ ChangeNavigateKeySetResultServerless (x, runtime);
890+ break ;
891+ }
765892 case TEvInterconnect::EvNodesInfo: {
766893 auto *x = reinterpret_cast <TEvInterconnect::TEvNodesInfo::TPtr*>(&ev);
767894 TVector<TEvInterconnect::TNodeInfo> &nodes = (*x)->Get ()->Nodes ;
@@ -773,11 +900,12 @@ Y_UNIT_TEST_SUITE(Viewer) {
773900 }
774901 case TEvStateStorage::EvBoardInfo: {
775902 auto *x = reinterpret_cast <TEvStateStorage::TEvBoardInfo::TPtr*>(&ev);
776- auto *record = (*x)->Get ();
777- using EStatus = TEvStateStorage::TEvBoardInfo::EStatus;
778- const_cast <EStatus&>(record->Status ) = EStatus::Ok;
779- TActorId actorOnSharedDynNode = TActorId (sharedDynNodeId, 0 , 0 , 0 );
780- record->InfoEntries [actorOnSharedDynNode] = {};
903+ ChangeBoardInfoServerless (x, { sharedDynNodeId }, { exclusiveDynNodeId });
904+ break ;
905+ }
906+ case TEvHive::EvResponseHiveNodeStats: {
907+ auto *x = reinterpret_cast <TEvHive::TEvResponseHiveNodeStats::TPtr*>(&ev);
908+ ChangeResponseHiveNodeStatsServerless (x, sharedDynNodeId, exclusiveDynNodeId);
781909 break ;
782910 }
783911 }
@@ -827,7 +955,6 @@ Y_UNIT_TEST_SUITE(Viewer) {
827955 TAutoPtr<IEventHandle> handle;
828956
829957 THttpRequest httpReq (HTTP_METHOD_GET);
830- httpReq.CgiParameters .emplace (" tenant" , " /Root/serverless" );
831958 httpReq.CgiParameters .emplace (" path" , " /Root/serverless/users" );
832959 httpReq.CgiParameters .emplace (" tablets" , " true" );
833960 httpReq.CgiParameters .emplace (" enums" , " true" );
@@ -837,10 +964,6 @@ Y_UNIT_TEST_SUITE(Viewer) {
837964 TMonService2HttpRequest monReq (nullptr , &httpReq, nullptr , page.Get (), " /json/nodes" , nullptr );
838965 auto request = MakeHolder<NMon::TEvHttpInfo>(monReq);
839966
840- const TPathId SERVERLESS_DOMAIN_KEY = {7000000000 , 2 };
841- const TPathId SHARED_DOMAIN_KEY = {7000000000 , 1 };
842- const TPathId SERVERLESS_TABLE = {7000000001 , 2 };
843-
844967 size_t staticNodeId = 0 ;
845968 size_t sharedDynNodeId = 0 ;
846969 size_t exclusiveDynNodeId = 0 ;
@@ -849,29 +972,7 @@ Y_UNIT_TEST_SUITE(Viewer) {
849972 switch (ev->GetTypeRewrite ()) {
850973 case TEvTxProxySchemeCache::EvNavigateKeySetResult: {
851974 auto *x = reinterpret_cast <TEvTxProxySchemeCache::TEvNavigateKeySetResult::TPtr*>(&ev);
852- TSchemeCacheNavigate::TEntry& entry ((*x)->Get ()->Request ->ResultSet .front ());
853- TString path = CanonizePath (entry.Path );
854- if (path == " /Root/serverless" || entry.TableId .PathId == SERVERLESS_DOMAIN_KEY) {
855- entry.Status = TSchemeCacheNavigate::EStatus::Ok;
856- entry.Kind = TSchemeCacheNavigate::EKind::KindExtSubdomain;
857- entry.DomainInfo = MakeIntrusive<TDomainInfo>(SERVERLESS_DOMAIN_KEY, SHARED_DOMAIN_KEY);
858- } else if (path == " /Root/shared" || entry.TableId .PathId == SHARED_DOMAIN_KEY) {
859- entry.Status = TSchemeCacheNavigate::EStatus::Ok;
860- entry.Kind = TSchemeCacheNavigate::EKind::KindExtSubdomain;
861- entry.DomainInfo = MakeIntrusive<TDomainInfo>(SHARED_DOMAIN_KEY, SHARED_DOMAIN_KEY);
862- auto domains = runtime.GetAppData ().DomainsInfo ;
863- auto domain = domains->Domains .begin ()->second ;
864- ui64 hiveId = domains->GetHive (domain->DefaultHiveUid );
865- entry.DomainInfo ->Params .SetHive (hiveId);
866- } else if (path == " /Root/serverless/users" || entry.TableId .PathId == SERVERLESS_TABLE) {
867- entry.Status = TSchemeCacheNavigate::EStatus::Ok;
868- entry.Kind = TSchemeCacheNavigate::EKind::KindTable;
869- entry.DomainInfo = MakeIntrusive<TDomainInfo>(SERVERLESS_DOMAIN_KEY, SHARED_DOMAIN_KEY);
870- auto dirEntryInfo = MakeIntrusive<TSchemeCacheNavigate::TDirEntryInfo>();
871- dirEntryInfo->Info .SetSchemeshardId (SERVERLESS_TABLE.OwnerId );
872- dirEntryInfo->Info .SetPathId (SERVERLESS_TABLE.LocalPathId );
873- entry.Self = dirEntryInfo;
874- }
975+ ChangeNavigateKeySetResultServerless (x, runtime);
875976 break ;
876977 }
877978 case TEvInterconnect::EvNodesInfo: {
@@ -886,38 +987,12 @@ Y_UNIT_TEST_SUITE(Viewer) {
886987 }
887988 case TEvStateStorage::EvBoardInfo: {
888989 auto *x = reinterpret_cast <TEvStateStorage::TEvBoardInfo::TPtr*>(&ev);
889- auto *record = (*x)->Get ();
890- using EStatus = TEvStateStorage::TEvBoardInfo::EStatus;
891- const_cast <EStatus&>(record->Status ) = EStatus::Ok;
892- TActorId actorOnExclusiveDynNode = TActorId (exclusiveDynNodeId, 0 , 0 , 0 );
893- record->InfoEntries [actorOnExclusiveDynNode] = {};
894- TActorId actorOnSecondExclusiveDynNode = TActorId (secondExclusiveDynNodeId, 0 , 0 , 0 );
895- record->InfoEntries [actorOnSecondExclusiveDynNode] = {};
990+ ChangeBoardInfoServerless (x, { sharedDynNodeId }, { exclusiveDynNodeId, secondExclusiveDynNodeId });
896991 break ;
897992 }
898993 case TEvHive::EvResponseHiveNodeStats: {
899994 auto *x = reinterpret_cast <TEvHive::TEvResponseHiveNodeStats::TPtr*>(&ev);
900- auto &record = (*x)->Get ()->Record ;
901- auto *sharedNodeStats = record.MutableNodeStats ()->Add ();
902- sharedNodeStats->SetNodeId (sharedDynNodeId);
903- sharedNodeStats->MutableNodeDomain ()->SetSchemeShard (SHARED_DOMAIN_KEY.OwnerId );
904- sharedNodeStats->MutableNodeDomain ()->SetPathId (SHARED_DOMAIN_KEY.LocalPathId );
905-
906- auto *exclusiveNodeStats = record.MutableNodeStats ()->Add ();
907- exclusiveNodeStats->SetNodeId (exclusiveDynNodeId);
908- exclusiveNodeStats->MutableNodeDomain ()->SetSchemeShard (SERVERLESS_DOMAIN_KEY.OwnerId );
909- exclusiveNodeStats->MutableNodeDomain ()->SetPathId (SERVERLESS_DOMAIN_KEY.LocalPathId );
910-
911- auto *secondExclusiveNodeStats = record.MutableNodeStats ()->Add ();
912- secondExclusiveNodeStats->SetNodeId (secondExclusiveDynNodeId);
913- secondExclusiveNodeStats->MutableNodeDomain ()->SetSchemeShard (SERVERLESS_DOMAIN_KEY.OwnerId );
914- secondExclusiveNodeStats->MutableNodeDomain ()->SetPathId (SERVERLESS_DOMAIN_KEY.LocalPathId );
915-
916- // filtered one datashard from /Root/serverless/users
917- auto *stateStats = secondExclusiveNodeStats->MutableStateStats ()->Add ();
918- stateStats->SetTabletType (NKikimrTabletBase::TTabletTypes::DataShard);
919- stateStats->SetVolatileState (NKikimrHive::TABLET_VOLATILE_STATE_RUNNING);
920- stateStats->SetCount (1 );
995+ ChangeResponseHiveNodeStatsServerless (x, sharedDynNodeId, exclusiveDynNodeId, secondExclusiveDynNodeId);
921996 break ;
922997 }
923998 }
0 commit comments