github.com/go-graphite/carbonapi@v0.17.0/expr/functions/seriesList/function_test.go (about) 1 package seriesList 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 TestFunction(t *testing.T) { 26 now32 := int64(time.Now().Unix()) 27 28 tests := []th.EvalTestItem{ 29 { 30 "diffSeriesLists(metric1,metric2)", 31 map[parser.MetricRequest][]*types.MetricData{ 32 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", []float64{1, math.NaN(), math.NaN(), 3, 4, 12}, 1, now32)}, 33 {Metric: "metric2", From: 0, Until: 1}: {types.MakeMetricData("metric2", []float64{2, math.NaN(), 3, math.NaN(), 0, 6}, 1, now32)}, 34 }, 35 []*types.MetricData{types.MakeMetricData("diffSeries(metric1,metric2)", 36 []float64{-1, math.NaN(), math.NaN(), math.NaN(), 4, 6}, 1, now32)}, 37 }, 38 { 39 "sumSeriesLists(metric1,metric2)", 40 map[parser.MetricRequest][]*types.MetricData{ 41 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", []float64{1, math.NaN(), math.NaN(), 3, 4, 12}, 1, now32)}, 42 {Metric: "metric2", From: 0, Until: 1}: {types.MakeMetricData("metric2", []float64{2, math.NaN(), 3, math.NaN(), 0, 6}, 1, now32)}, 43 }, 44 []*types.MetricData{types.MakeMetricData("sumSeries(metric1,metric2)", 45 []float64{3, math.NaN(), math.NaN(), math.NaN(), 4, 18}, 1, now32)}, 46 }, 47 } 48 49 for _, tt := range tests { 50 testName := tt.Target 51 t.Run(testName, func(t *testing.T) { 52 eval := th.EvaluatorFromFunc(md[0].F) 53 th.TestEvalExpr(t, eval, &tt) 54 }) 55 } 56 } 57 58 func TestSeriesListMultiReturn(t *testing.T) { 59 now32 := int64(time.Now().Unix()) 60 61 tests := []th.MultiReturnEvalTestItem{ 62 { 63 "divideSeriesLists(metric[12],metric[12])", 64 map[parser.MetricRequest][]*types.MetricData{ 65 {Metric: "metric[12]", From: 0, Until: 1}: { 66 types.MakeMetricData("metric1", []float64{1, 2, 3, 4, 5}, 1, now32), 67 types.MakeMetricData("metric2", []float64{2, 4, 6, 8, 10}, 1, now32), 68 }, 69 }, 70 "divideSeriesListSameGroups", 71 map[string][]*types.MetricData{ 72 "divideSeries(metric1,metric1)": {types.MakeMetricData("divideSeries(metric1,metric1)", []float64{1, 1, 1, 1, 1}, 1, now32)}, 73 "divideSeries(metric2,metric2)": {types.MakeMetricData("divideSeries(metric2,metric2)", []float64{1, 1, 1, 1, 1}, 1, now32)}, 74 }, 75 }, 76 { 77 "multiplySeriesLists(metric[12],metric[12])", 78 map[parser.MetricRequest][]*types.MetricData{ 79 {Metric: "metric[12]", From: 0, Until: 1}: { 80 types.MakeMetricData("metric1", []float64{1, 2, 3, 4, 5}, 1, now32), 81 types.MakeMetricData("metric2", []float64{2, 4, 6, 8, 10}, 1, now32), 82 }, 83 }, 84 "multiplySeriesListSameGroups", 85 map[string][]*types.MetricData{ 86 "multiplySeries(metric1,metric1)": {types.MakeMetricData("multiplySeries(metric1,metric1)", []float64{1, 4, 9, 16, 25}, 1, now32)}, 87 "multiplySeries(metric2,metric2)": {types.MakeMetricData("multiplySeries(metric2,metric2)", []float64{4, 16, 36, 64, 100}, 1, now32)}, 88 }, 89 }, 90 { 91 "diffSeriesLists(metric[12],metric[12])", 92 map[parser.MetricRequest][]*types.MetricData{ 93 {Metric: "metric[12]", From: 0, Until: 1}: { 94 types.MakeMetricData("metric1", []float64{1, 2, 3, 4, 5}, 1, now32), 95 types.MakeMetricData("metric2", []float64{2, 4, 6, 8, 10}, 1, now32), 96 }, 97 }, 98 "diffSeriesListSameGroups", 99 map[string][]*types.MetricData{ 100 "diffSeries(metric1,metric1)": {types.MakeMetricData("diffSeries(metric1,metric1)", []float64{0, 0, 0, 0, 0}, 1, now32)}, 101 "diffSeries(metric2,metric2)": {types.MakeMetricData("diffSeries(metric2,metric2)", []float64{0, 0, 0, 0, 0}, 1, now32)}, 102 }, 103 }, 104 { 105 "diffSeriesLists(metric[12],metric[134])", 106 map[parser.MetricRequest][]*types.MetricData{ 107 {Metric: "metric[12]", From: 0, Until: 1}: { 108 types.MakeMetricData("metric1", []float64{1, 2, 3, 4, 5}, 1, now32), 109 types.MakeMetricData("metric2", []float64{2, 4, 6, 8, 10}, 1, now32), 110 }, 111 {Metric: "metric[134]", From: 0, Until: 1}: { 112 types.MakeMetricData("metric1", []float64{1, 2, 3, 4, 5}, 1, now32), 113 types.MakeMetricData("metric3", []float64{2, 4, 6, 8, 10}, 1, now32), 114 types.MakeMetricData("metric4", []float64{2, 4, 6, 8, 10}, 1, now32), 115 }, 116 }, 117 "diffSeriesListSameGroups", 118 map[string][]*types.MetricData{ 119 "diffSeries(metric1,metric1)": {types.MakeMetricData("diffSeries(metric1,metric1)", []float64{0, 0, 0, 0, 0}, 1, now32)}, 120 }, 121 }, 122 { 123 "sumSeriesLists(metric[12],metric[12])", 124 map[parser.MetricRequest][]*types.MetricData{ 125 {Metric: "metric[12]", From: 0, Until: 1}: { 126 types.MakeMetricData("metric1", []float64{1, 2, 3, 4, 5}, 1, now32), 127 types.MakeMetricData("metric2", []float64{2, 4, 6, 8, 10}, 1, now32), 128 }, 129 }, 130 "sumSeriesListSameGroups", 131 map[string][]*types.MetricData{ 132 "sumSeries(metric1,metric1)": {types.MakeMetricData("sumSeries(metric1,metric1)", []float64{2, 4, 6, 8, 10}, 1, now32)}, 133 "sumSeries(metric2,metric2)": {types.MakeMetricData("sumSeries(metric2,metric2)", []float64{4, 8, 12, 16, 20}, 1, now32)}, 134 }, 135 }, 136 } 137 138 for _, tt := range tests { 139 testName := tt.Target 140 t.Run(testName, func(t *testing.T) { 141 eval := th.EvaluatorFromFunc(md[0].F) 142 th.TestMultiReturnEvalExpr(t, eval, &tt) 143 }) 144 } 145 146 } 147 148 func TestDivideSeriesMismatchedData(t *testing.T) { 149 var startTime int64 = 0 150 151 tests := []th.EvalTestItemWithRange{ 152 { 153 Target: `divideSeriesLists(metric1,metric2)`, // Test different step values for metrics 154 M: map[parser.MetricRequest][]*types.MetricData{ 155 {Metric: "metric1", From: startTime, Until: startTime + 1}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 4, 5}, 1, startTime)}, 156 {Metric: "metric2", From: startTime, Until: startTime + 1}: {types.MakeMetricData("metric2", []float64{1, 2, 3, 4, 5}, 2, startTime)}, 157 }, 158 Want: []*types.MetricData{types.MakeMetricData("divideSeries(metric1,metric2)", 159 []float64{1.5, 1.75, 1.6666666666666667, math.NaN(), math.NaN()}, 2, startTime)}, 160 From: startTime, 161 Until: startTime + 1, 162 }, 163 { 164 Target: `divideSeriesLists(metricA,metricB)`, // Test different step values for metrics 165 M: map[parser.MetricRequest][]*types.MetricData{ 166 {Metric: "metricA", From: startTime, Until: startTime + 1}: {types.MakeMetricData("metricA", []float64{1, 2, 3, 4, 5}, 10, startTime)}, 167 {Metric: "metricB", From: startTime, Until: startTime + 1}: {types.MakeMetricData("metricB", []float64{1, 2, 3, 4, 5}, 5, startTime)}, 168 }, 169 Want: []*types.MetricData{types.MakeMetricData("divideSeries(metricA,metricB)", 170 []float64{0.6666666666666666, 0.5714285714285714, 0.6, math.NaN(), math.NaN()}, 10, startTime)}, 171 From: startTime, 172 Until: startTime + 1, 173 }, 174 { 175 Target: `divideSeriesLists(metricC,metricD)`, // Test different number of values for metrics 176 M: map[parser.MetricRequest][]*types.MetricData{ 177 {Metric: "metricC", From: startTime, Until: startTime + 1}: {types.MakeMetricData("metricC", []float64{1, 2, 3, 4}, 1, startTime)}, 178 {Metric: "metricD", From: startTime, Until: startTime + 1}: {types.MakeMetricData("metricD", []float64{1, 2, 3, 4, 5}, 1, startTime)}, 179 }, 180 Want: []*types.MetricData{types.MakeMetricData("divideSeries(metricC,metricD)", 181 []float64{1, 1, 1, 1, math.NaN()}, 1, startTime)}, 182 From: startTime, 183 Until: startTime + 1, 184 }, 185 { 186 Target: `divideSeriesLists(metricE,metricF)`, // Test different number of values and steps in metrics 187 M: map[parser.MetricRequest][]*types.MetricData{ 188 {Metric: "metricE", From: startTime, Until: startTime + 1}: {types.MakeMetricData("metricE", []float64{1, 2, 3, 4, 5}, 2, startTime)}, 189 {Metric: "metricF", From: startTime, Until: startTime + 1}: {types.MakeMetricData("metricF", []float64{1, 2, 3, 4}, 1, startTime)}, 190 }, 191 Want: []*types.MetricData{types.MakeMetricData("divideSeries(metricE,metricF)", 192 []float64{0.6666666666666666, 0.5714285714285714, math.NaN(), math.NaN(), math.NaN()}, 2, startTime)}, 193 From: startTime, 194 Until: startTime + 1, 195 }, 196 } 197 198 for _, tt := range tests { 199 testName := tt.Target 200 t.Run(testName, func(t *testing.T) { 201 eval := th.EvaluatorFromFunc(md[0].F) 202 th.TestEvalExprWithRange(t, eval, &tt) 203 }) 204 } 205 }