(t *testing.T)
| 232 | } |
| 233 | |
| 234 | func TestAutoForgetDelegate(t *testing.T) { |
| 235 | const forgetPeriod = time.Minute |
| 236 | registeredAt := time.Now() |
| 237 | readOnlyUpdated := time.Time{} |
| 238 | |
| 239 | tests := map[string]struct { |
| 240 | setup func(ringDesc *Desc) |
| 241 | expectedInstances []string |
| 242 | }{ |
| 243 | "no unhealthy instance in the ring": { |
| 244 | setup: func(ringDesc *Desc) { |
| 245 | ringDesc.AddIngester("instance-1", "1.1.1.1", "", nil, ACTIVE, registeredAt, false, readOnlyUpdated, nil) |
| 246 | }, |
| 247 | expectedInstances: []string{testInstanceID, "instance-1"}, |
| 248 | }, |
| 249 | "unhealthy instance in the ring that has NOTreached the forget period yet": { |
| 250 | setup: func(ringDesc *Desc) { |
| 251 | i := ringDesc.AddIngester("instance-1", "1.1.1.1", "", nil, ACTIVE, registeredAt, false, readOnlyUpdated, nil) |
| 252 | i.Timestamp = time.Now().Add(-forgetPeriod).Add(5 * time.Second).Unix() |
| 253 | ringDesc.Ingesters["instance-1"] = i |
| 254 | }, |
| 255 | expectedInstances: []string{testInstanceID, "instance-1"}, |
| 256 | }, |
| 257 | "unhealthy instance in the ring that has reached the forget period": { |
| 258 | setup: func(ringDesc *Desc) { |
| 259 | i := ringDesc.AddIngester("instance-1", "1.1.1.1", "", nil, ACTIVE, registeredAt, false, readOnlyUpdated, nil) |
| 260 | i.Timestamp = time.Now().Add(-forgetPeriod).Add(-5 * time.Second).Unix() |
| 261 | ringDesc.Ingesters["instance-1"] = i |
| 262 | }, |
| 263 | expectedInstances: []string{testInstanceID}, |
| 264 | }, |
| 265 | } |
| 266 | |
| 267 | for testName, testData := range tests { |
| 268 | t.Run(testName, func(t *testing.T) { |
| 269 | ctx := context.Background() |
| 270 | cfg := prepareBasicLifecyclerConfig() |
| 271 | cfg.HeartbeatPeriod = 100 * time.Millisecond |
| 272 | |
| 273 | testDelegate := &mockDelegate{} |
| 274 | |
| 275 | autoForgetDelegate := NewAutoForgetDelegate(forgetPeriod, testDelegate, log.NewNopLogger()) |
| 276 | lifecycler, store, err := prepareBasicLifecyclerWithDelegate(t, cfg, autoForgetDelegate) |
| 277 | require.NoError(t, err) |
| 278 | |
| 279 | // Setup the initial state of the ring. |
| 280 | require.NoError(t, store.CAS(ctx, testRingKey, func(interface{}) (out interface{}, retry bool, err error) { |
| 281 | ringDesc := NewDesc() |
| 282 | testData.setup(ringDesc) |
| 283 | return ringDesc, true, nil |
| 284 | })) |
| 285 | |
| 286 | // Start the lifecycler. |
| 287 | require.NoError(t, services.StartAndAwaitRunning(ctx, lifecycler)) |
| 288 | defer services.StopAndAwaitTerminated(ctx, lifecycler) //nolint:errcheck |
| 289 | |
| 290 | // Wait until an heartbeat has been sent. |
| 291 | test.Poll(t, time.Second, true, func() interface{} { |
nothing calls this directly
no test coverage detected