Like Prometheus, but for logs.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
loki/pkg/querier/queryrange/index_stats_cache_test.go

97 lines
2.6 KiB

package queryrange
import (
"context"
"math"
"testing"
"time"
"github.com/go-kit/log"
"github.com/stretchr/testify/require"
"github.com/weaveworks/common/user"
"github.com/grafana/loki/pkg/logproto"
"github.com/grafana/loki/pkg/logqlmodel/stats"
"github.com/grafana/loki/pkg/querier/queryrange/queryrangebase"
"github.com/grafana/loki/pkg/storage/chunk/cache"
"github.com/grafana/loki/pkg/util"
)
func TestIndexStatsCache(t *testing.T) {
cfg := queryrangebase.ResultsCacheConfig{
CacheConfig: cache.Config{
Cache: cache.NewMockCache(),
},
}
c, err := cache.New(cfg.CacheConfig, nil, log.NewNopLogger(), stats.ResultCache)
require.NoError(t, err)
cacheMiddleware, err := NewIndexStatsCacheMiddleware(
log.NewNopLogger(),
WithSplitByLimits(fakeLimits{}, 24*time.Hour),
LokiCodec,
c,
nil,
nil,
func(_ context.Context, tenantIDs []string, r queryrangebase.Request) int {
return 1
},
false,
nil,
nil,
)
require.NoError(t, err)
from, through := util.RoundToMilliseconds(testTime, testTime.Add(1*time.Hour))
statsReq := &logproto.IndexStatsRequest{
From: from,
Through: through,
Matchers: `{foo="bar"}`,
}
statsResp := &IndexStatsResponse{
Response: &logproto.IndexStatsResponse{
Streams: 1,
Chunks: 2,
Bytes: 1 << 10,
Entries: 10,
},
}
var calls int
rc := cacheMiddleware.Wrap(queryrangebase.HandlerFunc(func(_ context.Context, req queryrangebase.Request) (queryrangebase.Response, error) {
calls++
return statsResp, nil
}))
ctx := user.InjectOrgID(context.Background(), "fake")
resp, err := rc.Do(ctx, statsReq)
require.NoError(t, err)
require.Equal(t, 1, calls)
require.Equal(t, statsResp, resp)
// Doing same request again shouldn't change anything.
calls = 0
resp, err = rc.Do(ctx, statsReq)
require.NoError(t, err)
require.Equal(t, 0, calls)
require.Equal(t, statsResp, resp)
// Doing a request with new start later than the previous query and end time later than the previous one,
// should reuse part of the previous request and issue a new request for the remaining time till end.
// The new start time is 15m (i.e. 25%) in the future with regard to the previous request time span.
calls = 0
req := statsReq.WithStartEnd(statsReq.GetStart()+(15*time.Minute).Milliseconds(), statsReq.GetEnd()+(15*time.Minute).Milliseconds())
expectedStats := &IndexStatsResponse{
Response: &logproto.IndexStatsResponse{
Streams: 2,
Chunks: 4,
Bytes: (1<<10)*0.75 + (1 << 10),
Entries: uint64(math.Floor(10*0.75) + 10),
},
}
resp, err = rc.Do(ctx, req)
require.NoError(t, err)
require.Equal(t, 1, calls)
require.Equal(t, expectedStats, resp)
}