44 "context"
55 "fmt"
66 "math"
7+ "math/rand"
78 "time"
89
910 . "github.com/pingcap/check"
@@ -292,7 +293,7 @@ func (s *testScatterRegionSuite) TestScatterCheck(c *C) {
292293 }
293294}
294295
295- func (s * testScatterRegionSuite ) TestScatterGroup (c * C ) {
296+ func (s * testScatterRegionSuite ) TestScatterGroupInConcurrency (c * C ) {
296297 opt := config .NewTestOptions ()
297298 tc := mockcluster .NewCluster (opt )
298299 // Add 5 stores.
@@ -318,43 +319,43 @@ func (s *testScatterRegionSuite) TestScatterGroup(c *C) {
318319 },
319320 }
320321
322+ // We send scatter interweave request for each group to simulate scattering multiple region groups in concurrency.
321323 for _ , testcase := range testcases {
322324 c .Logf (testcase .name )
323325 ctx , cancel := context .WithCancel (context .Background ())
324326 scatterer := NewRegionScatterer (ctx , tc )
325327 regionID := 1
326328 for i := 0 ; i < 100 ; i ++ {
327329 for j := 0 ; j < testcase .groupCount ; j ++ {
328- _ , err := scatterer .Scatter (tc .AddLeaderRegion (uint64 (regionID ), 1 , 2 , 3 ),
330+ scatterer .scatterRegion (tc .AddLeaderRegion (uint64 (regionID ), 1 , 2 , 3 ),
329331 fmt .Sprintf ("group-%v" , j ))
330- c .Assert (err , IsNil )
331332 regionID ++
332333 }
333- // insert region with no group
334- _ , err := scatterer .Scatter (tc .AddLeaderRegion (uint64 (regionID ), 1 , 2 , 3 ), "" )
335- c .Assert (err , IsNil )
336- regionID ++
337334 }
338335
339- for i := 0 ; i < testcase .groupCount ; i ++ {
340- // comparing the leader distribution
341- group := fmt .Sprintf ("group-%v" , i )
342- max := uint64 (0 )
343- min := uint64 (math .MaxUint64 )
344- groupDistribution , _ := scatterer .ordinaryEngine .selectedLeader .groupDistribution .Get (group )
345- for _ , count := range groupDistribution .(map [uint64 ]uint64 ) {
346- if count > max {
347- max = count
348- }
349- if count < min {
350- min = count
336+ checker := func (ss * selectedStores , expected uint64 , delta float64 ) {
337+ for i := 0 ; i < testcase .groupCount ; i ++ {
338+ // comparing the leader distribution
339+ group := fmt .Sprintf ("group-%v" , i )
340+ max := uint64 (0 )
341+ min := uint64 (math .MaxUint64 )
342+ groupDistribution , _ := ss .groupDistribution .Get (group )
343+ for _ , count := range groupDistribution .(map [uint64 ]uint64 ) {
344+ if count > max {
345+ max = count
346+ }
347+ if count < min {
348+ min = count
349+ }
351350 }
351+ c .Assert (math .Abs (float64 (max )- float64 (expected )), LessEqual , delta )
352+ c .Assert (math .Abs (float64 (min )- float64 (expected )), LessEqual , delta )
352353 }
353- // 100 regions divided 5 stores, each store expected to have about 20 regions.
354- c .Assert (min , LessEqual , uint64 (20 ))
355- c .Assert (max , GreaterEqual , uint64 (20 ))
356- c .Assert (max - min , LessEqual , uint64 (5 ))
357354 }
355+ // For leader, we expect each store have about 20 leader for each group
356+ checker (scatterer .ordinaryEngine .selectedLeader , 20 , 5 )
357+ // For peer, we expect each store have about 50 peers for each group
358+ checker (scatterer .ordinaryEngine .selectedPeer , 50 , 15 )
358359 cancel ()
359360 }
360361}
@@ -440,3 +441,38 @@ func (s *testScatterRegionSuite) TestSelectedStoreGC(c *C) {
440441 _ , ok = stores .GetGroupDistribution ("testgroup" )
441442 c .Assert (ok , Equals , false )
442443}
444+
445+ // TestRegionFromDifferentGroups test the multi regions. each region have its own group.
446+ // After scatter, the distribution for the whole cluster should be well.
447+ func (s * testScatterRegionSuite ) TestRegionFromDifferentGroups (c * C ) {
448+ opt := config .NewTestOptions ()
449+ tc := mockcluster .NewCluster (opt )
450+ // Add 6 stores.
451+ storeCount := 6
452+ for i := uint64 (1 ); i <= uint64 (storeCount ); i ++ {
453+ tc .AddRegionStore (i , 0 )
454+ }
455+ ctx , cancel := context .WithCancel (context .Background ())
456+ defer cancel ()
457+ scatterer := NewRegionScatterer (ctx , tc )
458+ regionCount := 50
459+ for i := 1 ; i <= regionCount ; i ++ {
460+ p := rand .Perm (storeCount )
461+ scatterer .scatterRegion (tc .AddLeaderRegion (uint64 (i ), uint64 (p [0 ])+ 1 , uint64 (p [1 ])+ 1 , uint64 (p [2 ])+ 1 ), fmt .Sprintf ("t%d" , i ))
462+ }
463+ check := func (ss * selectedStores ) {
464+ max := uint64 (0 )
465+ min := uint64 (math .MaxUint64 )
466+ for i := uint64 (1 ); i <= uint64 (storeCount ); i ++ {
467+ count := ss .totalCountByStore (i )
468+ if count > max {
469+ max = count
470+ }
471+ if count < min {
472+ min = count
473+ }
474+ }
475+ c .Assert (max - min , LessEqual , uint64 (2 ))
476+ }
477+ check (scatterer .ordinaryEngine .selectedPeer )
478+ }
0 commit comments