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/storage/lazy_chunk_test.go

186 lines
4.7 KiB

package storage
import (
"context"
"fmt"
"testing"
"time"
"github.com/cortexproject/cortex/pkg/chunk"
"github.com/stretchr/testify/require"
"github.com/grafana/loki/pkg/chunkenc"
"github.com/grafana/loki/pkg/iter"
"github.com/grafana/loki/pkg/logproto"
"github.com/grafana/loki/pkg/logql"
"github.com/grafana/loki/pkg/util"
)
func TestLazyChunkIterator(t *testing.T) {
for i, tc := range []struct {
chunk *LazyChunk
expected []logproto.Stream
}{
{
newLazyChunk(logproto.Stream{
Labels: fooLabelsWithName,
Entries: []logproto.Entry{
{
Timestamp: from,
Line: "1",
},
},
}),
[]logproto.Stream{
{
Entries: []logproto.Entry{
{
Timestamp: from,
Line: "1",
},
},
},
},
},
} {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
it, err := tc.chunk.Iterator(context.Background(), time.Unix(0, 0), time.Unix(1000, 0), logproto.FORWARD, logql.TrueFilter, nil)
require.Nil(t, err)
streams, _, err := iter.ReadBatch(it, 1000)
require.Nil(t, err)
_ = it.Close()
require.Equal(t, tc.expected, streams.Streams)
})
}
}
func TestLazyChunksPop(t *testing.T) {
for i, tc := range []struct {
initial int
n int
expectedLn int
rem int
}{
{1, 1, 1, 0},
{2, 1, 1, 1},
{3, 4, 3, 0},
} {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
lc := &lazyChunks{}
for i := 0; i < tc.initial; i++ {
lc.chunks = append(lc.chunks, &LazyChunk{})
}
out := lc.pop(tc.n)
for i := 0; i < tc.expectedLn; i++ {
require.NotNil(t, out[i])
}
for i := 0; i < tc.rem; i++ {
require.NotNil(t, lc.chunks[i])
}
})
}
}
func TestIsOverlapping(t *testing.T) {
tests := []struct {
name string
direction logproto.Direction
with *LazyChunk
b chunkenc.Block
want bool
}{
{
"equal forward",
logproto.FORWARD,
lazyChunkWithBounds(time.Unix(0, 0), time.Unix(0, int64(time.Millisecond*5))),
blockWithBounds(0, int64(time.Millisecond*5)),
true,
},
{
"equal backward",
logproto.BACKWARD,
lazyChunkWithBounds(time.Unix(0, 0), time.Unix(0, int64(time.Millisecond*5))),
blockWithBounds(0, int64(time.Millisecond*5)),
true,
},
{
"equal through backward",
logproto.BACKWARD,
lazyChunkWithBounds(time.Unix(0, int64(time.Millisecond*5)), time.Unix(0, int64(time.Millisecond*10))),
blockWithBounds(0, int64(time.Millisecond*10)),
true,
},
{
"< through backward",
logproto.BACKWARD,
lazyChunkWithBounds(time.Unix(0, int64(time.Millisecond*5)), time.Unix(0, int64(time.Millisecond*10))),
blockWithBounds(0, int64(time.Millisecond*5)),
true,
},
{
"from > forward",
logproto.FORWARD,
lazyChunkWithBounds(time.Unix(0, int64(time.Millisecond*4)), time.Unix(0, int64(time.Millisecond*10))),
blockWithBounds(int64(time.Millisecond*3), int64(time.Millisecond*5)),
true,
},
{
"from < forward",
logproto.FORWARD,
lazyChunkWithBounds(time.Unix(0, int64(time.Millisecond*5)), time.Unix(0, int64(time.Millisecond*10))),
blockWithBounds(int64(time.Millisecond*3), int64(time.Millisecond*4)),
false,
},
{
"from = forward",
logproto.FORWARD,
lazyChunkWithBounds(time.Unix(0, int64(time.Millisecond*5)), time.Unix(0, int64(time.Millisecond*10))),
blockWithBounds(int64(time.Millisecond*3), int64(time.Millisecond*5)),
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// testing the block one
require.Equal(t, tt.want, IsBlockOverlapping(tt.b, tt.with, tt.direction))
// testing the chunk one
l := lazyChunkWithBounds(time.Unix(0, tt.b.MinTime()), time.Unix(0, tt.b.MaxTime()))
require.Equal(t, tt.want, l.IsOverlapping(tt.with, tt.direction))
})
}
}
func lazyChunkWithBounds(from, through time.Time) *LazyChunk {
// In loki chunks are rounded when flushed fro nanoseconds to milliseconds.
fromM, throughM := util.RoundToMilliseconds(from, through)
return &LazyChunk{
Chunk: chunk.Chunk{
From: fromM,
Through: throughM,
},
}
}
type fakeBlock struct {
mint, maxt int64
}
Improve metric queries by computing samples at the edges. (#2293) * First pass breaking the code appart. Wondering how we're going to achieve fast mutation of labels. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Work in progress. I realize I need hash for deduping lines. going to benchmark somes. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Tested some hash and decided which one to use. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Wip Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Starting working on ingester. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Trying to find a better hash function. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * More hash testing we have a winner. xxhash it is. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Settle on xxhash Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Better params interfacing. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Add interface for queryparams for things that exist in both type of params. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Add storage sample iterator implementations. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Fixing tests and verifying we don't get collions for the hashing method. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Fixing ingesters tests and refactoring utility function/tests. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Fixing and testing that stats are still well computed. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Fixing more tests. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * More engine tests finished. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Fixes sharding evaluator. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Fixes more engine tests. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Fix error tests in the engine. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Finish fixing all tests. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Fixes a bug where extractor was not passed in correctly. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Add notes about upgrade. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Renamed and fix a bug. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Add memchunk tests and starting test for sampleIterator. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Test heap sample iterator. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * working on test. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Finishing testing all new iterators. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Making sure all store functions are tested. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Benchmark and verify everything is working well. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Make the linter happy. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * use xxhash v2. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * Fix a flaky test because of map. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> * go.mod. Signed-off-by: Cyril Tovena <cyril.tovena@gmail.com> Co-authored-by: Edward Welch <edward.welch@grafana.com>
6 years ago
func (fakeBlock) Entries() int { return 0 }
func (fakeBlock) Offset() int { return 0 }
func (f fakeBlock) MinTime() int64 { return f.mint }
func (f fakeBlock) MaxTime() int64 { return f.maxt }
func (fakeBlock) Iterator(context.Context, logql.LineFilter) iter.EntryIterator { return nil }
func (fakeBlock) SampleIterator(context.Context, logql.LineFilter, logql.SampleExtractor) iter.SampleIterator {
return nil
}
func blockWithBounds(mint, maxt int64) chunkenc.Block {
return &fakeBlock{
maxt: maxt,
mint: mint,
}
}