From 883fade9bd75fe595b6e947a33c59e27fca1abda Mon Sep 17 00:00:00 2001 From: Michael Hoffmann Date: Fri, 13 Sep 2024 18:52:22 +0200 Subject: [PATCH] *: build with stringlabels (#7745) Signed-off-by: Michael Hoffmann --- .promu.yml | 5 +- Makefile | 2 +- cmd/thanos/main_test.go | 16 +- pkg/api/query/grpc_test.go | 5 +- pkg/api/query/v1_test.go | 243 +---- pkg/compact/compact_e2e_test.go | 44 +- pkg/compact/compact_test.go | 39 - pkg/compact/downsample/downsample_test.go | 4 +- pkg/extprom/tx_gauge_test.go | 10 +- pkg/query/endpointset_test.go | 12 +- pkg/query/querier_test.go | 37 +- pkg/query/query_bench_test.go | 6 +- pkg/query/query_test.go | 124 --- pkg/query/test_test.go | 625 ------------ .../promql/prometheus/aggregators.test | 499 ---------- .../testdata/promql/prometheus/collision.test | 22 - .../testdata/promql/prometheus/functions.test | 892 ------------------ .../promql/prometheus/histograms.test | 193 ---- .../testdata/promql/prometheus/literals.test | 59 -- .../testdata/promql/prometheus/operators.test | 469 --------- .../testdata/promql/prometheus/selectors.test | 201 ---- .../testdata/promql/prometheus/staleness.test | 51 - .../testdata/promql/prometheus/subquery.test | 117 --- .../testdata/promql/thanos/aggregators.test | 220 ----- pkg/rules/rulespb/custom_test.go | 4 +- pkg/tenancy/tenancy_test.go | 5 +- 26 files changed, 116 insertions(+), 3788 deletions(-) delete mode 100644 pkg/query/test_test.go delete mode 100644 pkg/query/testdata/promql/prometheus/aggregators.test delete mode 100644 pkg/query/testdata/promql/prometheus/collision.test delete mode 100644 pkg/query/testdata/promql/prometheus/functions.test delete mode 100644 pkg/query/testdata/promql/prometheus/histograms.test delete mode 100644 pkg/query/testdata/promql/prometheus/literals.test delete mode 100644 pkg/query/testdata/promql/prometheus/operators.test delete mode 100644 pkg/query/testdata/promql/prometheus/selectors.test delete mode 100644 pkg/query/testdata/promql/prometheus/staleness.test delete mode 100644 pkg/query/testdata/promql/prometheus/subquery.test delete mode 100644 pkg/query/testdata/promql/thanos/aggregators.test diff --git a/.promu.yml b/.promu.yml index 095176fbf8..9350678c1e 100644 --- a/.promu.yml +++ b/.promu.yml @@ -6,7 +6,10 @@ build: binaries: - name: thanos path: ./cmd/thanos - flags: -a -tags netgo + flags: -a + tags: + - netgo + - stringlabels ldflags: | -X github.com/prometheus/common/version.Version={{.Version}} -X github.com/prometheus/common/version.Revision={{.Revision}} diff --git a/Makefile b/Makefile index a930af8dca..bca6345503 100644 --- a/Makefile +++ b/Makefile @@ -312,7 +312,7 @@ test: export THANOS_TEST_ALERTMANAGER_PATH= $(ALERTMANAGER) test: check-git install-tool-deps @echo ">> install thanos GOOPTS=${GOOPTS}" @echo ">> running unit tests (without /test/e2e). Do export THANOS_TEST_OBJSTORE_SKIP=GCS,S3,AZURE,SWIFT,COS,ALIYUNOSS,BOS,OCI,OBS if you want to skip e2e tests against all real store buckets. Current value: ${THANOS_TEST_OBJSTORE_SKIP}" - @go test -race -timeout 15m $(shell go list ./... | grep -v /vendor/ | grep -v /test/e2e); + @go test -race -tags stringlabels -timeout 15m $(shell go list ./... | grep -v /vendor/ | grep -v /test/e2e); .PHONY: test-local test-local: ## Runs test excluding tests for ALL object storage integrations. diff --git a/cmd/thanos/main_test.go b/cmd/thanos/main_test.go index fcc394a614..a08ccb16f3 100644 --- a/cmd/thanos/main_test.go +++ b/cmd/thanos/main_test.go @@ -123,9 +123,9 @@ func TestRegression4960_Deadlock(t *testing.T) { id, err = e2eutil.CreateBlock( ctx, dir, - []labels.Labels{{{Name: "a", Value: "1"}}}, + []labels.Labels{labels.FromStrings("a", "1")}, 1, 0, downsample.ResLevel1DownsampleRange+1, // Pass the minimum ResLevel1DownsampleRange check. - labels.Labels{{Name: "e1", Value: "1"}}, + labels.FromStrings("e1", "1"), downsample.ResLevel0, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, logger, bkt, path.Join(dir, id.String()), metadata.NoneFunc)) @@ -134,9 +134,9 @@ func TestRegression4960_Deadlock(t *testing.T) { id2, err = e2eutil.CreateBlock( ctx, dir, - []labels.Labels{{{Name: "a", Value: "2"}}}, + []labels.Labels{labels.FromStrings("a", "2")}, 1, 0, downsample.ResLevel1DownsampleRange+1, // Pass the minimum ResLevel1DownsampleRange check. - labels.Labels{{Name: "e1", Value: "2"}}, + labels.FromStrings("e1", "2"), downsample.ResLevel0, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, logger, bkt, path.Join(dir, id2.String()), metadata.NoneFunc)) @@ -145,9 +145,9 @@ func TestRegression4960_Deadlock(t *testing.T) { id3, err = e2eutil.CreateBlock( ctx, dir, - []labels.Labels{{{Name: "a", Value: "2"}}}, + []labels.Labels{labels.FromStrings("a", "2")}, 1, 0, downsample.ResLevel1DownsampleRange+1, // Pass the minimum ResLevel1DownsampleRange check. - labels.Labels{{Name: "e1", Value: "2"}}, + labels.FromStrings("e1", "2"), downsample.ResLevel0, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, logger, bkt, path.Join(dir, id3.String()), metadata.NoneFunc)) @@ -185,9 +185,9 @@ func TestCleanupDownsampleCacheFolder(t *testing.T) { id, err = e2eutil.CreateBlock( ctx, dir, - []labels.Labels{{{Name: "a", Value: "1"}}}, + []labels.Labels{labels.FromStrings("a", "1")}, 1, 0, downsample.ResLevel1DownsampleRange+1, // Pass the minimum ResLevel1DownsampleRange check. - labels.Labels{{Name: "e1", Value: "1"}}, + labels.FromStrings("e1", "1"), downsample.ResLevel0, metadata.NoneFunc) testutil.Ok(t, err) testutil.Ok(t, block.Upload(ctx, logger, bkt, path.Join(dir, id.String()), metadata.NoneFunc)) diff --git a/pkg/api/query/grpc_test.go b/pkg/api/query/grpc_test.go index 76d66b3254..b57ec7c9f7 100644 --- a/pkg/api/query/grpc_test.go +++ b/pkg/api/query/grpc_test.go @@ -12,6 +12,7 @@ import ( "github.com/efficientgo/core/testutil" "github.com/go-kit/log" "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/prometheus/model/labels" "github.com/prometheus/prometheus/promql" "github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/util/annotations" @@ -28,7 +29,7 @@ import ( func TestGRPCQueryAPIWithQueryPlan(t *testing.T) { logger := log.NewNopLogger() reg := prometheus.NewRegistry() - proxy := store.NewProxyStore(logger, reg, func() []store.Client { return nil }, component.Store, nil, 1*time.Minute, store.LazyRetrieval) + proxy := store.NewProxyStore(logger, reg, func() []store.Client { return nil }, component.Store, labels.EmptyLabels(), 1*time.Minute, store.LazyRetrieval) queryableCreator := query.NewQueryableCreator(logger, reg, proxy, 1, 1*time.Minute) lookbackDeltaFunc := func(i int64) time.Duration { return 5 * time.Minute } engineFactory := &QueryEngineFactory{ @@ -74,7 +75,7 @@ func TestGRPCQueryAPIWithQueryPlan(t *testing.T) { func TestGRPCQueryAPIErrorHandling(t *testing.T) { logger := log.NewNopLogger() reg := prometheus.NewRegistry() - proxy := store.NewProxyStore(logger, reg, func() []store.Client { return nil }, component.Store, nil, 1*time.Minute, store.LazyRetrieval) + proxy := store.NewProxyStore(logger, reg, func() []store.Client { return nil }, component.Store, labels.EmptyLabels(), 1*time.Minute, store.LazyRetrieval) queryableCreator := query.NewQueryableCreator(logger, reg, proxy, 1, 1*time.Minute) lookbackDeltaFunc := func(i int64) time.Duration { return 5 * time.Minute } tests := []struct { diff --git a/pkg/api/query/v1_test.go b/pkg/api/query/v1_test.go index 655a195e9c..71433530d2 100644 --- a/pkg/api/query/v1_test.go +++ b/pkg/api/query/v1_test.go @@ -136,38 +136,13 @@ func testEndpoint(t *testing.T, test endpointTestCase, name string, responseComp func TestQueryEndpoints(t *testing.T) { lbls := []labels.Labels{ - { - labels.Label{Name: "__name__", Value: "test_metric1"}, - labels.Label{Name: "foo", Value: "bar"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric1"}, - labels.Label{Name: "foo", Value: "boo"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric2"}, - labels.Label{Name: "foo", Value: "boo"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric_replica1"}, - labels.Label{Name: "foo", Value: "bar"}, - labels.Label{Name: "replica", Value: "a"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric_replica1"}, - labels.Label{Name: "foo", Value: "boo"}, - labels.Label{Name: "replica", Value: "a"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric_replica1"}, - labels.Label{Name: "foo", Value: "boo"}, - labels.Label{Name: "replica", Value: "b"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric_replica1"}, - labels.Label{Name: "foo", Value: "boo"}, - labels.Label{Name: "replica1", Value: "a"}, - }, + labels.FromStrings("__name__", "test_metric1", "foo", "bar"), + labels.FromStrings("__name__", "test_metric1", "foo", "bar"), + labels.FromStrings("__name__", "test_metric2", "foo", "boo"), + labels.FromStrings("__name__", "test_metric_replica1", "foo", "bar", "replica", "a"), + labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo", "replica", "a"), + labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo", "replica", "b"), + labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo", "replica1", "a"), } db, err := e2eutil.NewTSDB() @@ -265,76 +240,24 @@ func TestQueryEndpoints(t *testing.T) { ResultType: parser.ValueTypeVector, Result: promql.Vector{ { - Metric: labels.Labels{ - { - Name: "__name__", - Value: "test_metric_replica1", - }, - { - Name: "foo", - Value: "bar", - }, - { - Name: "replica", - Value: "a", - }, - }, - T: 123000, - F: 2, + Metric: labels.FromStrings("__name__", "test_metric_replica1", "foo", "bar", "replica", "a"), + T: 123000, + F: 2, }, { - Metric: labels.Labels{ - { - Name: "__name__", - Value: "test_metric_replica1", - }, - { - Name: "foo", - Value: "boo", - }, - { - Name: "replica", - Value: "a", - }, - }, - T: 123000, - F: 2, + Metric: labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo", "replica", "a"), + T: 123000, + F: 2, }, { - Metric: labels.Labels{ - { - Name: "__name__", - Value: "test_metric_replica1", - }, - { - Name: "foo", - Value: "boo", - }, - { - Name: "replica", - Value: "b", - }, - }, - T: 123000, - F: 2, + Metric: labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo", "replica", "b"), + T: 123000, + F: 2, }, { - Metric: labels.Labels{ - { - Name: "__name__", - Value: "test_metric_replica1", - }, - { - Name: "foo", - Value: "boo", - }, - { - Name: "replica1", - Value: "a", - }, - }, - T: 123000, - F: 2, + Metric: labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo", "replica1", "a"), + T: 123000, + F: 2, }, }, }, @@ -352,50 +275,19 @@ func TestQueryEndpoints(t *testing.T) { ResultType: parser.ValueTypeVector, Result: promql.Vector{ { - Metric: labels.Labels{ - { - Name: "__name__", - Value: "test_metric_replica1", - }, - { - Name: "foo", - Value: "bar", - }, - }, - T: 123000, - F: 2, + Metric: labels.FromStrings("__name__", "test_metric_replica1", "foo", "bar"), + T: 123000, + F: 2, }, { - Metric: labels.Labels{ - { - Name: "__name__", - Value: "test_metric_replica1", - }, - { - Name: "foo", - Value: "boo", - }, - }, - T: 123000, - F: 2, + Metric: labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo"), + T: 123000, + F: 2, }, { - Metric: labels.Labels{ - { - Name: "__name__", - Value: "test_metric_replica1", - }, - { - Name: "foo", - Value: "boo", - }, - { - Name: "replica1", - Value: "a", - }, - }, - T: 123000, - F: 2, + Metric: labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo", "replica1", "a"), + T: 123000, + F: 2, }, }, }, @@ -412,32 +304,14 @@ func TestQueryEndpoints(t *testing.T) { ResultType: parser.ValueTypeVector, Result: promql.Vector{ { - Metric: labels.Labels{ - { - Name: "__name__", - Value: "test_metric_replica1", - }, - { - Name: "foo", - Value: "bar", - }, - }, - T: 123000, - F: 2, + Metric: labels.FromStrings("__name__", "test_metric_replica1", "foo", "bar"), + T: 123000, + F: 2, }, { - Metric: labels.Labels{ - { - Name: "__name__", - Value: "test_metric_replica1", - }, - { - Name: "foo", - Value: "boo", - }, - }, - T: 123000, - F: 2, + Metric: labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo"), + T: 123000, + F: 2, }, }, }, @@ -483,7 +357,7 @@ func TestQueryEndpoints(t *testing.T) { } return res }(500, 1), - Metric: nil, + Metric: labels.EmptyLabels(), }, }, }, @@ -505,7 +379,7 @@ func TestQueryEndpoints(t *testing.T) { {F: 1, T: timestamp.FromTime(start.Add(1 * time.Second))}, {F: 2, T: timestamp.FromTime(start.Add(2 * time.Second))}, }, - Metric: nil, + Metric: labels.EmptyLabels(), }, }, }, @@ -768,7 +642,7 @@ func TestQueryAnalyzeEndpoints(t *testing.T) { } return res }(500, 1), - Metric: nil, + Metric: labels.EmptyLabels(), }, }, QueryAnalysis: queryTelemetry{}, @@ -785,7 +659,7 @@ func TestQueryAnalyzeEndpoints(t *testing.T) { func newProxyStoreWithTSDBStore(db store.TSDBReader) *store.ProxyStore { c := &storetestutil.TestClient{ Name: "1", - StoreClient: storepb.ServerAsClient(store.NewTSDBStore(nil, db, component.Query, nil)), + StoreClient: storepb.ServerAsClient(store.NewTSDBStore(nil, db, component.Query, labels.EmptyLabels())), MinTime: math.MinInt64, MaxTime: math.MaxInt64, } @@ -794,7 +668,7 @@ func newProxyStoreWithTSDBStore(db store.TSDBReader) *store.ProxyStore { nil, func() []store.Client { return []store.Client{c} }, component.Query, - nil, + labels.EmptyLabels(), 0, store.EagerRetrieval, ) @@ -802,41 +676,16 @@ func newProxyStoreWithTSDBStore(db store.TSDBReader) *store.ProxyStore { func TestMetadataEndpoints(t *testing.T) { var old = []labels.Labels{ - { - labels.Label{Name: "__name__", Value: "test_metric1"}, - labels.Label{Name: "foo", Value: "bar"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric1"}, - labels.Label{Name: "foo", Value: "boo"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric2"}, - labels.Label{Name: "foo", Value: "boo"}, - }, + labels.FromStrings("__name__", "test_metric1", "foo", "bar"), + labels.FromStrings("__name__", "test_metric1", "foo", "boo"), + labels.FromStrings("__name__", "test_metric2", "foo", "boo"), } var recent = []labels.Labels{ - { - labels.Label{Name: "__name__", Value: "test_metric_replica1"}, - labels.Label{Name: "foo", Value: "bar"}, - labels.Label{Name: "replica", Value: "a"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric_replica1"}, - labels.Label{Name: "foo", Value: "boo"}, - labels.Label{Name: "replica", Value: "a"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric_replica1"}, - labels.Label{Name: "foo", Value: "boo"}, - labels.Label{Name: "replica", Value: "b"}, - }, - { - labels.Label{Name: "__name__", Value: "test_metric_replica2"}, - labels.Label{Name: "foo", Value: "boo"}, - labels.Label{Name: "replica1", Value: "a"}, - }, + labels.FromStrings("__name__", "test_metric_replica1", "foo", "bar", "replica", "a"), + labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo", "replica", "a"), + labels.FromStrings("__name__", "test_metric_replica1", "foo", "boo", "replica", "b"), + labels.FromStrings("__name__", "test_metric_replica2", "foo", "boo", "replica1", "a"), } dir := t.TempDir() diff --git a/pkg/compact/compact_e2e_test.go b/pkg/compact/compact_e2e_test.go index e4f146e6eb..e1f13946e5 100644 --- a/pkg/compact/compact_e2e_test.go +++ b/pkg/compact/compact_e2e_test.go @@ -235,25 +235,25 @@ func testGroupCompactE2e(t *testing.T, mergeFunc storage.VerticalChunkSeriesMerg testutil.Assert(t, os.IsNotExist(err), "dir %s should be remove after compaction.", dir) // Test label name with slash, regression: https://github.com/thanos-io/thanos/issues/1661. - extLabels := labels.Labels{{Name: "e1", Value: "1/weird"}} - extLabels2 := labels.Labels{{Name: "e1", Value: "1"}} + extLabels := labels.FromStrings("e1", "1/weird") + extLabels2 := labels.FromStrings("e1", "1") metas := createAndUpload(t, bkt, []blockgenSpec{ { numSamples: 100, mint: 500, maxt: 1000, extLset: extLabels, res: 124, series: []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}, {Name: "b", Value: "2"}}, - {{Name: "a", Value: "3"}}, - {{Name: "a", Value: "4"}}, + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2", "b", "2"), + labels.FromStrings("a", "3"), + labels.FromStrings("a", "4"), }, }, { numSamples: 100, mint: 2000, maxt: 3000, extLset: extLabels, res: 124, series: []labels.Labels{ - {{Name: "a", Value: "3"}}, - {{Name: "a", Value: "4"}}, - {{Name: "a", Value: "5"}}, - {{Name: "a", Value: "6"}}, + labels.FromStrings("a", "3"), + labels.FromStrings("a", "4"), + labels.FromStrings("a", "5"), + labels.FromStrings("a", "6"), }, }, // Mix order to make sure compactor is able to deduct min time / max time. @@ -267,46 +267,46 @@ func testGroupCompactE2e(t *testing.T, mergeFunc storage.VerticalChunkSeriesMerg { numSamples: 100, mint: 3000, maxt: 4000, extLset: extLabels, res: 124, series: []labels.Labels{ - {{Name: "a", Value: "7"}}, + labels.FromStrings("a", "7"), }, }, // Extra block for "distraction" for different resolution and one for different labels. { - numSamples: 100, mint: 5000, maxt: 6000, extLset: labels.Labels{{Name: "e1", Value: "2"}}, res: 124, + numSamples: 100, mint: 5000, maxt: 6000, extLset: labels.FromStrings("e1", "2"), res: 124, series: []labels.Labels{ - {{Name: "a", Value: "7"}}, + labels.FromStrings("a", "7"), }, }, // Extra block for "distraction" for different resolution and one for different labels. { numSamples: 100, mint: 4000, maxt: 5000, extLset: extLabels, res: 0, series: []labels.Labels{ - {{Name: "a", Value: "7"}}, + labels.FromStrings("a", "7"), }, }, // Second group (extLabels2). { numSamples: 100, mint: 2000, maxt: 3000, extLset: extLabels2, res: 124, series: []labels.Labels{ - {{Name: "a", Value: "3"}}, - {{Name: "a", Value: "4"}}, - {{Name: "a", Value: "6"}}, + labels.FromStrings("a", "3"), + labels.FromStrings("a", "4"), + labels.FromStrings("a", "6"), }, }, { numSamples: 100, mint: 0, maxt: 1000, extLset: extLabels2, res: 124, series: []labels.Labels{ - {{Name: "a", Value: "1"}}, - {{Name: "a", Value: "2"}, {Name: "b", Value: "2"}}, - {{Name: "a", Value: "3"}}, - {{Name: "a", Value: "4"}}, + labels.FromStrings("a", "1"), + labels.FromStrings("a", "2", "b", "2"), + labels.FromStrings("a", "3"), + labels.FromStrings("a", "4"), }, }, // Due to TSDB compaction delay (not compacting fresh block), we need one more block to be pushed to trigger compaction. { numSamples: 100, mint: 3000, maxt: 4000, extLset: extLabels2, res: 124, series: []labels.Labels{ - {{Name: "a", Value: "7"}}, + labels.FromStrings("a", "7"), }, }, }) diff --git a/pkg/compact/compact_test.go b/pkg/compact/compact_test.go index 1d3764907c..f93fa9720c 100644 --- a/pkg/compact/compact_test.go +++ b/pkg/compact/compact_test.go @@ -91,45 +91,6 @@ func TestRetryError(t *testing.T) { testutil.Assert(t, IsHaltError(err), "not a halt error. Retry should not hide halt error") } -func TestGroupKey(t *testing.T) { - for _, tcase := range []struct { - input metadata.Thanos - expected string - }{ - { - input: metadata.Thanos{}, - expected: "0@17241709254077376921", - }, - { - input: metadata.Thanos{ - Labels: map[string]string{}, - Downsample: metadata.ThanosDownsample{Resolution: 0}, - }, - expected: "0@17241709254077376921", - }, - { - input: metadata.Thanos{ - Labels: map[string]string{"foo": "bar", "foo1": "bar2"}, - Downsample: metadata.ThanosDownsample{Resolution: 0}, - }, - expected: "0@2124638872457683483", - }, - { - input: metadata.Thanos{ - Labels: map[string]string{`foo/some..thing/some.thing/../`: `a_b_c/bar-something-a\metric/a\x`}, - Downsample: metadata.ThanosDownsample{Resolution: 0}, - }, - expected: "0@16590761456214576373", - }, - } { - if ok := t.Run("", func(t *testing.T) { - testutil.Equals(t, tcase.expected, tcase.input.GroupKey()) - }); !ok { - return - } - } -} - func TestGroupMaxMinTime(t *testing.T) { g := &Group{ metasByMinTime: []*metadata.Meta{ diff --git a/pkg/compact/downsample/downsample_test.go b/pkg/compact/downsample/downsample_test.go index b9d94e5589..2ef7c71b67 100644 --- a/pkg/compact/downsample/downsample_test.go +++ b/pkg/compact/downsample/downsample_test.go @@ -1770,10 +1770,10 @@ func (b *memBlock) addSeries(s *series) { b.postings = append(b.postings, sid) b.series = append(b.series, s) - for _, l := range s.lset { + s.lset.Range(func(l labels.Label) { b.symbols[l.Name] = struct{}{} b.symbols[l.Value] = struct{}{} - } + }) for i, cm := range s.chunks { if b.minTime == -1 || cm.MinTime < b.minTime { diff --git a/pkg/extprom/tx_gauge_test.go b/pkg/extprom/tx_gauge_test.go index ec45b1e081..c4b22045c0 100644 --- a/pkg/extprom/tx_gauge_test.go +++ b/pkg/extprom/tx_gauge_test.go @@ -483,16 +483,16 @@ func sortDtoMessages(msgs []proto.Message) { m1 := msgs[i].(*dto.Metric) m2 := msgs[j].(*dto.Metric) - lbls1 := labels.Labels{} + b1 := labels.NewBuilder(labels.EmptyLabels()) for _, p := range m1.GetLabel() { - lbls1 = append(lbls1, labels.Label{Name: *p.Name, Value: *p.Value}) + b1.Set(*p.Name, *p.Value) } - lbls2 := labels.Labels{} + b2 := labels.NewBuilder(labels.EmptyLabels()) for _, p := range m2.GetLabel() { - lbls2 = append(lbls2, labels.Label{Name: *p.Name, Value: *p.Value}) + b2.Set(*p.Name, *p.Value) } - return labels.Compare(lbls1, lbls2) < 0 + return labels.Compare(b1.Labels(), b2.Labels()) < 0 }) } diff --git a/pkg/query/endpointset_test.go b/pkg/query/endpointset_test.go index 3c19661ec2..f72e29c28a 100644 --- a/pkg/query/endpointset_test.go +++ b/pkg/query/endpointset_test.go @@ -720,10 +720,8 @@ func TestEndpointSetUpdate_AvailabilityScenarios(t *testing.T) { lset := e.LabelSets() testutil.Equals(t, 2, len(lset)) - testutil.Equals(t, "addr", lset[0][0].Name) - testutil.Equals(t, addr, lset[0][0].Value) - testutil.Equals(t, "a", lset[1][0].Name) - testutil.Equals(t, "b", lset[1][0].Value) + testutil.Equals(t, lset[0].Get("addr"), addr) + testutil.Equals(t, lset[1].Get("a"), "b") assertRegisteredAPIs(t, endpoints.exposedAPIs[addr], e) } @@ -755,10 +753,8 @@ func TestEndpointSetUpdate_AvailabilityScenarios(t *testing.T) { lset := st.LabelSets() testutil.Equals(t, 2, len(lset)) - testutil.Equals(t, "addr", lset[0][0].Name) - testutil.Equals(t, addr, lset[0][0].Value) - testutil.Equals(t, "a", lset[1][0].Name) - testutil.Equals(t, "b", lset[1][0].Value) + testutil.Equals(t, lset[0].Get("addr"), addr) + testutil.Equals(t, lset[1].Get("a"), "b") testutil.Equals(t, expected, endpointSet.endpointsMetric.storeNodes) // New big batch of endpoints. diff --git a/pkg/query/querier_test.go b/pkg/query/querier_test.go index 390afb14be..bebdfc768f 100644 --- a/pkg/query/querier_test.go +++ b/pkg/query/querier_test.go @@ -18,7 +18,6 @@ import ( "github.com/efficientgo/core/testutil" "github.com/go-kit/log" - "github.com/google/go-cmp/cmp" "github.com/pkg/errors" "github.com/prometheus/common/model" "github.com/prometheus/prometheus/model/histogram" @@ -352,7 +351,7 @@ func TestQuerier_Select_AfterPromQL(t *testing.T) { // Regression test 1 against https://github.com/thanos-io/thanos/issues/2890. name: "when switching replicas don't miss samples when set with a big enough lookback delta", storeAPI: newProxyStore(func() storepb.StoreServer { - s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2890-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) + s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, labels.EmptyLabels(), "./testdata/issue2890-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) testutil.Ok(t, err) return s }()), @@ -476,7 +475,7 @@ func TestQuerier_Select(t *testing.T) { }, }, expectedAfterDedup: []series{{ - lset: nil, + lset: labels.EmptyLabels(), // We don't expect correctness here, it's just random non-replica data. samples: []sample{{1, 1}, {2, 2}, {3, 3}, {5, 5}, {6, 6}, {7, 7}}, }}, @@ -485,7 +484,7 @@ func TestQuerier_Select(t *testing.T) { { name: "realistic data with stale marker", storeEndpoints: []storepb.StoreServer{func() storepb.StoreServer { - s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) + s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, labels.EmptyLabels(), "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) testutil.Ok(t, err) return s }()}, @@ -529,7 +528,7 @@ func TestQuerier_Select(t *testing.T) { { name: "realistic data with stale marker with 100000 step", storeEndpoints: []storepb.StoreServer{func() storepb.StoreServer { - s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) + s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, labels.EmptyLabels(), "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) testutil.Ok(t, err) return s }()}, @@ -580,7 +579,7 @@ func TestQuerier_Select(t *testing.T) { // Thanks to @Superq and GitLab for real data reproducing this. name: "realistic data with stale marker with hints rate function", storeEndpoints: []storepb.StoreServer{func() storepb.StoreServer { - s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) + s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, labels.EmptyLabels(), "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) testutil.Ok(t, err) return s }()}, @@ -847,19 +846,12 @@ func newProxyStore(storeAPIs ...storepb.StoreServer) *store.ProxyStore { nil, func() []store.Client { return cls }, component.Query, - nil, + labels.EmptyLabels(), 0, store.EagerRetrieval, ) } -var emptyLabelsSameAsNotAllocatedLabels = cmp.Transformer("", func(l labels.Labels) labels.Labels { - if len(l) == 0 { - return labels.Labels(nil) - } - return l -}) - func testSelectResponse(t *testing.T, expected []series, res storage.SeriesSet) { var series []storage.Series // Use it as PromQL would do, first gather all series. @@ -876,7 +868,7 @@ func testSelectResponse(t *testing.T, expected []series, res storage.SeriesSet) }()) for i, s := range series { - testutil.WithGoCmp(emptyLabelsSameAsNotAllocatedLabels).Equals(t, expected[i].lset, s.Labels()) + testutil.Equals(t, expected[i].lset, s.Labels()) samples := expandSeries(t, s.Iterator(nil)) expectedCpy := make([]sample, 0, len(expected[i].samples)) for _, s := range expected[i].samples { @@ -901,15 +893,12 @@ func jsonToSeries(t *testing.T, filename string) []series { var ss []series for _, ser := range data.Data.Results { - var lbls labels.Labels + b := labels.NewBuilder(labels.EmptyLabels()) for n, v := range ser.Metric { - lbls = append(lbls, labels.Label{ - Name: string(n), - Value: string(v), - }) + b.Set(string(n), string(v)) } // Label names need to be sorted. - sort.Sort(lbls) + lbls := b.Labels() var smpls []sample for _, smp := range ser.Values { @@ -1058,7 +1047,7 @@ func (s *mockedSeriesIterator) Err() error { return nil } func TestQuerierWithDedupUnderstoodByPromQL_Rate(t *testing.T) { logger := log.NewLogfmtLogger(os.Stderr) - s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, nil, "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) + s, err := store.NewLocalStoreFromJSONMmappableFile(logger, component.Debug, labels.EmptyLabels(), "./testdata/issue2401-seriesresponses.json", store.ScanGRPCCurlProtoStreamMessages) testutil.Ok(t, err) t.Run("dedup=false", func(t *testing.T) { @@ -1245,9 +1234,9 @@ func (s *testStoreServer) Series(r *storepb.SeriesRequest, srv storepb.Store_Ser func storeSeriesResponse(t testing.TB, lset labels.Labels, smplChunks ...[]sample) *storepb.SeriesResponse { var s storepb.Series - for _, l := range lset { + lset.Range(func(l labels.Label) { s.Labels = append(s.Labels, &labelpb.Label{Name: l.Name, Value: l.Value}) - } + }) for _, smpls := range smplChunks { c := chunkenc.NewXORChunk() diff --git a/pkg/query/query_bench_test.go b/pkg/query/query_bench_test.go index 01e5d35a89..737e927984 100644 --- a/pkg/query/query_bench_test.go +++ b/pkg/query/query_bench_test.go @@ -70,11 +70,11 @@ func benchQuerySelect(t testutil.TB, totalSamples, totalSeries int, dedup bool) testutil.Ok(t, head.Close()) for i := 0; i < len(created); i++ { if !dedup || j == 0 { - lset := labelpb.LabelpbLabelsToPromLabels(created[i].Labels).Copy() + b := labels.NewBuilder(labelpb.LabelpbLabelsToPromLabels(created[i].Labels)) if dedup { - lset = lset[1:] + b.Del("a_replica") } - expectedSeries = append(expectedSeries, lset) + expectedSeries = append(expectedSeries, b.Labels()) } resps = append(resps, storepb.NewSeriesResponse(created[i])) diff --git a/pkg/query/query_test.go b/pkg/query/query_test.go index 34121d75a0..097dc9c5d7 100644 --- a/pkg/query/query_test.go +++ b/pkg/query/query_test.go @@ -4,135 +4,11 @@ package query import ( - "fmt" - "os" - "path/filepath" - "sync" "testing" - "time" - "github.com/efficientgo/core/testutil" - "github.com/go-kit/log" - "github.com/prometheus/prometheus/storage" - "github.com/thanos-io/thanos/pkg/component" - "github.com/thanos-io/thanos/pkg/store" - "github.com/thanos-io/thanos/pkg/store/storepb" - storetestutil "github.com/thanos-io/thanos/pkg/store/storepb/testutil" "github.com/thanos-io/thanos/pkg/testutil/custom" - "google.golang.org/protobuf/proto" ) func TestMain(m *testing.M) { custom.TolerantVerifyLeakMain(m) } - -type safeClients struct { - sync.RWMutex - clients []store.Client -} - -func (sc *safeClients) get() []store.Client { - sc.RLock() - defer sc.RUnlock() - ret := make([]store.Client, len(sc.clients)) - copy(ret, sc.clients) - return ret -} - -func (sc *safeClients) reset() { - sc.Lock() - defer sc.Unlock() - sc.clients = sc.clients[:0] -} - -func (sc *safeClients) append(c store.Client) { - sc.Lock() - defer sc.Unlock() - sc.clients = append(sc.clients, c) -} - -func TestQuerier_Proxy(t *testing.T) { - files, err := filepath.Glob("testdata/promql/**/*.test") - testutil.Ok(t, err) - testutil.Equals(t, 10, len(files), "%v", files) - - logger := log.NewLogfmtLogger(os.Stderr) - t.Run("proxy", func(t *testing.T) { - var sc safeClients - q := NewQueryableCreator( - logger, - nil, - store.NewProxyStore(logger, nil, func() []store.Client { return sc.get() }, - component.Debug, nil, 5*time.Minute, store.EagerRetrieval), - 1000000, - 5*time.Minute, - ) - - createQueryableFn := func(stores []*testStore) storage.Queryable { - sc.reset() - for i, st := range stores { - m, err := storepb.PromMatchersToMatchers(st.matchers...) - testutil.Ok(t, err) - // TODO(bwplotka): Parse external labels. - sc.append(&storetestutil.TestClient{ - Name: fmt.Sprintf("store number %v", i), - StoreClient: storepb.ServerAsClient(selectedStore(store.NewTSDBStore(logger, st.storage.DB, component.Debug, nil), m, st.mint, st.maxt)), - MinTime: st.mint, - MaxTime: st.maxt, - }) - } - return q(true, - nil, - nil, - 0, - false, - false, - nil, - NoopSeriesStatsReporter, - ) - } - - for _, fn := range files { - t.Run(fn, func(t *testing.T) { - te, err := newTestFromFile(t, fn) - testutil.Ok(t, err) - testutil.Ok(t, te.run(createQueryableFn)) - te.close() - }) - } - }) -} - -// selectStore allows wrapping another storeEndpoints with additional time and matcher selection. -type selectStore struct { - matchers []*storepb.LabelMatcher - - storepb.StoreServer - mint, maxt int64 -} - -// selectedStore wraps given store with selectStore. -func selectedStore(wrapped storepb.StoreServer, matchers []*storepb.LabelMatcher, mint, maxt int64) *selectStore { - return &selectStore{ - StoreServer: wrapped, - matchers: matchers, - mint: mint, - maxt: maxt, - } -} - -func (s *selectStore) Series(r *storepb.SeriesRequest, srv storepb.Store_SeriesServer) error { - if r.MinTime < s.mint { - r.MinTime = s.mint - } - if r.MaxTime > s.maxt { - r.MaxTime = s.maxt - } - - matchers := make([]*storepb.LabelMatcher, 0, len(r.Matchers)) - matchers = append(matchers, r.Matchers...) - - req := proto.Clone(r).(*storepb.SeriesRequest) - req.Matchers = matchers - return s.StoreServer.Series(req, srv) -} diff --git a/pkg/query/test_test.go b/pkg/query/test_test.go deleted file mode 100644 index d8af78c66d..0000000000 --- a/pkg/query/test_test.go +++ /dev/null @@ -1,625 +0,0 @@ -// Copyright (c) The Thanos Authors. -// Licensed under the Apache License 2.0. - -package query - -import ( - "context" - "fmt" - "math" - "os" - "path/filepath" - "regexp" - "strconv" - "strings" - "testing" - "time" - - "github.com/pkg/errors" - "github.com/prometheus/common/model" - "github.com/prometheus/prometheus/model/labels" - "github.com/prometheus/prometheus/model/timestamp" - "github.com/prometheus/prometheus/promql" - "github.com/prometheus/prometheus/promql/parser" - "github.com/prometheus/prometheus/promql/parser/posrange" - "github.com/prometheus/prometheus/storage" - "github.com/prometheus/prometheus/util/teststorage" - - "github.com/thanos-io/thanos/pkg/extpromql" -) - -var ( - minNormal = math.Float64frombits(0x0010000000000000) // The smallest positive normal value of type float64. - - patSpace = regexp.MustCompile("[\t ]+") - // TODO(bwplotka): Parse external labels. - patStore = regexp.MustCompile(`^store\s+([{}=_"a-zA-Z0-9]+)\s+([0-9mds]+)\s+([0-9mds]+)$`) - patLoad = regexp.MustCompile(`^load\s+(.+?)$`) - patEvalInstant = regexp.MustCompile(`^eval(?:_(fail|ordered))?\s+instant\s+(?:at\s+(.+?))?\s+(.+)$`) -) - -const ( - epsilon = 0.000001 // Relative error allowed for sample values. -) - -var testStartTime = time.Unix(0, 0).UTC() - -func durationMilliseconds(d time.Duration) int64 { - return int64(d / (time.Millisecond / time.Nanosecond)) -} - -func timeMilliseconds(t time.Time) int64 { - return t.UnixNano() / int64(time.Millisecond/time.Nanosecond) -} - -type test struct { - testing.TB - - cmds []interface{} - rootEngine *promql.Engine - stores []*testStore - - ctx context.Context - cancelCtx context.CancelFunc -} - -type testStore struct { - storeCmd - - storage *teststorage.TestStorage - - ctx context.Context - cancelCtx context.CancelFunc -} - -func newTestStore(t testing.TB, cmd *storeCmd) *testStore { - s := &testStore{ - storeCmd: *cmd, - storage: teststorage.New(t), - } - s.ctx, s.cancelCtx = context.WithCancel(context.Background()) - return s -} - -// close closes resources associated with the testStore. -func (s *testStore) close(t testing.TB) { - s.cancelCtx() - - if err := s.storage.Close(); err != nil { - t.Fatalf("closing test storage: %s", err) - } -} - -// NewTest returns an initialized empty Test. -// It's compatible with promql.Test, allowing additionally multi StoreAPIs. -// TODO(bwplotka): Move to unittest and add add support for multi-store upstream. See: https://github.com/prometheus/prometheus/pull/8300 -func newTest(t testing.TB, input string) (*test, error) { - cmds, err := parse(input) - if err != nil { - return nil, err - } - - te := &test{TB: t, cmds: cmds} - te.reset() - return te, err -} - -func newTestFromFile(t testing.TB, filename string) (*test, error) { - content, err := os.ReadFile(filepath.Clean(filename)) - if err != nil { - return nil, err - } - return newTest(t, string(content)) -} - -// reset the current test storage of all inserted samples. -func (t *test) reset() { - if t.cancelCtx != nil { - t.cancelCtx() - } - t.ctx, t.cancelCtx = context.WithCancel(context.Background()) - - opts := promql.EngineOpts{ - Logger: nil, - Reg: nil, - MaxSamples: 10000, - Timeout: 100 * time.Second, - NoStepSubqueryIntervalFn: func(int64) int64 { return durationMilliseconds(1 * time.Minute) }, - } - t.rootEngine = promql.NewEngine(opts) - - for _, s := range t.stores { - s.close(t.TB) - } - t.stores = t.stores[:0] -} - -// close closes resources associated with the Test. -func (t *test) close() { - t.cancelCtx() - for _, s := range t.stores { - s.close(t.TB) - } -} - -// getLines returns trimmed lines after removing the comments. -func getLines(input string) []string { - lines := strings.Split(input, "\n") - for i, l := range lines { - l = strings.TrimSpace(l) - if strings.HasPrefix(l, "#") { - l = "" - } - lines[i] = l - } - return lines -} - -// parse parses the given input and returns command sequence. -func parse(input string) (cmds []interface{}, err error) { - lines := getLines(input) - - // Scan for steps line by line. - for i := 0; i < len(lines); i++ { - l := lines[i] - if l == "" { - continue - } - var cmd interface{} - - switch c := strings.ToLower(patSpace.Split(l, 2)[0]); { - case c == "clear": - cmd = &clearCmd{} - case c == "load": - i, cmd, err = ParseLoad(lines, i) - case strings.HasPrefix(c, "eval"): - i, cmd, err = ParseEval(lines, i) - case c == "store": - i, cmd, err = ParseStore(lines, i) - default: - return nil, raise(i, "invalid command %q", l) - } - if err != nil { - return nil, err - } - cmds = append(cmds, cmd) - } - return cmds, nil -} - -func raise(line int, format string, v ...interface{}) error { - return &parser.ParseErr{ - LineOffset: line, - Err: errors.Errorf(format, v...), - } -} - -// run executes the command sequence of the test. Until the maximum error number -// is reached, evaluation errors do not terminate execution. -func (t *test) run(createQueryableFn func([]*testStore) storage.Queryable) error { - for _, cmd := range t.cmds { - if err := t.exec(cmd, createQueryableFn); err != nil { - return err - } - } - return nil -} - -// exec processes a single step of the test. -func (t *test) exec(tc interface{}, createQueryableFn func([]*testStore) storage.Queryable) error { - switch cmd := tc.(type) { - case *clearCmd: - t.reset() - case *storeCmd: - t.stores = append(t.stores, newTestStore(t.TB, tc.(*storeCmd))) - - case *loadCmd: - if len(t.stores) == 0 { - t.stores = append(t.stores, newTestStore(t.TB, newStoreCmd(nil, math.MinInt64, math.MaxInt64))) - } - - app := t.stores[len(t.stores)-1].storage.Appender(t.ctx) - if err := cmd.Append(app); err != nil { - _ = app.Rollback() - return err - } - if err := app.Commit(); err != nil { - return err - } - - case *evalCmd: - if err := cmd.Eval(t.ctx, t.rootEngine, createQueryableFn(t.stores)); err != nil { - return err - } - - default: - return errors.Errorf("pkg/query.Test.exec: unknown test command type %v", cmd) - } - return nil -} - -// storeCmd is a command that appends new storage with filter. -type storeCmd struct { - matchers []*labels.Matcher - mint, maxt int64 -} - -func newStoreCmd(matchers []*labels.Matcher, mint, maxt int64) *storeCmd { - return &storeCmd{ - matchers: matchers, - mint: mint, - maxt: maxt, - } -} - -func (cmd storeCmd) String() string { - return "store" -} - -// ParseStore parses store statements. -func ParseStore(lines []string, i int) (int, *storeCmd, error) { - if !patStore.MatchString(lines[i]) { - return i, nil, raise(i, "invalid store command. (store )") - } - parts := patStore.FindStringSubmatch(lines[i]) - - m, err := extpromql.ParseMetricSelector(parts[1]) - if err != nil { - return i, nil, raise(i, "invalid matcher definition %q: %s", parts[1], err) - } - - offset, err := model.ParseDuration(parts[2]) - if err != nil { - return i, nil, raise(i, "invalid mint definition %q: %s", parts[2], err) - } - mint := testStartTime.Add(time.Duration(offset)) - - offset, err = model.ParseDuration(parts[3]) - if err != nil { - return i, nil, raise(i, "invalid maxt definition %q: %s", parts[3], err) - } - maxt := testStartTime.Add(time.Duration(offset)) - return i, newStoreCmd(m, timestamp.FromTime(mint), timestamp.FromTime(maxt)), nil -} - -// ParseLoad parses load statements. -func ParseLoad(lines []string, i int) (int, *loadCmd, error) { - if !patLoad.MatchString(lines[i]) { - return i, nil, raise(i, "invalid load command. (load )") - } - parts := patLoad.FindStringSubmatch(lines[i]) - - gap, err := model.ParseDuration(parts[1]) - if err != nil { - return i, nil, raise(i, "invalid step definition %q: %s", parts[1], err) - } - cmd := newLoadCmd(time.Duration(gap)) - for i+1 < len(lines) { - i++ - defLine := lines[i] - if defLine == "" { - i-- - break - } - metric, vals, err := parser.ParseSeriesDesc(defLine) - if err != nil { - if perr, ok := err.(*parser.ParseErr); ok { - perr.LineOffset = i - } - return i, nil, err - } - cmd.set(metric, vals...) - } - return i, cmd, nil -} - -// ParseEval parses eval statements. -func ParseEval(lines []string, i int) (int, *evalCmd, error) { - if !patEvalInstant.MatchString(lines[i]) { - return i, nil, raise(i, "invalid evaluation command. (eval[_fail|_ordered] instant [at ] ") - } - parts := patEvalInstant.FindStringSubmatch(lines[i]) - var ( - mod = parts[1] - at = parts[2] - expr = parts[3] - ) - _, err := extpromql.ParseExpr(expr) - if err != nil { - if perr, ok := err.(*parser.ParseErr); ok { - perr.LineOffset = i - posOffset := posrange.Pos(strings.Index(lines[i], expr)) - perr.PositionRange.Start += posOffset - perr.PositionRange.End += posOffset - perr.Query = lines[i] - } - return i, nil, err - } - - offset, err := model.ParseDuration(at) - if err != nil { - return i, nil, raise(i, "invalid step definition %q: %s", parts[1], err) - } - ts := testStartTime.Add(time.Duration(offset)) - - cmd := newEvalCmd(expr, ts, i+1) - switch mod { - case "ordered": - cmd.ordered = true - case "fail": - cmd.fail = true - } - - for j := 1; i+1 < len(lines); j++ { - i++ - defLine := lines[i] - if defLine == "" { - i-- - break - } - if f, err := parseNumber(defLine); err == nil { - cmd.expect(0, nil, parser.SequenceValue{Value: f}) - break - } - metric, vals, err := parser.ParseSeriesDesc(defLine) - if err != nil { - if perr, ok := err.(*parser.ParseErr); ok { - perr.LineOffset = i - } - return i, nil, err - } - - // Currently, we are not expecting any matrices. - if len(vals) > 1 { - return i, nil, raise(i, "expecting multiple values in instant evaluation not allowed") - } - cmd.expect(j, metric, vals...) - } - return i, cmd, nil -} - -func parseNumber(s string) (float64, error) { - n, err := strconv.ParseInt(s, 0, 64) - f := float64(n) - if err != nil { - f, err = strconv.ParseFloat(s, 64) - } - if err != nil { - return 0, errors.Wrap(err, "error parsing number") - } - return f, nil -} - -// loadCmd is a command that loads sequences of sample values for specific -// metrics into the storage. -type loadCmd struct { - gap time.Duration - metrics map[uint64]labels.Labels - defs map[uint64][]promql.FPoint -} - -func newLoadCmd(gap time.Duration) *loadCmd { - return &loadCmd{ - gap: gap, - metrics: map[uint64]labels.Labels{}, - defs: map[uint64][]promql.FPoint{}, - } -} - -func (cmd loadCmd) String() string { - return "load" -} - -// set a sequence of sample values for the given metric. -func (cmd *loadCmd) set(m labels.Labels, vals ...parser.SequenceValue) { - h := m.Hash() - - samples := make([]promql.FPoint, 0, len(vals)) - ts := testStartTime - for _, v := range vals { - if !v.Omitted { - samples = append(samples, promql.FPoint{ - T: ts.UnixNano() / int64(time.Millisecond/time.Nanosecond), - F: v.Value, - }) - } - ts = ts.Add(cmd.gap) - } - cmd.defs[h] = samples - cmd.metrics[h] = m -} - -// Append the defined time series to the storage. -func (cmd *loadCmd) Append(a storage.Appender) error { - for h, smpls := range cmd.defs { - m := cmd.metrics[h] - - for _, s := range smpls { - if _, err := a.Append(0, m, s.T, s.F); err != nil { - return err - } - } - } - return nil -} - -// evalCmd is a command that evaluates an expression for the given time (range) -// and expects a specific result. -type evalCmd struct { - expr string - start time.Time - line int - - fail, ordered bool - - metrics map[uint64]labels.Labels - expected map[uint64]entry -} - -type entry struct { - pos int - vals []parser.SequenceValue -} - -func (e entry) String() string { - return fmt.Sprintf("%d: %s", e.pos, e.vals) -} - -func newEvalCmd(expr string, start time.Time, line int) *evalCmd { - return &evalCmd{ - expr: expr, - start: start, - line: line, - - metrics: map[uint64]labels.Labels{}, - expected: map[uint64]entry{}, - } -} - -func (ev *evalCmd) String() string { - return "eval" -} - -// expect adds a new metric with a sequence of values to the set of expected -// results for the query. -func (ev *evalCmd) expect(pos int, m labels.Labels, vals ...parser.SequenceValue) { - if m == nil { - ev.expected[0] = entry{pos: pos, vals: vals} - return - } - h := m.Hash() - ev.metrics[h] = m - ev.expected[h] = entry{pos: pos, vals: vals} -} - -// samplesAlmostEqual returns true if the two sample lines only differ by a -// small relative error in their sample value. -func almostEqual(a, b float64) bool { - // NaN has no equality but for testing we still want to know whether both values - // are NaN. - if math.IsNaN(a) && math.IsNaN(b) { - return true - } - - // Cf. http://floating-point-gui.de/errors/comparison/ - if a == b { - return true - } - - diff := math.Abs(a - b) - - if a == 0 || b == 0 || diff < minNormal { - return diff < epsilon*minNormal - } - return diff/(math.Abs(a)+math.Abs(b)) < epsilon -} - -// compareResult compares the result value with the defined expectation. -func (ev *evalCmd) compareResult(result parser.Value) error { - switch val := result.(type) { - case promql.Matrix: - return errors.New("received range result on instant evaluation") - - case promql.Vector: - seen := map[uint64]bool{} - for pos, v := range val { - fp := v.Metric.Hash() - if _, ok := ev.metrics[fp]; !ok { - return errors.Errorf("unexpected metric %s in result", v.Metric) - } - exp := ev.expected[fp] - if ev.ordered && exp.pos != pos+1 { - return errors.Errorf("expected metric %s with %v at position %d but was at %d", v.Metric, exp.vals, exp.pos, pos+1) - } - if !almostEqual(exp.vals[0].Value, v.F) { - return errors.Errorf("expected %v for %s but got %v", exp.vals[0].Value, v.Metric, v.F) - } - - seen[fp] = true - } - for fp, expVals := range ev.expected { - if !seen[fp] { - details := fmt.Sprintln("vector result", len(val), ev.expr) - for _, ss := range val { - details += fmt.Sprintln(" ", ss.Metric, ss.T, ss.F) - } - return errors.Errorf("expected metric %s with %v not found; details: %v", ev.metrics[fp], expVals, details) - } - } - - case promql.Scalar: - if !almostEqual(ev.expected[0].vals[0].Value, val.V) { - return errors.Errorf("expected Scalar %v but got %v", val.V, ev.expected[0].vals[0].Value) - } - - default: - panic(errors.Errorf("promql.Test.compareResult: unexpected result type %T", result)) - } - return nil -} - -func (ev *evalCmd) Eval(ctx context.Context, queryEngine *promql.Engine, queryable storage.Queryable) error { - q, err := queryEngine.NewInstantQuery(ctx, queryable, promql.NewPrometheusQueryOpts(false, 0), ev.expr, ev.start) - if err != nil { - return err - } - defer q.Close() - - res := q.Exec(ctx) - if res.Err != nil { - if ev.fail { - return nil - } - return errors.Wrapf(res.Err, "error evaluating query %q (line %d)", ev.expr, ev.line) - } - if res.Err == nil && ev.fail { - return errors.Errorf("expected error evaluating query %q (line %d) but got none", ev.expr, ev.line) - } - - err = ev.compareResult(res.Value) - if err != nil { - return errors.Wrapf(err, "error in %s %s", ev, ev.expr) - } - - // Check query returns same result in range mode, - // by checking against the middle step. - q, err = queryEngine.NewRangeQuery(ctx, queryable, promql.NewPrometheusQueryOpts(false, 0), ev.expr, ev.start.Add(-time.Minute), ev.start.Add(time.Minute), time.Minute) - if err != nil { - return err - } - rangeRes := q.Exec(ctx) - if rangeRes.Err != nil { - return errors.Wrapf(rangeRes.Err, "error evaluating query %q (line %d) in range mode", ev.expr, ev.line) - } - defer q.Close() - if ev.ordered { - // Ordering isn't defined for range queries. - return nil - } - mat := rangeRes.Value.(promql.Matrix) - vec := make(promql.Vector, 0, len(mat)) - for _, series := range mat { - for _, point := range series.Floats { - if point.T == timeMilliseconds(ev.start) { - vec = append(vec, promql.Sample{Metric: series.Metric, T: point.T, F: point.F}) - break - } - } - } - if _, ok := res.Value.(promql.Scalar); ok { - err = ev.compareResult(promql.Scalar{V: vec[0].F}) - } else { - err = ev.compareResult(vec) - } - if err != nil { - return errors.Wrapf(err, "error in %s %s (line %d) rande mode", ev, ev.expr, ev.line) - } - return nil -} - -// clearCmd is a command that wipes the test's storage state. -type clearCmd struct{} - -func (cmd clearCmd) String() string { - return "clear" -} diff --git a/pkg/query/testdata/promql/prometheus/aggregators.test b/pkg/query/testdata/promql/prometheus/aggregators.test deleted file mode 100644 index cda2e7f4e0..0000000000 --- a/pkg/query/testdata/promql/prometheus/aggregators.test +++ /dev/null @@ -1,499 +0,0 @@ -load 5m - http_requests{job="api-server", instance="0", group="production"} 0+10x10 - http_requests{job="api-server", instance="1", group="production"} 0+20x10 - http_requests{job="api-server", instance="0", group="canary"} 0+30x10 - http_requests{job="api-server", instance="1", group="canary"} 0+40x10 - http_requests{job="app-server", instance="0", group="production"} 0+50x10 - http_requests{job="app-server", instance="1", group="production"} 0+60x10 - http_requests{job="app-server", instance="0", group="canary"} 0+70x10 - http_requests{job="app-server", instance="1", group="canary"} 0+80x10 - -load 5m - foo{job="api-server", instance="0", region="europe"} 0+90x10 - foo{job="api-server"} 0+100x10 - -# Simple sum. -eval instant at 50m SUM BY (group) (http_requests{job="api-server"}) - {group="canary"} 700 - {group="production"} 300 - -eval instant at 50m SUM BY (group) (((http_requests{job="api-server"}))) - {group="canary"} 700 - {group="production"} 300 - -# Test alternative "by"-clause order. -eval instant at 50m sum by (group) (http_requests{job="api-server"}) - {group="canary"} 700 - {group="production"} 300 - -# Simple average. -eval instant at 50m avg by (group) (http_requests{job="api-server"}) - {group="canary"} 350 - {group="production"} 150 - -# Simple count. -eval instant at 50m count by (group) (http_requests{job="api-server"}) - {group="canary"} 2 - {group="production"} 2 - -# Simple without. -eval instant at 50m sum without (instance) (http_requests{job="api-server"}) - {group="canary",job="api-server"} 700 - {group="production",job="api-server"} 300 - -# Empty by. -eval instant at 50m sum by () (http_requests{job="api-server"}) - {} 1000 - -# No by/without. -eval instant at 50m sum(http_requests{job="api-server"}) - {} 1000 - -# Empty without. -eval instant at 50m sum without () (http_requests{job="api-server",group="production"}) - {group="production",job="api-server",instance="0"} 100 - {group="production",job="api-server",instance="1"} 200 - -# Without with mismatched and missing labels. Do not do this. -eval instant at 50m sum without (instance) (http_requests{job="api-server"} or foo) - {group="canary",job="api-server"} 700 - {group="production",job="api-server"} 300 - {region="europe",job="api-server"} 900 - {job="api-server"} 1000 - -# Lower-cased aggregation operators should work too. -eval instant at 50m sum(http_requests) by (job) + min(http_requests) by (job) + max(http_requests) by (job) + avg(http_requests) by (job) - {job="app-server"} 4550 - {job="api-server"} 1750 - -# Test alternative "by"-clause order. -eval instant at 50m sum by (group) (http_requests{job="api-server"}) - {group="canary"} 700 - {group="production"} 300 - -# Test both alternative "by"-clause orders in one expression. -# Public health warning: stick to one form within an expression (or even -# in an organization), or risk serious user confusion. -eval instant at 50m sum(sum by (group) (http_requests{job="api-server"})) by (job) - {} 1000 - -eval instant at 50m SUM(http_requests) - {} 3600 - -eval instant at 50m SUM(http_requests{instance="0"}) BY(job) - {job="api-server"} 400 - {job="app-server"} 1200 - -eval instant at 50m SUM(http_requests) BY (job) - {job="api-server"} 1000 - {job="app-server"} 2600 - -# Non-existent labels mentioned in BY-clauses shouldn't propagate to output. -eval instant at 50m SUM(http_requests) BY (job, nonexistent) - {job="api-server"} 1000 - {job="app-server"} 2600 - -eval instant at 50m COUNT(http_requests) BY (job) - {job="api-server"} 4 - {job="app-server"} 4 - -eval instant at 50m SUM(http_requests) BY (job, group) - {group="canary", job="api-server"} 700 - {group="canary", job="app-server"} 1500 - {group="production", job="api-server"} 300 - {group="production", job="app-server"} 1100 - -eval instant at 50m AVG(http_requests) BY (job) - {job="api-server"} 250 - {job="app-server"} 650 - -eval instant at 50m MIN(http_requests) BY (job) - {job="api-server"} 100 - {job="app-server"} 500 - -eval instant at 50m MAX(http_requests) BY (job) - {job="api-server"} 400 - {job="app-server"} 800 - -eval instant at 50m abs(-1 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 100 - {group="production", instance="1", job="api-server"} 200 - -eval instant at 50m floor(0.004 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 0 - {group="production", instance="1", job="api-server"} 0 - -eval instant at 50m ceil(0.004 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 1 - {group="production", instance="1", job="api-server"} 1 - -eval instant at 50m round(0.004 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 0 - {group="production", instance="1", job="api-server"} 1 - -# Round should correctly handle negative numbers. -eval instant at 50m round(-1 * (0.004 * http_requests{group="production",job="api-server"})) - {group="production", instance="0", job="api-server"} 0 - {group="production", instance="1", job="api-server"} -1 - -# Round should round half up. -eval instant at 50m round(0.005 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 1 - {group="production", instance="1", job="api-server"} 1 - -eval instant at 50m round(-1 * (0.005 * http_requests{group="production",job="api-server"})) - {group="production", instance="0", job="api-server"} 0 - {group="production", instance="1", job="api-server"} -1 - -eval instant at 50m round(1 + 0.005 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 2 - {group="production", instance="1", job="api-server"} 2 - -eval instant at 50m round(-1 * (1 + 0.005 * http_requests{group="production",job="api-server"})) - {group="production", instance="0", job="api-server"} -1 - {group="production", instance="1", job="api-server"} -2 - -# Round should accept the number to round nearest to. -eval instant at 50m round(0.0005 * http_requests{group="production",job="api-server"}, 0.1) - {group="production", instance="0", job="api-server"} 0.1 - {group="production", instance="1", job="api-server"} 0.1 - -eval instant at 50m round(2.1 + 0.0005 * http_requests{group="production",job="api-server"}, 0.1) - {group="production", instance="0", job="api-server"} 2.2 - {group="production", instance="1", job="api-server"} 2.2 - -eval instant at 50m round(5.2 + 0.0005 * http_requests{group="production",job="api-server"}, 0.1) - {group="production", instance="0", job="api-server"} 5.3 - {group="production", instance="1", job="api-server"} 5.3 - -# Round should work correctly with negative numbers and multiple decimal places. -eval instant at 50m round(-1 * (5.2 + 0.0005 * http_requests{group="production",job="api-server"}), 0.1) - {group="production", instance="0", job="api-server"} -5.2 - {group="production", instance="1", job="api-server"} -5.3 - -# Round should work correctly with big toNearests. -eval instant at 50m round(0.025 * http_requests{group="production",job="api-server"}, 5) - {group="production", instance="0", job="api-server"} 5 - {group="production", instance="1", job="api-server"} 5 - -eval instant at 50m round(0.045 * http_requests{group="production",job="api-server"}, 5) - {group="production", instance="0", job="api-server"} 5 - {group="production", instance="1", job="api-server"} 10 - -# Standard deviation and variance. -eval instant at 50m stddev(http_requests) - {} 229.12878474779 - -eval instant at 50m stddev by (instance)(http_requests) - {instance="0"} 223.60679774998 - {instance="1"} 223.60679774998 - -eval instant at 50m stdvar(http_requests) - {} 52500 - -eval instant at 50m stdvar by (instance)(http_requests) - {instance="0"} 50000 - {instance="1"} 50000 - -# Float precision test for standard deviation and variance -clear -load 5m - http_requests{job="api-server", instance="0", group="production"} 0+1.33x10 - http_requests{job="api-server", instance="1", group="production"} 0+1.33x10 - http_requests{job="api-server", instance="0", group="canary"} 0+1.33x10 - -eval instant at 50m stddev(http_requests) - {} 0.0 - -eval instant at 50m stdvar(http_requests) - {} 0.0 - - -# Regression test for missing separator byte in labelsToGroupingKey. -clear -load 5m - label_grouping_test{a="aa", b="bb"} 0+10x10 - label_grouping_test{a="a", b="abb"} 0+20x10 - -eval instant at 50m sum(label_grouping_test) by (a, b) - {a="a", b="abb"} 200 - {a="aa", b="bb"} 100 - - - -# Tests for min/max. -clear -load 5m - http_requests{job="api-server", instance="0", group="production"} 1 - http_requests{job="api-server", instance="1", group="production"} 2 - http_requests{job="api-server", instance="0", group="canary"} NaN - http_requests{job="api-server", instance="1", group="canary"} 3 - http_requests{job="api-server", instance="2", group="canary"} 4 - -eval instant at 0m max(http_requests) - {} 4 - -eval instant at 0m min(http_requests) - {} 1 - -eval instant at 0m max by (group) (http_requests) - {group="production"} 2 - {group="canary"} 4 - -eval instant at 0m min by (group) (http_requests) - {group="production"} 1 - {group="canary"} 3 - -clear - -# Tests for topk/bottomk. -load 5m - http_requests{job="api-server", instance="0", group="production"} 0+10x10 - http_requests{job="api-server", instance="1", group="production"} 0+20x10 - http_requests{job="api-server", instance="2", group="production"} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN - http_requests{job="api-server", instance="0", group="canary"} 0+30x10 - http_requests{job="api-server", instance="1", group="canary"} 0+40x10 - http_requests{job="app-server", instance="0", group="production"} 0+50x10 - http_requests{job="app-server", instance="1", group="production"} 0+60x10 - http_requests{job="app-server", instance="0", group="canary"} 0+70x10 - http_requests{job="app-server", instance="1", group="canary"} 0+80x10 - foo 3+0x10 - -eval_ordered instant at 50m topk(3, http_requests) - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="production", instance="1", job="app-server"} 600 - -eval_ordered instant at 50m topk((3), (http_requests)) - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="production", instance="1", job="app-server"} 600 - -eval_ordered instant at 50m topk(5, http_requests{group="canary",job="app-server"}) - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="canary", instance="0", job="app-server"} 700 - -eval_ordered instant at 50m bottomk(3, http_requests) - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="canary", instance="0", job="api-server"} 300 - -eval_ordered instant at 50m bottomk(5, http_requests{group="canary",job="app-server"}) - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="canary", instance="1", job="app-server"} 800 - -eval instant at 50m topk by (group) (1, http_requests) - http_requests{group="production", instance="1", job="app-server"} 600 - http_requests{group="canary", instance="1", job="app-server"} 800 - -eval instant at 50m bottomk by (group) (2, http_requests) - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="production", instance="1", job="api-server"} 200 - -eval_ordered instant at 50m bottomk by (group) (2, http_requests{group="production"}) - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="production", instance="1", job="api-server"} 200 - -# Test NaN is sorted away from the top/bottom. -eval_ordered instant at 50m topk(3, http_requests{job="api-server",group="production"}) - http_requests{job="api-server", instance="1", group="production"} 200 - http_requests{job="api-server", instance="0", group="production"} 100 - http_requests{job="api-server", instance="2", group="production"} NaN - -eval_ordered instant at 50m bottomk(3, http_requests{job="api-server",group="production"}) - http_requests{job="api-server", instance="0", group="production"} 100 - http_requests{job="api-server", instance="1", group="production"} 200 - http_requests{job="api-server", instance="2", group="production"} NaN - -# Test topk and bottomk allocate min(k, input_vector) for results vector -eval_ordered instant at 50m bottomk(9999999999, http_requests{job="app-server",group="canary"}) - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="canary", instance="1", job="app-server"} 800 - -eval_ordered instant at 50m topk(9999999999, http_requests{job="api-server",group="production"}) - http_requests{job="api-server", instance="1", group="production"} 200 - http_requests{job="api-server", instance="0", group="production"} 100 - http_requests{job="api-server", instance="2", group="production"} NaN - -# Bug #5276. -eval_ordered instant at 50m topk(scalar(foo), http_requests) - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="production", instance="1", job="app-server"} 600 - -clear - -# Tests for count_values. -load 5m - version{job="api-server", instance="0", group="production"} 6 - version{job="api-server", instance="1", group="production"} 6 - version{job="api-server", instance="2", group="production"} 6 - version{job="api-server", instance="0", group="canary"} 8 - version{job="api-server", instance="1", group="canary"} 8 - version{job="app-server", instance="0", group="production"} 6 - version{job="app-server", instance="1", group="production"} 6 - version{job="app-server", instance="0", group="canary"} 7 - version{job="app-server", instance="1", group="canary"} 7 - -eval instant at 5m count_values("version", version) - {version="6"} 5 - {version="7"} 2 - {version="8"} 2 - - -eval instant at 5m count_values(((("version"))), version) - {version="6"} 5 - {version="7"} 2 - {version="8"} 2 - - -eval instant at 5m count_values without (instance)("version", version) - {job="api-server", group="production", version="6"} 3 - {job="api-server", group="canary", version="8"} 2 - {job="app-server", group="production", version="6"} 2 - {job="app-server", group="canary", version="7"} 2 - -# Overwrite label with output. Don't do this. -eval instant at 5m count_values without (instance)("job", version) - {job="6", group="production"} 5 - {job="8", group="canary"} 2 - {job="7", group="canary"} 2 - -# Overwrite label with output. Don't do this. -eval instant at 5m count_values by (job, group)("job", version) - {job="6", group="production"} 5 - {job="8", group="canary"} 2 - {job="7", group="canary"} 2 - - -# Tests for quantile. -clear - -load 10s - data{test="two samples",point="a"} 0 - data{test="two samples",point="b"} 1 - data{test="three samples",point="a"} 0 - data{test="three samples",point="b"} 1 - data{test="three samples",point="c"} 2 - data{test="uneven samples",point="a"} 0 - data{test="uneven samples",point="b"} 1 - data{test="uneven samples",point="c"} 4 - foo .8 - -eval instant at 1m quantile without(point)(0.8, data) - {test="two samples"} 0.8 - {test="three samples"} 1.6 - {test="uneven samples"} 2.8 - -# Bug #5276. -eval instant at 1m quantile without(point)(scalar(foo), data) - {test="two samples"} 0.8 - {test="three samples"} 1.6 - {test="uneven samples"} 2.8 - - -eval instant at 1m quantile without(point)((scalar(foo)), data) - {test="two samples"} 0.8 - {test="three samples"} 1.6 - {test="uneven samples"} 2.8 - -# Tests for group. -clear - -load 10s - data{test="two samples",point="a"} 0 - data{test="two samples",point="b"} 1 - data{test="three samples",point="a"} 0 - data{test="three samples",point="b"} 1 - data{test="three samples",point="c"} 2 - data{test="uneven samples",point="a"} 0 - data{test="uneven samples",point="b"} 1 - data{test="uneven samples",point="c"} 4 - foo .8 - -eval instant at 1m group without(point)(data) - {test="two samples"} 1 - {test="three samples"} 1 - {test="uneven samples"} 1 - -eval instant at 1m group(foo) - {} 1 - -# Tests for avg. -clear - -load 10s - data{test="ten",point="a"} 8 - data{test="ten",point="b"} 10 - data{test="ten",point="c"} 12 - data{test="inf",point="a"} 0 - data{test="inf",point="b"} Inf - data{test="inf",point="d"} Inf - data{test="inf",point="c"} 0 - data{test="-inf",point="a"} -Inf - data{test="-inf",point="b"} -Inf - data{test="-inf",point="c"} 0 - data{test="inf2",point="a"} Inf - data{test="inf2",point="b"} 0 - data{test="inf2",point="c"} Inf - data{test="-inf2",point="a"} -Inf - data{test="-inf2",point="b"} 0 - data{test="-inf2",point="c"} -Inf - data{test="inf3",point="b"} Inf - data{test="inf3",point="d"} Inf - data{test="inf3",point="c"} Inf - data{test="inf3",point="d"} -Inf - data{test="-inf3",point="b"} -Inf - data{test="-inf3",point="d"} -Inf - data{test="-inf3",point="c"} -Inf - data{test="-inf3",point="c"} Inf - data{test="nan",point="a"} -Inf - data{test="nan",point="b"} 0 - data{test="nan",point="c"} Inf - data{test="big",point="a"} 9.988465674311579e+307 - data{test="big",point="b"} 9.988465674311579e+307 - data{test="big",point="c"} 9.988465674311579e+307 - data{test="big",point="d"} 9.988465674311579e+307 - data{test="-big",point="a"} -9.988465674311579e+307 - data{test="-big",point="b"} -9.988465674311579e+307 - data{test="-big",point="c"} -9.988465674311579e+307 - data{test="-big",point="d"} -9.988465674311579e+307 - data{test="bigzero",point="a"} -9.988465674311579e+307 - data{test="bigzero",point="b"} -9.988465674311579e+307 - data{test="bigzero",point="c"} 9.988465674311579e+307 - data{test="bigzero",point="d"} 9.988465674311579e+307 - -eval instant at 1m avg(data{test="ten"}) - {} 10 - -eval instant at 1m avg(data{test="inf"}) - {} Inf - -eval instant at 1m avg(data{test="inf2"}) - {} Inf - -eval instant at 1m avg(data{test="inf3"}) - {} NaN - -eval instant at 1m avg(data{test="-inf"}) - {} -Inf - -eval instant at 1m avg(data{test="-inf2"}) - {} -Inf - -eval instant at 1m avg(data{test="-inf3"}) - {} NaN - -eval instant at 1m avg(data{test="nan"}) - {} NaN - -eval instant at 1m avg(data{test="big"}) - {} 9.988465674311579e+307 - -eval instant at 1m avg(data{test="-big"}) - {} -9.988465674311579e+307 - -eval instant at 1m avg(data{test="bigzero"}) - {} 0 diff --git a/pkg/query/testdata/promql/prometheus/collision.test b/pkg/query/testdata/promql/prometheus/collision.test deleted file mode 100644 index 4dcdfa4ddf..0000000000 --- a/pkg/query/testdata/promql/prometheus/collision.test +++ /dev/null @@ -1,22 +0,0 @@ - -load 1s - node_namespace_pod:kube_pod_info:{namespace="observability",node="gke-search-infra-custom-96-253440-fli-d135b119-jx00",pod="node-exporter-l454v"} 1 - node_cpu_seconds_total{cpu="10",endpoint="https",instance="10.253.57.87:9100",job="node-exporter",mode="idle",namespace="observability",pod="node-exporter-l454v",service="node-exporter"} 449 - node_cpu_seconds_total{cpu="35",endpoint="https",instance="10.253.57.87:9100",job="node-exporter",mode="idle",namespace="observability",pod="node-exporter-l454v",service="node-exporter"} 449 - node_cpu_seconds_total{cpu="89",endpoint="https",instance="10.253.57.87:9100",job="node-exporter",mode="idle",namespace="observability",pod="node-exporter-l454v",service="node-exporter"} 449 - -eval instant at 4s count by(namespace, pod, cpu) (node_cpu_seconds_total{cpu=~".*",job="node-exporter",mode="idle",namespace="observability",pod="node-exporter-l454v"}) * on(namespace, pod) group_left(node) node_namespace_pod:kube_pod_info:{namespace="observability",pod="node-exporter-l454v"} - {cpu="10",namespace="observability",node="gke-search-infra-custom-96-253440-fli-d135b119-jx00",pod="node-exporter-l454v"} 1 - {cpu="35",namespace="observability",node="gke-search-infra-custom-96-253440-fli-d135b119-jx00",pod="node-exporter-l454v"} 1 - {cpu="89",namespace="observability",node="gke-search-infra-custom-96-253440-fli-d135b119-jx00",pod="node-exporter-l454v"} 1 - -clear - -# Test duplicate labelset in promql output. -load 5m - testmetric1{src="a",dst="b"} 0 - testmetric2{src="a",dst="b"} 1 - -eval_fail instant at 0m ceil({__name__=~'testmetric1|testmetric2'}) - -clear diff --git a/pkg/query/testdata/promql/prometheus/functions.test b/pkg/query/testdata/promql/prometheus/functions.test deleted file mode 100644 index 6a3d274513..0000000000 --- a/pkg/query/testdata/promql/prometheus/functions.test +++ /dev/null @@ -1,892 +0,0 @@ -# Testdata for resets() and changes(). -load 5m - http_requests{path="/foo"} 1 2 3 0 1 0 0 1 2 0 - http_requests{path="/bar"} 1 2 3 4 5 1 2 3 4 5 - http_requests{path="/biz"} 0 0 0 0 0 1 1 1 1 1 - -# TODO(bwplotka): Tests for resets() were removed for now. See https://github.com/thanos-io/thanos/issues/3644 - -# Tests for changes(). -eval instant at 50m changes(http_requests[5m]) - {path="/foo"} 0 - {path="/bar"} 0 - {path="/biz"} 0 - -eval instant at 50m changes(http_requests[20m]) - {path="/foo"} 3 - {path="/bar"} 3 - {path="/biz"} 0 - -eval instant at 50m changes(http_requests[30m]) - {path="/foo"} 4 - {path="/bar"} 5 - {path="/biz"} 1 - -eval instant at 50m changes(http_requests[50m]) - {path="/foo"} 8 - {path="/bar"} 9 - {path="/biz"} 1 - -eval instant at 50m changes((http_requests[50m])) - {path="/foo"} 8 - {path="/bar"} 9 - {path="/biz"} 1 - -eval instant at 50m changes(nonexistent_metric[50m]) - -clear - -load 5m - x{a="b"} NaN NaN NaN - x{a="c"} 0 NaN 0 - -eval instant at 15m changes(x[15m]) - {a="b"} 0 - {a="c"} 2 - -clear - -# Tests for increase(). -load 5m - http_requests{path="/foo"} 0+10x10 - http_requests{path="/bar"} 0+10x5 0+10x5 - -# Tests for increase(). -eval instant at 50m increase(http_requests[50m]) - {path="/foo"} 100 - {path="/bar"} 90 - -eval instant at 50m increase(http_requests[100m]) - {path="/foo"} 100 - {path="/bar"} 90 - -clear - -# Test for increase() with counter reset. -# When the counter is reset, it always starts at 0. -# So the sequence 3 2 (decreasing counter = reset) is interpreted the same as 3 0 1 2. -# Prometheus assumes it missed the intermediate values 0 and 1. -load 5m - http_requests{path="/foo"} 0 1 2 3 2 3 4 - -eval instant at 30m increase(http_requests[30m]) - {path="/foo"} 7 - -clear - -# Tests for rate(). -load 5m - testcounter_reset_middle 0+10x4 0+10x5 - testcounter_reset_end 0+10x9 0 10 - -# Counter resets at in the middle of range are handled correctly by rate(). -eval instant at 50m rate(testcounter_reset_middle[50m]) - {} 0.03 - -# Counter resets at end of range are ignored by rate(). -eval instant at 50m rate(testcounter_reset_end[5m]) - {} 0 - -clear - -load 5m - calculate_rate_offset{x="a"} 0+10x10 - calculate_rate_offset{x="b"} 0+20x10 - calculate_rate_window 0+80x10 - -# Rates should calculate per-second rates. -eval instant at 50m rate(calculate_rate_window[50m]) - {} 0.26666666666666666 - -eval instant at 50m rate(calculate_rate_offset[10m] offset 5m) - {x="a"} 0.03333333333333333 - {x="b"} 0.06666666666666667 - -clear - -load 4m - testcounter_zero_cutoff{start="0m"} 0+240x10 - testcounter_zero_cutoff{start="1m"} 60+240x10 - testcounter_zero_cutoff{start="2m"} 120+240x10 - testcounter_zero_cutoff{start="3m"} 180+240x10 - testcounter_zero_cutoff{start="4m"} 240+240x10 - testcounter_zero_cutoff{start="5m"} 300+240x10 - -# Zero cutoff for left-side extrapolation. -eval instant at 10m rate(testcounter_zero_cutoff[20m]) - {start="0m"} 0.5 - {start="1m"} 0.55 - {start="2m"} 0.6 - {start="3m"} 0.6 - {start="4m"} 0.6 - {start="5m"} 0.6 - -# Normal half-interval cutoff for left-side extrapolation. -eval instant at 50m rate(testcounter_zero_cutoff[20m]) - {start="0m"} 0.6 - {start="1m"} 0.6 - {start="2m"} 0.6 - {start="3m"} 0.6 - {start="4m"} 0.6 - {start="5m"} 0.6 - -clear - -# Tests for irate(). -load 5m - http_requests{path="/foo"} 0+10x10 - http_requests{path="/bar"} 0+10x5 0+10x5 - -eval instant at 50m irate(http_requests[50m]) - {path="/foo"} .03333333333333333333 - {path="/bar"} .03333333333333333333 - -# Counter reset. -eval instant at 30m irate(http_requests[50m]) - {path="/foo"} .03333333333333333333 - {path="/bar"} 0 - -clear - -# Tests for delta(). -load 5m - http_requests{path="/foo"} 0 50 100 150 200 - http_requests{path="/bar"} 200 150 100 50 0 - -eval instant at 20m delta(http_requests[20m]) - {path="/foo"} 200 - {path="/bar"} -200 - -clear - -# Tests for idelta(). -load 5m - http_requests{path="/foo"} 0 50 100 150 - http_requests{path="/bar"} 0 50 100 50 - -eval instant at 20m idelta(http_requests[20m]) - {path="/foo"} 50 - {path="/bar"} -50 - -clear - -# Tests for deriv() and predict_linear(). -load 5m - testcounter_reset_middle 0+10x4 0+10x5 - http_requests{job="app-server", instance="1", group="canary"} 0+80x10 - -# deriv should return the same as rate in simple cases. -eval instant at 50m rate(http_requests{group="canary", instance="1", job="app-server"}[50m]) - {group="canary", instance="1", job="app-server"} 0.26666666666666666 - -eval instant at 50m deriv(http_requests{group="canary", instance="1", job="app-server"}[50m]) - {group="canary", instance="1", job="app-server"} 0.26666666666666666 - -# deriv should return correct result. -eval instant at 50m deriv(testcounter_reset_middle[100m]) - {} 0.010606060606060607 - -# predict_linear should return correct result. -# X/s = [ 0, 300, 600, 900,1200,1500,1800,2100,2400,2700,3000] -# Y = [ 0, 10, 20, 30, 40, 0, 10, 20, 30, 40, 50] -# sumX = 16500 -# sumY = 250 -# sumXY = 480000 -# sumX2 = 34650000 -# n = 11 -# covXY = 105000 -# varX = 9900000 -# slope = 0.010606060606060607 -# intercept at t=0: 6.818181818181818 -# intercept at t=3000: 38.63636363636364 -# intercept at t=3000+3600: 76.81818181818181 -eval instant at 50m predict_linear(testcounter_reset_middle[100m], 3600) - {} 76.81818181818181 - -# With http_requests, there is a sample value exactly at the end of -# the range, and it has exactly the predicted value, so predict_linear -# can be emulated with deriv. -eval instant at 50m predict_linear(http_requests[50m], 3600) - (http_requests + deriv(http_requests[50m]) * 3600) - {group="canary", instance="1", job="app-server"} 0 - -clear - -# Tests for label_replace. -load 5m - testmetric{src="source-value-10",dst="original-destination-value"} 0 - testmetric{src="source-value-20",dst="original-destination-value"} 1 - -# label_replace does a full-string match and replace. -eval instant at 0m label_replace(testmetric, "dst", "destination-value-$1", "src", "source-value-(.*)") - testmetric{src="source-value-10",dst="destination-value-10"} 0 - testmetric{src="source-value-20",dst="destination-value-20"} 1 - -# label_replace does not do a sub-string match. -eval instant at 0m label_replace(testmetric, "dst", "destination-value-$1", "src", "value-(.*)") - testmetric{src="source-value-10",dst="original-destination-value"} 0 - testmetric{src="source-value-20",dst="original-destination-value"} 1 - -# label_replace works with multiple capture groups. -eval instant at 0m label_replace(testmetric, "dst", "$1-value-$2", "src", "(.*)-value-(.*)") - testmetric{src="source-value-10",dst="source-value-10"} 0 - testmetric{src="source-value-20",dst="source-value-20"} 1 - -# label_replace does not overwrite the destination label if the source label -# does not exist. -eval instant at 0m label_replace(testmetric, "dst", "value-$1", "nonexistent-src", "source-value-(.*)") - testmetric{src="source-value-10",dst="original-destination-value"} 0 - testmetric{src="source-value-20",dst="original-destination-value"} 1 - -# label_replace overwrites the destination label if the source label is empty, -# but matched. -eval instant at 0m label_replace(testmetric, "dst", "value-$1", "nonexistent-src", "(.*)") - testmetric{src="source-value-10",dst="value-"} 0 - testmetric{src="source-value-20",dst="value-"} 1 - -# label_replace does not overwrite the destination label if the source label -# is not matched. -eval instant at 0m label_replace(testmetric, "dst", "value-$1", "src", "non-matching-regex") - testmetric{src="source-value-10",dst="original-destination-value"} 0 - testmetric{src="source-value-20",dst="original-destination-value"} 1 - -eval instant at 0m label_replace((((testmetric))), (("dst")), (("value-$1")), (("src")), (("non-matching-regex"))) - testmetric{src="source-value-10",dst="original-destination-value"} 0 - testmetric{src="source-value-20",dst="original-destination-value"} 1 - -# label_replace drops labels that are set to empty values. -eval instant at 0m label_replace(testmetric, "dst", "", "dst", ".*") - testmetric{src="source-value-10"} 0 - testmetric{src="source-value-20"} 1 - -# label_replace fails when the regex is invalid. -eval_fail instant at 0m label_replace(testmetric, "dst", "value-$1", "src", "(.*") - -# label_replace fails when the destination label name is not a valid Prometheus label name. -eval_fail instant at 0m label_replace(testmetric, "invalid-label-name", "", "src", "(.*)") - -# label_replace fails when there would be duplicated identical output label sets. -eval_fail instant at 0m label_replace(testmetric, "src", "", "", "") - -clear - -# Tests for vector, time and timestamp. -load 10s - metric 1 1 - -eval instant at 0s timestamp(metric) - {} 0 - -eval instant at 5s timestamp(metric) - {} 0 - -eval instant at 5s timestamp(((metric))) - {} 0 - -eval instant at 10s timestamp(metric) - {} 10 - -eval instant at 10s timestamp(((metric))) - {} 10 - -# Tests for label_join. -load 5m - testmetric{src="a",src1="b",src2="c",dst="original-destination-value"} 0 - testmetric{src="d",src1="e",src2="f",dst="original-destination-value"} 1 - -# label_join joins all src values in order. -eval instant at 0m label_join(testmetric, "dst", "-", "src", "src1", "src2") - testmetric{src="a",src1="b",src2="c",dst="a-b-c"} 0 - testmetric{src="d",src1="e",src2="f",dst="d-e-f"} 1 - -# label_join treats non existent src labels as empty strings. -eval instant at 0m label_join(testmetric, "dst", "-", "src", "src3", "src1") - testmetric{src="a",src1="b",src2="c",dst="a--b"} 0 - testmetric{src="d",src1="e",src2="f",dst="d--e"} 1 - -# label_join overwrites the destination label even if the resulting dst label is empty string -eval instant at 0m label_join(testmetric, "dst", "", "emptysrc", "emptysrc1", "emptysrc2") - testmetric{src="a",src1="b",src2="c"} 0 - testmetric{src="d",src1="e",src2="f"} 1 - -# test without src label for label_join -eval instant at 0m label_join(testmetric, "dst", ", ") - testmetric{src="a",src1="b",src2="c"} 0 - testmetric{src="d",src1="e",src2="f"} 1 - -# test without dst label for label_join -load 5m - testmetric1{src="foo",src1="bar",src2="foobar"} 0 - testmetric1{src="fizz",src1="buzz",src2="fizzbuzz"} 1 - -# label_join creates dst label if not present. -eval instant at 0m label_join(testmetric1, "dst", ", ", "src", "src1", "src2") - testmetric1{src="foo",src1="bar",src2="foobar",dst="foo, bar, foobar"} 0 - testmetric1{src="fizz",src1="buzz",src2="fizzbuzz",dst="fizz, buzz, fizzbuzz"} 1 - -clear - -# Tests for vector. -eval instant at 0m vector(1) - {} 1 - -eval instant at 0s vector(time()) - {} 0 - -eval instant at 5s vector(time()) - {} 5 - -eval instant at 60m vector(time()) - {} 3600 - - -# Tests for clamp_max and clamp_min(). -load 5m - test_clamp{src="clamp-a"} -50 - test_clamp{src="clamp-b"} 0 - test_clamp{src="clamp-c"} 100 - -eval instant at 0m clamp_max(test_clamp, 75) - {src="clamp-a"} -50 - {src="clamp-b"} 0 - {src="clamp-c"} 75 - -eval instant at 0m clamp_min(test_clamp, -25) - {src="clamp-a"} -25 - {src="clamp-b"} 0 - {src="clamp-c"} 100 - -eval instant at 0m clamp_max(clamp_min(test_clamp, -20), 70) - {src="clamp-a"} -20 - {src="clamp-b"} 0 - {src="clamp-c"} 70 - -eval instant at 0m clamp_max((clamp_min(test_clamp, (-20))), (70)) - {src="clamp-a"} -20 - {src="clamp-b"} 0 - {src="clamp-c"} 70 - - -# Tests for sort/sort_desc. -clear -load 5m - http_requests{job="api-server", instance="0", group="production"} 0+10x10 - http_requests{job="api-server", instance="1", group="production"} 0+20x10 - http_requests{job="api-server", instance="0", group="canary"} 0+30x10 - http_requests{job="api-server", instance="1", group="canary"} 0+40x10 - http_requests{job="api-server", instance="2", group="canary"} NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN - http_requests{job="app-server", instance="0", group="production"} 0+50x10 - http_requests{job="app-server", instance="1", group="production"} 0+60x10 - http_requests{job="app-server", instance="0", group="canary"} 0+70x10 - http_requests{job="app-server", instance="1", group="canary"} 0+80x10 - -eval_ordered instant at 50m sort(http_requests) - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="production", instance="0", job="app-server"} 500 - http_requests{group="production", instance="1", job="app-server"} 600 - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="canary", instance="2", job="api-server"} NaN - -eval_ordered instant at 50m sort_desc(http_requests) - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="production", instance="1", job="app-server"} 600 - http_requests{group="production", instance="0", job="app-server"} 500 - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="canary", instance="2", job="api-server"} NaN - -# Tests for holt_winters -clear - -# positive trends -load 10s - http_requests{job="api-server", instance="0", group="production"} 0+10x1000 100+30x1000 - http_requests{job="api-server", instance="1", group="production"} 0+20x1000 200+30x1000 - http_requests{job="api-server", instance="0", group="canary"} 0+30x1000 300+80x1000 - http_requests{job="api-server", instance="1", group="canary"} 0+40x2000 - -eval instant at 8000s holt_winters(http_requests[1m], 0.01, 0.1) - {job="api-server", instance="0", group="production"} 8000 - {job="api-server", instance="1", group="production"} 16000 - {job="api-server", instance="0", group="canary"} 24000 - {job="api-server", instance="1", group="canary"} 32000 - -# negative trends -clear -load 10s - http_requests{job="api-server", instance="0", group="production"} 8000-10x1000 - http_requests{job="api-server", instance="1", group="production"} 0-20x1000 - http_requests{job="api-server", instance="0", group="canary"} 0+30x1000 300-80x1000 - http_requests{job="api-server", instance="1", group="canary"} 0-40x1000 0+40x1000 - -eval instant at 8000s holt_winters(http_requests[1m], 0.01, 0.1) - {job="api-server", instance="0", group="production"} 0 - {job="api-server", instance="1", group="production"} -16000 - {job="api-server", instance="0", group="canary"} 24000 - {job="api-server", instance="1", group="canary"} -32000 - -# Tests for avg_over_time -clear -load 10s - metric 1 2 3 4 5 - metric2 1 2 3 4 Inf - metric3 1 2 3 4 -Inf - metric4 1 2 3 Inf -Inf - metric5 Inf 0 Inf - metric5b Inf 0 Inf - metric5c Inf Inf Inf -Inf - metric6 1 2 3 -Inf -Inf - metric6b -Inf 0 -Inf - metric6c -Inf -Inf -Inf Inf - metric7 1 2 -Inf -Inf Inf - metric8 9.988465674311579e+307 9.988465674311579e+307 - metric9 -9.988465674311579e+307 -9.988465674311579e+307 -9.988465674311579e+307 - metric10 -9.988465674311579e+307 9.988465674311579e+307 - -eval instant at 1m avg_over_time(metric[1m]) - {} 3 - -eval instant at 1m sum_over_time(metric[1m])/count_over_time(metric[1m]) - {} 3 - -eval instant at 1m avg_over_time(metric2[1m]) - {} Inf - -eval instant at 1m sum_over_time(metric2[1m])/count_over_time(metric2[1m]) - {} Inf - -eval instant at 1m avg_over_time(metric3[1m]) - {} -Inf - -eval instant at 1m sum_over_time(metric3[1m])/count_over_time(metric3[1m]) - {} -Inf - -eval instant at 1m avg_over_time(metric4[1m]) - {} NaN - -eval instant at 1m sum_over_time(metric4[1m])/count_over_time(metric4[1m]) - {} NaN - -eval instant at 1m avg_over_time(metric5[1m]) - {} Inf - -eval instant at 1m sum_over_time(metric5[1m])/count_over_time(metric5[1m]) - {} Inf - -eval instant at 1m avg_over_time(metric5b[1m]) - {} Inf - -eval instant at 1m sum_over_time(metric5b[1m])/count_over_time(metric5b[1m]) - {} Inf - -eval instant at 1m avg_over_time(metric5c[1m]) - {} NaN - -eval instant at 1m sum_over_time(metric5c[1m])/count_over_time(metric5c[1m]) - {} NaN - -eval instant at 1m avg_over_time(metric6[1m]) - {} -Inf - -eval instant at 1m sum_over_time(metric6[1m])/count_over_time(metric6[1m]) - {} -Inf - -eval instant at 1m avg_over_time(metric6b[1m]) - {} -Inf - -eval instant at 1m sum_over_time(metric6b[1m])/count_over_time(metric6b[1m]) - {} -Inf - -eval instant at 1m avg_over_time(metric6c[1m]) - {} NaN - -eval instant at 1m sum_over_time(metric6c[1m])/count_over_time(metric6c[1m]) - {} NaN - - -eval instant at 1m avg_over_time(metric7[1m]) - {} NaN - -eval instant at 1m sum_over_time(metric7[1m])/count_over_time(metric7[1m]) - {} NaN - -eval instant at 1m avg_over_time(metric8[1m]) - {} 9.988465674311579e+307 - -# This overflows float64. -eval instant at 1m sum_over_time(metric8[1m])/count_over_time(metric8[1m]) - {} Inf - -eval instant at 1m avg_over_time(metric9[1m]) - {} -9.988465674311579e+307 - -# This overflows float64. -eval instant at 1m sum_over_time(metric9[1m])/count_over_time(metric9[1m]) - {} -Inf - -eval instant at 1m avg_over_time(metric10[1m]) - {} 0 - -eval instant at 1m sum_over_time(metric10[1m])/count_over_time(metric10[1m]) - {} 0 - -# Tests for stddev_over_time and stdvar_over_time. -clear -load 10s - metric 0 8 8 2 3 - -eval instant at 1m stdvar_over_time(metric[1m]) - {} 10.56 - -eval instant at 1m stddev_over_time(metric[1m]) - {} 3.249615 - -eval instant at 1m stddev_over_time((metric[1m])) - {} 3.249615 - -# Tests for stddev_over_time and stdvar_over_time #4927. -clear -load 10s - metric 1.5990505637277868 1.5990505637277868 1.5990505637277868 - -eval instant at 1m stdvar_over_time(metric[1m]) - {} 0 - -eval instant at 1m stddev_over_time(metric[1m]) - {} 0 - -# Tests for quantile_over_time -clear - -load 10s - data{test="two samples"} 0 1 - data{test="three samples"} 0 1 2 - data{test="uneven samples"} 0 1 4 - -eval instant at 1m quantile_over_time(0, data[1m]) - {test="two samples"} 0 - {test="three samples"} 0 - {test="uneven samples"} 0 - -eval instant at 1m quantile_over_time(0.5, data[1m]) - {test="two samples"} 0.5 - {test="three samples"} 1 - {test="uneven samples"} 1 - -eval instant at 1m quantile_over_time(0.75, data[1m]) - {test="two samples"} 0.75 - {test="three samples"} 1.5 - {test="uneven samples"} 2.5 - -eval instant at 1m quantile_over_time(0.8, data[1m]) - {test="two samples"} 0.8 - {test="three samples"} 1.6 - {test="uneven samples"} 2.8 - -eval instant at 1m quantile_over_time(1, data[1m]) - {test="two samples"} 1 - {test="three samples"} 2 - {test="uneven samples"} 4 - -eval instant at 1m quantile_over_time(-1, data[1m]) - {test="two samples"} -Inf - {test="three samples"} -Inf - {test="uneven samples"} -Inf - -eval instant at 1m quantile_over_time(2, data[1m]) - {test="two samples"} +Inf - {test="three samples"} +Inf - {test="uneven samples"} +Inf - -eval instant at 1m (quantile_over_time(2, (data[1m]))) - {test="two samples"} +Inf - {test="three samples"} +Inf - {test="uneven samples"} +Inf - -clear - -# Test time-related functions. -eval instant at 0m year() - {} 1970 - -eval instant at 1ms time() - 0.001 - -eval instant at 50m time() - 3000 - -eval instant at 0m year(vector(1136239445)) - {} 2006 - -eval instant at 0m month() - {} 1 - -eval instant at 0m month(vector(1136239445)) - {} 1 - -eval instant at 0m day_of_month() - {} 1 - -eval instant at 0m day_of_month(vector(1136239445)) - {} 2 - -# Thursday. -eval instant at 0m day_of_week() - {} 4 - -eval instant at 0m day_of_week(vector(1136239445)) - {} 1 - -eval instant at 0m hour() - {} 0 - -eval instant at 0m hour(vector(1136239445)) - {} 22 - -eval instant at 0m minute() - {} 0 - -eval instant at 0m minute(vector(1136239445)) - {} 4 - -# 2008-12-31 23:59:59 just before leap second. -eval instant at 0m year(vector(1230767999)) - {} 2008 - -# 2009-01-01 00:00:00 just after leap second. -eval instant at 0m year(vector(1230768000)) - {} 2009 - -# 2016-02-29 23:59:59 February 29th in leap year. -eval instant at 0m month(vector(1456790399)) + day_of_month(vector(1456790399)) / 100 - {} 2.29 - -# 2016-03-01 00:00:00 March 1st in leap year. -eval instant at 0m month(vector(1456790400)) + day_of_month(vector(1456790400)) / 100 - {} 3.01 - -# February 1st 2016 in leap year. -eval instant at 0m days_in_month(vector(1454284800)) - {} 29 - -# February 1st 2017 not in leap year. -eval instant at 0m days_in_month(vector(1485907200)) - {} 28 - -clear - -# Test duplicate labelset in promql output. -load 5m - testmetric1{src="a",dst="b"} 0 - testmetric2{src="a",dst="b"} 1 - -eval_fail instant at 0m changes({__name__=~'testmetric1|testmetric2'}[5m]) - -# Tests for *_over_time -clear - -load 10s - data{type="numbers"} 2 0 3 - data{type="some_nan"} 2 0 NaN - data{type="some_nan2"} 2 NaN 1 - data{type="some_nan3"} NaN 0 1 - data{type="only_nan"} NaN NaN NaN - -eval instant at 1m min_over_time(data[1m]) - {type="numbers"} 0 - {type="some_nan"} 0 - {type="some_nan2"} 1 - {type="some_nan3"} 0 - {type="only_nan"} NaN - -eval instant at 1m max_over_time(data[1m]) - {type="numbers"} 3 - {type="some_nan"} 2 - {type="some_nan2"} 2 - {type="some_nan3"} 1 - {type="only_nan"} NaN - -clear - -# Test for absent() -eval instant at 50m absent(nonexistent) - {} 1 - -eval instant at 50m absent(nonexistent{job="testjob", instance="testinstance", method=~".x"}) - {instance="testinstance", job="testjob"} 1 - -eval instant at 50m absent(nonexistent{job="testjob",job="testjob2",foo="bar"}) - {foo="bar"} 1 - -eval instant at 50m absent(nonexistent{job="testjob",job="testjob2",job="three",foo="bar"}) - {foo="bar"} 1 - -eval instant at 50m absent(nonexistent{job="testjob",job=~"testjob2",foo="bar"}) - {foo="bar"} 1 - -clear - -# Don't return anything when there's something there. -load 5m - http_requests{job="api-server", instance="0", group="production"} 0+10x10 - -eval instant at 50m absent(http_requests) - -eval instant at 50m absent(sum(http_requests)) - -clear - -eval instant at 50m absent(sum(nonexistent{job="testjob", instance="testinstance"})) - {} 1 - -eval instant at 50m absent(max(nonexistent)) - {} 1 - -eval instant at 50m absent(nonexistent > 1) - {} 1 - -eval instant at 50m absent(a + b) - {} 1 - -eval instant at 50m absent(a and b) - {} 1 - -eval instant at 50m absent(rate(nonexistent[5m])) - {} 1 - -clear - -# Testdata for absent_over_time() -eval instant at 1m absent_over_time(http_requests[5m]) - {} 1 - -eval instant at 1m absent_over_time(http_requests{handler="/foo"}[5m]) - {handler="/foo"} 1 - -eval instant at 1m absent_over_time(http_requests{handler!="/foo"}[5m]) - {} 1 - -eval instant at 1m absent_over_time(http_requests{handler="/foo", handler="/bar", handler="/foobar"}[5m]) - {} 1 - -eval instant at 1m absent_over_time(rate(nonexistent[5m])[5m:]) - {} 1 - -eval instant at 1m absent_over_time(http_requests{handler="/foo", handler="/bar", instance="127.0.0.1"}[5m]) - {instance="127.0.0.1"} 1 - -load 1m - http_requests{path="/foo",instance="127.0.0.1",job="httpd"} 1+1x10 - http_requests{path="/bar",instance="127.0.0.1",job="httpd"} 1+1x10 - httpd_handshake_failures_total{instance="127.0.0.1",job="node"} 1+1x15 - httpd_log_lines_total{instance="127.0.0.1",job="node"} 1 - ssl_certificate_expiry_seconds{job="ingress"} NaN NaN NaN NaN NaN - -eval instant at 5m absent_over_time(http_requests[5m]) - -eval instant at 5m absent_over_time(rate(http_requests[5m])[5m:1m]) - -eval instant at 0m absent_over_time(httpd_log_lines_total[30s]) - -eval instant at 1m absent_over_time(httpd_log_lines_total[30s]) - {} 1 - -eval instant at 15m absent_over_time(http_requests[5m]) - -eval instant at 16m absent_over_time(http_requests[5m]) - {} 1 - -eval instant at 16m absent_over_time(http_requests[6m]) - -eval instant at 16m absent_over_time(httpd_handshake_failures_total[1m]) - -eval instant at 16m absent_over_time({instance="127.0.0.1"}[5m]) - -eval instant at 16m absent_over_time({instance="127.0.0.1"}[5m]) - -eval instant at 21m absent_over_time({instance="127.0.0.1"}[5m]) - {instance="127.0.0.1"} 1 - -eval instant at 21m absent_over_time({instance="127.0.0.1"}[20m]) - -eval instant at 21m absent_over_time({job="grok"}[20m]) - {job="grok"} 1 - -eval instant at 30m absent_over_time({instance="127.0.0.1"}[5m:5s]) - {} 1 - -eval instant at 5m absent_over_time({job="ingress"}[4m]) - -eval instant at 10m absent_over_time({job="ingress"}[4m]) - {job="ingress"} 1 - -clear - -# Testing exp() sqrt() log2() log10() ln() -load 5m - exp_root_log{l="x"} 10 - exp_root_log{l="y"} 20 - -eval instant at 5m exp(exp_root_log) - {l="x"} 22026.465794806718 - {l="y"} 485165195.4097903 - -eval instant at 5m exp(exp_root_log - 10) - {l="y"} 22026.465794806718 - {l="x"} 1 - -eval instant at 5m exp(exp_root_log - 20) - {l="x"} 4.5399929762484854e-05 - {l="y"} 1 - -eval instant at 5m ln(exp_root_log) - {l="x"} 2.302585092994046 - {l="y"} 2.995732273553991 - -eval instant at 5m ln(exp_root_log - 10) - {l="y"} 2.302585092994046 - {l="x"} -Inf - -eval instant at 5m ln(exp_root_log - 20) - {l="y"} -Inf - {l="x"} NaN - -eval instant at 5m exp(ln(exp_root_log)) - {l="y"} 20 - {l="x"} 10 - -eval instant at 5m sqrt(exp_root_log) - {l="x"} 3.1622776601683795 - {l="y"} 4.47213595499958 - -eval instant at 5m log2(exp_root_log) - {l="x"} 3.3219280948873626 - {l="y"} 4.321928094887363 - -eval instant at 5m log2(exp_root_log - 10) - {l="y"} 3.3219280948873626 - {l="x"} -Inf - -eval instant at 5m log2(exp_root_log - 20) - {l="x"} NaN - {l="y"} -Inf - -eval instant at 5m log10(exp_root_log) - {l="x"} 1 - {l="y"} 1.301029995663981 - -eval instant at 5m log10(exp_root_log - 10) - {l="y"} 1 - {l="x"} -Inf - -eval instant at 5m log10(exp_root_log - 20) - {l="x"} NaN - {l="y"} -Inf - -clear diff --git a/pkg/query/testdata/promql/prometheus/histograms.test b/pkg/query/testdata/promql/prometheus/histograms.test deleted file mode 100644 index ec236576b4..0000000000 --- a/pkg/query/testdata/promql/prometheus/histograms.test +++ /dev/null @@ -1,193 +0,0 @@ -# Two histograms with 4 buckets each (x_sum and x_count not included, -# only buckets). Lowest bucket for one histogram < 0, for the other > -# 0. They have the same name, just separated by label. Not useful in -# practice, but can happen (if clients change bucketing), and the -# server has to cope with it. - -# Test histogram. -load 5m - testhistogram_bucket{le="0.1", start="positive"} 0+5x10 - testhistogram_bucket{le=".2", start="positive"} 0+7x10 - testhistogram_bucket{le="1e0", start="positive"} 0+11x10 - testhistogram_bucket{le="+Inf", start="positive"} 0+12x10 - testhistogram_bucket{le="-.2", start="negative"} 0+1x10 - testhistogram_bucket{le="-0.1", start="negative"} 0+2x10 - testhistogram_bucket{le="0.3", start="negative"} 0+2x10 - testhistogram_bucket{le="+Inf", start="negative"} 0+3x10 - - -# Now a more realistic histogram per job and instance to test aggregation. -load 5m - request_duration_seconds_bucket{job="job1", instance="ins1", le="0.1"} 0+1x10 - request_duration_seconds_bucket{job="job1", instance="ins1", le="0.2"} 0+3x10 - request_duration_seconds_bucket{job="job1", instance="ins1", le="+Inf"} 0+4x10 - request_duration_seconds_bucket{job="job1", instance="ins2", le="0.1"} 0+2x10 - request_duration_seconds_bucket{job="job1", instance="ins2", le="0.2"} 0+5x10 - request_duration_seconds_bucket{job="job1", instance="ins2", le="+Inf"} 0+6x10 - request_duration_seconds_bucket{job="job2", instance="ins1", le="0.1"} 0+3x10 - request_duration_seconds_bucket{job="job2", instance="ins1", le="0.2"} 0+4x10 - request_duration_seconds_bucket{job="job2", instance="ins1", le="+Inf"} 0+6x10 - request_duration_seconds_bucket{job="job2", instance="ins2", le="0.1"} 0+4x10 - request_duration_seconds_bucket{job="job2", instance="ins2", le="0.2"} 0+7x10 - request_duration_seconds_bucket{job="job2", instance="ins2", le="+Inf"} 0+9x10 - -# Different le representations in one histogram. -load 5m - mixed_bucket{job="job1", instance="ins1", le="0.1"} 0+1x10 - mixed_bucket{job="job1", instance="ins1", le="0.2"} 0+1x10 - mixed_bucket{job="job1", instance="ins1", le="2e-1"} 0+1x10 - mixed_bucket{job="job1", instance="ins1", le="2.0e-1"} 0+1x10 - mixed_bucket{job="job1", instance="ins1", le="+Inf"} 0+4x10 - mixed_bucket{job="job1", instance="ins2", le="+inf"} 0+0x10 - mixed_bucket{job="job1", instance="ins2", le="+Inf"} 0+0x10 - -# Quantile too low. -eval instant at 50m histogram_quantile(-0.1, testhistogram_bucket) - {start="positive"} -Inf - {start="negative"} -Inf - -# Quantile too high. -eval instant at 50m histogram_quantile(1.01, testhistogram_bucket) - {start="positive"} +Inf - {start="negative"} +Inf - -# Quantile value in lowest bucket, which is positive. -eval instant at 50m histogram_quantile(0, testhistogram_bucket{start="positive"}) - {start="positive"} 0 - -# Quantile value in lowest bucket, which is negative. -eval instant at 50m histogram_quantile(0, testhistogram_bucket{start="negative"}) - {start="negative"} -0.2 - -# Quantile value in highest bucket. -eval instant at 50m histogram_quantile(1, testhistogram_bucket) - {start="positive"} 1 - {start="negative"} 0.3 - -# Finally some useful quantiles. -eval instant at 50m histogram_quantile(0.2, testhistogram_bucket) - {start="positive"} 0.048 - {start="negative"} -0.2 - - -eval instant at 50m histogram_quantile(0.5, testhistogram_bucket) - {start="positive"} 0.15 - {start="negative"} -0.15 - -eval instant at 50m histogram_quantile(0.8, testhistogram_bucket) - {start="positive"} 0.72 - {start="negative"} 0.3 - -# More realistic with rates. -eval instant at 50m histogram_quantile(0.2, rate(testhistogram_bucket[5m])) - {start="positive"} 0.048 - {start="negative"} -0.2 - -eval instant at 50m histogram_quantile(0.5, rate(testhistogram_bucket[5m])) - {start="positive"} 0.15 - {start="negative"} -0.15 - -eval instant at 50m histogram_quantile(0.8, rate(testhistogram_bucket[5m])) - {start="positive"} 0.72 - {start="negative"} 0.3 - -# Aggregated histogram: Everything in one. -eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le)) - {} 0.075 - -eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le)) - {} 0.1277777777777778 - -# Aggregated histogram: Everything in one. Now with avg, which does not change anything. -eval instant at 50m histogram_quantile(0.3, avg(rate(request_duration_seconds_bucket[5m])) by (le)) - {} 0.075 - -eval instant at 50m histogram_quantile(0.5, avg(rate(request_duration_seconds_bucket[5m])) by (le)) - {} 0.12777777777777778 - -# Aggregated histogram: By job. -eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, instance)) - {instance="ins1"} 0.075 - {instance="ins2"} 0.075 - -eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, instance)) - {instance="ins1"} 0.1333333333 - {instance="ins2"} 0.125 - -# Aggregated histogram: By instance. -eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, job)) - {job="job1"} 0.1 - {job="job2"} 0.0642857142857143 - -eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, job)) - {job="job1"} 0.14 - {job="job2"} 0.1125 - -# Aggregated histogram: By job and instance. -eval instant at 50m histogram_quantile(0.3, sum(rate(request_duration_seconds_bucket[5m])) by (le, job, instance)) - {instance="ins1", job="job1"} 0.11 - {instance="ins2", job="job1"} 0.09 - {instance="ins1", job="job2"} 0.06 - {instance="ins2", job="job2"} 0.0675 - -eval instant at 50m histogram_quantile(0.5, sum(rate(request_duration_seconds_bucket[5m])) by (le, job, instance)) - {instance="ins1", job="job1"} 0.15 - {instance="ins2", job="job1"} 0.1333333333333333 - {instance="ins1", job="job2"} 0.1 - {instance="ins2", job="job2"} 0.1166666666666667 - -# The unaggregated histogram for comparison. Same result as the previous one. -eval instant at 50m histogram_quantile(0.3, rate(request_duration_seconds_bucket[5m])) - {instance="ins1", job="job1"} 0.11 - {instance="ins2", job="job1"} 0.09 - {instance="ins1", job="job2"} 0.06 - {instance="ins2", job="job2"} 0.0675 - -eval instant at 50m histogram_quantile(0.5, rate(request_duration_seconds_bucket[5m])) - {instance="ins1", job="job1"} 0.15 - {instance="ins2", job="job1"} 0.13333333333333333 - {instance="ins1", job="job2"} 0.1 - {instance="ins2", job="job2"} 0.11666666666666667 - -# A histogram with nonmonotonic bucket counts. This may happen when recording -# rule evaluation or federation races scrape ingestion, causing some buckets -# counts to be derived from fewer samples. - -load 5m - nonmonotonic_bucket{le="0.1"} 0+2x10 - nonmonotonic_bucket{le="1"} 0+1x10 - nonmonotonic_bucket{le="10"} 0+5x10 - nonmonotonic_bucket{le="100"} 0+4x10 - nonmonotonic_bucket{le="1000"} 0+9x10 - nonmonotonic_bucket{le="+Inf"} 0+8x10 - -# Nonmonotonic buckets -eval instant at 50m histogram_quantile(0.01, nonmonotonic_bucket) - {} 0.0045 - -eval instant at 50m histogram_quantile(0.5, nonmonotonic_bucket) - {} 8.5 - -eval instant at 50m histogram_quantile(0.99, nonmonotonic_bucket) - {} 979.75 - -# Buckets with different representations of the same upper bound. -eval instant at 50m histogram_quantile(0.5, rate(mixed_bucket[5m])) - {instance="ins1", job="job1"} 0.15 - {instance="ins2", job="job1"} NaN - -eval instant at 50m histogram_quantile(0.75, rate(mixed_bucket[5m])) - {instance="ins1", job="job1"} 0.2 - {instance="ins2", job="job1"} NaN - -eval instant at 50m histogram_quantile(1, rate(mixed_bucket[5m])) - {instance="ins1", job="job1"} 0.2 - {instance="ins2", job="job1"} NaN - -load 5m - empty_bucket{le="0.1", job="job1", instance="ins1"} 0x10 - empty_bucket{le="0.2", job="job1", instance="ins1"} 0x10 - empty_bucket{le="+Inf", job="job1", instance="ins1"} 0x10 - -eval instant at 50m histogram_quantile(0.2, rate(empty_bucket[5m])) - {instance="ins1", job="job1"} NaN \ No newline at end of file diff --git a/pkg/query/testdata/promql/prometheus/literals.test b/pkg/query/testdata/promql/prometheus/literals.test deleted file mode 100644 index 0d86638429..0000000000 --- a/pkg/query/testdata/promql/prometheus/literals.test +++ /dev/null @@ -1,59 +0,0 @@ -eval instant at 50m 12.34e6 - 12340000 - -eval instant at 50m 12.34e+6 - 12340000 - -eval instant at 50m 12.34e-6 - 0.00001234 - -eval instant at 50m 1+1 - 2 - -eval instant at 50m 1-1 - 0 - -eval instant at 50m 1 - -1 - 2 - -eval instant at 50m .2 - 0.2 - -eval instant at 50m +0.2 - 0.2 - -eval instant at 50m -0.2e-6 - -0.0000002 - -eval instant at 50m +Inf - +Inf - -eval instant at 50m inF - +Inf - -eval instant at 50m -inf - -Inf - -eval instant at 50m NaN - NaN - -eval instant at 50m nan - NaN - -eval instant at 50m 2. - 2 - -eval instant at 50m 1 / 0 - +Inf - -eval instant at 50m ((1) / (0)) - +Inf - -eval instant at 50m -1 / 0 - -Inf - -eval instant at 50m 0 / 0 - NaN - -eval instant at 50m 1 % 0 - NaN diff --git a/pkg/query/testdata/promql/prometheus/operators.test b/pkg/query/testdata/promql/prometheus/operators.test deleted file mode 100644 index d5a4d76f50..0000000000 --- a/pkg/query/testdata/promql/prometheus/operators.test +++ /dev/null @@ -1,469 +0,0 @@ -load 5m - http_requests{job="api-server", instance="0", group="production"} 0+10x10 - http_requests{job="api-server", instance="1", group="production"} 0+20x10 - http_requests{job="api-server", instance="0", group="canary"} 0+30x10 - http_requests{job="api-server", instance="1", group="canary"} 0+40x10 - http_requests{job="app-server", instance="0", group="production"} 0+50x10 - http_requests{job="app-server", instance="1", group="production"} 0+60x10 - http_requests{job="app-server", instance="0", group="canary"} 0+70x10 - http_requests{job="app-server", instance="1", group="canary"} 0+80x10 - -load 5m - vector_matching_a{l="x"} 0+1x100 - vector_matching_a{l="y"} 0+2x50 - vector_matching_b{l="x"} 0+4x25 - - -eval instant at 50m SUM(http_requests) BY (job) - COUNT(http_requests) BY (job) - {job="api-server"} 996 - {job="app-server"} 2596 - -eval instant at 50m 2 - SUM(http_requests) BY (job) - {job="api-server"} -998 - {job="app-server"} -2598 - -eval instant at 50m -http_requests{job="api-server",instance="0",group="production"} - {job="api-server",instance="0",group="production"} -100 - -eval instant at 50m +http_requests{job="api-server",instance="0",group="production"} - http_requests{job="api-server",instance="0",group="production"} 100 - -eval instant at 50m - - - SUM(http_requests) BY (job) - {job="api-server"} -1000 - {job="app-server"} -2600 - -eval instant at 50m - - - 1 - -1 - -eval instant at 50m -2^---1*3 - -1.5 - -eval instant at 50m 2/-2^---1*3+2 - -10 - -eval instant at 50m -10^3 * - SUM(http_requests) BY (job) ^ -1 - {job="api-server"} 1 - {job="app-server"} 0.38461538461538464 - -eval instant at 50m 1000 / SUM(http_requests) BY (job) - {job="api-server"} 1 - {job="app-server"} 0.38461538461538464 - -eval instant at 50m SUM(http_requests) BY (job) - 2 - {job="api-server"} 998 - {job="app-server"} 2598 - -eval instant at 50m SUM(http_requests) BY (job) % 3 - {job="api-server"} 1 - {job="app-server"} 2 - -eval instant at 50m SUM(http_requests) BY (job) % 0.3 - {job="api-server"} 0.1 - {job="app-server"} 0.2 - -eval instant at 50m SUM(http_requests) BY (job) ^ 2 - {job="api-server"} 1000000 - {job="app-server"} 6760000 - -eval instant at 50m SUM(http_requests) BY (job) % 3 ^ 2 - {job="api-server"} 1 - {job="app-server"} 8 - -eval instant at 50m SUM(http_requests) BY (job) % 2 ^ (3 ^ 2) - {job="api-server"} 488 - {job="app-server"} 40 - -eval instant at 50m SUM(http_requests) BY (job) % 2 ^ 3 ^ 2 - {job="api-server"} 488 - {job="app-server"} 40 - -eval instant at 50m SUM(http_requests) BY (job) % 2 ^ 3 ^ 2 ^ 2 - {job="api-server"} 1000 - {job="app-server"} 2600 - -eval instant at 50m COUNT(http_requests) BY (job) ^ COUNT(http_requests) BY (job) - {job="api-server"} 256 - {job="app-server"} 256 - -eval instant at 50m SUM(http_requests) BY (job) / 0 - {job="api-server"} +Inf - {job="app-server"} +Inf - -eval instant at 50m http_requests{group="canary", instance="0", job="api-server"} / 0 - {group="canary", instance="0", job="api-server"} +Inf - -eval instant at 50m -1 * http_requests{group="canary", instance="0", job="api-server"} / 0 - {group="canary", instance="0", job="api-server"} -Inf - -eval instant at 50m 0 * http_requests{group="canary", instance="0", job="api-server"} / 0 - {group="canary", instance="0", job="api-server"} NaN - -eval instant at 50m 0 * http_requests{group="canary", instance="0", job="api-server"} % 0 - {group="canary", instance="0", job="api-server"} NaN - -eval instant at 50m SUM(http_requests) BY (job) + SUM(http_requests) BY (job) - {job="api-server"} 2000 - {job="app-server"} 5200 - -eval instant at 50m (SUM((http_requests)) BY (job)) + SUM(http_requests) BY (job) - {job="api-server"} 2000 - {job="app-server"} 5200 - -eval instant at 50m http_requests{job="api-server", group="canary"} - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="1", job="api-server"} 400 - -eval instant at 50m http_requests{job="api-server", group="canary"} + rate(http_requests{job="api-server"}[5m]) * 5 * 60 - {group="canary", instance="0", job="api-server"} 330 - {group="canary", instance="1", job="api-server"} 440 - -eval instant at 50m rate(http_requests[25m]) * 25 * 60 - {group="canary", instance="0", job="api-server"} 150 - {group="canary", instance="0", job="app-server"} 350 - {group="canary", instance="1", job="api-server"} 200 - {group="canary", instance="1", job="app-server"} 400 - {group="production", instance="0", job="api-server"} 50 - {group="production", instance="0", job="app-server"} 249.99999999999997 - {group="production", instance="1", job="api-server"} 100 - {group="production", instance="1", job="app-server"} 300 - -eval instant at 50m (rate((http_requests[25m])) * 25) * 60 - {group="canary", instance="0", job="api-server"} 150 - {group="canary", instance="0", job="app-server"} 350 - {group="canary", instance="1", job="api-server"} 200 - {group="canary", instance="1", job="app-server"} 400 - {group="production", instance="0", job="api-server"} 50 - {group="production", instance="0", job="app-server"} 249.99999999999997 - {group="production", instance="1", job="api-server"} 100 - {group="production", instance="1", job="app-server"} 300 - - -eval instant at 50m http_requests{group="canary"} and http_requests{instance="0"} - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="0", job="app-server"} 700 - -eval instant at 50m (http_requests{group="canary"} + 1) and http_requests{instance="0"} - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - -eval instant at 50m (http_requests{group="canary"} + 1) and on(instance, job) http_requests{instance="0", group="production"} - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - -eval instant at 50m (http_requests{group="canary"} + 1) and on(instance) http_requests{instance="0", group="production"} - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - -eval instant at 50m (http_requests{group="canary"} + 1) and ignoring(group) http_requests{instance="0", group="production"} - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - -eval instant at 50m (http_requests{group="canary"} + 1) and ignoring(group, job) http_requests{instance="0", group="production"} - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - -eval instant at 50m http_requests{group="canary"} or http_requests{group="production"} - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="production", instance="0", job="app-server"} 500 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="production", instance="1", job="app-server"} 600 - -# On overlap the rhs samples must be dropped. -eval instant at 50m (http_requests{group="canary"} + 1) or http_requests{instance="1"} - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - {group="canary", instance="1", job="api-server"} 401 - {group="canary", instance="1", job="app-server"} 801 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="production", instance="1", job="app-server"} 600 - - -# Matching only on instance excludes everything that has instance=0/1 but includes -# entries without the instance label. -eval instant at 50m (http_requests{group="canary"} + 1) or on(instance) (http_requests or cpu_count or vector_matching_a) - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - {group="canary", instance="1", job="api-server"} 401 - {group="canary", instance="1", job="app-server"} 801 - vector_matching_a{l="x"} 10 - vector_matching_a{l="y"} 20 - -eval instant at 50m (http_requests{group="canary"} + 1) or ignoring(l, group, job) (http_requests or cpu_count or vector_matching_a) - {group="canary", instance="0", job="api-server"} 301 - {group="canary", instance="0", job="app-server"} 701 - {group="canary", instance="1", job="api-server"} 401 - {group="canary", instance="1", job="app-server"} 801 - vector_matching_a{l="x"} 10 - vector_matching_a{l="y"} 20 - -eval instant at 50m http_requests{group="canary"} unless http_requests{instance="0"} - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="canary", instance="1", job="app-server"} 800 - -eval instant at 50m http_requests{group="canary"} unless on(job) http_requests{instance="0"} - -eval instant at 50m http_requests{group="canary"} unless on(job, instance) http_requests{instance="0"} - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="canary", instance="1", job="app-server"} 800 - -eval instant at 50m http_requests{group="canary"} / on(instance,job) http_requests{group="production"} - {instance="0", job="api-server"} 3 - {instance="0", job="app-server"} 1.4 - {instance="1", job="api-server"} 2 - {instance="1", job="app-server"} 1.3333333333333333 - -eval instant at 50m http_requests{group="canary"} unless ignoring(group, instance) http_requests{instance="0"} - -eval instant at 50m http_requests{group="canary"} unless ignoring(group) http_requests{instance="0"} - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="canary", instance="1", job="app-server"} 800 - -eval instant at 50m http_requests{group="canary"} / ignoring(group) http_requests{group="production"} - {instance="0", job="api-server"} 3 - {instance="0", job="app-server"} 1.4 - {instance="1", job="api-server"} 2 - {instance="1", job="app-server"} 1.3333333333333333 - -# https://github.com/prometheus/prometheus/issues/1489 -eval instant at 50m http_requests AND ON (dummy) vector(1) - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="production", instance="0", job="app-server"} 500 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="production", instance="1", job="app-server"} 600 - -eval instant at 50m http_requests AND IGNORING (group, instance, job) vector(1) - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="production", instance="0", job="app-server"} 500 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="production", instance="1", job="app-server"} 600 - - -# Comparisons. -eval instant at 50m SUM(http_requests) BY (job) > 1000 - {job="app-server"} 2600 - -eval instant at 50m 1000 < SUM(http_requests) BY (job) - {job="app-server"} 2600 - -eval instant at 50m SUM(http_requests) BY (job) <= 1000 - {job="api-server"} 1000 - -eval instant at 50m SUM(http_requests) BY (job) != 1000 - {job="app-server"} 2600 - -eval instant at 50m SUM(http_requests) BY (job) == 1000 - {job="api-server"} 1000 - -eval instant at 50m SUM(http_requests) BY (job) == bool 1000 - {job="api-server"} 1 - {job="app-server"} 0 - -eval instant at 50m SUM(http_requests) BY (job) == bool SUM(http_requests) BY (job) - {job="api-server"} 1 - {job="app-server"} 1 - -eval instant at 50m SUM(http_requests) BY (job) != bool SUM(http_requests) BY (job) - {job="api-server"} 0 - {job="app-server"} 0 - -eval instant at 50m 0 == bool 1 - 0 - -eval instant at 50m 1 == bool 1 - 1 - -eval instant at 50m http_requests{job="api-server", instance="0", group="production"} == bool 100 - {job="api-server", instance="0", group="production"} 1 - -# group_left/group_right. - -clear - -load 5m - node_var{instance="abc",job="node"} 2 - node_role{instance="abc",job="node",role="prometheus"} 1 - -load 5m - node_cpu{instance="abc",job="node",mode="idle"} 3 - node_cpu{instance="abc",job="node",mode="user"} 1 - node_cpu{instance="def",job="node",mode="idle"} 8 - node_cpu{instance="def",job="node",mode="user"} 2 - -load 5m - random{foo="bar"} 1 - -load 5m - threshold{instance="abc",job="node",target="a@b.com"} 0 - -# Copy machine role to node variable. -eval instant at 5m node_role * on (instance) group_right (role) node_var - {instance="abc",job="node",role="prometheus"} 2 - -eval instant at 5m node_var * on (instance) group_left (role) node_role - {instance="abc",job="node",role="prometheus"} 2 - -eval instant at 5m node_var * ignoring (role) group_left (role) node_role - {instance="abc",job="node",role="prometheus"} 2 - -eval instant at 5m node_role * ignoring (role) group_right (role) node_var - {instance="abc",job="node",role="prometheus"} 2 - -# Copy machine role to node variable with instrumentation labels. -eval instant at 5m node_cpu * ignoring (role, mode) group_left (role) node_role - {instance="abc",job="node",mode="idle",role="prometheus"} 3 - {instance="abc",job="node",mode="user",role="prometheus"} 1 - -eval instant at 5m node_cpu * on (instance) group_left (role) node_role - {instance="abc",job="node",mode="idle",role="prometheus"} 3 - {instance="abc",job="node",mode="user",role="prometheus"} 1 - - -# Ratio of total. -eval instant at 5m node_cpu / on (instance) group_left sum by (instance,job)(node_cpu) - {instance="abc",job="node",mode="idle"} .75 - {instance="abc",job="node",mode="user"} .25 - {instance="def",job="node",mode="idle"} .80 - {instance="def",job="node",mode="user"} .20 - -eval instant at 5m sum by (mode, job)(node_cpu) / on (job) group_left sum by (job)(node_cpu) - {job="node",mode="idle"} 0.7857142857142857 - {job="node",mode="user"} 0.21428571428571427 - -eval instant at 5m sum(sum by (mode, job)(node_cpu) / on (job) group_left sum by (job)(node_cpu)) - {} 1.0 - - -eval instant at 5m node_cpu / ignoring (mode) group_left sum without (mode)(node_cpu) - {instance="abc",job="node",mode="idle"} .75 - {instance="abc",job="node",mode="user"} .25 - {instance="def",job="node",mode="idle"} .80 - {instance="def",job="node",mode="user"} .20 - -eval instant at 5m node_cpu / ignoring (mode) group_left(dummy) sum without (mode)(node_cpu) - {instance="abc",job="node",mode="idle"} .75 - {instance="abc",job="node",mode="user"} .25 - {instance="def",job="node",mode="idle"} .80 - {instance="def",job="node",mode="user"} .20 - -eval instant at 5m sum without (instance)(node_cpu) / ignoring (mode) group_left sum without (instance, mode)(node_cpu) - {job="node",mode="idle"} 0.7857142857142857 - {job="node",mode="user"} 0.21428571428571427 - -eval instant at 5m sum(sum without (instance)(node_cpu) / ignoring (mode) group_left sum without (instance, mode)(node_cpu)) - {} 1.0 - - -# Copy over label from metric with no matching labels, without having to list cross-job target labels ('job' here). -eval instant at 5m node_cpu + on(dummy) group_left(foo) random*0 - {instance="abc",job="node",mode="idle",foo="bar"} 3 - {instance="abc",job="node",mode="user",foo="bar"} 1 - {instance="def",job="node",mode="idle",foo="bar"} 8 - {instance="def",job="node",mode="user",foo="bar"} 2 - - -# Use threshold from metric, and copy over target. -eval instant at 5m node_cpu > on(job, instance) group_left(target) threshold - node_cpu{instance="abc",job="node",mode="idle",target="a@b.com"} 3 - node_cpu{instance="abc",job="node",mode="user",target="a@b.com"} 1 - -# Use threshold from metric, and a default (1) if it's not present. -eval instant at 5m node_cpu > on(job, instance) group_left(target) (threshold or on (job, instance) (sum by (job, instance)(node_cpu) * 0 + 1)) - node_cpu{instance="abc",job="node",mode="idle",target="a@b.com"} 3 - node_cpu{instance="abc",job="node",mode="user",target="a@b.com"} 1 - node_cpu{instance="def",job="node",mode="idle"} 8 - node_cpu{instance="def",job="node",mode="user"} 2 - - -# Check that binops drop the metric name. -eval instant at 5m node_cpu + 2 - {instance="abc",job="node",mode="idle"} 5 - {instance="abc",job="node",mode="user"} 3 - {instance="def",job="node",mode="idle"} 10 - {instance="def",job="node",mode="user"} 4 - -eval instant at 5m node_cpu - 2 - {instance="abc",job="node",mode="idle"} 1 - {instance="abc",job="node",mode="user"} -1 - {instance="def",job="node",mode="idle"} 6 - {instance="def",job="node",mode="user"} 0 - -eval instant at 5m node_cpu / 2 - {instance="abc",job="node",mode="idle"} 1.5 - {instance="abc",job="node",mode="user"} 0.5 - {instance="def",job="node",mode="idle"} 4 - {instance="def",job="node",mode="user"} 1 - -eval instant at 5m node_cpu * 2 - {instance="abc",job="node",mode="idle"} 6 - {instance="abc",job="node",mode="user"} 2 - {instance="def",job="node",mode="idle"} 16 - {instance="def",job="node",mode="user"} 4 - -eval instant at 5m node_cpu ^ 2 - {instance="abc",job="node",mode="idle"} 9 - {instance="abc",job="node",mode="user"} 1 - {instance="def",job="node",mode="idle"} 64 - {instance="def",job="node",mode="user"} 4 - -eval instant at 5m node_cpu % 2 - {instance="abc",job="node",mode="idle"} 1 - {instance="abc",job="node",mode="user"} 1 - {instance="def",job="node",mode="idle"} 0 - {instance="def",job="node",mode="user"} 0 - - -clear - -load 5m - random{foo="bar"} 2 - metricA{baz="meh"} 3 - metricB{baz="meh"} 4 - -# On with no labels, for metrics with no common labels. -eval instant at 5m random + on() metricA - {} 5 - -# Ignoring with no labels is the same as no ignoring. -eval instant at 5m metricA + ignoring() metricB - {baz="meh"} 7 - -eval instant at 5m metricA + metricB - {baz="meh"} 7 - -clear - -# Test duplicate labelset in promql output. -load 5m - testmetric1{src="a",dst="b"} 0 - testmetric2{src="a",dst="b"} 1 - -eval_fail instant at 0m -{__name__=~'testmetric1|testmetric2'} - -clear - -load 5m - test_total{instance="localhost"} 50 - test_smaller{instance="localhost"} 10 - -eval instant at 5m test_total > bool test_smaller - {instance="localhost"} 1 - -eval instant at 5m test_total > test_smaller - test_total{instance="localhost"} 50 - -eval instant at 5m test_total < bool test_smaller - {instance="localhost"} 0 - -eval instant at 5m test_total < test_smaller diff --git a/pkg/query/testdata/promql/prometheus/selectors.test b/pkg/query/testdata/promql/prometheus/selectors.test deleted file mode 100644 index c4309957b0..0000000000 --- a/pkg/query/testdata/promql/prometheus/selectors.test +++ /dev/null @@ -1,201 +0,0 @@ -load 10s - http_requests{job="api-server", instance="0", group="production"} 0+10x1000 100+30x1000 - http_requests{job="api-server", instance="1", group="production"} 0+20x1000 200+30x1000 - http_requests{job="api-server", instance="0", group="canary"} 0+30x1000 300+80x1000 - http_requests{job="api-server", instance="1", group="canary"} 0+40x2000 - -eval instant at 8000s rate(http_requests[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - {job="api-server", instance="0", group="canary"} 3 - {job="api-server", instance="1", group="canary"} 4 - -eval instant at 18000s rate(http_requests[1m]) - {job="api-server", instance="0", group="production"} 3 - {job="api-server", instance="1", group="production"} 3 - {job="api-server", instance="0", group="canary"} 8 - {job="api-server", instance="1", group="canary"} 4 - -eval instant at 8000s rate(http_requests{group=~"pro.*"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - -eval instant at 18000s rate(http_requests{group=~".*ry", instance="1"}[1m]) - {job="api-server", instance="1", group="canary"} 4 - -eval instant at 18000s rate(http_requests{instance!="3"}[1m] offset 10000s) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - {job="api-server", instance="0", group="canary"} 3 - {job="api-server", instance="1", group="canary"} 4 - -eval instant at 18000s rate(http_requests[40s]) - rate(http_requests[1m] offset 10000s) - {job="api-server", instance="0", group="production"} 2 - {job="api-server", instance="1", group="production"} 1 - {job="api-server", instance="0", group="canary"} 5 - {job="api-server", instance="1", group="canary"} 0 - -# https://github.com/prometheus/prometheus/issues/3575 -eval instant at 0s http_requests{foo!="bar"} - http_requests{job="api-server", instance="0", group="production"} 0 - http_requests{job="api-server", instance="1", group="production"} 0 - http_requests{job="api-server", instance="0", group="canary"} 0 - http_requests{job="api-server", instance="1", group="canary"} 0 - -eval instant at 0s http_requests{foo!="bar", job="api-server"} - http_requests{job="api-server", instance="0", group="production"} 0 - http_requests{job="api-server", instance="1", group="production"} 0 - http_requests{job="api-server", instance="0", group="canary"} 0 - http_requests{job="api-server", instance="1", group="canary"} 0 - -eval instant at 0s http_requests{foo!~"bar", job="api-server"} - http_requests{job="api-server", instance="0", group="production"} 0 - http_requests{job="api-server", instance="1", group="production"} 0 - http_requests{job="api-server", instance="0", group="canary"} 0 - http_requests{job="api-server", instance="1", group="canary"} 0 - -eval instant at 0s http_requests{foo!~"bar", job="api-server", instance="1", x!="y", z="", group!=""} - http_requests{job="api-server", instance="1", group="production"} 0 - http_requests{job="api-server", instance="1", group="canary"} 0 - -# https://github.com/prometheus/prometheus/issues/7994 -eval instant at 8000s rate(http_requests{group=~"(?i:PRO).*"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - -eval instant at 8000s rate(http_requests{group=~".*?(?i:PRO).*"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - -eval instant at 8000s rate(http_requests{group=~".*(?i:DUC).*"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - -eval instant at 8000s rate(http_requests{group=~".*(?i:TION)"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - -eval instant at 8000s rate(http_requests{group=~".*(?i:TION).*?"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - - -eval instant at 8000s rate(http_requests{group=~"((?i)PRO).*"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - -eval instant at 8000s rate(http_requests{group=~".*((?i)DUC).*"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - -eval instant at 8000s rate(http_requests{group=~".*((?i)TION)"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - - -eval instant at 8000s rate(http_requests{group=~"(?i:PRODUCTION)"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - -eval instant at 8000s rate(http_requests{group=~".*(?i:C).*"}[1m]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - {job="api-server", instance="0", group="canary"} 3 - {job="api-server", instance="1", group="canary"} 4 - -clear -load 1m - metric1{a="a"} 0+1x100 - metric2{b="b"} 0+1x50 - -eval instant at 90m metric1 offset 15m or metric2 offset 45m - metric1{a="a"} 75 - metric2{b="b"} 45 - -clear - -load 5m - x{y="testvalue"} 0+10x10 - -load 5m - cpu_count{instance="0", type="numa"} 0+30x10 - cpu_count{instance="0", type="smp"} 0+10x20 - cpu_count{instance="1", type="smp"} 0+20x10 - -load 5m - label_grouping_test{a="aa", b="bb"} 0+10x10 - label_grouping_test{a="a", b="abb"} 0+20x10 - -load 5m - http_requests{job="api-server", instance="0", group="production"} 0+10x10 - http_requests{job="api-server", instance="1", group="production"} 0+20x10 - http_requests{job="api-server", instance="0", group="canary"} 0+30x10 - http_requests{job="api-server", instance="1", group="canary"} 0+40x10 - http_requests{job="app-server", instance="0", group="production"} 0+50x10 - http_requests{job="app-server", instance="1", group="production"} 0+60x10 - http_requests{job="app-server", instance="0", group="canary"} 0+70x10 - http_requests{job="app-server", instance="1", group="canary"} 0+80x10 - -# Single-letter label names and values. -eval instant at 50m x{y="testvalue"} - x{y="testvalue"} 100 - -# Basic Regex -eval instant at 50m {__name__=~".+"} - http_requests{group="canary", instance="0", job="api-server"} 300 - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="canary", instance="1", job="api-server"} 400 - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="production", instance="0", job="app-server"} 500 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="production", instance="1", job="app-server"} 600 - x{y="testvalue"} 100 - label_grouping_test{a="a", b="abb"} 200 - label_grouping_test{a="aa", b="bb"} 100 - cpu_count{instance="1", type="smp"} 200 - cpu_count{instance="0", type="smp"} 100 - cpu_count{instance="0", type="numa"} 300 - -eval instant at 50m {job=~".+-server", job!~"api-.+"} - http_requests{group="canary", instance="0", job="app-server"} 700 - http_requests{group="canary", instance="1", job="app-server"} 800 - http_requests{group="production", instance="0", job="app-server"} 500 - http_requests{group="production", instance="1", job="app-server"} 600 - -eval instant at 50m http_requests{group!="canary"} - http_requests{group="production", instance="1", job="app-server"} 600 - http_requests{group="production", instance="0", job="app-server"} 500 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="production", instance="0", job="api-server"} 100 - -eval instant at 50m http_requests{job=~".+-server",group!="canary"} - http_requests{group="production", instance="1", job="app-server"} 600 - http_requests{group="production", instance="0", job="app-server"} 500 - http_requests{group="production", instance="1", job="api-server"} 200 - http_requests{group="production", instance="0", job="api-server"} 100 - -eval instant at 50m http_requests{job!~"api-.+",group!="canary"} - http_requests{group="production", instance="1", job="app-server"} 600 - http_requests{group="production", instance="0", job="app-server"} 500 - -eval instant at 50m http_requests{group="production",job=~"api-.+"} - http_requests{group="production", instance="0", job="api-server"} 100 - http_requests{group="production", instance="1", job="api-server"} 200 - -eval instant at 50m http_requests{group="production",job="api-server"} offset 5m - http_requests{group="production", instance="0", job="api-server"} 90 - http_requests{group="production", instance="1", job="api-server"} 180 - -clear - -# Matrix tests. -load 1h - testmetric{aa="bb"} 1 - testmetric{a="abb"} 2 - -eval instant at 0h testmetric - testmetric{aa="bb"} 1 - testmetric{a="abb"} 2 - -clear diff --git a/pkg/query/testdata/promql/prometheus/staleness.test b/pkg/query/testdata/promql/prometheus/staleness.test deleted file mode 100644 index 76ee2f2878..0000000000 --- a/pkg/query/testdata/promql/prometheus/staleness.test +++ /dev/null @@ -1,51 +0,0 @@ -load 10s - metric 0 1 stale 2 - -# Instant vector doesn't return series when stale. -eval instant at 10s metric - {__name__="metric"} 1 - -eval instant at 20s metric - -eval instant at 30s metric - {__name__="metric"} 2 - -eval instant at 40s metric - {__name__="metric"} 2 - -# It goes stale 5 minutes after the last sample. -eval instant at 330s metric - {__name__="metric"} 2 - -eval instant at 331s metric - - -# Range vector ignores stale sample. -eval instant at 30s count_over_time(metric[1m]) - {} 3 - -eval instant at 10s count_over_time(metric[1s]) - {} 1 - -eval instant at 20s count_over_time(metric[1s]) - -eval instant at 20s count_over_time(metric[10s]) - {} 1 - - -clear - -load 10s - metric 0 - -# Series with single point goes stale after 5 minutes. -eval instant at 0s metric - {__name__="metric"} 0 - -eval instant at 150s metric - {__name__="metric"} 0 - -eval instant at 300s metric - {__name__="metric"} 0 - -eval instant at 301s metric diff --git a/pkg/query/testdata/promql/prometheus/subquery.test b/pkg/query/testdata/promql/prometheus/subquery.test deleted file mode 100644 index db85b16227..0000000000 --- a/pkg/query/testdata/promql/prometheus/subquery.test +++ /dev/null @@ -1,117 +0,0 @@ -load 10s - metric 1 2 - -# Evaluation before 0s gets no sample. -eval instant at 10s sum_over_time(metric[50s:10s]) - {} 3 - -eval instant at 10s sum_over_time(metric[50s:5s]) - {} 4 - -# Every evaluation yields the last value, i.e. 2 -eval instant at 5m sum_over_time(metric[50s:10s]) - {} 12 - -# Series becomes stale at 5m10s (5m after last sample) -# Hence subquery gets a single sample at 6m-50s=5m10s. -eval instant at 6m sum_over_time(metric[50s:10s]) - {} 2 - -eval instant at 10s rate(metric[20s:10s]) - {} 0.1 - -eval instant at 20s rate(metric[20s:5s]) - {} 0.05 - -clear - -load 10s - http_requests{job="api-server", instance="1", group="production"} 0+20x1000 200+30x1000 - http_requests{job="api-server", instance="0", group="production"} 0+10x1000 100+30x1000 - http_requests{job="api-server", instance="0", group="canary"} 0+30x1000 300+80x1000 - http_requests{job="api-server", instance="1", group="canary"} 0+40x2000 - -eval instant at 8000s rate(http_requests{group=~"pro.*"}[1m:10s]) - {job="api-server", instance="0", group="production"} 1 - {job="api-server", instance="1", group="production"} 2 - -eval instant at 20000s avg_over_time(rate(http_requests[1m])[1m:1s]) - {job="api-server", instance="0", group="canary"} 8 - {job="api-server", instance="1", group="canary"} 4 - {job="api-server", instance="1", group="production"} 3 - {job="api-server", instance="0", group="production"} 3 - -clear - -load 10s - metric1 0+1x1000 - metric2 0+2x1000 - metric3 0+3x1000 - -eval instant at 1000s sum_over_time(metric1[30s:10s]) - {} 394 - -# This is (394*2 - 100), because other than the last 100 at 1000s, -# everything else is repeated with the 5s step. -eval instant at 1000s sum_over_time(metric1[30s:5s]) - {} 688 - -# Offset is aligned with the step. -eval instant at 1010s sum_over_time(metric1[30s:10s] offset 10s) - {} 394 - -# Same result for different offsets due to step alignment. -eval instant at 1010s sum_over_time(metric1[30s:10s] offset 9s) - {} 297 - -eval instant at 1010s sum_over_time(metric1[30s:10s] offset 7s) - {} 297 - -eval instant at 1010s sum_over_time(metric1[30s:10s] offset 5s) - {} 297 - -eval instant at 1010s sum_over_time(metric1[30s:10s] offset 3s) - {} 297 - -eval instant at 1010s sum_over_time((metric1)[30s:10s] offset 3s) - {} 297 - -# Nested subqueries -eval instant at 1000s rate(sum_over_time(metric1[30s:10s])[50s:10s]) - {} 0.4 - -eval instant at 1000s rate(sum_over_time(metric2[30s:10s])[50s:10s]) - {} 0.8 - -eval instant at 1000s rate(sum_over_time(metric3[30s:10s])[50s:10s]) - {} 1.2 - -eval instant at 1000s rate(sum_over_time((metric1+metric2+metric3)[30s:10s])[30s:10s]) - {} 2.4 - -clear - -# Fibonacci sequence, to ensure the rate is not constant. -# Additional note: using subqueries unnecessarily is unwise. -load 7s - metric 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 2971215073 4807526976 7778742049 12586269025 20365011074 32951280099 53316291173 86267571272 139583862445 225851433717 365435296162 591286729879 956722026041 1548008755920 2504730781961 4052739537881 6557470319842 10610209857723 17167680177565 27777890035288 44945570212853 72723460248141 117669030460994 190392490709135 308061521170129 498454011879264 806515533049393 1304969544928657 2111485077978050 3416454622906707 5527939700884757 8944394323791464 14472334024676221 23416728348467685 37889062373143906 61305790721611591 99194853094755497 160500643816367088 259695496911122585 420196140727489673 679891637638612258 1100087778366101931 1779979416004714189 2880067194370816120 4660046610375530309 7540113804746346429 12200160415121876738 19740274219868223167 31940434634990099905 51680708854858323072 83621143489848422977 135301852344706746049 218922995834555169026 354224848179261915075 573147844013817084101 927372692193078999176 1500520536206896083277 2427893228399975082453 3928413764606871165730 6356306993006846248183 10284720757613717413913 16641027750620563662096 26925748508234281076009 43566776258854844738105 70492524767089125814114 114059301025943970552219 184551825793033096366333 298611126818977066918552 483162952612010163284885 781774079430987230203437 1264937032042997393488322 2046711111473984623691759 3311648143516982017180081 5358359254990966640871840 8670007398507948658051921 14028366653498915298923761 22698374052006863956975682 36726740705505779255899443 59425114757512643212875125 96151855463018422468774568 155576970220531065681649693 251728825683549488150424261 407305795904080553832073954 659034621587630041982498215 1066340417491710595814572169 1725375039079340637797070384 2791715456571051233611642553 4517090495650391871408712937 7308805952221443105020355490 11825896447871834976429068427 19134702400093278081449423917 30960598847965113057878492344 50095301248058391139327916261 81055900096023504197206408605 131151201344081895336534324866 212207101440105399533740733471 343358302784187294870275058337 555565404224292694404015791808 898923707008479989274290850145 1454489111232772683678306641953 2353412818241252672952597492098 3807901929474025356630904134051 6161314747715278029583501626149 9969216677189303386214405760200 16130531424904581415797907386349 26099748102093884802012313146549 42230279526998466217810220532898 68330027629092351019822533679447 110560307156090817237632754212345 178890334785183168257455287891792 289450641941273985495088042104137 468340976726457153752543329995929 757791618667731139247631372100066 1226132595394188293000174702095995 1983924214061919432247806074196061 3210056809456107725247980776292056 5193981023518027157495786850488117 8404037832974134882743767626780173 13598018856492162040239554477268290 22002056689466296922983322104048463 35600075545958458963222876581316753 57602132235424755886206198685365216 93202207781383214849429075266681969 150804340016807970735635273952047185 244006547798191185585064349218729154 394810887814999156320699623170776339 638817435613190341905763972389505493 1033628323428189498226463595560281832 1672445759041379840132227567949787325 2706074082469569338358691163510069157 4378519841510949178490918731459856482 7084593923980518516849609894969925639 11463113765491467695340528626429782121 18547707689471986212190138521399707760 - -# Extrapolated from [3@21, 144@77]: (144 - 3) / (77 - 21) -eval instant at 80s rate(metric[1m]) - {} 2.517857143 - -# No extrapolation, [2@20, 144@80]: (144 - 2) / 60 -eval instant at 80s rate(metric[1m:10s]) - {} 2.366666667 - -# Only one value between 10s and 20s, 2@14 -eval instant at 20s min_over_time(metric[10s]) - {} 2 - -# min(1@10, 2@20) -eval instant at 20s min_over_time(metric[10s:10s]) - {} 1 - -eval instant at 20m min_over_time(rate(metric[5m])[20m:1m]) - {} 0.12119047619047618 - diff --git a/pkg/query/testdata/promql/thanos/aggregators.test b/pkg/query/testdata/promql/thanos/aggregators.test deleted file mode 100644 index 075a3f9c3e..0000000000 --- a/pkg/query/testdata/promql/thanos/aggregators.test +++ /dev/null @@ -1,220 +0,0 @@ -store {} 0 30m - -load 5m - http_requests{job="api-server", instance="0", group="production"} 0+10x10 - http_requests{job="api-server", instance="1", group="production"} 0+20x10 - http_requests{job="api-server", instance="0", group="canary"} 0+30x10 - http_requests{job="api-server", instance="1", group="canary"} 0+40x10 - -store {} 30m 10d - -load 5m - http_requests{job="api-server", instance="0", group="production"} 0+10x10 - http_requests{job="api-server", instance="1", group="production"} 0+20x10 - http_requests{job="api-server", instance="0", group="canary"} 0+30x10 - http_requests{job="api-server", instance="1", group="canary"} 0+40x10 - -store {} 0 30m - -load 5m - http_requests{job="app-server", instance="0", group="production"} 0+50x10 - http_requests{job="app-server", instance="1", group="production"} 0+60x10 - http_requests{job="app-server", instance="0", group="canary"} 0+70x10 - http_requests{job="app-server", instance="1", group="canary"} 0+80x10 - -store {} 30m 10d - -load 5m - http_requests{job="app-server", instance="0", group="production"} 0+50x10 - http_requests{job="app-server", instance="1", group="production"} 0+60x10 - http_requests{job="app-server", instance="0", group="canary"} 0+70x10 - http_requests{job="app-server", instance="1", group="canary"} 0+80x10 - -store {} 0 10d - -load 5m - foo{job="api-server", instance="0", region="europe"} 0+90x10 - foo{job="api-server"} 0+100x10 - -# Simple sum. -eval instant at 50m SUM BY (group) (http_requests{job="api-server"}) - {group="canary"} 700 - {group="production"} 300 - -eval instant at 50m SUM BY (group) (((http_requests{job="api-server"}))) - {group="canary"} 700 - {group="production"} 300 - -# Test alternative "by"-clause order. -eval instant at 50m sum by (group) (http_requests{job="api-server"}) - {group="canary"} 700 - {group="production"} 300 - -# Simple average. -eval instant at 50m avg by (group) (http_requests{job="api-server"}) - {group="canary"} 350 - {group="production"} 150 - -# Simple count. -eval instant at 50m count by (group) (http_requests{job="api-server"}) - {group="canary"} 2 - {group="production"} 2 - -# Simple without. -eval instant at 50m sum without (instance) (http_requests{job="api-server"}) - {group="canary",job="api-server"} 700 - {group="production",job="api-server"} 300 - -# Empty by. -eval instant at 50m sum by () (http_requests{job="api-server"}) - {} 1000 - -# No by/without. -eval instant at 50m sum(http_requests{job="api-server"}) - {} 1000 - -# Empty without. -eval instant at 50m sum without () (http_requests{job="api-server",group="production"}) - {group="production",job="api-server",instance="0"} 100 - {group="production",job="api-server",instance="1"} 200 - -# Without with mismatched and missing labels. Do not do this. -eval instant at 50m sum without (instance) (http_requests{job="api-server"} or foo) - {group="canary",job="api-server"} 700 - {group="production",job="api-server"} 300 - {region="europe",job="api-server"} 900 - {job="api-server"} 1000 - -# Lower-cased aggregation operators should work too. -eval instant at 50m sum(http_requests) by (job) + min(http_requests) by (job) + max(http_requests) by (job) + avg(http_requests) by (job) - {job="app-server"} 4550 - {job="api-server"} 1750 - -# Test alternative "by"-clause order. -eval instant at 50m sum by (group) (http_requests{job="api-server"}) - {group="canary"} 700 - {group="production"} 300 - -# Test both alternative "by"-clause orders in one expression. -# Public health warning: stick to one form within an expression (or even -# in an organization), or risk serious user confusion. -eval instant at 50m sum(sum by (group) (http_requests{job="api-server"})) by (job) - {} 1000 - -eval instant at 50m SUM(http_requests) - {} 3600 - -eval instant at 50m SUM(http_requests{instance="0"}) BY(job) - {job="api-server"} 400 - {job="app-server"} 1200 - -eval instant at 50m SUM(http_requests) BY (job) - {job="api-server"} 1000 - {job="app-server"} 2600 - -# Non-existent labels mentioned in BY-clauses shouldn't propagate to output. -eval instant at 50m SUM(http_requests) BY (job, nonexistent) - {job="api-server"} 1000 - {job="app-server"} 2600 - -eval instant at 50m COUNT(http_requests) BY (job) - {job="api-server"} 4 - {job="app-server"} 4 - -eval instant at 50m SUM(http_requests) BY (job, group) - {group="canary", job="api-server"} 700 - {group="canary", job="app-server"} 1500 - {group="production", job="api-server"} 300 - {group="production", job="app-server"} 1100 - -eval instant at 50m AVG(http_requests) BY (job) - {job="api-server"} 250 - {job="app-server"} 650 - -eval instant at 50m MIN(http_requests) BY (job) - {job="api-server"} 100 - {job="app-server"} 500 - -eval instant at 50m MAX(http_requests) BY (job) - {job="api-server"} 400 - {job="app-server"} 800 - -eval instant at 50m abs(-1 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 100 - {group="production", instance="1", job="api-server"} 200 - -eval instant at 50m floor(0.004 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 0 - {group="production", instance="1", job="api-server"} 0 - -eval instant at 50m ceil(0.004 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 1 - {group="production", instance="1", job="api-server"} 1 - -eval instant at 50m round(0.004 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 0 - {group="production", instance="1", job="api-server"} 1 - -# Round should correctly handle negative numbers. -eval instant at 50m round(-1 * (0.004 * http_requests{group="production",job="api-server"})) - {group="production", instance="0", job="api-server"} 0 - {group="production", instance="1", job="api-server"} -1 - -# Round should round half up. -eval instant at 50m round(0.005 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 1 - {group="production", instance="1", job="api-server"} 1 - -eval instant at 50m round(-1 * (0.005 * http_requests{group="production",job="api-server"})) - {group="production", instance="0", job="api-server"} 0 - {group="production", instance="1", job="api-server"} -1 - -eval instant at 50m round(1 + 0.005 * http_requests{group="production",job="api-server"}) - {group="production", instance="0", job="api-server"} 2 - {group="production", instance="1", job="api-server"} 2 - -eval instant at 50m round(-1 * (1 + 0.005 * http_requests{group="production",job="api-server"})) - {group="production", instance="0", job="api-server"} -1 - {group="production", instance="1", job="api-server"} -2 - -# Round should accept the number to round nearest to. -eval instant at 50m round(0.0005 * http_requests{group="production",job="api-server"}, 0.1) - {group="production", instance="0", job="api-server"} 0.1 - {group="production", instance="1", job="api-server"} 0.1 - -eval instant at 50m round(2.1 + 0.0005 * http_requests{group="production",job="api-server"}, 0.1) - {group="production", instance="0", job="api-server"} 2.2 - {group="production", instance="1", job="api-server"} 2.2 - -eval instant at 50m round(5.2 + 0.0005 * http_requests{group="production",job="api-server"}, 0.1) - {group="production", instance="0", job="api-server"} 5.3 - {group="production", instance="1", job="api-server"} 5.3 - -# Round should work correctly with negative numbers and multiple decimal places. -eval instant at 50m round(-1 * (5.2 + 0.0005 * http_requests{group="production",job="api-server"}), 0.1) - {group="production", instance="0", job="api-server"} -5.2 - {group="production", instance="1", job="api-server"} -5.3 - -# Round should work correctly with big toNearests. -eval instant at 50m round(0.025 * http_requests{group="production",job="api-server"}, 5) - {group="production", instance="0", job="api-server"} 5 - {group="production", instance="1", job="api-server"} 5 - -eval instant at 50m round(0.045 * http_requests{group="production",job="api-server"}, 5) - {group="production", instance="0", job="api-server"} 5 - {group="production", instance="1", job="api-server"} 10 - -# Standard deviation and variance. -eval instant at 50m stddev(http_requests) - {} 229.12878474779 - -eval instant at 50m stddev by (instance)(http_requests) - {instance="0"} 223.60679774998 - {instance="1"} 223.60679774998 - -eval instant at 50m stdvar(http_requests) - {} 52500 - -eval instant at 50m stdvar by (instance)(http_requests) - {instance="0"} 50000 - {instance="1"} 50000 diff --git a/pkg/rules/rulespb/custom_test.go b/pkg/rules/rulespb/custom_test.go index 860d565bb4..74a8b05ceb 100644 --- a/pkg/rules/rulespb/custom_test.go +++ b/pkg/rules/rulespb/custom_test.go @@ -452,7 +452,7 @@ func TestRulesComparator(t *testing.T) { Labels: &labelpb.LabelSet{Labels: []*labelpb.Label{ {Name: "a", Value: "1"}, }}}), - want: -1, + want: -4, }, { name: "label ordering", @@ -481,7 +481,7 @@ func TestRulesComparator(t *testing.T) { {Name: "a", Value: "1"}, {Name: "b", Value: "1"}, }}}), - want: -1, + want: -4, }, { name: "different durations", diff --git a/pkg/tenancy/tenancy_test.go b/pkg/tenancy/tenancy_test.go index e4fcc1d3ac..a9365bf12f 100644 --- a/pkg/tenancy/tenancy_test.go +++ b/pkg/tenancy/tenancy_test.go @@ -10,6 +10,7 @@ import ( "github.com/efficientgo/core/testutil" "github.com/pkg/errors" + "github.com/prometheus/prometheus/model/labels" "github.com/thanos-io/thanos/pkg/component" "github.com/thanos-io/thanos/pkg/store" "github.com/thanos-io/thanos/pkg/store/storepb" @@ -129,7 +130,7 @@ func TestTenantProxyPassing(t *testing.T) { nil, func() []store.Client { return cls }, component.Query, - nil, 0*time.Second, store.EagerRetrieval, + labels.EmptyLabels(), 0*time.Second, store.EagerRetrieval, ) // We assert directly in the mocked store apis LabelValues/LabelNames/Series funcs _, _ = q.LabelValues(ctx, &storepb.LabelValuesRequest{}) @@ -174,7 +175,7 @@ func TestTenantProxyPassing(t *testing.T) { nil, func() []store.Client { return cls }, component.Query, - nil, 0*time.Second, store.EagerRetrieval, + labels.EmptyLabels(), 0*time.Second, store.EagerRetrieval, ) // We assert directly in the mocked store apis LabelValues/LabelNames/Series funcs