(t *testing.T)
| 2038 | } |
| 2039 | |
| 2040 | func TestRing_ShuffleShard_Shuffling(t *testing.T) { |
| 2041 | var ( |
| 2042 | numTenants = 1000 |
| 2043 | numInstances = 90 |
| 2044 | numZones = 3 |
| 2045 | shardSize = 3 |
| 2046 | |
| 2047 | // This is the expected theoretical distribution of matching instances |
| 2048 | // between different shards, given the settings above. It has been computed |
| 2049 | // using this spreadsheet: |
| 2050 | // https://docs.google.com/spreadsheets/d/1FXbiWTXi6bdERtamH-IfmpgFq1fNL4GP_KX_yJvbRi4/edit |
| 2051 | theoreticalMatchings = map[int]float64{ |
| 2052 | 0: 90.2239, |
| 2053 | 1: 9.55312, |
| 2054 | 2: 0.22217, |
| 2055 | 3: 0.00085, |
| 2056 | } |
| 2057 | ) |
| 2058 | |
| 2059 | // Initialise the ring instances. To have stable tests we generate tokens using a linear |
| 2060 | // distribution. Tokens within the same zone are evenly distributed too. |
| 2061 | instances := make(map[string]InstanceDesc, numInstances) |
| 2062 | for i := 0; i < numInstances; i++ { |
| 2063 | id := fmt.Sprintf("instance-%d", i) |
| 2064 | instances[id] = InstanceDesc{ |
| 2065 | Addr: fmt.Sprintf("127.0.0.%d", i), |
| 2066 | Timestamp: time.Now().Unix(), |
| 2067 | RegisteredTimestamp: time.Now().Unix(), |
| 2068 | State: ACTIVE, |
| 2069 | Tokens: generateTokensLinear(i, numInstances, 128), |
| 2070 | Zone: fmt.Sprintf("zone-%d", i%numZones), |
| 2071 | } |
| 2072 | } |
| 2073 | |
| 2074 | // Initialise the ring. |
| 2075 | ringDesc := &Desc{Ingesters: instances} |
| 2076 | ring := newRingForTesting(Config{ |
| 2077 | HeartbeatTimeout: time.Hour, |
| 2078 | ZoneAwarenessEnabled: true, |
| 2079 | }, false) |
| 2080 | ring.setRingStateFromDesc(ringDesc, false, false, false) |
| 2081 | |
| 2082 | // Compute the shard for each tenant. |
| 2083 | shards := map[string][]string{} |
| 2084 | |
| 2085 | for i := 1; i <= numTenants; i++ { |
| 2086 | tenantID := fmt.Sprintf("%d", i) |
| 2087 | r := ring.ShuffleShard(tenantID, shardSize) |
| 2088 | set, err := r.GetAllHealthy(Read) |
| 2089 | require.NoError(t, err) |
| 2090 | |
| 2091 | instances := make([]string, 0, len(set.Instances)) |
| 2092 | for _, instance := range set.Instances { |
| 2093 | instances = append(instances, instance.Addr) |
| 2094 | } |
| 2095 | |
| 2096 | shards[tenantID] = instances |
| 2097 | } |
nothing calls this directly
no test coverage detected