karlseguin / ccache

A golang LRU Cache for high concurrency
MIT License
1.27k stars 118 forks source link

Fix flaky test #90

Closed miparnisari closed 7 months ago

miparnisari commented 7 months ago

Flaky test sen in https://github.com/karlseguin/ccache/actions/runs/6953182798/job/18917940507#step:4:7

go test -race -count=1 ./...
--- FAIL: Test_ConcurrentClearAndSet (0.09s)
    cache_test.go:438: expected true, got false
FAIL
FAIL    github.com/karlseguin/ccache/v3 [7](https://github.com/karlseguin/ccache/actions/runs/6953182798/job/18917940507#step:4:8).077s
?       github.com/karlseguin/ccache/v3/assert  [no test files]
FAIL
make: *** [Makefile:17: t] Error 1
Error: Process completed with exit code 2.
karlseguin commented 7 months ago

This version of the test reproduces the issue more reliably:

func Test_ConcurrentClearAndSet(t *testing.T) {
    for i := 0; i < 100000; i++ {
        var stop atomic.Bool
        var wg sync.WaitGroup

        cache := New(Configure[string]())
        r := func() {
            for !stop.Load() {
                cache.Set("a", "a", time.Minute)
            }
            wg.Done()
        }
        go r()
        wg.Add(1)
        cache.Clear()
        stop.Store(true)
        wg.Wait()
        cache.SyncUpdates()

        expectedCount := 0
        if cache.list.Head != nil {
            expectedCount = 1
        }
        assert.Equal(t, cache.ItemCount(), expectedCount)
    }
}

Haven't figured it out yet.

karlseguin commented 7 months ago

Slightly simplified replication. Have a vague sense of what's going on, but not sure how to fix it.

func Test_ClearSyncUpdates(t *testing.T) {
    for i := 0; i < 1000; i++ {
        cache := New(Configure[string]())
        go func() {
            cache.Set("a", "a", time.Minute)
            cache.Set("a", "a", time.Minute)
        }()
        cache.Clear()
        cache.SyncUpdates()

        expectedCount := 0
        if cache.list.Head != nil {
            expectedCount = 1
        }
        assert.Equal(t, cache.ItemCount(), expectedCount)
    }
}