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/ingester/streams_map_test.go

134 lines
2.8 KiB

package ingester
import (
"testing"
"github.com/prometheus/common/model"
"github.com/prometheus/prometheus/model/labels"
"github.com/stretchr/testify/require"
"github.com/grafana/loki/v3/pkg/validation"
)
func TestStreamsMap(t *testing.T) {
limits, err := validation.NewOverrides(defaultLimitsTestConfig(), nil)
require.NoError(t, err)
limiter := NewLimiter(limits, NilMetrics, newIngesterRingLimiterStrategy(&ringCountMock{count: 1}, 1), &TenantBasedStrategy{limits: limits})
Pin `chunk` and `index` format to `schema` version. (#10213) We pin all three `Chunk`, `HeadBlock` and `TSDB` Version to `schema` version in period config. This is the following mapping (after being discussed with @owen-d and @sandeepsukhani ) `v12` (current existing schema) - ChunkFormatV3 (UnorderedHeadBlock) + TSDBv2 `v13` (introducing new schema) - ChunkFormatV4 (UnorderedWithNonIndexedLabelsHeadBlockFmt) + TSDBv3 Note the new schema `v13` supports the latest chunk and index format. **NOTES for Reviewer** 1. General approach is we removed the idea of `index.LiveFormat`, `chunkenc.DefaultChunkFormat` and `chunkenc.DefaultHeadBlockFmt` and made following two changes. These variables were used before to tie chunk and tsdb formats specific to Loki versions. This PR remove that coupling and pin these formats to `schema` version instead. 1. These variables were replaced with explicit chunk and index formats within those packages (and it's tests) 2. If these variables were used outside it's own packages say by ingester, compactor, etc. Then we extract correct chunk and index versions from the `schema` config. 2. Add two methods to `periodConfig`. (1) `ChunkFormat()` returning chunk and head format tied to schema (2) `TSDBFormat()` returning tsdb format tied to schema. 2. Other ideas I thought of doing but didn't end up doing is make `ChunkFormat` and `IndexFormat` as separate type (rather than `byte` and `int` currently. Similar to `HeadBlockFmt` type). But didnt' do it eventually to keep the PR small and don't want to complicate with lots of changes. 4. Moved couple of test cases from `chunkenc` to `config` package, because the test case was actually testing methods on `schemaconfig` and it was creating cycling dependencies. --------- Signed-off-by: Kaviraj <kavirajkanagaraj@gmail.com>
2 years ago
chunkfmt, headfmt := defaultChunkFormat(t)
ss := []*stream{
newStream(
Pin `chunk` and `index` format to `schema` version. (#10213) We pin all three `Chunk`, `HeadBlock` and `TSDB` Version to `schema` version in period config. This is the following mapping (after being discussed with @owen-d and @sandeepsukhani ) `v12` (current existing schema) - ChunkFormatV3 (UnorderedHeadBlock) + TSDBv2 `v13` (introducing new schema) - ChunkFormatV4 (UnorderedWithNonIndexedLabelsHeadBlockFmt) + TSDBv3 Note the new schema `v13` supports the latest chunk and index format. **NOTES for Reviewer** 1. General approach is we removed the idea of `index.LiveFormat`, `chunkenc.DefaultChunkFormat` and `chunkenc.DefaultHeadBlockFmt` and made following two changes. These variables were used before to tie chunk and tsdb formats specific to Loki versions. This PR remove that coupling and pin these formats to `schema` version instead. 1. These variables were replaced with explicit chunk and index formats within those packages (and it's tests) 2. If these variables were used outside it's own packages say by ingester, compactor, etc. Then we extract correct chunk and index versions from the `schema` config. 2. Add two methods to `periodConfig`. (1) `ChunkFormat()` returning chunk and head format tied to schema (2) `TSDBFormat()` returning tsdb format tied to schema. 2. Other ideas I thought of doing but didn't end up doing is make `ChunkFormat` and `IndexFormat` as separate type (rather than `byte` and `int` currently. Similar to `HeadBlockFmt` type). But didnt' do it eventually to keep the PR small and don't want to complicate with lots of changes. 4. Moved couple of test cases from `chunkenc` to `config` package, because the test case was actually testing methods on `schemaconfig` and it was creating cycling dependencies. --------- Signed-off-by: Kaviraj <kavirajkanagaraj@gmail.com>
2 years ago
chunkfmt,
headfmt,
defaultConfig(),
limiter.rateLimitStrategy,
"fake",
model.Fingerprint(1),
labels.Labels{
{Name: "foo", Value: "bar"},
},
true,
NewStreamRateCalculator(),
NilMetrics,
nil,
nil,
),
newStream(
Pin `chunk` and `index` format to `schema` version. (#10213) We pin all three `Chunk`, `HeadBlock` and `TSDB` Version to `schema` version in period config. This is the following mapping (after being discussed with @owen-d and @sandeepsukhani ) `v12` (current existing schema) - ChunkFormatV3 (UnorderedHeadBlock) + TSDBv2 `v13` (introducing new schema) - ChunkFormatV4 (UnorderedWithNonIndexedLabelsHeadBlockFmt) + TSDBv3 Note the new schema `v13` supports the latest chunk and index format. **NOTES for Reviewer** 1. General approach is we removed the idea of `index.LiveFormat`, `chunkenc.DefaultChunkFormat` and `chunkenc.DefaultHeadBlockFmt` and made following two changes. These variables were used before to tie chunk and tsdb formats specific to Loki versions. This PR remove that coupling and pin these formats to `schema` version instead. 1. These variables were replaced with explicit chunk and index formats within those packages (and it's tests) 2. If these variables were used outside it's own packages say by ingester, compactor, etc. Then we extract correct chunk and index versions from the `schema` config. 2. Add two methods to `periodConfig`. (1) `ChunkFormat()` returning chunk and head format tied to schema (2) `TSDBFormat()` returning tsdb format tied to schema. 2. Other ideas I thought of doing but didn't end up doing is make `ChunkFormat` and `IndexFormat` as separate type (rather than `byte` and `int` currently. Similar to `HeadBlockFmt` type). But didnt' do it eventually to keep the PR small and don't want to complicate with lots of changes. 4. Moved couple of test cases from `chunkenc` to `config` package, because the test case was actually testing methods on `schemaconfig` and it was creating cycling dependencies. --------- Signed-off-by: Kaviraj <kavirajkanagaraj@gmail.com>
2 years ago
chunkfmt,
headfmt,
defaultConfig(),
limiter.rateLimitStrategy,
"fake",
model.Fingerprint(2),
labels.Labels{
{Name: "bar", Value: "foo"},
},
true,
NewStreamRateCalculator(),
NilMetrics,
nil,
nil,
),
}
var s *stream
var loaded bool
streams := newStreamsMap()
require.Equal(t, 0, streams.Len())
s, loaded = streams.Load(ss[0].labelsString)
require.Nil(t, s)
require.False(t, loaded)
s, loaded = streams.LoadByFP(ss[1].fp)
require.Nil(t, s)
require.False(t, loaded)
// Test LoadOrStoreNew
s, loaded, err = streams.LoadOrStoreNew(ss[0].labelsString, func() (*stream, error) {
return ss[0], nil
}, nil)
require.Equal(t, s, ss[0])
require.False(t, loaded)
require.Nil(t, err)
// Test LoadOrStoreNewByFP
s, loaded, err = streams.LoadOrStoreNewByFP(ss[1].fp, func() (*stream, error) {
return ss[1], nil
}, nil)
require.Equal(t, s, ss[1])
require.False(t, loaded)
require.Nil(t, err)
require.Equal(t, len(ss), streams.Len())
for _, st := range ss {
s, loaded = streams.Load(st.labelsString)
require.Equal(t, st, s)
require.True(t, loaded)
s, loaded = streams.LoadByFP(st.fp)
require.Equal(t, st, s)
require.True(t, loaded)
}
// Test Delete
for _, st := range ss {
deleted := streams.Delete(st)
require.True(t, deleted)
s, loaded = streams.Load(st.labelsString)
require.Nil(t, s)
require.False(t, loaded)
s, loaded = streams.LoadByFP(st.fp)
require.Nil(t, s)
require.False(t, loaded)
}
require.Equal(t, 0, streams.Len())
// Test Store
streams.Store(ss[0].labelsString, ss[0])
s, loaded = streams.Load(ss[0].labelsString)
require.Equal(t, ss[0], s)
require.True(t, loaded)
s, loaded = streams.LoadByFP(ss[0].fp)
require.Equal(t, ss[0], s)
require.True(t, loaded)
// Test StoreByFP
streams.StoreByFP(ss[1].fp, ss[1])
s, loaded = streams.Load(ss[1].labelsString)
require.Equal(t, ss[1], s)
require.True(t, loaded)
s, loaded = streams.LoadByFP(ss[1].fp)
require.Equal(t, ss[1], s)
require.True(t, loaded)
require.Equal(t, len(ss), streams.Len())
}