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  }