Files
upstream-centrifugo/internal/config/cache_test.go
upstream-mirror b352a9a30d
Some checks failed
test / Lint (push) Failing after 3s
test / Test with Go 1.26.8 (push) Failing after 2s
snapshot of https://github.com/centrifugal/centrifugo.git (master, 2026-09-16; blobs > 131072B omitted)
2026-09-16 01:17:21 +05:00

81 lines
2.5 KiB
Go

package config
import (
"math"
"strconv"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestRollingCache(t *testing.T) {
size := 30
shardCount := 1
cache := newRollingCache(size, shardCount)
// Testing Set.
channel := "channel1"
value := channelOptionsResult{nsName: "value1"}
ttl := 200 * time.Millisecond
cache.Set(channel, value, ttl)
// Testing Get after Set.
gotValue, ok := cache.Get(channel)
require.True(t, ok)
require.Equal(t, value, gotValue)
// Testing Get after expiry.
time.Sleep(400 * time.Millisecond)
_, ok = cache.Get(channel)
require.False(t, ok)
// Testing if data rolls over.
// Setting more data than cache size, to see if rolling over works without errors.
for i := 0; i < size+10; i++ {
channel := "channel" + strconv.Itoa(i)
value := channelOptionsResult{nsName: "value" + strconv.Itoa(i)}
cache.Set(channel, value, ttl)
}
// The first 10 items should have been rolled over and replaced.
// So, channel0, channel1, ... channel9 should no longer be in the cache.
for i := 0; i < 10; i++ {
channel := "channel" + strconv.Itoa(i)
_, ok = cache.Get(channel)
require.False(t, ok, channel)
}
// Whereas, the items from channel10 onwards should still be there.
for i := 10; i < size+10; i++ {
channel := "channel" + strconv.Itoa(i)
gotValue, ok := cache.Get(channel)
require.True(t, ok)
require.Equal(t, channelOptionsResult{nsName: "value" + strconv.Itoa(i)}, gotValue)
}
}
// TestRollingCacheIndexOverflow guards against the rolling index wrapping into
// negative values. The index is bumped on every Set, so on a long-running node
// it eventually overflows; with a signed counter the wrap made the modulo
// negative and Set panicked with "index out of range".
func TestRollingCacheIndexOverflow(t *testing.T) {
cache := newRollingCache(channelOptionsCacheSize, 1)
shard := cache.shardForKey("channel")
shard.index.Store(math.MaxUint32) // Next Set wraps the index.
ttl := time.Minute
for i := 0; i < 2*channelOptionsCacheSize; i++ {
channel := "channel" + strconv.Itoa(i)
cache.Set(channel, channelOptionsResult{nsName: "value" + strconv.Itoa(i)}, ttl)
}
// The most recent shardSize items must still be readable after the wrap.
for i := channelOptionsCacheSize; i < 2*channelOptionsCacheSize; i++ {
channel := "channel" + strconv.Itoa(i)
gotValue, ok := cache.Get(channel)
require.True(t, ok, channel)
require.Equal(t, channelOptionsResult{nsName: "value" + strconv.Itoa(i)}, gotValue)
}
}