testCacheConcurrentAccess tests concurrent cache operations.
(t *testing.T, c interfaces.Cache)
| 320 | |
| 321 | // testCacheConcurrentAccess tests concurrent cache operations. |
| 322 | func testCacheConcurrentAccess(t *testing.T, c interfaces.Cache) { |
| 323 | t.Run("concurrent_set_get", func(t *testing.T) { |
| 324 | const numGoroutines = 10 |
| 325 | |
| 326 | const numOperations = 20 |
| 327 | |
| 328 | results := make(chan error, numGoroutines*numOperations*2) // *2 for set and get |
| 329 | |
| 330 | // Launch concurrent goroutines |
| 331 | for i := 0; i < numGoroutines; i++ { |
| 332 | go func(goroutineID int) { |
| 333 | for j := 0; j < numOperations; j++ { |
| 334 | key := fmt.Sprintf("concurrent-%d-%d", goroutineID, j) |
| 335 | value := fmt.Sprintf("value-%d-%d", goroutineID, j) |
| 336 | |
| 337 | // Set operation |
| 338 | err := c.Set(key, value, time.Hour) |
| 339 | results <- err |
| 340 | |
| 341 | // Get operation |
| 342 | var result string |
| 343 | _, err = c.Get(key, &result) |
| 344 | results <- err |
| 345 | } |
| 346 | }(i) |
| 347 | } |
| 348 | |
| 349 | // Collect results |
| 350 | var errors []error |
| 351 | |
| 352 | for i := 0; i < numGoroutines*numOperations*2; i++ { |
| 353 | if err := <-results; err != nil { |
| 354 | errors = append(errors, err) |
| 355 | } |
| 356 | } |
| 357 | |
| 358 | // All operations should succeed |
| 359 | assert.Empty(t, errors, "Expected no errors from concurrent operations") |
| 360 | }) |
| 361 | |
| 362 | t.Run("concurrent_delete_clear", func(t *testing.T) { |
| 363 | // Pre-populate cache |
| 364 | for i := 0; i < 100; i++ { |
| 365 | key := fmt.Sprintf("delete-test-%d", i) |
| 366 | err := c.Set(key, fmt.Sprintf("value-%d", i), time.Hour) |
| 367 | require.NoError(t, err) |
| 368 | } |
| 369 | |
| 370 | const numGoroutines = 5 |
| 371 | results := make(chan error, numGoroutines) |
| 372 | |
| 373 | // Launch concurrent delete operations |
| 374 | for i := 0; i < numGoroutines; i++ { |
| 375 | go func(goroutineID int) { |
| 376 | if goroutineID == 0 { |
| 377 | // One goroutine clears the cache |
| 378 | results <- c.Clear() |
| 379 | } else { |
no test coverage detected