github.com/go-graphite/carbonapi@v0.17.0/expr/functions/percentileOfSeries/function_test.go (about)

     1  package percentileOfSeries
     2  
     3  import (
     4  	"math"
     5  	"testing"
     6  	"time"
     7  
     8  	fconfig "github.com/go-graphite/carbonapi/expr/functions/config"
     9  	"github.com/go-graphite/carbonapi/expr/interfaces"
    10  	"github.com/go-graphite/carbonapi/expr/metadata"
    11  	"github.com/go-graphite/carbonapi/expr/types"
    12  	"github.com/go-graphite/carbonapi/pkg/parser"
    13  	th "github.com/go-graphite/carbonapi/tests"
    14  )
    15  
    16  var (
    17  	md []interfaces.FunctionMetadata = New("")
    18  )
    19  
    20  func init() {
    21  	for _, m := range md {
    22  		metadata.RegisterFunction(m.Name, m.F)
    23  	}
    24  }
    25  
    26  func TestPercentileOfSeries(t *testing.T) {
    27  	fconfig.Config.ExtractTagsFromArgs = false
    28  
    29  	now32 := int64(time.Now().Unix())
    30  
    31  	tests := []th.EvalTestItem{
    32  		{
    33  			`percentileOfSeries(metric1.empty,4)`,
    34  			map[parser.MetricRequest][]*types.MetricData{
    35  				{Metric: "metric1.empty", From: 0, Until: 1}: {},
    36  			},
    37  			[]*types.MetricData{},
    38  		},
    39  		{
    40  			`percentileOfSeries(metric1,4)`,
    41  			map[parser.MetricRequest][]*types.MetricData{
    42  				{Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", []float64{1, 1, 1, 1, 2, 2, 2, 4, 6, 4, 6, 8, math.NaN()}, 1, now32)},
    43  			},
    44  			[]*types.MetricData{types.MakeMetricData("percentileOfSeries(metric1,4)", []float64{1, 1, 1, 1, 2, 2, 2, 4, 6, 4, 6, 8, math.NaN()}, 1, now32)},
    45  		},
    46  		{
    47  			`percentileOfSeries(metric1.foo.*.*,50)`,
    48  			map[parser.MetricRequest][]*types.MetricData{
    49  				{Metric: "metric1.foo.*.*", From: 0, Until: 1}: {
    50  					types.MakeMetricData("metric1.foo.bar1.baz", []float64{1, 2, 3, 4, math.NaN(), math.NaN()}, 1, now32),
    51  					types.MakeMetricData("metric1.foo.bar1.qux", []float64{6, 7, 8, 9, 10, math.NaN()}, 1, now32),
    52  					types.MakeMetricData("metric1.foo.bar2.baz", []float64{11, 12, 13, 14, 15, math.NaN()}, 1, now32),
    53  					types.MakeMetricData("metric1.foo.bar2.qux", []float64{7, 8, 9, 10, 11, math.NaN()}, 1, now32),
    54  				},
    55  			},
    56  			[]*types.MetricData{types.MakeMetricData("percentileOfSeries(metric1.foo.*.*,50)", []float64{7, 8, 9, 10, 11, math.NaN()}, 1, now32)},
    57  		},
    58  		{
    59  			`percentileOfSeries(metric1.foo.*.*,50,interpolate=true)`,
    60  			map[parser.MetricRequest][]*types.MetricData{
    61  				{Metric: "metric1.foo.*.*", From: 0, Until: 1}: {
    62  					types.MakeMetricData("metric1.foo.bar1.baz", []float64{1, 2, 3, 4, math.NaN(), math.NaN()}, 1, now32),
    63  					types.MakeMetricData("metric1.foo.bar1.qux", []float64{6, 7, 8, 9, 10, math.NaN()}, 1, now32),
    64  					types.MakeMetricData("metric1.foo.bar2.baz", []float64{11, 12, 13, 14, 15, math.NaN()}, 1, now32),
    65  					types.MakeMetricData("metric1.foo.bar2.qux", []float64{7, 8, 9, 10, 11, math.NaN()}, 1, now32),
    66  				},
    67  			},
    68  			[]*types.MetricData{types.MakeMetricData("percentileOfSeries(metric1.foo.*.*,50,interpolate=true)", []float64{6.5, 7.5, 8.5, 9.5, 11, math.NaN()}, 1, now32)},
    69  		},
    70  		{
    71  			`percentileOfSeries(metric1.foo.*.*,95,false)`,
    72  			map[parser.MetricRequest][]*types.MetricData{
    73  				{Metric: "metric1.foo.*.*", From: 0, Until: 1}: {
    74  					types.MakeMetricData("metric1.foo.bar1.qux", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, now32),
    75  					types.MakeMetricData("metric1.foo.bar2.qux", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0}, 1, now32),
    76  					types.MakeMetricData("metric1.foo.bar3.qux", []float64{0, 0, 0, 100500, 100501, 1005002}, 1, now32),
    77  					types.MakeMetricData("metric1.foo.bar4.qux", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0}, 1, now32),
    78  					types.MakeMetricData("metric1.foo.bar5.qux", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0}, 1, now32),
    79  				},
    80  			},
    81  			[]*types.MetricData{types.MakeMetricData("percentileOfSeries(metric1.foo.*.*,95,false)", []float64{0, 0, 0, 100500, 100501, 1005002}, 1, now32)},
    82  		},
    83  		// seriesByTag
    84  		{
    85  			`percentileOfSeries(seriesByTag('tag2=value*', 'name=metric'),95,false)`,
    86  			map[parser.MetricRequest][]*types.MetricData{
    87  				{Metric: "seriesByTag('tag2=value*', 'name=metric')", From: 0, Until: 1}: {
    88  					types.MakeMetricData("metric;tag1=value1;tag2=value21;tag3=value3", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, now32),
    89  					types.MakeMetricData("metric;tag2=value21", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0}, 1, now32),
    90  					types.MakeMetricData("metric;tag1=value1;tag2=value21", []float64{0, 0, 0, 100500, 100501, 1005002}, 1, now32),
    91  					types.MakeMetricData("metric;tag1=value1;tag2=value21", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0}, 1, now32),
    92  					types.MakeMetricData("metric;tag1=value1;tag2=value21", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0}, 1, now32),
    93  				},
    94  			},
    95  			[]*types.MetricData{types.MakeMetricData(`percentileOfSeries(seriesByTag('tag2=value*', 'name=metric'),95,false)`, []float64{0, 0, 0, 100500, 100501, 1005002}, 1, now32).
    96  				SetTags(map[string]string{"name": "metric", "tag2": "value21"})},
    97  		},
    98  	}
    99  
   100  	for _, tt := range tests {
   101  		testName := tt.Target
   102  		t.Run(testName, func(t *testing.T) {
   103  			eval := th.EvaluatorFromFunc(md[0].F)
   104  			th.TestEvalExpr(t, eval, &tt)
   105  		})
   106  	}
   107  
   108  }
   109  
   110  func TestPercentileOfSeriesExtractSeriesByTag(t *testing.T) {
   111  	fconfig.Config.ExtractTagsFromArgs = true
   112  
   113  	now32 := int64(time.Now().Unix())
   114  
   115  	tests := []th.EvalTestItem{
   116  		{
   117  			`percentileOfSeries(seriesByTag('tag2=value*', 'name=metric'),95,false)`,
   118  			map[parser.MetricRequest][]*types.MetricData{
   119  				{Metric: "seriesByTag('tag2=value*', 'name=metric')", From: 0, Until: 1}: {
   120  					types.MakeMetricData("metric;tag1=value1;tag2=value21;tag3=value3", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, now32),
   121  					types.MakeMetricData("metric;tag2=value22", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0}, 1, now32),
   122  					types.MakeMetricData("metric;tag1=value1;tag2=value23", []float64{0, 0, 0, 100500, 100501, 1005002}, 1, now32),
   123  					types.MakeMetricData("metric;tag1=value1;tag2=value24", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0}, 1, now32),
   124  					types.MakeMetricData("metric;tag1=value1;tag2=value25", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0}, 1, now32),
   125  				},
   126  			},
   127  			[]*types.MetricData{types.MakeMetricData(`percentileOfSeries(seriesByTag('tag2=value*', 'name=metric'),95,false)`, []float64{0, 0, 0, 100500, 100501, 1005002}, 1, now32).
   128  				SetTags(map[string]string{"name": "metric", "tag2": "value*"})},
   129  		},
   130  	}
   131  
   132  	for _, tt := range tests {
   133  		testName := tt.Target
   134  		t.Run(testName, func(t *testing.T) {
   135  			eval := th.EvaluatorFromFunc(md[0].F)
   136  			th.TestEvalExpr(t, eval, &tt)
   137  		})
   138  	}
   139  
   140  }