Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 18 additions & 10 deletions test/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,40 @@ import (
)

type TestStatSink struct {
sync.Mutex
mu sync.Mutex
Record map[string]interface{}
}

func NewTestStatSink() *TestStatSink {
return &TestStatSink{
mu: sync.Mutex{},
Record: make(map[string]interface{}),
}
}

func (s *TestStatSink) Clear() {
s.Lock()
s.Record = map[string]interface{}{}
s.Unlock()
s.mu.Lock()
s.Record = make(map[string]interface{})
s.mu.Unlock()
}

func (s *TestStatSink) FlushCounter(name string, value uint64) {
s.Lock()
s.mu.Lock()
s.Record[name] = value
s.Unlock()
s.mu.Unlock()
}

func (s *TestStatSink) FlushGauge(name string, value uint64) {
s.Lock()
s.mu.Lock()
fmt.Println("FlushGauge", name, value)
s.Record[name] = value
s.Unlock()
s.mu.Unlock()
}

func (s *TestStatSink) FlushTimer(name string, value float64) {
s.Lock()
s.mu.Lock()
s.Record[name] = value
s.Unlock()
s.mu.Unlock()
}

func NewRateLimitRequest(domain string, descriptors [][][2]string, hitsAddend uint32) *pb.RateLimitRequest {
Expand Down
79 changes: 43 additions & 36 deletions test/redis/fixed_cache_impl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,38 +144,39 @@ func testRedis(usePerSecondRedis bool) func(*testing.T) {
}
}

func testLocalCacheStats(localCacheStats gostats.StatGenerator, statsStore gostats.Store, sink *common.TestStatSink,
expectedHitCount int, expectedMissCount int, expectedLookUpCount int, expectedExpiredCount int,
expectedEntryCount int,
func testLocalCacheStats(localCacheScopeName string, localCacheStats gostats.StatGenerator, statsStore gostats.Store, sink *common.TestStatSink,
expectedHitCount uint64, expectedMissCount uint64, expectedLookUpCount uint64, expectedExpiredCount uint64,
expectedEntryCount uint64,
) func(*testing.T) {
return func(t *testing.T) {
localCacheStats.GenerateStats()
statsStore.Flush()

prefix := localCacheScopeName + "."
// Check whether all local_cache related stats are available.
_, ok := sink.Record["averageAccessTime"]
_, ok := sink.Record[prefix+"averageAccessTime"]
assert.Equal(t, true, ok)
hitCount, ok := sink.Record["hitCount"]
hitCount, ok := sink.Record[prefix+"hitCount"]
assert.Equal(t, true, ok)
missCount, ok := sink.Record["missCount"]
missCount, ok := sink.Record[prefix+"missCount"]
assert.Equal(t, true, ok)
lookupCount, ok := sink.Record["lookupCount"]
lookupCount, ok := sink.Record[prefix+"lookupCount"]
assert.Equal(t, true, ok)
_, ok = sink.Record["overwriteCount"]
_, ok = sink.Record[prefix+"overwriteCount"]
assert.Equal(t, true, ok)
_, ok = sink.Record["evacuateCount"]
_, ok = sink.Record[prefix+"evacuateCount"]
assert.Equal(t, true, ok)
expiredCount, ok := sink.Record["expiredCount"]
expiredCount, ok := sink.Record[prefix+"expiredCount"]
assert.Equal(t, true, ok)
entryCount, ok := sink.Record["entryCount"]
entryCount, ok := sink.Record[prefix+"entryCount"]
assert.Equal(t, true, ok)

// Check the correctness of hitCount, missCount, lookupCount, expiredCount and entryCount
assert.Equal(t, expectedHitCount, hitCount.(int))
assert.Equal(t, expectedMissCount, missCount.(int))
assert.Equal(t, expectedLookUpCount, lookupCount.(int))
assert.Equal(t, expectedExpiredCount, expiredCount.(int))
assert.Equal(t, expectedEntryCount, entryCount.(int))
assert.Equal(t, expectedHitCount, hitCount.(uint64))
assert.Equal(t, expectedMissCount, missCount.(uint64))
assert.Equal(t, expectedLookUpCount, lookupCount.(uint64))
assert.Equal(t, expectedExpiredCount, expiredCount.(uint64))
assert.Equal(t, expectedEntryCount, entryCount.(uint64))

sink.Clear()
}
Expand All @@ -189,11 +190,13 @@ func TestOverLimitWithLocalCache(t *testing.T) {
client := mock_redis.NewMockClient(controller)
timeSource := mock_utils.NewMockTimeSource(controller)
localCache := freecache.NewCache(100)
statsStore := gostats.NewStore(gostats.NewNullSink(), false)
sink := common.NewTestStatSink()
statsStore := gostats.NewStore(sink, false)
sm := stats.NewMockStatManager(statsStore)
cache := redis.NewFixedRateLimitCacheImpl(client, nil, timeSource, rand.New(rand.NewSource(1)), 0, localCache, 0.8, "", sm, false)
sink := &common.TestStatSink{}
localCacheStats := limiter.NewLocalCacheStats(localCache, statsStore.Scope("localcache"))

localCacheScopeName := "localcache"
localCacheStats := limiter.NewLocalCacheStats(localCache, statsStore.Scope(localCacheScopeName))

// Test Near Limit Stats. Under Near Limit Ratio
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(3)
Expand All @@ -220,7 +223,7 @@ func TestOverLimitWithLocalCache(t *testing.T) {
assert.Equal(uint64(1), limits[0].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 0, 1, 1, 0, 0)
t.Run("TestLocalCacheStats", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 0, 1, 1, 0, 0))

// Test Near Limit Stats. At Near Limit Ratio, still OK
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(3)
Expand All @@ -241,7 +244,7 @@ func TestOverLimitWithLocalCache(t *testing.T) {
assert.Equal(uint64(2), limits[0].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 0, 2, 2, 0, 0)
t.Run("TestLocalCacheStats_1", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 0, 2, 2, 0, 0))

// Test Over limit stats
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(3)
Expand All @@ -262,7 +265,7 @@ func TestOverLimitWithLocalCache(t *testing.T) {
assert.Equal(uint64(2), limits[0].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 0, 2, 3, 0, 1)
t.Run("TestLocalCacheStats_2", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 0, 3, 3, 0, 1))

// Test Over limit stats with local cache
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(3)
Expand All @@ -281,7 +284,7 @@ func TestOverLimitWithLocalCache(t *testing.T) {
assert.Equal(uint64(2), limits[0].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 1, 3, 4, 0, 1)
t.Run("TestLocalCacheStats_3", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 1, 3, 4, 0, 1))
}

func TestNearLimit(t *testing.T) {
Expand Down Expand Up @@ -495,11 +498,13 @@ func TestOverLimitWithLocalCacheShadowRule(t *testing.T) {
client := mock_redis.NewMockClient(controller)
timeSource := mock_utils.NewMockTimeSource(controller)
localCache := freecache.NewCache(100)
statsStore := gostats.NewStore(gostats.NewNullSink(), false)
sink := common.NewTestStatSink()
statsStore := gostats.NewStore(sink, false)
sm := stats.NewMockStatManager(statsStore)
cache := redis.NewFixedRateLimitCacheImpl(client, nil, timeSource, rand.New(rand.NewSource(1)), 0, localCache, 0.8, "", sm, false)
sink := &common.TestStatSink{}
localCacheStats := limiter.NewLocalCacheStats(localCache, statsStore.Scope("localcache"))

localCacheScopeName := "localcache"
localCacheStats := limiter.NewLocalCacheStats(localCache, statsStore.Scope(localCacheScopeName))

// Test Near Limit Stats. Under Near Limit Ratio
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(3)
Expand All @@ -526,7 +531,7 @@ func TestOverLimitWithLocalCacheShadowRule(t *testing.T) {
assert.Equal(uint64(1), limits[0].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 0, 1, 1, 0, 0)
t.Run("TestLocalCacheStats", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 0, 1, 1, 0, 0))

// Test Near Limit Stats. At Near Limit Ratio, still OK
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(3)
Expand All @@ -547,7 +552,7 @@ func TestOverLimitWithLocalCacheShadowRule(t *testing.T) {
assert.Equal(uint64(2), limits[0].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 0, 2, 2, 0, 0)
t.Run("TestLocalCacheStats_1", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 0, 2, 2, 0, 0))

// Test Over limit stats
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(3)
Expand All @@ -570,7 +575,7 @@ func TestOverLimitWithLocalCacheShadowRule(t *testing.T) {
assert.Equal(uint64(2), limits[0].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 0, 2, 3, 0, 1)
t.Run("TestLocalCacheStats_2", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 0, 3, 3, 0, 1))

// Test Over limit stats with local cache
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(3)
Expand All @@ -594,7 +599,7 @@ func TestOverLimitWithLocalCacheShadowRule(t *testing.T) {
assert.Equal(uint64(2), limits[0].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 1, 3, 4, 0, 1)
t.Run("TestLocalCacheStats_3", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 1, 3, 4, 0, 1))
}

func TestRedisTracer(t *testing.T) {
Expand Down Expand Up @@ -636,11 +641,13 @@ func TestOverLimitWithStopCacheKeyIncrementWhenOverlimitConfig(t *testing.T) {
client := mock_redis.NewMockClient(controller)
timeSource := mock_utils.NewMockTimeSource(controller)
localCache := freecache.NewCache(100)
statsStore := gostats.NewStore(gostats.NewNullSink(), false)
sink := common.NewTestStatSink()
statsStore := gostats.NewStore(sink, false)
sm := stats.NewMockStatManager(statsStore)
cache := redis.NewFixedRateLimitCacheImpl(client, nil, timeSource, rand.New(rand.NewSource(1)), 0, localCache, 0.8, "", sm, true)
sink := &common.TestStatSink{}
localCacheStats := limiter.NewLocalCacheStats(localCache, statsStore.Scope("localcache"))

localCacheScopeName := "localcache"
localCacheStats := limiter.NewLocalCacheStats(localCache, statsStore.Scope(localCacheScopeName))

// Test Near Limit Stats. Under Near Limit Ratio
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(5)
Expand Down Expand Up @@ -681,7 +688,7 @@ func TestOverLimitWithStopCacheKeyIncrementWhenOverlimitConfig(t *testing.T) {
assert.Equal(uint64(1), limits[1].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 0, 1, 1, 0, 0)
t.Run("TestLocalCacheStats", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 0, 2, 2, 0, 0))

// Test Near Limit Stats. Some hits at Near Limit Ratio, but still OK.
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(5)
Expand Down Expand Up @@ -715,7 +722,7 @@ func TestOverLimitWithStopCacheKeyIncrementWhenOverlimitConfig(t *testing.T) {
assert.Equal(uint64(3), limits[1].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 0, 2, 2, 0, 0)
t.Run("TestLocalCacheStats_1", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 0, 4, 4, 0, 0))

// Test one key is reaching to the Overlimit threshold
timeSource.EXPECT().UnixNow().Return(int64(1000000)).MaxTimes(5)
Expand Down Expand Up @@ -747,5 +754,5 @@ func TestOverLimitWithStopCacheKeyIncrementWhenOverlimitConfig(t *testing.T) {
assert.Equal(uint64(3), limits[1].Stats.WithinLimit.Value())

// Check the local cache stats.
testLocalCacheStats(localCacheStats, statsStore, sink, 0, 2, 3, 0, 1)
t.Run("TestLocalCacheStats_2", testLocalCacheStats(localCacheScopeName, localCacheStats, statsStore, sink, 0, 6, 6, 0, 1))
}
Loading