@@ -2523,6 +2523,111 @@ func TestRing_ShuffleShardWithLookback(t *testing.T) {
2523
2523
}
2524
2524
}
2525
2525
2526
+ func TestRing_ShuffleShardWithReadOnlyIngesters (t * testing.T ) {
2527
+ g := NewRandomTokenGenerator ()
2528
+
2529
+ const (
2530
+ userID = "user-1"
2531
+ )
2532
+
2533
+ tests := map [string ]struct {
2534
+ ringInstances map [string ]InstanceDesc
2535
+ ringReplicationFactor int
2536
+ shardSize int
2537
+ expectedSize int
2538
+ op Operation
2539
+ expectedToBePresent []string
2540
+ }{
2541
+ "single zone, shard size = 1, default scenario" : {
2542
+ ringInstances : map [string ]InstanceDesc {
2543
+ "instance-1" : {Addr : "127.0.0.1" , Zone : "zone-a" , State : ACTIVE , Tokens : g .GenerateTokens (NewDesc (), "instance-1" , "zone-a" , 128 , true )},
2544
+ "instance-2" : {Addr : "127.0.0.2" , Zone : "zone-a" , State : ACTIVE , Tokens : g .GenerateTokens (NewDesc (), "instance-2" , "zone-a" , 128 , true )},
2545
+ },
2546
+ ringReplicationFactor : 1 ,
2547
+ shardSize : 1 ,
2548
+ expectedSize : 1 ,
2549
+ },
2550
+ "single zone, shard size = 1, not filter ReadOnly" : {
2551
+ ringInstances : map [string ]InstanceDesc {
2552
+ "instance-1" : {Addr : "127.0.0.1" , Zone : "zone-a" , State : ACTIVE , Tokens : g .GenerateTokens (NewDesc (), "instance-1" , "zone-a" , 128 , true )},
2553
+ "instance-2" : {Addr : "127.0.0.2" , Zone : "zone-a" , State : READONLY , Tokens : g .GenerateTokens (NewDesc (), "instance-2" , "zone-a" , 128 , true )},
2554
+ },
2555
+ ringReplicationFactor : 1 ,
2556
+ shardSize : 2 ,
2557
+ expectedSize : 2 ,
2558
+ },
2559
+ "single zone, shard size = 4, do not filter other states" : {
2560
+ ringInstances : map [string ]InstanceDesc {
2561
+ "instance-1" : {Addr : "127.0.0.1" , Zone : "zone-a" , State : ACTIVE , Tokens : g .GenerateTokens (NewDesc (), "instance-1" , "zone-a" , 128 , true )},
2562
+ "instance-2" : {Addr : "127.0.0.2" , Zone : "zone-a" , State : JOINING , Tokens : g .GenerateTokens (NewDesc (), "instance-2" , "zone-a" , 128 , true )},
2563
+ "instance-3" : {Addr : "127.0.0.3" , Zone : "zone-a" , State : LEAVING , Tokens : g .GenerateTokens (NewDesc (), "instance-3" , "zone-a" , 128 , true )},
2564
+ "instance-4" : {Addr : "127.0.0.4" , Zone : "zone-a" , State : PENDING , Tokens : g .GenerateTokens (NewDesc (), "instance-4" , "zone-a" , 128 , true )},
2565
+ },
2566
+ ringReplicationFactor : 1 ,
2567
+ shardSize : 4 ,
2568
+ expectedSize : 4 ,
2569
+ },
2570
+ "single zone, shard size = 4, extend on readOnly" : {
2571
+ ringInstances : map [string ]InstanceDesc {
2572
+ "instance-1" : {Addr : "127.0.0.1" , Zone : "zone-a" , State : ACTIVE , Tokens : []uint32 {2 }},
2573
+ "instance-2" : {Addr : "127.0.0.2" , Zone : "zone-a" , State : ACTIVE , Tokens : []uint32 {4 }},
2574
+ "instance-3" : {Addr : "127.0.0.3" , Zone : "zone-a" , State : ACTIVE , Tokens : []uint32 {6 }},
2575
+ "instance-4" : {Addr : "127.0.0.4" , Zone : "zone-a" , State : READONLY , Tokens : []uint32 {1 , 3 , 5 }},
2576
+ },
2577
+ ringReplicationFactor : 1 ,
2578
+ shardSize : 2 ,
2579
+ expectedSize : 3 ,
2580
+ expectedToBePresent : []string {"instance-4" },
2581
+ },
2582
+ "rf = 3, shard size = 4, extend readOnly from different zones" : {
2583
+ ringInstances : map [string ]InstanceDesc {
2584
+ "instance-1" : {Addr : "127.0.0.1" , Zone : "zone-a" , State : ACTIVE , Tokens : []uint32 {2 }},
2585
+ "instance-2" : {Addr : "127.0.0.2" , Zone : "zone-b" , State : ACTIVE , Tokens : []uint32 {12 }},
2586
+ "instance-3" : {Addr : "127.0.0.3" , Zone : "zone-c" , State : ACTIVE , Tokens : []uint32 {22 }},
2587
+ "instance-4" : {Addr : "127.0.0.4" , Zone : "zone-a" , State : ACTIVE , Tokens : []uint32 {4 }},
2588
+ "instance-5" : {Addr : "127.0.0.5" , Zone : "zone-b" , State : ACTIVE , Tokens : []uint32 {14 }},
2589
+ "instance-6" : {Addr : "127.0.0.6" , Zone : "zone-c" , State : ACTIVE , Tokens : []uint32 {24 }},
2590
+ "instance-7" : {Addr : "127.0.0.7" , Zone : "zone-a" , State : READONLY , Tokens : []uint32 {1 , 3 }},
2591
+ "instance-8" : {Addr : "127.0.0.8" , Zone : "zone-b" , State : READONLY , Tokens : []uint32 {11 , 13 }},
2592
+ "instance-9" : {Addr : "127.0.0.9" , Zone : "zone-c" , State : READONLY , Tokens : []uint32 {21 , 23 }},
2593
+ },
2594
+ ringReplicationFactor : 3 ,
2595
+ shardSize : 6 ,
2596
+ expectedSize : 9 ,
2597
+ expectedToBePresent : []string {"instance-7" , "instance-8" , "instance-9" },
2598
+ },
2599
+ }
2600
+
2601
+ for testName , testData := range tests {
2602
+ t .Run (testName , func (t * testing.T ) {
2603
+ // Init the ring.
2604
+ ringDesc := & Desc {Ingesters : testData .ringInstances }
2605
+ for id , instance := range ringDesc .Ingesters {
2606
+ ringDesc .Ingesters [id ] = instance
2607
+ }
2608
+
2609
+ ring := Ring {
2610
+ cfg : Config {
2611
+ ReplicationFactor : testData .ringReplicationFactor ,
2612
+ },
2613
+ ringDesc : ringDesc ,
2614
+ ringTokens : ringDesc .GetTokens (),
2615
+ ringTokensByZone : ringDesc .getTokensByZone (),
2616
+ ringInstanceByToken : ringDesc .getTokensInfo (),
2617
+ ringZones : getZones (ringDesc .getTokensByZone ()),
2618
+ strategy : NewDefaultReplicationStrategy (),
2619
+ KVClient : & MockClient {},
2620
+ }
2621
+
2622
+ shardRing := ring .ShuffleShard (userID , testData .shardSize )
2623
+ assert .Equal (t , testData .expectedSize , shardRing .InstancesCount ())
2624
+ for _ , expectedInstance := range testData .expectedToBePresent {
2625
+ assert .True (t , shardRing .HasInstance (expectedInstance ))
2626
+ }
2627
+ })
2628
+ }
2629
+ }
2630
+
2526
2631
func TestRing_ShuffleShardWithLookback_CorrectnessWithFuzzy (t * testing.T ) {
2527
2632
// The goal of this test is NOT to ensure that the minimum required number of instances
2528
2633
// are returned at any given time, BUT at least all required instances are returned.
0 commit comments