TestThreadSafeCache tests the thread-safe wrapper
(t *testing.T)
| 250 | |
| 251 | // TestThreadSafeCache tests the thread-safe wrapper |
| 252 | func TestThreadSafeCache(t *testing.T) { |
| 253 | t.Run("Concurrent Access", func(t *testing.T) { |
| 254 | baseCache := NewLRUCache(100) |
| 255 | cache := NewThreadSafeCache(baseCache) |
| 256 | if cache == nil { |
| 257 | t.Fatal("NewThreadSafeCache returned nil") |
| 258 | } |
| 259 | |
| 260 | const numGoroutines = 10 |
| 261 | const numOperations = 100 |
| 262 | |
| 263 | var wg sync.WaitGroup |
| 264 | for i := 0; i < numGoroutines; i++ { |
| 265 | wg.Add(1) |
| 266 | go func(id int) { |
| 267 | defer wg.Done() |
| 268 | for j := 0; j < numOperations; j++ { |
| 269 | key := fmt.Sprintf("key-%d-%d", id, j) |
| 270 | cache.Put(key, j) |
| 271 | cache.Get(key) |
| 272 | if j%10 == 0 { |
| 273 | cache.Delete(key) |
| 274 | } |
| 275 | } |
| 276 | }(i) |
| 277 | } |
| 278 | |
| 279 | wg.Wait() |
| 280 | |
| 281 | // Should not panic and should have some items |
| 282 | if cache.Size() < 0 { |
| 283 | t.Error("Cache size should not be negative after concurrent operations") |
| 284 | } |
| 285 | }) |
| 286 | |
| 287 | t.Run("Interface Compatibility", func(t *testing.T) { |
| 288 | baseCache := NewLRUCache(2) |
| 289 | cache := NewThreadSafeCache(baseCache) |
| 290 | |
| 291 | // Test that all methods work through the interface |
| 292 | cache.Put("a", 1) |
| 293 | value, found := cache.Get("a") |
| 294 | if !found || value != 1 { |
| 295 | t.Errorf("Expected (1, true), got (%v, %v)", value, found) |
| 296 | } |
| 297 | |
| 298 | if cache.Size() != 1 { |
| 299 | t.Errorf("Expected size 1, got %d", cache.Size()) |
| 300 | } |
| 301 | |
| 302 | if cache.Capacity() != 2 { |
| 303 | t.Errorf("Expected capacity 2, got %d", cache.Capacity()) |
| 304 | } |
| 305 | |
| 306 | deleted := cache.Delete("a") |
| 307 | if !deleted { |
| 308 | t.Error("Expected Delete to return true") |
| 309 | } |
nothing calls this directly
no test coverage detected