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/logql/log/metrics_extraction_test.go

159 lines
3.9 KiB

package log
import (
"sort"
"testing"
"github.com/prometheus/prometheus/pkg/labels"
"github.com/stretchr/testify/require"
)
func Test_labelSampleExtractor_Extract(t *testing.T) {
tests := []struct {
name string
ex SampleExtractor
in labels.Labels
want float64
wantLbs labels.Labels
wantOk bool
}{
{
"convert float",
mustSampleExtractor(LabelExtractorWithStages(
"foo", ConvertFloat, nil, false, false, nil, NoopStage,
)),
labels.Labels{labels.Label{Name: "foo", Value: "15.0"}},
15,
labels.Labels{},
true,
},
{
"convert float as vector with no grouping",
mustSampleExtractor(LabelExtractorWithStages(
"foo", ConvertFloat, nil, false, true, nil, NoopStage,
)),
labels.Labels{labels.Label{Name: "foo", Value: "15.0"}, labels.Label{Name: "bar", Value: "buzz"}},
15,
labels.Labels{},
true,
},
{
"convert float without",
mustSampleExtractor(LabelExtractorWithStages(
"foo", ConvertFloat, []string{"bar", "buzz"}, true, false, nil, NoopStage,
)),
labels.Labels{
{Name: "foo", Value: "10"},
{Name: "bar", Value: "foo"},
{Name: "buzz", Value: "blip"},
{Name: "namespace", Value: "dev"},
},
10,
labels.Labels{
{Name: "namespace", Value: "dev"},
},
true,
},
{
"convert float with",
mustSampleExtractor(LabelExtractorWithStages(
"foo", ConvertFloat, []string{"bar", "buzz"}, false, false, nil, NoopStage,
)),
labels.Labels{
{Name: "foo", Value: "0.6"},
{Name: "bar", Value: "foo"},
{Name: "buzz", Value: "blip"},
{Name: "namespace", Value: "dev"},
},
0.6,
labels.Labels{
{Name: "bar", Value: "foo"},
{Name: "buzz", Value: "blip"},
},
true,
},
{
"convert duration with",
mustSampleExtractor(LabelExtractorWithStages(
"foo", ConvertDuration, []string{"bar", "buzz"}, false, false, nil, NoopStage,
)),
labels.Labels{
{Name: "foo", Value: "500ms"},
{Name: "bar", Value: "foo"},
{Name: "buzz", Value: "blip"},
{Name: "namespace", Value: "dev"},
},
0.5,
labels.Labels{
{Name: "bar", Value: "foo"},
{Name: "buzz", Value: "blip"},
},
true,
},
{
"convert bytes",
mustSampleExtractor(LabelExtractorWithStages(
"foo", ConvertBytes, []string{"bar", "buzz"}, false, false, nil, NoopStage,
)),
labels.Labels{
{Name: "foo", Value: "13 MiB"},
{Name: "bar", Value: "foo"},
{Name: "buzz", Value: "blip"},
{Name: "namespace", Value: "dev"},
},
13 * 1024 * 1024,
labels.Labels{
{Name: "bar", Value: "foo"},
{Name: "buzz", Value: "blip"},
},
true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
sort.Sort(tt.in)
outval, outlbs, ok := tt.ex.ForStream(tt.in).Process([]byte(""))
require.Equal(t, tt.wantOk, ok)
require.Equal(t, tt.want, outval)
require.Equal(t, tt.wantLbs, outlbs.Labels())
})
}
}
func mustSampleExtractor(ex SampleExtractor, err error) SampleExtractor {
if err != nil {
panic(err)
}
return ex
}
func TestNewLineSampleExtractor(t *testing.T) {
se, err := NewLineSampleExtractor(CountExtractor, nil, nil, false, false)
require.NoError(t, err)
lbs := labels.Labels{
{Name: "namespace", Value: "dev"},
{Name: "cluster", Value: "us-central1"},
}
sort.Sort(lbs)
sse := se.ForStream(lbs)
f, l, ok := sse.Process([]byte(`foo`))
require.True(t, ok)
require.Equal(t, 1., f)
assertLabelResult(t, lbs, l)
filter, err := NewFilter("foo", labels.MatchEqual)
require.NoError(t, err)
se, err = NewLineSampleExtractor(BytesExtractor, []Stage{filter.ToStage()}, []string{"namespace"}, false, false)
require.NoError(t, err)
sse = se.ForStream(lbs)
f, l, ok = sse.Process([]byte(`foo`))
require.True(t, ok)
require.Equal(t, 3., f)
assertLabelResult(t, labels.Labels{labels.Label{Name: "namespace", Value: "dev"}}, l)
sse = se.ForStream(lbs)
_, _, ok = sse.Process([]byte(`nope`))
require.False(t, ok)
}