github.com/go-graphite/carbonapi@v0.17.0/expr/functions/moving/function_test.go (about) 1 package moving 2 3 import ( 4 "context" 5 "math" 6 "strconv" 7 "testing" 8 "time" 9 10 "github.com/go-graphite/carbonapi/expr/interfaces" 11 "github.com/go-graphite/carbonapi/expr/metadata" 12 "github.com/go-graphite/carbonapi/expr/types" 13 "github.com/go-graphite/carbonapi/pkg/parser" 14 th "github.com/go-graphite/carbonapi/tests" 15 "github.com/go-graphite/carbonapi/tests/compare" 16 ) 17 18 var ( 19 md []interfaces.FunctionMetadata = New("") 20 ) 21 22 func init() { 23 for _, m := range md { 24 metadata.RegisterFunction(m.Name, m.F) 25 } 26 } 27 28 // Note: some of these tests are influenced by the testcases for moving* functions 29 // in Graphite-web. See: https://github.com/graphite-project/graphite-web/blob/master/webapp/tests/test_functions.py 30 func TestMoving(t *testing.T) { 31 tests := []th.EvalTestItemWithRange{ 32 { 33 Target: "movingAverage(metric1,10)", 34 M: map[parser.MetricRequest][]*types.MetricData{ 35 {Metric: "metric1", From: 20, Until: 25}: {types.MakeMetricData("metric1", th.GenerateValues(10, 25, 1), 1, 20)}, 36 {Metric: "metric1", From: 10, Until: 25}: {types.MakeMetricData("metric1", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, 10)}, 37 }, 38 Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,10)`, 39 []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, 20).SetTag("movingAverage", "10").SetNameTag(`metric1`)}, 40 From: 20, 41 Until: 25, 42 }, 43 { 44 Target: "movingAverage(metric1,10)", 45 M: map[parser.MetricRequest][]*types.MetricData{ 46 {Metric: "metric1", From: 20, Until: 30}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 20)}, 47 {Metric: "metric1", From: 10, Until: 30}: {types.MakeMetricData("metric1", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 1, 10)}, 48 }, 49 Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,10)`, 50 []float64{0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5}, 1, 20).SetTag("movingAverage", "10").SetNameTag(`metric1`)}, 51 From: 20, 52 Until: 30, 53 }, 54 { 55 Target: "movingAverage(metric1,60)", 56 M: map[parser.MetricRequest][]*types.MetricData{ 57 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 610)}, 58 {Metric: "metric1", From: 550, Until: 710}: {types.MakeMetricData("metric1", th.GenerateValues(0, 100, 1), 1, 600)}, 59 }, 60 Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,60)`, 61 []float64{30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5}, 1, 660).SetTag("movingAverage", "60").SetNameTag(`metric1`)}, 62 From: 610, 63 Until: 710, 64 }, 65 { 66 Target: "movingAverage(metric1,'-1min')", 67 M: map[parser.MetricRequest][]*types.MetricData{ 68 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 610)}, 69 {Metric: "metric1", From: 550, Until: 710}: {types.MakeMetricData("metric1", th.GenerateValues(0, 100, 1), 1, 600)}, 70 }, 71 Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,'-1min')`, 72 []float64{30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5}, 1, 660).SetTag("movingAverage", "'-1min'").SetNameTag(`metric1`)}, 73 From: 610, 74 Until: 710, 75 }, 76 { 77 Target: "movingMedian(metric1,10)", 78 M: map[parser.MetricRequest][]*types.MetricData{ 79 {Metric: "metric1", From: 20, Until: 30}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 20)}, 80 {Metric: "metric1", From: 10, Until: 30}: {types.MakeMetricData("metric1", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, 1, 10)}, 81 }, 82 Want: []*types.MetricData{types.MakeMetricData(`movingMedian(metric1,10)`, 83 []float64{0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5}, 1, 20).SetTag("movingMedian", "10").SetNameTag(`metric1`)}, 84 From: 20, 85 Until: 30, 86 }, 87 { 88 Target: "movingMedian(metric1,10)", 89 M: map[parser.MetricRequest][]*types.MetricData{ 90 {Metric: "metric1", From: 20, Until: 25}: {types.MakeMetricData("metric1", th.GenerateValues(10, 25, 1), 1, 20)}, 91 {Metric: "metric1", From: 10, Until: 25}: {types.MakeMetricData("metric1", []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, 10)}, 92 }, 93 Want: []*types.MetricData{types.MakeMetricData(`movingMedian(metric1,10)`, 94 []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, 20).SetTag("movingMedian", "10").SetNameTag(`metric1`)}, 95 From: 20, 96 Until: 25, 97 }, 98 { 99 Target: "movingMedian(metric1,60)", 100 M: map[parser.MetricRequest][]*types.MetricData{ 101 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 610)}, 102 {Metric: "metric1", From: 550, Until: 710}: {types.MakeMetricData("metric1", th.GenerateValues(0, 100, 1), 1, 600)}, 103 }, 104 Want: []*types.MetricData{types.MakeMetricData(`movingMedian(metric1,60)`, 105 []float64{30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5}, 1, 660).SetTag("movingMedian", "60").SetNameTag(`metric1`)}, 106 From: 610, 107 Until: 710, 108 }, 109 { 110 Target: "movingMedian(metric1,'1min')", 111 M: map[parser.MetricRequest][]*types.MetricData{ 112 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 610)}, 113 {Metric: "metric1", From: 550, Until: 710}: {types.MakeMetricData("metric1", th.GenerateValues(0, 100, 1), 1, 600)}, 114 }, 115 Want: []*types.MetricData{types.MakeMetricData(`movingMedian(metric1,'1min')`, 116 []float64{30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5}, 1, 660).SetTag("movingMedian", "'1min'").SetNameTag(`metric1`)}, 117 From: 610, 118 Until: 710, 119 }, 120 { 121 Target: "movingMedian(metric1,'-1min')", 122 M: map[parser.MetricRequest][]*types.MetricData{ 123 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", th.GenerateValues(10, 110, 1), 1, 610)}, 124 {Metric: "metric1", From: 550, Until: 710}: {types.MakeMetricData("metric1", th.GenerateValues(0, 100, 1), 1, 600)}, 125 }, 126 Want: []*types.MetricData{types.MakeMetricData(`movingMedian(metric1,'-1min')`, 127 []float64{30.5, 31.5, 32.5, 33.5, 34.5, 35.5, 36.5, 37.5, 38.5, 39.5, 40.5, 41.5, 42.5, 43.5, 44.5, 45.5, 46.5, 47.5, 48.5, 49.5, 50.5, 51.5, 52.5, 53.5, 54.5, 55.5, 56.5, 57.5, 58.5, 59.5, 60.5, 61.5, 62.5, 63.5, 64.5, 65.5, 66.5, 67.5, 68.5, 69.5}, 1, 660).SetTag("movingMedian", "'-1min'").SetNameTag(`metric1`)}, 128 From: 610, 129 Until: 710, 130 }, 131 { 132 Target: "movingWindow(metric1,'3sec','average')", 133 M: map[parser.MetricRequest][]*types.MetricData{ 134 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 1, 2, 3}, 1, 610)}, 135 {Metric: "metric1", From: 607, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 1, 2, 3}, 1, 607)}, 136 }, 137 Want: []*types.MetricData{types.MakeMetricData(`movingWindow(metric1,'3sec')`, 138 []float64{2, 2, 2}, 1, 610).SetTag("movingWindow", "'3sec'").SetNameTag(`metric1`)}, 139 From: 610, 140 Until: 710, 141 }, 142 { 143 Target: "movingWindow(metric1,'3sec','avg_zero')", 144 M: map[parser.MetricRequest][]*types.MetricData{ 145 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, math.NaN(), 1, math.NaN(), 3}, 1, 610)}, 146 {Metric: "metric1", From: 607, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, math.NaN(), 1, math.NaN(), 3}, 1, 607)}, 147 }, 148 Want: []*types.MetricData{types.MakeMetricData(`movingWindow(metric1,'3sec')`, 149 []float64{1, 0.3333333333333333, 1.3333333333333333}, 1, 610).SetTag("movingWindow", "'3sec'").SetNameTag(`metric1`)}, 150 From: 610, 151 Until: 710, 152 }, 153 { 154 Target: "movingWindow(metric1,'3sec','count')", 155 M: map[parser.MetricRequest][]*types.MetricData{ 156 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, math.NaN(), 1, math.NaN(), 3}, 1, 610)}, 157 {Metric: "metric1", From: 607, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, math.NaN(), 1, math.NaN(), 3}, 1, 607)}, 158 }, 159 Want: []*types.MetricData{types.MakeMetricData(`movingWindow(metric1,'3sec')`, 160 []float64{2, 1, 2}, 1, 610).SetTag("movingWindow", "'3sec'").SetNameTag(`metric1`)}, 161 From: 610, 162 Until: 710, 163 }, 164 { 165 Target: "movingWindow(metric1,'3sec','diff')", 166 M: map[parser.MetricRequest][]*types.MetricData{ 167 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 0, math.NaN(), 5}, 1, 610)}, 168 {Metric: "metric1", From: 607, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 0, math.NaN(), 5}, 1, 607)}, 169 }, 170 Want: []*types.MetricData{types.MakeMetricData(`movingWindow(metric1,'3sec')`, 171 []float64{-1, 3, -5}, 1, 610).SetTag("movingWindow", "'3sec'").SetNameTag(`metric1`)}, 172 From: 610, 173 Until: 710, 174 }, 175 { 176 Target: "movingWindow(metric1,'3sec','range')", 177 M: map[parser.MetricRequest][]*types.MetricData{ 178 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 0, math.NaN(), 5}, 1, 610)}, 179 {Metric: "metric1", From: 607, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 0, math.NaN(), 5}, 1, 607)}, 180 }, 181 Want: []*types.MetricData{types.MakeMetricData(`movingWindow(metric1,'3sec')`, 182 []float64{3, 3, 5}, 1, 610).SetTag("movingWindow", "'3sec'").SetNameTag(`metric1`)}, 183 From: 610, 184 Until: 710, 185 }, 186 { 187 Target: "movingWindow(metric1,'3sec','stddev')", 188 M: map[parser.MetricRequest][]*types.MetricData{ 189 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 0, math.NaN(), 5}, 1, 610)}, 190 {Metric: "metric1", From: 607, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 0, math.NaN(), 5}, 1, 607)}, 191 }, 192 Want: []*types.MetricData{types.MakeMetricData(`movingWindow(metric1,'3sec')`, 193 []float64{1.247219128924647, 1.5, 2.5}, 1, 610).SetTag("movingWindow", "'3sec'").SetNameTag(`metric1`)}, // StartTime = from 194 From: 610, 195 Until: 710, 196 }, 197 { 198 Target: "movingWindow(metric1,'3sec','last')", 199 M: map[parser.MetricRequest][]*types.MetricData{ 200 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 0, math.NaN(), 5}, 1, 610)}, 201 {Metric: "metric1", From: 607, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 0, math.NaN(), 5}, 1, 607)}, 202 }, 203 Want: []*types.MetricData{types.MakeMetricData(`movingWindow(metric1,'3sec')`, 204 []float64{0, math.NaN(), 5}, 1, 610).SetTag("movingWindow", "'3sec'").SetNameTag(`metric1`)}, // StartTime = from 205 From: 610, 206 Until: 710, 207 }, 208 { 209 Target: "movingWindow(metric1,'3sec')", 210 M: map[parser.MetricRequest][]*types.MetricData{ 211 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 1, 2, 3}, 1, 610)}, 212 {Metric: "metric1", From: 607, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 1, 2, 3}, 1, 607)}, 213 }, 214 Want: []*types.MetricData{types.MakeMetricData(`movingWindow(metric1,'3sec')`, 215 []float64{2, 2, 2}, 1, 610).SetTag("movingWindow", "'3sec'").SetNameTag(`metric1`)}, // StartTime = from 216 From: 610, 217 Until: 710, 218 }, 219 { 220 Target: "movingAverage(metric1,4)", 221 M: map[parser.MetricRequest][]*types.MetricData{ 222 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 1, 1, 1, 2, 2, 2, 4, 6, 4, 6, 8}, 1, 610)}, 223 {Metric: "metric1", From: 606, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 1, 1, 1, 2, 2, 2, 4, 6, 4, 6, 8}, 1, 606)}, 224 }, 225 Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,4)`, 226 []float64{1.25, 1.5, 1.75, 2.5, 3.5, 4.0, 5.0, 6.0}, 1, 610).SetTag("movingAverage", "4").SetNameTag(`metric1`)}, // StartTime = from 227 From: 610, 228 Until: 710, 229 }, 230 { 231 Target: "movingAverage(metric1,'5s')", 232 M: map[parser.MetricRequest][]*types.MetricData{ 233 {Metric: "metric1", From: 610, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3}, 10, 610)}, // step > windowSize 234 {Metric: "metric1", From: 605, Until: 710}: {types.MakeMetricData("metric1", []float64{1, 2, 3}, 10, 605)}, 235 }, 236 Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,'5s')`, 237 []float64{math.NaN(), math.NaN(), math.NaN()}, 10, 610).SetTag("movingAverage", "'5s'").SetNameTag(`metric1`)}, // StartTime = from 238 From: 610, 239 Until: 710, 240 }, 241 { 242 Target: "movingAverage(metric1,10)", 243 M: map[parser.MetricRequest][]*types.MetricData{ 244 {Metric: "metric1", From: 610, Until: 700}: {types.MakeMetricData("metric1", []float64{1, 2, 3}, 30, 610)}, // step > windowSize 245 {Metric: "metric1", From: 310, Until: 700}: {types.MakeMetricData("metric1", []float64{1, 2, 3}, 30, 310)}, 246 }, 247 Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,10)`, 248 []float64{}, 30, 610).SetTag("movingAverage", "10").SetNameTag(`metric1`)}, 249 From: 610, 250 Until: 700, 251 }, 252 } 253 254 for n, tt := range tests { 255 testName := tt.Target 256 t.Run(testName+"#"+strconv.Itoa(n), func(t *testing.T) { 257 eval := th.EvaluatorFromFunc(md[0].F) 258 th.TestEvalExprWithRange(t, eval, &tt) 259 }) 260 } 261 } 262 263 func TestMovingXFilesFactor(t *testing.T) { 264 tests := []th.EvalTestItemWithRange{ 265 { 266 Target: "movingSum(metric1,'3sec',0.5)", 267 M: map[parser.MetricRequest][]*types.MetricData{ 268 {Metric: "metric1", From: 610, Until: 618}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 1, math.NaN(), 2, math.NaN(), 3}, 1, 610)}, 269 {Metric: "metric1", From: 607, Until: 618}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 1, math.NaN(), 2, math.NaN(), 3}, 1, 607)}, 270 }, 271 Want: []*types.MetricData{types.MakeMetricData(`movingSum(metric1,'3sec')`, 272 []float64{6, 4, 3, math.NaN(), 5}, 1, 610).SetTag("movingSum", "'3sec'").SetNameTag(`metric1`)}, 273 From: 610, 274 Until: 618, 275 }, 276 { 277 Target: "movingAverage(metric1,4,0.6)", 278 M: map[parser.MetricRequest][]*types.MetricData{ 279 {Metric: "metric1", From: 610, Until: 622}: {types.MakeMetricData("metric1", []float64{1, 1, 1, 1, 2, math.NaN(), 2, 4, math.NaN(), 4, 6, 8}, 1, 610)}, 280 {Metric: "metric1", From: 606, Until: 622}: {types.MakeMetricData("metric1", []float64{1, 1, 1, 1, 2, math.NaN(), 2, 4, math.NaN(), 4, 6, 8}, 1, 606)}, 281 }, 282 Want: []*types.MetricData{types.MakeMetricData(`movingAverage(metric1,4)`, 283 []float64{1.25, 1.3333333333333333, 1.6666666666666667, 2.6666666666666665, math.NaN(), 3.3333333333333335, 4.666666666666667, 6}, 1, 610).SetTag("movingAverage", "4").SetNameTag(`metric1`)}, 284 From: 610, 285 Until: 622, 286 }, 287 { 288 Target: "movingMax(metric1,2,0.5)", 289 M: map[parser.MetricRequest][]*types.MetricData{ 290 {Metric: "metric1", From: 610, Until: 616}: {types.MakeMetricData("metric1", []float64{1, 2, 3, math.NaN(), math.NaN(), 0}, 1, 610)}, 291 {Metric: "metric1", From: 608, Until: 616}: {types.MakeMetricData("metric1", []float64{1, 2, 3, math.NaN(), math.NaN(), 0}, 1, 608)}, 292 }, 293 Want: []*types.MetricData{types.MakeMetricData(`movingMax(metric1,2)`, 294 []float64{3, 3, math.NaN(), 0}, 1, 610).SetTag("movingMax", "2").SetNameTag(`metric1`)}, 295 From: 610, 296 Until: 616, 297 }, 298 } 299 300 for n, tt := range tests { 301 testName := tt.Target 302 t.Run(testName+"#"+strconv.Itoa(n), func(t *testing.T) { 303 eval := th.EvaluatorFromFunc(md[0].F) 304 th.TestEvalExprWithRange(t, eval, &tt) 305 }) 306 } 307 } 308 309 func TestMovingError(t *testing.T) { 310 now32 := int64(time.Now().Unix()) 311 312 tests := []th.EvalTestItemWithError{ 313 { 314 Target: "movingWindow(metric1,'','average')", 315 M: map[parser.MetricRequest][]*types.MetricData{ 316 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 1, 2, 3}, 1, 0)}, 317 }, 318 Error: parser.ErrBadType, 319 }, 320 { 321 Target: "movingWindow(metric1,'-','average')", 322 M: map[parser.MetricRequest][]*types.MetricData{ 323 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 1, 2, 3}, 1, 0)}, 324 }, 325 Error: parser.ErrBadType, 326 }, 327 { 328 Target: "movingWindow(metric1,'+','average')", 329 M: map[parser.MetricRequest][]*types.MetricData{ 330 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 1, 2, 3}, 1, 0)}, 331 }, 332 Error: parser.ErrBadType, 333 }, 334 { 335 Target: "movingWindow(metric1,'-s1','average')", 336 M: map[parser.MetricRequest][]*types.MetricData{ 337 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", []float64{1, 2, 3, 1, 2, 3}, 1, now32)}, 338 }, 339 Error: parser.ErrBadType, 340 }, 341 } 342 343 for n, tt := range tests { 344 testName := tt.Target 345 t.Run(testName+"#"+strconv.Itoa(n), func(t *testing.T) { 346 eval := th.EvaluatorFromFunc(md[0].F) 347 th.TestEvalExprWithError(t, eval, &tt) 348 }) 349 } 350 351 } 352 353 func BenchmarkMoving(b *testing.B) { 354 benchmarks := []struct { 355 target string 356 M map[parser.MetricRequest][]*types.MetricData 357 }{ 358 { 359 target: "movingAverage(metric1,'5s')", 360 M: map[parser.MetricRequest][]*types.MetricData{ 361 {Metric: "metric1", From: -5, Until: 1}: {types.MakeMetricData("metric1", []float64{1, 2, 3}, 10, 1)}, // step > windowSize 362 }, 363 }, 364 { 365 target: "movingAverage(metric1,4)", 366 M: map[parser.MetricRequest][]*types.MetricData{ 367 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", compare.GenerateMetrics(1024, 1.0, 9.0, 1.0), 1, 1)}, 368 }, 369 }, 370 { 371 target: "movingAverage(metric1,2)", 372 M: map[parser.MetricRequest][]*types.MetricData{ 373 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", compare.GenerateMetrics(1024, 1.0, 9.0, 1.0), 1, 1)}, 374 }, 375 }, 376 { 377 target: "movingSum(metric1,2)", 378 M: map[parser.MetricRequest][]*types.MetricData{ 379 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", compare.GenerateMetrics(1024, 1.0, 9.0, 1.0), 1, 1)}, 380 }, 381 }, 382 { 383 target: "movingMin(metric1,2)", 384 M: map[parser.MetricRequest][]*types.MetricData{ 385 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", compare.GenerateMetrics(1024, 1.0, 9.0, 1.0), 1, 1)}, 386 }, 387 }, 388 { 389 target: "movingMax(metric1,2)", 390 M: map[parser.MetricRequest][]*types.MetricData{ 391 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", compare.GenerateMetrics(1024, 1.0, 9.0, 1.0), 1, 1)}, 392 }, 393 }, 394 { 395 target: "movingAverage(metric1,600)", 396 M: map[parser.MetricRequest][]*types.MetricData{ 397 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", compare.GenerateMetrics(1024, 1.0, 9.0, 1.0), 1, 1)}, 398 }, 399 }, 400 { 401 target: "movingSum(metric1,600)", 402 M: map[parser.MetricRequest][]*types.MetricData{ 403 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", compare.GenerateMetrics(1024, 1.0, 9.0, 1.0), 1, 1)}, 404 }, 405 }, 406 { 407 target: "movingMin(metric1,600)", 408 M: map[parser.MetricRequest][]*types.MetricData{ 409 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", compare.GenerateMetrics(1024, 1.0, 9.0, 1.0), 1, 1)}, 410 }, 411 }, 412 { 413 target: "movingMax(metric1,600)", 414 M: map[parser.MetricRequest][]*types.MetricData{ 415 {Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", compare.GenerateMetrics(1024, 1.0, 9.0, 1.0), 1, 1)}, 416 }, 417 }, 418 } 419 420 eval := th.EvaluatorFromFunc(md[0].F) 421 422 for _, bm := range benchmarks { 423 b.Run(bm.target, func(b *testing.B) { 424 exp, _, err := parser.ParseExpr(bm.target) 425 if err != nil { 426 b.Fatalf("failed to parse %s: %+v", bm.target, err) 427 } 428 429 b.ResetTimer() 430 431 for i := 0; i < b.N; i++ { 432 g, err := eval.Eval(context.Background(), exp, 0, 1, bm.M) 433 if err != nil { 434 b.Fatalf("failed to eval %s: %+v", bm.target, err) 435 } 436 _ = g 437 } 438 }) 439 } 440 }