nolint: funlen, gocognit
(t *testing.T)
| 296 | |
| 297 | // nolint: funlen, gocognit |
| 298 | func TestHashMap_parallel(t *testing.T) { |
| 299 | m := New[int, int]() |
| 300 | |
| 301 | max := 10 |
| 302 | dur := 2 * time.Second |
| 303 | |
| 304 | do := func(t *testing.T, max int, d time.Duration, fn func(*testing.T, int)) <-chan error { |
| 305 | t.Helper() |
| 306 | done := make(chan error) |
| 307 | var times int64 |
| 308 | // This goroutines will terminate test in case if closure hangs. |
| 309 | go func() { |
| 310 | for { |
| 311 | select { |
| 312 | case <-time.After(d + 500*time.Millisecond): |
| 313 | if atomic.LoadInt64(×) == 0 { |
| 314 | done <- fmt.Errorf("closure was not executed even once, something blocks it") |
| 315 | } |
| 316 | close(done) |
| 317 | case <-done: |
| 318 | } |
| 319 | } |
| 320 | }() |
| 321 | go func() { |
| 322 | timer := time.NewTimer(d) |
| 323 | defer timer.Stop() |
| 324 | InfLoop: |
| 325 | for { |
| 326 | for i := 0; i < max; i++ { |
| 327 | select { |
| 328 | case <-timer.C: |
| 329 | break InfLoop |
| 330 | default: |
| 331 | } |
| 332 | fn(t, i) |
| 333 | atomic.AddInt64(×, 1) |
| 334 | } |
| 335 | } |
| 336 | close(done) |
| 337 | }() |
| 338 | return done |
| 339 | } |
| 340 | |
| 341 | wait := func(t *testing.T, done <-chan error) { |
| 342 | t.Helper() |
| 343 | if err := <-done; err != nil { |
| 344 | t.Error(err) |
| 345 | } |
| 346 | } |
| 347 | |
| 348 | // Initial fill. |
| 349 | for i := 0; i < max; i++ { |
| 350 | m.Set(i, i) |
| 351 | } |
| 352 | t.Run("set_get", func(t *testing.T) { |
| 353 | doneSet := do(t, max, dur, func(t *testing.T, i int) { |
| 354 | t.Helper() |
| 355 | m.Set(i, i) |
nothing calls this directly
no test coverage detected
searching dependent graphs…