@@ -4776,6 +4776,84 @@ Y_UNIT_TEST_SUITE(THiveTest) {
4776
4776
}
4777
4777
}
4778
4778
4779
+ Y_UNIT_TEST (TestHiveBalancerUselessNeighbourMoves) {
4780
+ // 7 tablets of same object, 3 nodes, one of nodes cannot run them
4781
+ // distribution should be (4, 3, 0)
4782
+ // this should trigger balancer, but not lead to any moves
4783
+ static constexpr ui64 NUM_NODES = 3 ;
4784
+ static constexpr ui64 NUM_TABLETS = 7 ;
4785
+ TTestBasicRuntime runtime (NUM_NODES, false );
4786
+ Setup (runtime, true , 1 , [](TAppPrepare& app) {
4787
+ app.HiveConfig .SetTabletKickCooldownPeriod (0 );
4788
+ app.HiveConfig .SetResourceChangeReactionPeriod (0 );
4789
+ app.HiveConfig .SetMetricsWindowSize (1 );
4790
+ });
4791
+ const int nodeBase = runtime.GetNodeId (0 );
4792
+ TActorId senderA = runtime.AllocateEdgeActor ();
4793
+ const ui64 hiveTablet = MakeDefaultHiveID ();
4794
+ const ui64 testerTablet = MakeTabletID (false , 1 );
4795
+
4796
+ auto getDistribution = [hiveTablet, nodeBase, senderA, &runtime]() -> std::array<std::vector<ui64>, NUM_NODES> {
4797
+ std::array<std::vector<ui64>, NUM_NODES> nodeTablets = {};
4798
+ {
4799
+ runtime.SendToPipe (hiveTablet, senderA, new TEvHive::TEvRequestHiveInfo ());
4800
+ TAutoPtr<IEventHandle> handle;
4801
+ TEvHive::TEvResponseHiveInfo* response = runtime.GrabEdgeEventRethrow <TEvHive::TEvResponseHiveInfo>(handle);
4802
+ for (const NKikimrHive::TTabletInfo& tablet : response->Record .GetTablets ()) {
4803
+ UNIT_ASSERT_C (((int )tablet.GetNodeID () - nodeBase >= 0 ) && (tablet.GetNodeID () - nodeBase < NUM_NODES),
4804
+ " nodeId# " << tablet.GetNodeID () << " nodeBase# " << nodeBase);
4805
+ nodeTablets[tablet.GetNodeID () - nodeBase].push_back (tablet.GetTabletID ());
4806
+ }
4807
+ }
4808
+ return nodeTablets;
4809
+ };
4810
+
4811
+ CreateTestBootstrapper (runtime, CreateTestTabletInfo (hiveTablet, TTabletTypes::Hive), &CreateDefaultHive);
4812
+
4813
+ // wait for creation of nodes
4814
+ {
4815
+ TDispatchOptions options;
4816
+ options.FinalEvents .emplace_back (TEvLocal::EvStatus, NUM_NODES);
4817
+ runtime.DispatchEvents (options);
4818
+ }
4819
+
4820
+ TTabletTypes::EType tabletType = TTabletTypes::Dummy;
4821
+ std::vector<ui64> tablets;
4822
+ tablets.reserve (NUM_TABLETS);
4823
+ for (size_t i = 0 ; i < NUM_TABLETS; ++i) {
4824
+ THolder<TEvHive::TEvCreateTablet> ev (new TEvHive::TEvCreateTablet (testerTablet, 100500 + i, tabletType, BINDED_CHANNELS));
4825
+ ev->Record .SetObjectId (1 );
4826
+ ev->Record .AddAllowedNodeIDs (nodeBase);
4827
+ ev->Record .AddAllowedNodeIDs (nodeBase + 1 );
4828
+ ui64 tabletId = SendCreateTestTablet (runtime, hiveTablet, testerTablet, std::move (ev), 0 , true );
4829
+ MakeSureTabletIsUp (runtime, tabletId, 0 );
4830
+ tablets.push_back (tabletId);
4831
+ }
4832
+
4833
+ auto initialDistribution = getDistribution ();
4834
+
4835
+ for (auto tablet : tablets) {
4836
+ THolder<TEvHive::TEvTabletMetrics> metrics = MakeHolder<TEvHive::TEvTabletMetrics>();
4837
+ NKikimrHive::TTabletMetrics* metric = metrics->Record .AddTabletMetrics ();
4838
+ metric->SetTabletID (tablet);
4839
+ metric->MutableResourceUsage ()->SetCPU (0 );
4840
+ metric->MutableResourceUsage ()->SetMemory (0 );
4841
+
4842
+ runtime.SendToPipe (hiveTablet, senderA, metrics.Release ());
4843
+ }
4844
+
4845
+ {
4846
+ TDispatchOptions options;
4847
+ options.FinalEvents .emplace_back (NHive::TEvPrivate::EvBalancerOut);
4848
+ runtime.DispatchEvents (options, TDuration::Seconds (10 ));
4849
+ }
4850
+
4851
+ // Check that balancer moved no tablets
4852
+ auto newDistribution = getDistribution ();
4853
+
4854
+ UNIT_ASSERT_EQUAL (initialDistribution, newDistribution);
4855
+ }
4856
+
4779
4857
Y_UNIT_TEST (TestHiveBalancerWithImmovableTablets) {
4780
4858
static constexpr ui64 TABLETS_PER_NODE = 10 ;
4781
4859
TTestBasicRuntime runtime (3 , false );
0 commit comments