From 5af14c07907d841c21ba53d5e7103ef553505782 Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Wed, 31 Jul 2024 15:49:57 +0700 Subject: [PATCH 1/2] fix: working with second argument of highest... and lowest... functions --- expr/functions/highestLowest/function.go | 4 ++ expr/functions/highestLowest/function_test.go | 42 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/expr/functions/highestLowest/function.go b/expr/functions/highestLowest/function.go index 93e8cb7d7..d6ccdba4b 100644 --- a/expr/functions/highestLowest/function.go +++ b/expr/functions/highestLowest/function.go @@ -100,6 +100,10 @@ func (f *highest) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Ex return nil, fmt.Errorf("unsupported function %v", e.Target()) } + if n <= 0 { + n = 1 + } + if isHighest { for i, a := range arg { m := compute(a.Values) diff --git a/expr/functions/highestLowest/function_test.go b/expr/functions/highestLowest/function_test.go index cb1864ef0..f4a5838c5 100644 --- a/expr/functions/highestLowest/function_test.go +++ b/expr/functions/highestLowest/function_test.go @@ -55,6 +55,20 @@ func TestHighestMultiReturn(t *testing.T) { "metricC": {types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 15}, 1, now32)}, }, }, + { + "highestCurrent(metric1,0)", + map[parser.MetricRequest][]*types.MetricData{ + parser.MetricRequest{Metric: "metric1", From: 0, Until: 1}: { + types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 4, 12}, 1, now32), + types.MakeMetricData("metricB", []float64{1, 1, 3, 3, 4, 1}, 1, now32), + types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 15}, 1, now32), + }, + }, + "highestCurrent", + map[string][]*types.MetricData{ + "metricC": {types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 15}, 1, now32)}, + }, + }, { "highestMax(metric1, 2)", map[parser.MetricRequest][]*types.MetricData{ @@ -100,6 +114,34 @@ func TestHighestMultiReturn(t *testing.T) { "metricC": {types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 10}, 1, now32)}, }, }, + { + "highest(metric1, 0, \"max\")", + map[parser.MetricRequest][]*types.MetricData{ + {Metric: "metric1", From: 0, Until: 1}: { + types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32), + types.MakeMetricData("metricB", []float64{1, 1, 3, 3, 4, 1}, 1, now32), + types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 10}, 1, now32), + }, + }, + "highest", + map[string][]*types.MetricData{ + "metricA": {types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32)}, + }, + }, + { + "highest(metric1, -1, \"max\")", + map[parser.MetricRequest][]*types.MetricData{ + {Metric: "metric1", From: 0, Until: 1}: { + types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32), + types.MakeMetricData("metricB", []float64{1, 1, 3, 3, 4, 1}, 1, now32), + types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 10}, 1, now32), + }, + }, + "highest", + map[string][]*types.MetricData{ + "metricA": {types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32)}, + }, + }, { "lowest(metric1, 2, \"max\")", map[parser.MetricRequest][]*types.MetricData{ From bebe5eff6feebabf093427869c655bc8c59a295b Mon Sep 17 00:00:00 2001 From: AleksandrMatsko Date: Wed, 31 Jul 2024 18:06:54 +0700 Subject: [PATCH 2/2] fix: `highest...` and `lowest...` returns nothing on `n` <= 0 --- expr/functions/highestLowest/function.go | 6 +- expr/functions/highestLowest/function_test.go | 75 ++++++++----------- 2 files changed, 36 insertions(+), 45 deletions(-) diff --git a/expr/functions/highestLowest/function.go b/expr/functions/highestLowest/function.go index d6ccdba4b..a27770f5e 100644 --- a/expr/functions/highestLowest/function.go +++ b/expr/functions/highestLowest/function.go @@ -45,8 +45,6 @@ func (f *highest) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Ex } } - var results []*types.MetricData - // we have fewer arguments than we want result series if len(arg) < n { return arg, nil @@ -100,8 +98,10 @@ func (f *highest) Do(ctx context.Context, eval interfaces.Evaluator, e parser.Ex return nil, fmt.Errorf("unsupported function %v", e.Target()) } + var results []*types.MetricData + if n <= 0 { - n = 1 + return results, nil } if isHighest { diff --git a/expr/functions/highestLowest/function_test.go b/expr/functions/highestLowest/function_test.go index f4a5838c5..175357f45 100644 --- a/expr/functions/highestLowest/function_test.go +++ b/expr/functions/highestLowest/function_test.go @@ -55,20 +55,6 @@ func TestHighestMultiReturn(t *testing.T) { "metricC": {types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 15}, 1, now32)}, }, }, - { - "highestCurrent(metric1,0)", - map[parser.MetricRequest][]*types.MetricData{ - parser.MetricRequest{Metric: "metric1", From: 0, Until: 1}: { - types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 4, 12}, 1, now32), - types.MakeMetricData("metricB", []float64{1, 1, 3, 3, 4, 1}, 1, now32), - types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 15}, 1, now32), - }, - }, - "highestCurrent", - map[string][]*types.MetricData{ - "metricC": {types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 15}, 1, now32)}, - }, - }, { "highestMax(metric1, 2)", map[parser.MetricRequest][]*types.MetricData{ @@ -114,34 +100,6 @@ func TestHighestMultiReturn(t *testing.T) { "metricC": {types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 10}, 1, now32)}, }, }, - { - "highest(metric1, 0, \"max\")", - map[parser.MetricRequest][]*types.MetricData{ - {Metric: "metric1", From: 0, Until: 1}: { - types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32), - types.MakeMetricData("metricB", []float64{1, 1, 3, 3, 4, 1}, 1, now32), - types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 10}, 1, now32), - }, - }, - "highest", - map[string][]*types.MetricData{ - "metricA": {types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32)}, - }, - }, - { - "highest(metric1, -1, \"max\")", - map[parser.MetricRequest][]*types.MetricData{ - {Metric: "metric1", From: 0, Until: 1}: { - types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32), - types.MakeMetricData("metricB", []float64{1, 1, 3, 3, 4, 1}, 1, now32), - types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 10}, 1, now32), - }, - }, - "highest", - map[string][]*types.MetricData{ - "metricA": {types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32)}, - }, - }, { "lowest(metric1, 2, \"max\")", map[parser.MetricRequest][]*types.MetricData{ @@ -273,6 +231,17 @@ func TestHighest(t *testing.T) { []*types.MetricData{types.MakeMetricData("metricB", // NOTE(dgryski): not sure if this matches graphite []float64{2, 5, 5, 5, 5, 5}, 1, now32)}, }, + { + "highestCurrent(metric1,0)", + map[parser.MetricRequest][]*types.MetricData{ + parser.MetricRequest{Metric: "metric1", From: 0, Until: 1}: { + types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 4, 12}, 1, now32), + types.MakeMetricData("metricB", []float64{1, 1, 3, 3, 4, 1}, 1, now32), + types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 15}, 1, now32), + }, + }, + []*types.MetricData{}, + }, { "highest(metric1,\"max\")", map[parser.MetricRequest][]*types.MetricData{ @@ -285,6 +254,28 @@ func TestHighest(t *testing.T) { []*types.MetricData{types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32)}, }, + { + "highest(metric1, 0, \"max\")", + map[parser.MetricRequest][]*types.MetricData{ + {Metric: "metric1", From: 0, Until: 1}: { + types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32), + types.MakeMetricData("metricB", []float64{1, 1, 3, 3, 4, 1}, 1, now32), + types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 10}, 1, now32), + }, + }, + []*types.MetricData{}, + }, + { + "highest(metric1, -1, \"max\")", + map[parser.MetricRequest][]*types.MetricData{ + {Metric: "metric1", From: 0, Until: 1}: { + types.MakeMetricData("metricA", []float64{1, 1, 3, 3, 12, 11}, 1, now32), + types.MakeMetricData("metricB", []float64{1, 1, 3, 3, 4, 1}, 1, now32), + types.MakeMetricData("metricC", []float64{1, 1, 3, 3, 4, 10}, 1, now32), + }, + }, + []*types.MetricData{}, + }, { "lowest(metric1,\"max\")", map[parser.MetricRequest][]*types.MetricData{