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

     1  package divideSeries
     2  
     3  import (
     4  	"math"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/go-graphite/carbonapi/expr/interfaces"
     9  	"github.com/go-graphite/carbonapi/expr/metadata"
    10  	"github.com/go-graphite/carbonapi/expr/types"
    11  	"github.com/go-graphite/carbonapi/pkg/parser"
    12  	th "github.com/go-graphite/carbonapi/tests"
    13  )
    14  
    15  var (
    16  	md []interfaces.FunctionMetadata = New("")
    17  )
    18  
    19  func init() {
    20  	for _, m := range md {
    21  		metadata.RegisterFunction(m.Name, m.F)
    22  	}
    23  }
    24  
    25  func TestDivideSeriesMultiReturn(t *testing.T) {
    26  	now32 := time.Now().Unix()
    27  
    28  	tests := []th.MultiReturnEvalTestItem{
    29  		{
    30  			"divideSeries(metric[12],metric2)",
    31  			map[parser.MetricRequest][]*types.MetricData{
    32  				{Metric: "metric[12]", From: 0, Until: 1}: {
    33  					types.MakeMetricData("metric1", []float64{1, 2, 3, 4, 5}, 1, now32),
    34  					types.MakeMetricData("metric2", []float64{2, 4, 6, 8, 10}, 1, now32),
    35  				},
    36  				{Metric: "metric1", From: 0, Until: 1}: {
    37  					types.MakeMetricData("metric1", []float64{1, 2, 3, 4, 5}, 1, now32),
    38  				},
    39  				{Metric: "metric2", From: 0, Until: 1}: {
    40  					types.MakeMetricData("metric2", []float64{2, 4, 6, 8, 10}, 1, now32),
    41  				},
    42  			},
    43  			"divideSeries",
    44  			map[string][]*types.MetricData{
    45  				"divideSeries(metric1,metric2)": {types.MakeMetricData("divideSeries(metric1,metric2)", []float64{0.5, 0.5, 0.5, 0.5, 0.5}, 1, now32)},
    46  				"divideSeries(metric2,metric2)": {types.MakeMetricData("divideSeries(metric2,metric2)", []float64{1, 1, 1, 1, 1}, 1, now32)},
    47  			},
    48  		},
    49  	}
    50  
    51  	for _, tt := range tests {
    52  		testName := tt.Target
    53  		t.Run(testName, func(t *testing.T) {
    54  			eval := th.EvaluatorFromFunc(md[0].F)
    55  			th.TestMultiReturnEvalExpr(t, eval, &tt)
    56  		})
    57  	}
    58  }
    59  
    60  func TestDivideSeries(t *testing.T) {
    61  	now32 := time.Now().Unix()
    62  
    63  	tests := []th.EvalTestItem{
    64  		{
    65  			"divideSeries(metric1,metric2)",
    66  			map[parser.MetricRequest][]*types.MetricData{
    67  				{Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", []float64{1, math.NaN(), math.NaN(), 3, 4, 12}, 1, now32)},
    68  				{Metric: "metric2", From: 0, Until: 1}: {types.MakeMetricData("metric2", []float64{2, math.NaN(), 3, math.NaN(), 0, 6}, 1, now32)},
    69  			},
    70  			[]*types.MetricData{types.MakeMetricData("divideSeries(metric1,metric2)",
    71  				[]float64{0.5, math.NaN(), math.NaN(), math.NaN(), math.NaN(), 2}, 1, now32)},
    72  		},
    73  		{
    74  			"divideSeries(metric[12])",
    75  			map[parser.MetricRequest][]*types.MetricData{
    76  				{Metric: "metric[12]", From: 0, Until: 1}: {
    77  					types.MakeMetricData("metric1", []float64{1, math.NaN(), math.NaN(), 3, 4, 12}, 1, now32),
    78  					types.MakeMetricData("metric2", []float64{2, math.NaN(), 3, math.NaN(), 0, 6}, 1, now32),
    79  				},
    80  			},
    81  			[]*types.MetricData{types.MakeMetricData("divideSeries(metric[12])",
    82  				[]float64{0.5, math.NaN(), math.NaN(), math.NaN(), math.NaN(), 2}, 1, now32).SetNameTag("metric1")},
    83  		},
    84  		{
    85  			"divideSeries(testMetric,metric)", // verify that a non-existant denominator will not error out and instead will return a list of math.NaN() values
    86  			map[parser.MetricRequest][]*types.MetricData{
    87  				{Metric: "testMetric", From: 0, Until: 1}: {types.MakeMetricData("testMetric", []float64{1, math.NaN(), math.NaN(), 3, 4, 12}, 1, now32)},
    88  			},
    89  			[]*types.MetricData{types.MakeMetricData("divideSeries(testMetric,MISSING)",
    90  				[]float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, now32)},
    91  		},
    92  	}
    93  
    94  	for _, tt := range tests {
    95  		testName := tt.Target
    96  		t.Run(testName, func(t *testing.T) {
    97  			eval := th.EvaluatorFromFunc(md[0].F)
    98  			th.TestEvalExpr(t, eval, &tt)
    99  		})
   100  	}
   101  }
   102  
   103  func TestDivideSeriesAligned(t *testing.T) {
   104  	startTime := int64(0)
   105  
   106  	tests := []th.EvalTestItemWithRange{
   107  		{
   108  			"divideSeries(metric1,metric2)",
   109  			map[parser.MetricRequest][]*types.MetricData{
   110  				{Metric: "metric1", From: 0, Until: 1}: {
   111  					types.MakeMetricData("metric1", []float64{1, math.NaN(), math.NaN(), 3, 4, 12, 2}, 1, startTime),
   112  				},
   113  				{Metric: "metric2", From: 0, Until: 1}: {
   114  					types.MakeMetricData("metric2", []float64{2, math.NaN(), 3, math.NaN(), 0, 6}, 1, startTime),
   115  				},
   116  			},
   117  			[]*types.MetricData{types.MakeMetricData("divideSeries(metric1,metric2)",
   118  				[]float64{0.5, math.NaN(), math.NaN(), math.NaN(), math.NaN(), 2, math.NaN()}, 1, startTime)},
   119  			startTime,
   120  			startTime + 1,
   121  		},
   122  		{
   123  			"divideSeries(metric[23])",
   124  			map[parser.MetricRequest][]*types.MetricData{
   125  				{Metric: "metric[23]", From: 0, Until: 1}: {
   126  					types.MakeMetricData("metric2", []float64{1, math.NaN(), math.NaN(), 3, 4, 12, 2}, 1, startTime),
   127  					types.MakeMetricData("metric3", []float64{2, math.NaN(), 3, math.NaN(), 0, 6}, 1, startTime),
   128  				},
   129  			},
   130  			[]*types.MetricData{types.MakeMetricData("divideSeries(metric[23])",
   131  				[]float64{0.5, math.NaN(), math.NaN(), math.NaN(), math.NaN(), 2, math.NaN()}, 1, startTime).SetNameTag("metric2")},
   132  			startTime,
   133  			startTime + 1,
   134  		},
   135  		{
   136  			"divideSeries(metric3,metric4)",
   137  			map[parser.MetricRequest][]*types.MetricData{
   138  				{Metric: "metric3", From: 0, Until: 1}: {
   139  					types.MakeMetricData("metric3", []float64{1, math.NaN(), math.NaN(), 3, 4, 8, 2, math.NaN(), 3, math.NaN(), 0, 6}, 5, startTime),
   140  				},
   141  				{Metric: "metric4", From: 0, Until: 1}: {
   142  					types.MakeMetricData("metric4", []float64{2, math.NaN(), 3, math.NaN(), 0, 6}, 10, startTime),
   143  				},
   144  			},
   145  			[]*types.MetricData{types.MakeMetricData("divideSeries(metric3,metric4)",
   146  				[]float64{0.5, math.NaN(), 2, math.NaN(), math.NaN(), 0.5}, 10, startTime)},
   147  			startTime,
   148  			startTime + 1,
   149  		},
   150  	}
   151  
   152  	for _, tt := range tests {
   153  		t.Run(tt.Target, func(t *testing.T) {
   154  			eval := th.EvaluatorFromFunc(md[0].F)
   155  			th.TestEvalExprWithRange(t, eval, &tt)
   156  		})
   157  	}
   158  }