@ -10,6 +10,8 @@ import (
"testing"
"time"
"github.com/grafana/loki/pkg/logql/log"
"github.com/grafana/dskit/flagext"
"github.com/pkg/errors"
"github.com/prometheus/common/model"
@ -65,7 +67,7 @@ func TestLabelsCollisions(t *testing.T) {
require . NoError ( t , err )
limiter := NewLimiter ( limits , NilMetrics , & ringCountMock { count : 1 } , 1 )
i , err := newInstance ( defaultConfig ( ) , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , NewStreamRateCalculator ( ) , nil )
i , err := newInstance ( defaultConfig ( ) , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , nil , nil , NewStreamRateCalculator ( ) , nil )
require . Nil ( t , err )
// avoid entries from the future.
@ -93,7 +95,7 @@ func TestConcurrentPushes(t *testing.T) {
require . NoError ( t , err )
limiter := NewLimiter ( limits , NilMetrics , & ringCountMock { count : 1 } , 1 )
inst , err := newInstance ( defaultConfig ( ) , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , NewStreamRateCalculator ( ) , nil )
inst , err := newInstance ( defaultConfig ( ) , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , nil , nil , NewStreamRateCalculator ( ) , nil )
require . Nil ( t , err )
const (
@ -145,7 +147,7 @@ func TestGetStreamRates(t *testing.T) {
require . NoError ( t , err )
limiter := NewLimiter ( limits , NilMetrics , & ringCountMock { count : 1 } , 1 )
inst , err := newInstance ( defaultConfig ( ) , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , NewStreamRateCalculator ( ) , nil )
inst , err := newInstance ( defaultConfig ( ) , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , nil , nil , NewStreamRateCalculator ( ) , nil )
require . NoError ( t , err )
const (
@ -239,7 +241,7 @@ func TestSyncPeriod(t *testing.T) {
minUtil = 0.20
)
inst , err := newInstance ( defaultConfig ( ) , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , NewStreamRateCalculator ( ) , nil )
inst , err := newInstance ( defaultConfig ( ) , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , nil , nil , NewStreamRateCalculator ( ) , nil )
require . Nil ( t , err )
lbls := makeRandomLabels ( )
@ -284,7 +286,7 @@ func setupTestStreams(t *testing.T) (*instance, time.Time, int) {
cfg . SyncMinUtilization = 0.20
cfg . IndexShards = indexShards
instance , err := newInstance ( cfg , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , NewStreamRateCalculator ( ) , nil )
instance , err := newInstance ( cfg , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , nil , nil , NewStreamRateCalculator ( ) , nil )
require . Nil ( t , err )
currentTime := time . Now ( )
@ -493,7 +495,7 @@ func Benchmark_PushInstance(b *testing.B) {
require . NoError ( b , err )
limiter := NewLimiter ( limits , NilMetrics , & ringCountMock { count : 1 } , 1 )
i , _ := newInstance ( & Config { IndexShards : 1 } , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , NewStreamRateCalculator ( ) , nil )
i , _ := newInstance ( & Config { IndexShards : 1 } , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , nil , nil , NewStreamRateCalculator ( ) , nil )
ctx := context . Background ( )
for n := 0 ; n < b . N ; n ++ {
@ -537,7 +539,7 @@ func Benchmark_instance_addNewTailer(b *testing.B) {
ctx := context . Background ( )
inst , _ := newInstance ( & Config { } , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , NewStreamRateCalculator ( ) , nil )
inst , _ := newInstance ( & Config { } , defaultPeriodConfigs , "test" , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , nil , nil , NewStreamRateCalculator ( ) , nil )
expr , err := syntax . ParseLogSelector ( ` { namespace="foo",pod="bar",instance=~"10.*"} ` , true )
require . NoError ( b , err )
t , err := newTailer ( "foo" , expr , nil , 10 )
@ -671,6 +673,172 @@ func Test_ChunkFilter(t *testing.T) {
}
}
func Test_PipelineWrapper ( t * testing . T ) {
instance := defaultInstance ( t )
wrapper := & testPipelineWrapper {
pipeline : newMockPipeline ( ) ,
}
instance . pipelineWrapper = wrapper
it , err := instance . Query ( context . TODO ( ) ,
logql . SelectLogParams {
QueryRequest : & logproto . QueryRequest {
Selector : ` { job="3"} ` ,
Limit : uint32 ( 2 ) ,
Start : time . Unix ( 0 , 0 ) ,
End : time . Unix ( 0 , 100000000 ) ,
Direction : logproto . BACKWARD ,
Plan : & plan . QueryPlan {
AST : syntax . MustParseExpr ( ` { job="3"} ` ) ,
} ,
} ,
} ,
)
require . NoError ( t , err )
defer it . Close ( )
for it . Next ( ) {
// Consume the iterator
require . NoError ( t , it . Error ( ) )
}
require . Equal ( t , ` { job="3"} ` , wrapper . query )
require . Equal ( t , 10 , wrapper . pipeline . sp . called ) // we've passed every log line through the wrapper
}
type testPipelineWrapper struct {
query string
pipeline * mockPipeline
}
func ( t * testPipelineWrapper ) Wrap ( pipeline log . Pipeline , query string ) log . Pipeline {
t . query = query
t . pipeline . wrappedExtractor = pipeline
return t . pipeline
}
func newMockPipeline ( ) * mockPipeline {
return & mockPipeline {
sp : & mockStreamPipeline { } ,
}
}
type mockPipeline struct {
wrappedExtractor log . Pipeline
sp * mockStreamPipeline
}
func ( p * mockPipeline ) ForStream ( l labels . Labels ) log . StreamPipeline {
sp := p . wrappedExtractor . ForStream ( l )
p . sp . wrappedSP = sp
return p . sp
}
func ( p * mockPipeline ) Reset ( ) { }
// A stub always returns the same data
type mockStreamPipeline struct {
wrappedSP log . StreamPipeline
called int
}
func ( p * mockStreamPipeline ) BaseLabels ( ) log . LabelsResult {
return p . wrappedSP . BaseLabels ( )
}
func ( p * mockStreamPipeline ) Process ( ts int64 , line [ ] byte , lbs ... labels . Label ) ( [ ] byte , log . LabelsResult , bool ) {
p . called ++
return p . wrappedSP . Process ( ts , line , lbs ... )
}
func ( p * mockStreamPipeline ) ProcessString ( ts int64 , line string , lbs ... labels . Label ) ( string , log . LabelsResult , bool ) {
p . called ++
return p . wrappedSP . ProcessString ( ts , line , lbs ... )
}
func Test_ExtractorWrapper ( t * testing . T ) {
instance := defaultInstance ( t )
wrapper := & testExtractorWrapper {
extractor : newMockExtractor ( ) ,
}
instance . extractorWrapper = wrapper
it , err := instance . QuerySample ( context . TODO ( ) ,
logql . SelectSampleParams {
SampleQueryRequest : & logproto . SampleQueryRequest {
Selector : ` sum(count_over_time( { job="3"}[1m])) ` ,
Start : time . Unix ( 0 , 0 ) ,
End : time . Unix ( 0 , 100000000 ) ,
Plan : & plan . QueryPlan {
AST : syntax . MustParseExpr ( ` sum(count_over_time( { job="3"}[1m])) ` ) ,
} ,
} ,
} ,
)
require . NoError ( t , err )
defer it . Close ( )
for it . Next ( ) {
// Consume the iterator
require . NoError ( t , it . Error ( ) )
}
require . Equal ( t , ` sum(count_over_time( { job="3"}[1m])) ` , wrapper . query )
require . Equal ( t , 10 , wrapper . extractor . sp . called ) // we've passed every log line through the wrapper
}
type testExtractorWrapper struct {
query string
extractor * mockExtractor
}
func ( t * testExtractorWrapper ) Wrap ( extractor log . SampleExtractor , query string ) log . SampleExtractor {
t . query = query
t . extractor . wrappedExtractor = extractor
return t . extractor
}
func newMockExtractor ( ) * mockExtractor {
return & mockExtractor {
sp : & mockStreamExtractor { } ,
}
}
type mockExtractor struct {
wrappedExtractor log . SampleExtractor
sp * mockStreamExtractor
}
func ( p * mockExtractor ) ForStream ( l labels . Labels ) log . StreamSampleExtractor {
sp := p . wrappedExtractor . ForStream ( l )
p . sp . wrappedSP = sp
return p . sp
}
func ( p * mockExtractor ) Reset ( ) { }
// A stub always returns the same data
type mockStreamExtractor struct {
wrappedSP log . StreamSampleExtractor
called int
}
func ( p * mockStreamExtractor ) BaseLabels ( ) log . LabelsResult {
return p . wrappedSP . BaseLabels ( )
}
func ( p * mockStreamExtractor ) Process ( ts int64 , line [ ] byte , lbs ... labels . Label ) ( float64 , log . LabelsResult , bool ) {
p . called ++
return p . wrappedSP . Process ( ts , line , lbs ... )
}
func ( p * mockStreamExtractor ) ProcessString ( ts int64 , line string , lbs ... labels . Label ) ( float64 , log . LabelsResult , bool ) {
p . called ++
return p . wrappedSP . ProcessString ( ts , line , lbs ... )
}
func Test_QueryWithDelete ( t * testing . T ) {
instance := defaultInstance ( t )
@ -824,7 +992,7 @@ func TestStreamShardingUsage(t *testing.T) {
} )
t . Run ( "invalid push returns error" , func ( t * testing . T ) {
i , _ := newInstance ( & Config { IndexShards : 1 } , defaultPeriodConfigs , customTenant1 , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , NewStreamRateCalculator ( ) , nil )
i , _ := newInstance ( & Config { IndexShards : 1 } , defaultPeriodConfigs , customTenant1 , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , nil , nil , NewStreamRateCalculator ( ) , nil )
ctx := context . Background ( )
err = i . Push ( ctx , & logproto . PushRequest {
@ -843,7 +1011,7 @@ func TestStreamShardingUsage(t *testing.T) {
} )
t . Run ( "valid push returns no error" , func ( t * testing . T ) {
i , _ := newInstance ( & Config { IndexShards : 1 } , defaultPeriodConfigs , customTenant2 , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , NewStreamRateCalculator ( ) , nil )
i , _ := newInstance ( & Config { IndexShards : 1 } , defaultPeriodConfigs , customTenant2 , limiter , loki_runtime . DefaultTenantConfigs ( ) , noopWAL { } , NilMetrics , & OnceSwitch { } , nil , nil , nil , NewStreamRateCalculator ( ) , nil )
ctx := context . Background ( )
err = i . Push ( ctx , & logproto . PushRequest {
@ -1174,6 +1342,8 @@ func defaultInstance(t *testing.T) *instance {
NilMetrics ,
nil ,
nil ,
nil ,
nil ,
NewStreamRateCalculator ( ) ,
nil ,
)