| 269 | } |
| 270 | |
| 271 | func TestPathLockRace(t *testing.T) { |
| 272 | pl := NewLocker() |
| 273 | |
| 274 | counter := 0 |
| 275 | hitError := false |
| 276 | |
| 277 | wg := new(sync.WaitGroup) |
| 278 | |
| 279 | numGoroutines := 100 |
| 280 | for range numGoroutines { |
| 281 | wg.Go(func() { |
| 282 | // Pick from three different path values that should all be |
| 283 | // covered by the same lock. |
| 284 | path := "/some/path/a/b/c" |
| 285 | for range rand.Intn(3) { |
| 286 | path = filepath.Dir(path) |
| 287 | } |
| 288 | |
| 289 | lock, err := pl.Lock(path) |
| 290 | if err != nil { |
| 291 | t.Logf("Unexpected path lock error: %v", err) |
| 292 | |
| 293 | hitError = true |
| 294 | |
| 295 | return |
| 296 | } |
| 297 | |
| 298 | counter++ |
| 299 | |
| 300 | lock.Unlock() |
| 301 | }) |
| 302 | } |
| 303 | |
| 304 | wg.Wait() |
| 305 | |
| 306 | if hitError { |
| 307 | t.Fatal("Hit unexpected error locking paths") |
| 308 | } |
| 309 | |
| 310 | if counter != numGoroutines { |
| 311 | t.Fatalf("counter %v != numgoroutines %v", counter, numGoroutines) |
| 312 | } |
| 313 | } |