mirror of https://github.com/status-im/consul.git
agent/cache test for cache throttling. (#8396)
This commit is contained in:
parent
4c8a15b698
commit
054595b1f8
|
@ -1219,3 +1219,76 @@ func TestCacheGet_nonBlockingType(t *testing.T) {
|
|||
time.Sleep(20 * time.Millisecond)
|
||||
typ.AssertExpectations(t)
|
||||
}
|
||||
|
||||
// TestCacheThrottle checks the assumptions for the cache throttling. It sets
|
||||
// up a cache with Options{EntryFetchRate: 10.0, EntryFetchMaxBurst: 1}, which
|
||||
// allows for 10req/s, or one request every 100ms.
|
||||
// It configures two different cache types with each 3 updates. Each type has
|
||||
// its own rate limiter which starts initially full, and we expect the
|
||||
// following requests when creating blocking queries against both waiting for
|
||||
// the third update:
|
||||
// at ~0ms: typ1 and typ2 receive first value and are blocked until
|
||||
// ~100ms: typ1 and typ2 receive second value and are blocked until
|
||||
// ~200ms: typ1 and typ2 receive third value which we check
|
||||
//
|
||||
// This test will verify waiting with a blocking query for the last update will
|
||||
// block for 190ms and only afterwards have the expected result.
|
||||
// It demonstrates the ratelimiting waits for the expected amount of time and
|
||||
// also that each type has its own ratelimiter, because results for both types
|
||||
// are arriving at similar times, which wouldn't be the case if they use a
|
||||
// shared limiter.
|
||||
func TestCacheThrottle(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
typ1 := TestType(t)
|
||||
typ2 := TestType(t)
|
||||
defer typ1.AssertExpectations(t)
|
||||
defer typ2.AssertExpectations(t)
|
||||
|
||||
c := New(Options{EntryFetchRate: 10.0, EntryFetchMaxBurst: 1})
|
||||
c.RegisterType("t1", typ1)
|
||||
c.RegisterType("t2", typ2)
|
||||
|
||||
// Configure the type
|
||||
typ1.Static(FetchResult{Value: 1, Index: 4}, nil).Once()
|
||||
typ1.Static(FetchResult{Value: 12, Index: 5}, nil).Once()
|
||||
typ1.Static(FetchResult{Value: 42, Index: 6}, nil).Once()
|
||||
|
||||
typ2.Static(FetchResult{Value: 1, Index: 4}, nil).Once()
|
||||
typ2.Static(FetchResult{Value: 12, Index: 5}, nil).Once()
|
||||
typ2.Static(FetchResult{Value: 43, Index: 6}, nil).Once()
|
||||
|
||||
result1Ch := TestCacheGetCh(t, c, "t1", TestRequest(t, RequestInfo{
|
||||
Key: "hello1", MinIndex: 5}))
|
||||
|
||||
result2Ch := TestCacheGetCh(t, c, "t2", TestRequest(t, RequestInfo{
|
||||
Key: "hello2", MinIndex: 5}))
|
||||
|
||||
select {
|
||||
case <-result1Ch:
|
||||
t.Fatal("result1Ch should block")
|
||||
case <-result2Ch:
|
||||
t.Fatal("result2Ch should block")
|
||||
case <-time.After(190 * time.Millisecond):
|
||||
}
|
||||
|
||||
after := time.After(30 * time.Millisecond)
|
||||
var res1, res2 bool
|
||||
OUT:
|
||||
for {
|
||||
select {
|
||||
case result := <-result1Ch:
|
||||
require.Equal(t, 42, result)
|
||||
|
||||
res1 = true
|
||||
case result := <-result2Ch:
|
||||
require.Equal(t, 43, result)
|
||||
res2 = true
|
||||
case <-after:
|
||||
t.Fatal("shouldn't block that long")
|
||||
}
|
||||
if res1 && res2 {
|
||||
break OUT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue