Regression: old code had a `default` branch that spawned an async goroutine. If the goroutine sent successfully, wg.Done() was never called — wg leak. This test verifies wg stays balanced after many addAddition calls.
(t *testing.T)
| 304 | // If the goroutine sent successfully, wg.Done() was never called — wg leak. |
| 305 | // This test verifies wg stays balanced after many addAddition calls. |
| 306 | func TestAddAddition_WgBalance(t *testing.T) { |
| 307 | ctx, cancel := context.WithCancel(context.Background()) |
| 308 | defer cancel() |
| 309 | pool := newTestBasePool(ctx, cancel) |
| 310 | |
| 311 | const N = 100 |
| 312 | // drain concurrently so addAddition never blocks on a full buffer |
| 313 | var received int32 |
| 314 | go func() { |
| 315 | for range pool.additionCh { |
| 316 | atomic.AddInt32(&received, 1) |
| 317 | pool.wg.Done() |
| 318 | } |
| 319 | }() |
| 320 | |
| 321 | for i := 0; i < N; i++ { |
| 322 | pool.addAddition(&Unit{path: "/x", source: parsers.WordSource}) |
| 323 | } |
| 324 | |
| 325 | mustFinish(t, 2*time.Second, "wg.Wait hung — wg counter leaked", func() { |
| 326 | pool.wg.Wait() |
| 327 | }) |
| 328 | close(pool.additionCh) // stop drain goroutine |
| 329 | if r := atomic.LoadInt32(&received); r != N { |
| 330 | t.Fatalf("received %d items, want %d", r, N) |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | func TestAddAddition_FullBufferUnblocksOnCancel(t *testing.T) { |
| 335 | ctx, cancel := context.WithCancel(context.Background()) |
nothing calls this directly
no test coverage detected