TestManager_IdleTimeoutRacesWithOnCallBegin tests the case where firing of the idle timeout races with an incoming RPC. The test verifies that if the timer callback wins the race and puts the channel in idle, the RPCs can kick it out of idle. And if the RPCs win the race and keep the channel active,
(t *testing.T)
| 341 | // it out of idle. And if the RPCs win the race and keep the channel active, |
| 342 | // then the timer callback should not attempt to put the channel in idle mode. |
| 343 | func (s) TestManager_IdleTimeoutRacesWithOnCallBegin(t *testing.T) { |
| 344 | // Run multiple iterations to simulate different possibilities. |
| 345 | for i := 0; i < 20; i++ { |
| 346 | t.Run(fmt.Sprintf("iteration=%d", i), func(t *testing.T) { |
| 347 | var idlenessState racyState |
| 348 | enforcer := &racyEnforcer{t: t, state: &idlenessState} |
| 349 | |
| 350 | // Configure a large idle timeout so that we can control the |
| 351 | // race between the timer callback and RPCs. |
| 352 | mgr := NewManager(enforcer, time.Duration(10*time.Minute)) |
| 353 | defer mgr.Close() |
| 354 | mgr.ExitIdleMode() |
| 355 | |
| 356 | var wg sync.WaitGroup |
| 357 | wg.Add(1) |
| 358 | go func() { |
| 359 | defer wg.Done() |
| 360 | <-time.After(defaultTestIdleTimeout / 50) |
| 361 | mgr.handleIdleTimeout() |
| 362 | }() |
| 363 | for j := 0; j < 5; j++ { |
| 364 | wg.Add(1) |
| 365 | go func() { |
| 366 | defer wg.Done() |
| 367 | // Wait for the configured idle timeout and simulate an RPC to |
| 368 | // race with the idle timeout timer callback. |
| 369 | <-time.After(defaultTestIdleTimeout / 50) |
| 370 | mgr.OnCallBegin() |
| 371 | atomic.StoreInt32((*int32)(&idlenessState), int32(stateActiveRPCs)) |
| 372 | mgr.OnCallEnd() |
| 373 | }() |
| 374 | } |
| 375 | wg.Wait() |
| 376 | }) |
| 377 | } |
| 378 | } |
nothing calls this directly
no test coverage detected