MCPcopy Index your code
hub / github.com/golang/groupcache / TestNoDedup

Function TestNoDedup

groupcache_test.go:388–446  ·  view source on GitHub ↗

TestNoDedup tests invariants on the cache size when singleflight is unable to dedup calls.

(t *testing.T)

Source from the content-addressed store, hash-verified

386// TestNoDedup tests invariants on the cache size when singleflight is
387// unable to dedup calls.
388func TestNoDedup(t *testing.T) {
389 const testkey = "testkey"
390 const testval = "testval"
391 g := newGroup("testgroup", 1024, GetterFunc(func(_ context.Context, key string, dest Sink) error {
392 return dest.SetString(testval)
393 }), nil)
394
395 orderedGroup := &orderedFlightGroup{
396 stage1: make(chan bool),
397 stage2: make(chan bool),
398 orig: g.loadGroup,
399 }
400 // Replace loadGroup with our wrapper so we can control when
401 // loadGroup.Do is entered for each concurrent request.
402 g.loadGroup = orderedGroup
403
404 // Issue two idential requests concurrently. Since the cache is
405 // empty, it will miss. Both will enter load(), but we will only
406 // allow one at a time to enter singleflight.Do, so the callback
407 // function will be called twice.
408 resc := make(chan string, 2)
409 for i := 0; i < 2; i++ {
410 go func() {
411 var s string
412 if err := g.Get(dummyCtx, testkey, StringSink(&s)); err != nil {
413 resc <- "ERROR:" + err.Error()
414 return
415 }
416 resc <- s
417 }()
418 }
419
420 // Ensure both goroutines have entered the Do routine. This implies
421 // both concurrent requests have checked the cache, found it empty,
422 // and called load().
423 orderedGroup.stage1 <- true
424 orderedGroup.stage1 <- true
425 orderedGroup.stage2 <- true
426 orderedGroup.stage2 <- true
427
428 for i := 0; i < 2; i++ {
429 if s := <-resc; s != testval {
430 t.Errorf("result is %s want %s", s, testval)
431 }
432 }
433
434 const wantItems = 1
435 if g.mainCache.items() != wantItems {
436 t.Errorf("mainCache has %d items, want %d", g.mainCache.items(), wantItems)
437 }
438
439 // If the singleflight callback doesn't double-check the cache again
440 // upon entry, we would increment nbytes twice but the entry would
441 // only be in the cache once.
442 const wantBytes = int64(len(testkey) + len(testval))
443 if g.mainCache.nbytes != wantBytes {
444 t.Errorf("cache has %d bytes, want %d", g.mainCache.nbytes, wantBytes)
445 }

Callers

nothing calls this directly

Calls 6

newGroupFunction · 0.85
GetterFuncFuncType · 0.85
StringSinkFunction · 0.85
itemsMethod · 0.80
SetStringMethod · 0.65
GetMethod · 0.65

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…