github.com/go-graphite/carbonapi@v0.17.0/expr/functions/summarize/function_test.go (about) 1 package summarize 2 3 import ( 4 "math" 5 "testing" 6 7 "github.com/go-graphite/carbonapi/expr/interfaces" 8 "github.com/go-graphite/carbonapi/expr/metadata" 9 "github.com/go-graphite/carbonapi/expr/types" 10 "github.com/go-graphite/carbonapi/pkg/parser" 11 th "github.com/go-graphite/carbonapi/tests" 12 ) 13 14 var ( 15 md []interfaces.FunctionMetadata = New("") 16 ) 17 18 func init() { 19 for _, m := range md { 20 metadata.RegisterFunction(m.Name, m.F) 21 } 22 } 23 24 func TestEvalSummarize(t *testing.T) { 25 tenThirtyTwo, _, tenThirty := th.InitTestSummarize() 26 now32 := tenThirty 27 28 tests := []th.SummarizeEvalTestItem{ 29 { 30 Target: "summarize(metric1,'5s')", 31 M: map[parser.MetricRequest][]*types.MetricData{ 32 {Metric: "metric1", From: now32, Until: now32 + 35}: {types.MakeMetricData("metric1", []float64{ 33 1, 1, 1, 1, 1, 34 2, 2, 2, 2, 2, 35 3, 3, 3, 3, 3, 36 4, 4, 4, 4, 4, 37 5, 5, 5, 5, 5, 38 math.NaN(), 2, 3, 4, 5, 39 math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), 40 }, 1, now32)}, 41 }, 42 Want: []float64{5, 10, 15, 20, 25, 14, math.NaN(), math.NaN()}, 43 From: now32, 44 Until: now32 + 35, 45 Name: "summarize(metric1,'5s')", 46 Step: 5, 47 Start: now32, 48 Stop: now32 + 40, 49 }, 50 { 51 Target: "summarize(metric1,'5s')", 52 M: map[parser.MetricRequest][]*types.MetricData{ 53 {Metric: "metric1", From: now32, Until: now32 + 50}: {types.MakeMetricData("metric1", []float64{ 54 1, 2, 3, 4, 5, 55 }, 10, now32)}, 56 }, 57 Want: []float64{1, math.NaN(), 2, math.NaN(), 3, math.NaN(), 4, math.NaN(), 5, math.NaN(), math.NaN()}, 58 From: now32, 59 Until: now32 + 50, 60 Name: "summarize(metric1,'5s')", 61 Step: 5, 62 Start: now32, 63 Stop: now32 + 55, 64 }, 65 { 66 Target: "summarize(metric1,'5s','avg')", 67 M: map[parser.MetricRequest][]*types.MetricData{ 68 {Metric: "metric1", From: now32, Until: now32 + 35}: {types.MakeMetricData("metric1", []float64{1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 1, 2, 3, math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, now32)}, 69 }, 70 Want: []float64{1, 2, 3, 4, 5, 2, math.NaN(), math.NaN()}, 71 From: now32, 72 Until: now32 + 35, 73 Name: "summarize(metric1,'5s','avg')", 74 Step: 5, 75 Start: now32, 76 Stop: now32 + 40, 77 }, 78 { 79 Target: "summarize(metric1,'5s','max')", 80 M: map[parser.MetricRequest][]*types.MetricData{ 81 {Metric: "metric1", From: now32, Until: now32 + 25*1}: {types.MakeMetricData("metric1", []float64{1, 0, 0, 0.5, 1, 2, 1, 1, 1.5, 2, 3, 2, 2, 1.5, 3, 4, 3, 2, 3, 4.5, 5, 5, 5, 5, 5}, 1, now32)}, 82 }, 83 Want: []float64{1, 2, 3, 4.5, 5, math.NaN()}, 84 From: now32, 85 Until: now32 + 25*1, 86 Name: "summarize(metric1,'5s','max')", 87 Step: 5, 88 Start: now32, 89 Stop: now32 + 30, 90 }, 91 { 92 Target: "summarize(metric1,'5s','min')", 93 M: map[parser.MetricRequest][]*types.MetricData{ 94 {Metric: "metric1", From: now32, Until: now32 + 25*1}: {types.MakeMetricData("metric1", []float64{1, 0, 0, 0.5, 1, 2, 1, 1, 1.5, 2, 3, 2, 2, 1.5, 3, 4, 3, 2, 3, 4.5, 5, 5, 5, 5, 5}, 1, now32)}, 95 }, 96 Want: []float64{0, 1, 1.5, 2, 5, math.NaN()}, 97 From: now32, 98 Until: now32 + 25*1, 99 Name: "summarize(metric1,'5s','min')", 100 Step: 5, 101 Start: now32, 102 Stop: now32 + 30, 103 }, 104 { 105 Target: "summarize(metric1,'5s','last')", 106 M: map[parser.MetricRequest][]*types.MetricData{ 107 {Metric: "metric1", From: now32, Until: now32 + 25*1}: {types.MakeMetricData("metric1", []float64{1, 0, 0, 0.5, 1, 2, 1, 1, 1.5, 2, 3, 2, 2, 1.5, 3, 4, 3, 2, 3, 4.5, 5, 5, 5, 5, 5}, 1, now32)}, 108 }, 109 Want: []float64{1, 2, 3, 4.5, 5, math.NaN()}, 110 From: now32, 111 Until: now32 + 25*1, 112 Name: "summarize(metric1,'5s','last')", 113 Step: 5, 114 Start: now32, 115 Stop: now32 + 30, 116 }, 117 { 118 Target: "summarize(metric1,'5s','count')", 119 M: map[parser.MetricRequest][]*types.MetricData{ 120 {Metric: "metric1", From: now32, Until: now32 + 35}: {types.MakeMetricData("metric1", []float64{1, math.NaN(), 1, 1, math.NaN(), math.NaN(), 2, 2, 2, 2, 3, math.NaN(), math.NaN(), 3, 3, 4, 4, 4, math.NaN(), 4, 5, 5, math.NaN(), 5, 5, 1, 2, 3, math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 1, now32)}, 121 }, 122 Want: []float64{3, 4, 3, 4, 4, 3, math.NaN(), math.NaN()}, 123 From: now32, 124 Until: now32 + 35, 125 Name: "summarize(metric1,'5s','count')", 126 Step: 5, 127 Start: now32, 128 Stop: now32 + 40, 129 }, 130 { 131 Target: "summarize(metric1,'5s','p50')", 132 M: map[parser.MetricRequest][]*types.MetricData{ 133 {Metric: "metric1", From: now32, Until: now32 + 25*1}: {types.MakeMetricData("metric1", []float64{1, 0, 0, 0.5, 1, 2, 1, 1, 1.5, 2, 3, 2, 2, 1.5, 3, 4, 3, 2, 3, 4.5, 5, 5, 5, 5, 5}, 1, now32)}, 134 }, 135 Want: []float64{0.5, 1.5, 2, 3, 5, math.NaN()}, 136 From: now32, 137 Until: now32 + 25*1, 138 Name: "summarize(metric1,'5s','p50')", 139 Step: 5, 140 Start: now32, 141 Stop: now32 + 30, 142 }, 143 { 144 Target: "summarize(metric1,'5s','p25')", 145 M: map[parser.MetricRequest][]*types.MetricData{ 146 {Metric: "metric1", From: now32, Until: now32 + 25*1}: {types.MakeMetricData("metric1", []float64{1, 0, 0, 0.5, 1, 2, 1, 1, 1.5, 2, 3, 2, 2, 1.5, 3, 4, 3, 2, 3, 4.5, 5, 5, 5, 5, 5}, 1, now32)}, 147 }, 148 Want: []float64{0, 1, 2, 3, 5, math.NaN()}, 149 From: now32, 150 Until: now32 + 25*1, 151 Name: "summarize(metric1,'5s','p25')", 152 Step: 5, 153 Start: now32, 154 Stop: now32 + 30, 155 }, 156 { 157 Target: "summarize(metric1,'5s','p99.9')", 158 M: map[parser.MetricRequest][]*types.MetricData{ 159 {Metric: "metric1", From: now32, Until: now32 + 25*1}: {types.MakeMetricData("metric1", []float64{1, 0, 0, 0.5, 1, 2, 1, 1, 1.5, 2, 3, 2, 2, 1.5, 3, 4, 3, 2, 3, 4.5, 5, 5, 5, 5, 5}, 1, now32)}, 160 }, 161 Want: []float64{1, 2, 3, 4.498, 5, math.NaN()}, 162 From: now32, 163 Until: now32 + 25*1, 164 Name: "summarize(metric1,'5s','p99.9')", 165 Step: 5, 166 Start: now32, 167 Stop: now32 + 30, 168 }, 169 { 170 Target: "summarize(metric1,'5s','p100.1')", 171 M: map[parser.MetricRequest][]*types.MetricData{ 172 {Metric: "metric1", From: now32, Until: now32 + 25*1}: {types.MakeMetricData("metric1", []float64{1, 0, 0, 0.5, 1, 2, 1, 1, 1.5, 2, 3, 2, 2, 1.5, 3, 4, 3, 2, 3, 4.5, 5, 5, 5, 5, 5}, 1, now32)}, 173 }, 174 Want: []float64{math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN(), math.NaN()}, 175 From: now32, 176 Until: now32 + 25*1, 177 Name: "summarize(metric1,'5s','p100.1')", 178 Step: 5, 179 Start: now32, 180 Stop: now32 + 30, 181 }, 182 { 183 Target: "summarize(metric1,'1s','p50')", 184 M: map[parser.MetricRequest][]*types.MetricData{ 185 {Metric: "metric1", From: now32, Until: now32 + 25*1}: {types.MakeMetricData("metric1", []float64{1, 0, 0, 0.5, 1, 2, 1, 1, 1.5, 2, 3, 2, 2, 1.5, 3, 4, 3, 2, 3, 4.5, 5, 5, 5, 5, 5}, 1, now32)}, 186 }, 187 Want: []float64{1, 0, 0, 0.5, 1, 2, 1, 1, 1.5, 2, 3, 2, 2, 1.5, 3, 4, 3, 2, 3, 4.5, 5, 5, 5, 5, 5, math.NaN()}, 188 From: now32, 189 Until: now32 + 25*1, 190 Name: "summarize(metric1,'1s','p50')", 191 Step: 1, 192 Start: now32, 193 Stop: now32 + 25 + 1, 194 }, 195 { 196 Target: "summarize(metric1,'10min')", 197 M: map[parser.MetricRequest][]*types.MetricData{ 198 {Metric: "metric1", From: tenThirtyTwo, Until: tenThirty + 30*60}: {types.MakeMetricData("metric1", []float64{ 199 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 200 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 201 5, 5, 5, 5, 5}, 60, tenThirtyTwo)}, 202 }, 203 Want: []float64{11, 31, 33, math.NaN()}, 204 From: tenThirtyTwo, 205 Until: tenThirty + 30*60, 206 Name: "summarize(metric1,'10min')", 207 Step: 600, 208 Start: tenThirty, 209 Stop: (tenThirty + 30*60) - ((tenThirty + 30*60) % 600) + 600, // When alignToFrom is false, the new stop time is calculated with: stop - (stop % bucketSize) + bucketSize 210 }, 211 { 212 Target: "summarize(metric1,'10min','sum',true)", 213 M: map[parser.MetricRequest][]*types.MetricData{ 214 {Metric: "metric1", From: tenThirtyTwo, Until: tenThirtyTwo + 25*60}: {types.MakeMetricData("metric1", []float64{ 215 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 216 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 217 5, 5, 5, 5, 5}, 60, tenThirtyTwo)}, 218 }, 219 Want: []float64{15, 35, 25}, 220 From: tenThirtyTwo, 221 Until: tenThirtyTwo + 25*60, 222 Name: "summarize(metric1,'10min','sum',true)", 223 Step: 600, 224 Start: tenThirtyTwo, 225 Stop: tenThirtyTwo + (int64(math.Ceil(float64((tenThirtyTwo+25*60)-tenThirtyTwo)/float64(600))) * 600), // The end time for queries with alignToFrom set to true will have a stop time of start time + (number of buckets for results)*interval 226 }, 227 } 228 229 for _, tt := range tests { 230 eval := th.EvaluatorFromFunc(md[0].F) 231 th.TestSummarizeEvalExpr(t, eval, &tt) 232 } 233 } 234 235 func TestEvalSummarize1Minute(t *testing.T) { 236 tests := []th.SummarizeEvalTestItem{ 237 { 238 Target: "summarize(metric1,'1min','sum')", 239 M: map[parser.MetricRequest][]*types.MetricData{ 240 {Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)}, 241 }, 242 Want: []float64{1770, 5370, 8970, 12570, math.NaN()}, 243 From: 0, 244 Until: 240, 245 Name: "summarize(metric1,'1min','sum')", 246 Step: 60, 247 Start: 0, 248 Stop: 300, 249 }, 250 { 251 Target: "summarize(metric1,'1min','avg')", 252 M: map[parser.MetricRequest][]*types.MetricData{ 253 {Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)}, 254 }, 255 Want: []float64{29.5, 89.5, 149.5, 209.5, math.NaN()}, 256 From: 0, 257 Until: 240, 258 Name: "summarize(metric1,'1min','avg')", 259 Step: 60, 260 Start: 0, 261 Stop: 300, 262 }, 263 { 264 Target: "summarize(metric1,'1min','last')", 265 M: map[parser.MetricRequest][]*types.MetricData{ 266 {Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)}, 267 }, 268 Want: []float64{59, 119, 179, 239, math.NaN()}, 269 From: 0, 270 Until: 240, 271 Name: "summarize(metric1,'1min','last')", 272 Step: 60, 273 Start: 0, 274 Stop: 300, 275 }, 276 { 277 Target: "summarize(metric1,'1min','max')", 278 M: map[parser.MetricRequest][]*types.MetricData{ 279 {Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)}, 280 }, 281 Want: []float64{59, 119, 179, 239, math.NaN()}, 282 From: 0, 283 Until: 240, 284 Name: "summarize(metric1,'1min','max')", 285 Step: 60, 286 Start: 0, 287 Stop: 300, 288 }, 289 { 290 Target: "summarize(metric1,'1min','min')", 291 M: map[parser.MetricRequest][]*types.MetricData{ 292 {Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)}, 293 }, 294 Want: []float64{0, 60, 120, 180, math.NaN()}, 295 From: 0, 296 Until: 240, 297 Name: "summarize(metric1,'1min','min')", 298 Step: 60, 299 Start: 0, 300 Stop: 300, 301 }, 302 { 303 Target: "summarize(metric1,'1min','sum',true)", 304 M: map[parser.MetricRequest][]*types.MetricData{ 305 {Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)}, 306 }, 307 Want: []float64{1770, 5370, 8970, 12570}, 308 From: 0, 309 Until: 240, 310 Name: "summarize(metric1,'1min','sum',true)", 311 Step: 60, 312 Start: 0, 313 Stop: 240, 314 }, 315 { 316 Target: "summarize(metric1,'1min','avg',true)", 317 M: map[parser.MetricRequest][]*types.MetricData{ 318 {Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)}, 319 }, 320 Want: []float64{29.5, 89.5, 149.5, 209.5}, 321 From: 0, 322 Until: 240, 323 Name: "summarize(metric1,'1min','avg',true)", 324 Step: 60, 325 Start: 0, 326 Stop: 240, 327 }, 328 { 329 Target: "summarize(metric1,'1min','last',true)", 330 M: map[parser.MetricRequest][]*types.MetricData{ 331 {Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)}, 332 }, 333 Want: []float64{59, 119, 179, 239}, 334 From: 0, 335 Until: 240, 336 Name: "summarize(metric1,'1min','last',true)", 337 Step: 60, 338 Start: 0, 339 Stop: 240, 340 }, 341 { 342 Target: "summarize(metric1,'1min','max',true)", 343 M: map[parser.MetricRequest][]*types.MetricData{ 344 {Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)}, 345 }, 346 Want: []float64{59, 119, 179, 239}, 347 From: 0, 348 Until: 240, 349 Name: "summarize(metric1,'1min','max',true)", 350 Step: 60, 351 Start: 0, 352 Stop: 240, 353 }, 354 { 355 Target: "summarize(metric1,'1min','min',true)", 356 M: map[parser.MetricRequest][]*types.MetricData{ 357 {Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)}, 358 }, 359 Want: []float64{0, 60, 120, 180}, 360 From: 0, 361 Until: 240, 362 Name: "summarize(metric1,'1min','min',true)", 363 Step: 60, 364 Start: 0, 365 Stop: 240, 366 }, 367 } 368 369 for _, tt := range tests { 370 eval := th.EvaluatorFromFunc(md[0].F) 371 th.TestSummarizeEvalExpr(t, eval, &tt) 372 } 373 } 374 375 func generateValues(start, stop, step int64) (values []float64) { 376 for i := start; i < stop; i += step { 377 values = append(values, float64(i)) 378 } 379 return 380 }