TestConcurrentHasLink tests concurrent HasLink calls for race conditions. This test verifies that concurrent HasLink calls with matching functions don't produce inconsistent results due to temporary role creation/deletion races. Regression test for issue #1318.
(t *testing.T)
| 394 | // don't produce inconsistent results due to temporary role creation/deletion races. |
| 395 | // Regression test for issue #1318. |
| 396 | func TestConcurrentHasLink(t *testing.T) { |
| 397 | rm := NewRoleManager(10) |
| 398 | rm.AddMatchingFunc("keyMatch2", util.KeyMatch2) |
| 399 | |
| 400 | _ = rm.AddLink("alice", "admin") |
| 401 | _ = rm.AddLink("admin", "/data/*") |
| 402 | |
| 403 | expected, _ := rm.HasLink("alice", "/data/123") |
| 404 | |
| 405 | const numGoroutines = 20 |
| 406 | const numIterations = 100 |
| 407 | |
| 408 | var inconsistencies int64 |
| 409 | var wg sync.WaitGroup |
| 410 | |
| 411 | for i := 0; i < numGoroutines; i++ { |
| 412 | wg.Add(1) |
| 413 | go func() { |
| 414 | defer wg.Done() |
| 415 | for j := 0; j < numIterations; j++ { |
| 416 | result, err := rm.HasLink("alice", "/data/123") |
| 417 | if err != nil { |
| 418 | t.Errorf("HasLink failed: %v", err) |
| 419 | return |
| 420 | } else if result != expected { |
| 421 | atomic.AddInt64(&inconsistencies, 1) |
| 422 | } |
| 423 | } |
| 424 | }() |
| 425 | } |
| 426 | |
| 427 | wg.Wait() |
| 428 | |
| 429 | if inconsistencies > 0 { |
| 430 | t.Errorf("Found %d inconsistencies in %d total operations", |
| 431 | inconsistencies, numGoroutines*numIterations) |
| 432 | } |
| 433 | } |
nothing calls this directly
no test coverage detected
searching dependent graphs…