TestOptionsCloneMaintNotificationsRace verifies that cloning options via baseClient is safe when initConn concurrently writes MaintNotificationsConfig.Mode. Run with -race to detect the data race.
(t *testing.T)
| 398 | // baseClient is safe when initConn concurrently writes MaintNotificationsConfig.Mode. |
| 399 | // Run with -race to detect the data race. |
| 400 | func TestOptionsCloneMaintNotificationsRace(t *testing.T) { |
| 401 | opt := &Options{ |
| 402 | Addr: "localhost:6379", |
| 403 | MaintNotificationsConfig: &maintnotifications.Config{ |
| 404 | Mode: maintnotifications.ModeAuto, |
| 405 | }, |
| 406 | } |
| 407 | |
| 408 | bc := baseClient{opt: opt} |
| 409 | |
| 410 | var wg sync.WaitGroup |
| 411 | const iterations = 1000 |
| 412 | |
| 413 | // Writer: simulates initConn toggling MaintNotificationsConfig.Mode under optLock |
| 414 | wg.Add(1) |
| 415 | go func() { |
| 416 | defer wg.Done() |
| 417 | for i := 0; i < iterations; i++ { |
| 418 | bc.optLock.Lock() |
| 419 | bc.opt.MaintNotificationsConfig.Mode = maintnotifications.ModeDisabled |
| 420 | bc.optLock.Unlock() |
| 421 | |
| 422 | bc.optLock.Lock() |
| 423 | bc.opt.MaintNotificationsConfig.Mode = maintnotifications.ModeAuto |
| 424 | bc.optLock.Unlock() |
| 425 | } |
| 426 | }() |
| 427 | |
| 428 | // Reader: simulates newTx / withTimeout calling cloneOpt() (acquires RLock) |
| 429 | wg.Add(1) |
| 430 | go func() { |
| 431 | defer wg.Done() |
| 432 | for i := 0; i < iterations; i++ { |
| 433 | cloned := bc.cloneOpt() |
| 434 | _ = cloned |
| 435 | } |
| 436 | }() |
| 437 | |
| 438 | wg.Wait() |
| 439 | } |