@@ -3961,6 +3961,7 @@ Y_UNIT_TEST_SUITE(THiveTest) {
3961
3961
// this value of MaxNodeUsageToKick is selected specifically to make test scenario work
3962
3962
// in link with number of tablets and values of network usage metrics used below
3963
3963
app.HiveConfig .SetMaxNodeUsageToKick (0.01 );
3964
+ app.HiveConfig .SetNodeUsageRangeToKick (0 );
3964
3965
app.HiveConfig .SetEmergencyBalancerInflight (1 ); // to ensure fair distribution
3965
3966
});
3966
3967
@@ -4933,6 +4934,75 @@ Y_UNIT_TEST_SUITE(THiveTest) {
4933
4934
UNIT_ASSERT_VALUES_EQUAL (newDistribution[1 ].size (), TABLETS_PER_NODE - 1 );
4934
4935
}
4935
4936
4937
+ Y_UNIT_TEST (TestHiveBalancerHighUsage) {
4938
+ static constexpr ui64 NUM_NODES = 2 ;
4939
+ TTestBasicRuntime runtime (2 , false );
4940
+ Setup (runtime, true , 1 , [](TAppPrepare& app) {
4941
+ app.HiveConfig .SetTabletKickCooldownPeriod (0 );
4942
+ app.HiveConfig .SetResourceChangeReactionPeriod (0 );
4943
+ });
4944
+ const int nodeBase = runtime.GetNodeId (0 );
4945
+ TActorId senderA = runtime.AllocateEdgeActor ();
4946
+ const ui64 hiveTablet = MakeDefaultHiveID ();
4947
+ const ui64 testerTablet = MakeTabletID (false , 1 );
4948
+
4949
+ auto getDistribution = [hiveTablet, nodeBase, senderA, &runtime]() -> std::array<std::vector<ui64>, NUM_NODES> {
4950
+ std::array<std::vector<ui64>, NUM_NODES> nodeTablets = {};
4951
+ {
4952
+ runtime.SendToPipe (hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo ());
4953
+ TAutoPtr<IEventHandle> handle;
4954
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow <TEvHive::TEvResponseHiveInfo>(handle);
4955
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record .GetTablets ()) {
4956
+ UNIT_ASSERT_C (((int )tablet.GetNodeID () - nodeBase >= 0 ) && (tablet.GetNodeID () - nodeBase < NUM_NODES),
4957
+ " nodeId# " << tablet.GetNodeID () << " nodeBase# " << nodeBase);
4958
+ nodeTablets[tablet.GetNodeID () - nodeBase].push_back (tablet.GetTabletID ());
4959
+ }
4960
+ }
4961
+ return nodeTablets;
4962
+ };
4963
+
4964
+ CreateTestBootstrapper (runtime, CreateTestTabletInfo (hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
4965
+
4966
+ // wait for creation of nodes
4967
+ {
4968
+ TDispatchOptions options;
4969
+ options.FinalEvents .emplace_back (TEvLocal::EvStatus, NUM_NODES);
4970
+ runtime.DispatchEvents (options);
4971
+ }
4972
+
4973
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
4974
+ for (size_t i = 0 ; i < 2 ; ++i) {
4975
+ THolder<TEvHive::TEvCreateTablet> ev (new TEvHive::TEvCreateTablet (testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
4976
+ ev->Record .SetObjectId (i);
4977
+ ui64 tabletId = SendCreateTestTablet (runtime, hiveTablet, testerTablet, std::move (ev), 0 , true );
4978
+ MakeSureTabletIsUp (runtime, tabletId, 0 );
4979
+ }
4980
+
4981
+ auto initialDistribution = getDistribution ();
4982
+
4983
+ std::array<double , NUM_NODES> usages = {.89 , .91 };
4984
+ for (ui32 i = 0 ; i < 2 ; ++i) {
4985
+ for (ui32 node = 0 ; node < NUM_NODES; ++node) {
4986
+ TActorId sender = runtime.AllocateEdgeActor (node);
4987
+ THolder<TEvHive::TEvTabletMetrics> metrics = MakeHolder<TEvHive::TEvTabletMetrics>();
4988
+ metrics->Record .SetTotalNodeUsage (usages[node]);
4989
+
4990
+ runtime.SendToPipe (hiveTablet, sender, metrics.Release (), node);
4991
+ }
4992
+ }
4993
+
4994
+ {
4995
+ TDispatchOptions options;
4996
+ options.FinalEvents .emplace_back (NHive::TEvPrivate::EvBalancerOut);
4997
+ runtime.DispatchEvents (options, TDuration::Seconds (10 ));
4998
+ }
4999
+
5000
+ // Check that balancer moved no tablets
5001
+ auto newDistribution = getDistribution ();
5002
+
5003
+ UNIT_ASSERT_EQUAL (initialDistribution, newDistribution);
5004
+ }
5005
+
4936
5006
Y_UNIT_TEST (TestUpdateTabletsObjectUpdatesMetrics) {
4937
5007
TTestBasicRuntime runtime (1 , false );
4938
5008
Setup (runtime, true );
0 commit comments