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

     1  package smartSummarize
     2  
     3  import (
     4  	"math"
     5  	"strconv"
     6  	"testing"
     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 TestSummarizeEmptyData(t *testing.T) {
    26  	tests := []th.EvalTestItem{
    27  		{
    28  			"smartSummarize(metric1,'1hour','sum','1y')",
    29  			map[parser.MetricRequest][]*types.MetricData{
    30  				{Metric: "foo.bar", From: 0, Until: 1}: {},
    31  			},
    32  			[]*types.MetricData{},
    33  		},
    34  	}
    35  
    36  	for _, tt := range tests {
    37  		testName := tt.Target
    38  		t.Run(testName, func(t *testing.T) {
    39  			eval := th.EvaluatorFromFunc(md[0].F)
    40  			th.TestEvalExpr(t, eval, &tt)
    41  		})
    42  	}
    43  
    44  }
    45  
    46  func TestEvalSummarize(t *testing.T) {
    47  	tests := []th.SummarizeEvalTestItem{
    48  		{
    49  			Target: "smartSummarize(metric1,'1hour','sum','1y')",
    50  			M: map[parser.MetricRequest][]*types.MetricData{
    51  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
    52  			},
    53  			Want:  []float64{6478200, 19438200, 32398200, 45358200},
    54  			From:  0,
    55  			Until: 14400,
    56  			Name:  "smartSummarize(metric1,'1hour','sum','1y')",
    57  			Step:  3600,
    58  			Start: 0,
    59  			Stop:  14400,
    60  		},
    61  		{
    62  			Target: "smartSummarize(metric1,'1hour','sum','y')",
    63  			M: map[parser.MetricRequest][]*types.MetricData{
    64  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
    65  			},
    66  			Want:  []float64{6478200, 19438200, 32398200, 45358200},
    67  			Name:  "smartSummarize(metric1,'1hour','sum','y')",
    68  			From:  0,
    69  			Until: 14400,
    70  			Step:  3600,
    71  			Start: 0,
    72  			Stop:  14400,
    73  		},
    74  		{
    75  			Target: "smartSummarize(metric1,'1hour','sum','month')",
    76  			M: map[parser.MetricRequest][]*types.MetricData{
    77  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
    78  			},
    79  			Want:  []float64{6478200, 19438200, 32398200, 45358200},
    80  			Name:  "smartSummarize(metric1,'1hour','sum','month')",
    81  			From:  0,
    82  			Until: 14400,
    83  			Step:  3600,
    84  			Start: 0,
    85  			Stop:  14400,
    86  		},
    87  		{
    88  			Target: "smartSummarize(metric1,'1hour','sum','1month')",
    89  			M: map[parser.MetricRequest][]*types.MetricData{
    90  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
    91  			},
    92  			Want:  []float64{6478200, 19438200, 32398200, 45358200},
    93  			Name:  "smartSummarize(metric1,'1hour','sum','1month')",
    94  			From:  0,
    95  			Until: 14400,
    96  			Step:  3600,
    97  			Start: 0,
    98  			Stop:  14400,
    99  		},
   100  		{
   101  			Target: "smartSummarize(metric1,'1minute','sum','minute')",
   102  			M: map[parser.MetricRequest][]*types.MetricData{
   103  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   104  			},
   105  			Want:  []float64{1770, 5370, 8970, 12570},
   106  			From:  0,
   107  			Until: 240,
   108  			Name:  "smartSummarize(metric1,'1minute','sum','minute')",
   109  			Step:  60,
   110  			Start: 0,
   111  			Stop:  240,
   112  		},
   113  		{
   114  			Target: "smartSummarize(metric1,'1minute','sum','1minute')",
   115  			M: map[parser.MetricRequest][]*types.MetricData{
   116  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   117  			},
   118  			Want:  []float64{1770, 5370, 8970, 12570},
   119  			Name:  "smartSummarize(metric1,'1minute','sum','1minute')",
   120  			From:  0,
   121  			Until: 240,
   122  			Step:  60,
   123  			Start: 0,
   124  			Stop:  240,
   125  		},
   126  		{
   127  			Target: "smartSummarize(metric1,'1minute','avg','minute')",
   128  			M: map[parser.MetricRequest][]*types.MetricData{
   129  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   130  			},
   131  			Want:  []float64{29.5, 89.5, 149.5, 209.5},
   132  			From:  0,
   133  			Until: 240,
   134  			Name:  "smartSummarize(metric1,'1minute','avg','minute')",
   135  			Step:  60,
   136  			Start: 0,
   137  			Stop:  240,
   138  		},
   139  		{
   140  			Target: "smartSummarize(metric1,'1minute','last','minute')",
   141  			M: map[parser.MetricRequest][]*types.MetricData{
   142  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   143  			},
   144  			Want:  []float64{59, 119, 179, 239},
   145  			From:  0,
   146  			Until: 240,
   147  			Name:  "smartSummarize(metric1,'1minute','last','minute')",
   148  			Step:  60,
   149  			Start: 0,
   150  			Stop:  240,
   151  		},
   152  		{
   153  			Target: "smartSummarize(metric1,'1d','sum','days')",
   154  			M: map[parser.MetricRequest][]*types.MetricData{
   155  				{Metric: "metric1", From: 0, Until: 86400}: {types.MakeMetricData("metric1", generateValues(0, 86400, 60), 60, 0)},
   156  			},
   157  			Want:  []float64{62164800},
   158  			From:  0,
   159  			Until: 86400,
   160  			Name:  "smartSummarize(metric1,'1d','sum','days')",
   161  			Step:  86400,
   162  			Start: 0,
   163  			Stop:  86400,
   164  		},
   165  		{
   166  			Target: "smartSummarize(metric1,'1minute','sum','seconds')",
   167  			M: map[parser.MetricRequest][]*types.MetricData{
   168  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   169  			},
   170  			Want:  []float64{1770, 5370, 8970, 12570},
   171  			From:  0,
   172  			Until: 240,
   173  			Name:  "smartSummarize(metric1,'1minute','sum','seconds')",
   174  			Step:  60,
   175  			Start: 0,
   176  			Stop:  240,
   177  		},
   178  		{
   179  			Target: "smartSummarize(metric1,'1hour','max','hours')",
   180  			M: map[parser.MetricRequest][]*types.MetricData{
   181  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   182  			},
   183  			Want:  []float64{3599, 7199, 10799, 14399},
   184  			From:  0,
   185  			Until: 14400,
   186  			Name:  "smartSummarize(metric1,'1hour','max','hours')",
   187  			Step:  3600,
   188  			Start: 0,
   189  			Stop:  14400,
   190  		},
   191  		{
   192  			Target: "smartSummarize(metric1,'6m','sum', 'minutes')", // Test having a smaller interval than the data's step
   193  			M: map[parser.MetricRequest][]*types.MetricData{
   194  				{Metric: "metric1", From: 1410345000, Until: 1410345000 + 3*600}: {types.MakeMetricData("metric1", []float64{
   195  					2, 4, 6}, 600, 1410345000)},
   196  			},
   197  			Want:  []float64{2, 4, math.NaN(), 6, math.NaN()},
   198  			From:  1410345000,
   199  			Until: 1410345000 + 3*600,
   200  			Name:  "smartSummarize(metric1,'6m','sum','minutes')",
   201  			Step:  360,
   202  			Start: 1410345000,
   203  			Stop:  1410345000 + 3*600,
   204  		},
   205  		{
   206  			Target: "smartSummarize(metric2,'2minute','sum')",
   207  			M: map[parser.MetricRequest][]*types.MetricData{
   208  				{Metric: "metric2", From: 0, Until: 300}: {types.MakeMetricData("metric2", []float64{1, 2, 3, 4}, 60, 0)},
   209  			},
   210  			Want:  []float64{3, 7},
   211  			From:  0,
   212  			Until: 300,
   213  			Name:  "smartSummarize(metric2,'2minute','sum')",
   214  			Step:  120,
   215  			Start: 0,
   216  			Stop:  240,
   217  		},
   218  		{
   219  			// This test case is to check that the stop time of the results will be updated to the final bucket's lower bound
   220  			// if it is smaller than the final bucket's upper bound
   221  			Target: "smartSummarize(metric1,'5s','sum')",
   222  			M: map[parser.MetricRequest][]*types.MetricData{
   223  				{Metric: "metric1", From: 0, Until: 243}: {types.MakeMetricData("metric1", generateValues(0, 243, 3), 3, 0)},
   224  			},
   225  			Want:  []float64{3, 15, 12, 33, 45, 27, 63, 75, 42, 93, 105, 57, 123, 135, 72, 153, 165, 87, 183, 195, 102, 213, 225, 117, 243, 255, 132, 273, 285, 147, 303, 315, 162, 333, 345, 177, 363, 375, 192, 393, 405, 207, 423, 435, 222, 453, 465, 237, 240},
   226  			Name:  "smartSummarize(metric1,'5s','sum')",
   227  			From:  0,
   228  			Until: 243,
   229  			Step:  5,
   230  			Start: 0,
   231  			Stop:  245,
   232  		},
   233  	}
   234  
   235  	for _, tt := range tests {
   236  		eval := th.EvaluatorFromFunc(md[0].F)
   237  		th.TestSummarizeEvalExpr(t, eval, &tt)
   238  	}
   239  }
   240  
   241  func TestSmartSummarizeAlignTo1Year(t *testing.T) {
   242  	tests := []th.SummarizeEvalTestItem{
   243  		{
   244  			Target: "smartSummarize(metric1,'1hour','sum','1y')",
   245  			M: map[parser.MetricRequest][]*types.MetricData{
   246  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   247  			},
   248  			Want:  []float64{6478200, 19438200, 32398200, 45358200},
   249  			From:  1800,
   250  			Until: 14400,
   251  			Name:  "smartSummarize(metric1,'1hour','sum','1y')",
   252  			Step:  3600,
   253  			Start: 0,
   254  			Stop:  14400,
   255  		},
   256  		{
   257  			Target: "smartSummarize(metric1,'1hour','avg','1y')",
   258  			M: map[parser.MetricRequest][]*types.MetricData{
   259  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   260  			},
   261  			Want:  []float64{1799.5, 5399.5, 8999.5, 12599.5},
   262  			From:  1800,
   263  			Until: 14400,
   264  			Name:  "smartSummarize(metric1,'1hour','avg','1y')",
   265  			Step:  3600,
   266  			Start: 0,
   267  			Stop:  14400,
   268  		},
   269  		{
   270  			Target: "smartSummarize(metric1,'1hour','last','1y')",
   271  			M: map[parser.MetricRequest][]*types.MetricData{
   272  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   273  			},
   274  			Want:  []float64{3599, 7199, 10799, 14399},
   275  			From:  1800,
   276  			Until: 14400,
   277  			Name:  "smartSummarize(metric1,'1hour','last','1y')",
   278  			Step:  3600,
   279  			Start: 0,
   280  			Stop:  14400,
   281  		},
   282  		{
   283  			Target: "smartSummarize(metric1,'1hour','max','1y')",
   284  			M: map[parser.MetricRequest][]*types.MetricData{
   285  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   286  			},
   287  			Want:  []float64{3599, 7199, 10799, 14399},
   288  			From:  1800,
   289  			Until: 14400,
   290  			Name:  "smartSummarize(metric1,'1hour','max','1y')",
   291  			Step:  3600,
   292  			Start: 0,
   293  			Stop:  14400,
   294  		},
   295  		{
   296  			Target: "smartSummarize(metric1,'1hour','min','1y')",
   297  			M: map[parser.MetricRequest][]*types.MetricData{
   298  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   299  			},
   300  			Want:  []float64{0, 3600, 7200, 10800},
   301  			From:  1800,
   302  			Until: 14400,
   303  			Name:  "smartSummarize(metric1,'1hour','min','1y')",
   304  			Step:  3600,
   305  			Start: 0,
   306  			Stop:  14400,
   307  		},
   308  	}
   309  
   310  	for _, tt := range tests {
   311  		eval := th.EvaluatorFromFunc(md[0].F)
   312  		th.TestSummarizeEvalExpr(t, eval, &tt)
   313  	}
   314  }
   315  
   316  func TestSmartSummarizeAlignToMonths(t *testing.T) {
   317  	tests := []th.SummarizeEvalTestItem{
   318  		{
   319  			Target: "smartSummarize(metric1,'1hour','sum','months')",
   320  			M: map[parser.MetricRequest][]*types.MetricData{
   321  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   322  			},
   323  			Want:  []float64{6478200, 19438200, 32398200, 45358200},
   324  			From:  1800,
   325  			Until: 14400,
   326  			Name:  "smartSummarize(metric1,'1hour','sum','months')",
   327  			Step:  3600,
   328  			Start: 0,
   329  			Stop:  14400,
   330  		},
   331  		{
   332  			Target: "smartSummarize(metric1,'1hour','avg','months')",
   333  			M: map[parser.MetricRequest][]*types.MetricData{
   334  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   335  			},
   336  			Want:  []float64{1799.5, 5399.5, 8999.5, 12599.5},
   337  			Name:  "smartSummarize(metric1,'1hour','avg','months')",
   338  			From:  1800,
   339  			Until: 14400,
   340  			Step:  3600,
   341  			Start: 0,
   342  			Stop:  14400,
   343  		},
   344  		{
   345  			Target: "smartSummarize(metric1,'1hour','last','months')",
   346  			M: map[parser.MetricRequest][]*types.MetricData{
   347  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   348  			},
   349  			Want:  []float64{3599, 7199, 10799, 14399},
   350  			From:  1800,
   351  			Until: 14400,
   352  			Name:  "smartSummarize(metric1,'1hour','last','months')",
   353  			Step:  3600,
   354  			Start: 0,
   355  			Stop:  14400,
   356  		},
   357  		{
   358  			Target: "smartSummarize(metric1,'1hour','max','months')",
   359  			M: map[parser.MetricRequest][]*types.MetricData{
   360  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   361  			},
   362  			Want:  []float64{3599, 7199, 10799, 14399},
   363  			From:  1800,
   364  			Until: 14400,
   365  			Name:  "smartSummarize(metric1,'1hour','max','months')",
   366  			Step:  3600,
   367  			Start: 0,
   368  			Stop:  14400,
   369  		},
   370  		{
   371  			Target: "smartSummarize(metric1,'1hour','min','months')",
   372  			M: map[parser.MetricRequest][]*types.MetricData{
   373  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   374  			},
   375  			Want:  []float64{0, 3600, 7200, 10800},
   376  			From:  1800,
   377  			Until: 14400,
   378  			Name:  "smartSummarize(metric1,'1hour','min','months')",
   379  			Step:  3600,
   380  			Start: 0,
   381  			Stop:  14400,
   382  		},
   383  	}
   384  
   385  	for _, tt := range tests {
   386  		eval := th.EvaluatorFromFunc(md[0].F)
   387  		th.TestSummarizeEvalExpr(t, eval, &tt)
   388  	}
   389  }
   390  
   391  func TestSmartSummarizeAlignToWeeksThursday(t *testing.T) {
   392  	tests := []th.SummarizeEvalTestItem{
   393  		{
   394  			Target: "smartSummarize(metric1,'4hours','sum','weeks4')",
   395  			M: map[parser.MetricRequest][]*types.MetricData{
   396  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   397  			},
   398  			Want:  []float64{103672800},
   399  			From:  174600,
   400  			Until: 14400,
   401  			Name:  "smartSummarize(metric1,'4hours','sum','weeks4')",
   402  			Step:  14400,
   403  			Start: 0,
   404  			Stop:  14400,
   405  		},
   406  		{
   407  			Target: "smartSummarize(metric1,'4hours','avg','weeks4')",
   408  			M: map[parser.MetricRequest][]*types.MetricData{
   409  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   410  			},
   411  			Want:  []float64{7199.5},
   412  			From:  174600,
   413  			Until: 14400,
   414  			Name:  "smartSummarize(metric1,'4hours','avg','weeks4')",
   415  			Step:  14400,
   416  			Start: 0,
   417  			Stop:  14400,
   418  		},
   419  		{
   420  			Target: "smartSummarize(metric1,'4hours','last','weeks4')",
   421  			M: map[parser.MetricRequest][]*types.MetricData{
   422  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   423  			},
   424  			Want:  []float64{14399},
   425  			From:  174600,
   426  			Until: 14400,
   427  			Name:  "smartSummarize(metric1,'4hours','last','weeks4')",
   428  			Step:  14400,
   429  			Start: 0,
   430  			Stop:  14400,
   431  		},
   432  		{
   433  			Target: "smartSummarize(metric1,'4hours','max','weeks4')",
   434  			M: map[parser.MetricRequest][]*types.MetricData{
   435  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   436  			},
   437  			Want:  []float64{14399},
   438  			From:  174600,
   439  			Until: 14400,
   440  			Name:  "smartSummarize(metric1,'4hours','max','weeks4')",
   441  			Step:  14400,
   442  			Start: 0,
   443  			Stop:  14400,
   444  		},
   445  		{
   446  			Target: "smartSummarize(metric1,'4hours','min','weeks4')",
   447  			M: map[parser.MetricRequest][]*types.MetricData{
   448  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   449  			},
   450  			Want:  []float64{0},
   451  			From:  174600,
   452  			Until: 14400,
   453  			Name:  "smartSummarize(metric1,'4hours','min','weeks4')",
   454  			Step:  14400,
   455  			Start: 0,
   456  			Stop:  14400,
   457  		},
   458  	}
   459  
   460  	for _, tt := range tests {
   461  		eval := th.EvaluatorFromFunc(md[0].F)
   462  		th.TestSummarizeEvalExpr(t, eval, &tt)
   463  	}
   464  }
   465  
   466  func TestSmartSummarizeAlignToDays(t *testing.T) {
   467  	tests := []th.SummarizeEvalTestItem{
   468  		{
   469  			Target: "smartSummarize(metric1,'1day','sum','days')",
   470  			M: map[parser.MetricRequest][]*types.MetricData{
   471  				{Metric: "metric1", From: 0, Until: 86400}: {types.MakeMetricData("metric1", generateValues(0, 86400, 60), 60, 0)},
   472  			},
   473  			Want:  []float64{62164800},
   474  			From:  86399,
   475  			Until: 86400,
   476  			Name:  "smartSummarize(metric1,'1day','sum','days')",
   477  			Step:  86400,
   478  			Start: 0,
   479  			Stop:  86400,
   480  		},
   481  		{
   482  			Target: "smartSummarize(metric1,'1day','avg','days')",
   483  			M: map[parser.MetricRequest][]*types.MetricData{
   484  				{Metric: "metric1", From: 0, Until: 86400}: {types.MakeMetricData("metric1", generateValues(0, 86400, 60), 60, 0)},
   485  			},
   486  			Want:  []float64{43170.0},
   487  			From:  86399,
   488  			Until: 86400,
   489  			Name:  "smartSummarize(metric1,'1day','avg','days')",
   490  			Step:  86400,
   491  			Start: 0,
   492  			Stop:  86400,
   493  		},
   494  		{
   495  			Target: "smartSummarize(metric1,'1day','last','days')",
   496  			M: map[parser.MetricRequest][]*types.MetricData{
   497  				{Metric: "metric1", From: 0, Until: 86400}: {types.MakeMetricData("metric1", generateValues(0, 86400, 60), 60, 0)},
   498  			},
   499  			Want:  []float64{86340},
   500  			From:  86399,
   501  			Until: 86400,
   502  			Name:  "smartSummarize(metric1,'1day','last','days')",
   503  			Step:  86400,
   504  			Start: 0,
   505  			Stop:  86400,
   506  		},
   507  		{
   508  			Target: "smartSummarize(metric1,'1day','max','days')",
   509  			M: map[parser.MetricRequest][]*types.MetricData{
   510  				{Metric: "metric1", From: 0, Until: 86400}: {types.MakeMetricData("metric1", generateValues(0, 86400, 60), 60, 0)},
   511  			},
   512  			Want:  []float64{86340},
   513  			From:  86399,
   514  			Until: 86400,
   515  			Name:  "smartSummarize(metric1,'1day','max','days')",
   516  			Step:  86400,
   517  			Start: 0,
   518  			Stop:  86400,
   519  		},
   520  		{
   521  			Target: "smartSummarize(metric1,'1day','min','days')",
   522  			M: map[parser.MetricRequest][]*types.MetricData{
   523  				{Metric: "metric1", From: 0, Until: 86400}: {types.MakeMetricData("metric1", generateValues(0, 86400, 60), 60, 0)},
   524  			},
   525  			Want:  []float64{0},
   526  			From:  86399,
   527  			Until: 86400,
   528  			Name:  "smartSummarize(metric1,'1day','min','days')",
   529  			Step:  86400,
   530  			Start: 0,
   531  			Stop:  86400,
   532  		},
   533  	}
   534  
   535  	for _, tt := range tests {
   536  		eval := th.EvaluatorFromFunc(md[0].F)
   537  		th.TestSummarizeEvalExpr(t, eval, &tt)
   538  	}
   539  }
   540  
   541  func TestSmartSummarizeAlignToHours(t *testing.T) {
   542  	tests := []th.SummarizeEvalTestItem{
   543  		{
   544  			Target: "smartSummarize(metric1,'1hour','sum','hours')",
   545  			M: map[parser.MetricRequest][]*types.MetricData{
   546  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   547  			},
   548  			Want:  []float64{6478200, 19438200, 32398200, 45358200},
   549  			From:  1800,
   550  			Until: 14400,
   551  			Name:  "smartSummarize(metric1,'1hour','sum','hours')",
   552  			Step:  3600,
   553  			Start: 0,
   554  			Stop:  14400,
   555  		},
   556  		{
   557  			Target: "smartSummarize(metric1,'1hour','avg','hours')",
   558  			M: map[parser.MetricRequest][]*types.MetricData{
   559  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   560  			},
   561  			Want:  []float64{1799.5, 5399.5, 8999.5, 12599.5},
   562  			From:  1800,
   563  			Until: 14400,
   564  			Name:  "smartSummarize(metric1,'1hour','avg','hours')",
   565  			Step:  3600,
   566  			Start: 0,
   567  			Stop:  14400,
   568  		},
   569  		{
   570  			Target: "smartSummarize(metric1,'1hour','last','hours')",
   571  			M: map[parser.MetricRequest][]*types.MetricData{
   572  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   573  			},
   574  			Want:  []float64{3599, 7199, 10799, 14399},
   575  			From:  1800,
   576  			Until: 14400,
   577  			Name:  "smartSummarize(metric1,'1hour','last','hours')",
   578  			Step:  3600,
   579  			Start: 0,
   580  			Stop:  14400,
   581  		},
   582  		{
   583  			Target: "smartSummarize(metric1,'1hour','max','hours')",
   584  			M: map[parser.MetricRequest][]*types.MetricData{
   585  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   586  			},
   587  			Want:  []float64{3599, 7199, 10799, 14399},
   588  			From:  1800,
   589  			Until: 14400,
   590  			Name:  "smartSummarize(metric1,'1hour','max','hours')",
   591  			Step:  3600,
   592  			Start: 0,
   593  			Stop:  14400,
   594  		},
   595  		{
   596  			Target: "smartSummarize(metric1,'1hour','min','hours')",
   597  			M: map[parser.MetricRequest][]*types.MetricData{
   598  				{Metric: "metric1", From: 0, Until: 14400}: {types.MakeMetricData("metric1", generateValues(0, 14400, 1), 1, 0)},
   599  			},
   600  			Want:  []float64{0, 3600, 7200, 10800},
   601  			From:  1800,
   602  			Until: 14400,
   603  			Name:  "smartSummarize(metric1,'1hour','min','hours')",
   604  			Step:  3600,
   605  			Start: 0,
   606  			Stop:  14400,
   607  		},
   608  	}
   609  
   610  	for _, tt := range tests {
   611  		eval := th.EvaluatorFromFunc(md[0].F)
   612  		th.TestSummarizeEvalExpr(t, eval, &tt)
   613  	}
   614  }
   615  
   616  func TestSmartSummarizeAlignToMinutes(t *testing.T) {
   617  	tests := []th.SummarizeEvalTestItem{
   618  		{
   619  			Target: "smartSummarize(metric1,'1minute','sum','minutes')",
   620  			M: map[parser.MetricRequest][]*types.MetricData{
   621  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   622  			},
   623  			Want:  []float64{1770, 5370, 8970, 12570},
   624  			From:  59,
   625  			Until: 240,
   626  			Name:  "smartSummarize(metric1,'1minute','sum','minutes')",
   627  			Step:  60,
   628  			Start: 0,
   629  			Stop:  240,
   630  		},
   631  		{
   632  			Target: "smartSummarize(metric1,'1minute','avg','minutes')",
   633  			M: map[parser.MetricRequest][]*types.MetricData{
   634  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   635  			},
   636  			Want:  []float64{29.5, 89.5, 149.5, 209.5},
   637  			From:  59,
   638  			Until: 240,
   639  			Name:  "smartSummarize(metric1,'1minute','avg','minutes')",
   640  			Step:  60,
   641  			Start: 0,
   642  			Stop:  240,
   643  		},
   644  		{
   645  			Target: "smartSummarize(metric1,'1minute','last','minutes')",
   646  			M: map[parser.MetricRequest][]*types.MetricData{
   647  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   648  			},
   649  			Want:  []float64{59, 119, 179, 239},
   650  			From:  59,
   651  			Until: 240,
   652  			Name:  "smartSummarize(metric1,'1minute','last','minutes')",
   653  			Step:  60,
   654  			Start: 0,
   655  			Stop:  240,
   656  		},
   657  		{
   658  			Target: "smartSummarize(metric1,'1minute','max','minutes')",
   659  			M: map[parser.MetricRequest][]*types.MetricData{
   660  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   661  			},
   662  			Want:  []float64{59, 119, 179, 239},
   663  			From:  59,
   664  			Until: 240,
   665  			Name:  "smartSummarize(metric1,'1minute','max','minutes')",
   666  			Step:  60,
   667  			Start: 0,
   668  			Stop:  240,
   669  		},
   670  		{
   671  			Target: "smartSummarize(metric1,'1minute','min','minutes')",
   672  			M: map[parser.MetricRequest][]*types.MetricData{
   673  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   674  			},
   675  			Want:  []float64{0, 60, 120, 180},
   676  			From:  59,
   677  			Until: 240,
   678  			Name:  "smartSummarize(metric1,'1minute','min','minutes')",
   679  			Step:  60,
   680  			Start: 0,
   681  			Stop:  240,
   682  		},
   683  	}
   684  
   685  	for _, tt := range tests {
   686  		eval := th.EvaluatorFromFunc(md[0].F)
   687  		th.TestSummarizeEvalExpr(t, eval, &tt)
   688  	}
   689  }
   690  
   691  func TestSmartSummarizeAlignToSeconds(t *testing.T) {
   692  	tests := []th.SummarizeEvalTestItem{
   693  		{
   694  			Target: "smartSummarize(metric1,'1minute','sum','seconds')",
   695  			M: map[parser.MetricRequest][]*types.MetricData{
   696  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   697  			},
   698  			Want:  []float64{1770, 5370, 8970, 12570},
   699  			From:  0,
   700  			Until: 240,
   701  			Name:  "smartSummarize(metric1,'1minute','sum','seconds')",
   702  			Step:  60,
   703  			Start: 0,
   704  			Stop:  240,
   705  		},
   706  		{
   707  			Target: "smartSummarize(metric1,'1minute','avg','seconds')",
   708  			M: map[parser.MetricRequest][]*types.MetricData{
   709  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   710  			},
   711  			Want:  []float64{29.5, 89.5, 149.5, 209.5},
   712  			From:  0,
   713  			Until: 240,
   714  			Name:  "smartSummarize(metric1,'1minute','avg','seconds')",
   715  			Step:  60,
   716  			Start: 0,
   717  			Stop:  240,
   718  		},
   719  		{
   720  			Target: "smartSummarize(metric1,'1minute','last','seconds')",
   721  			M: map[parser.MetricRequest][]*types.MetricData{
   722  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   723  			},
   724  			Want:  []float64{59, 119, 179, 239},
   725  			From:  0,
   726  			Until: 240,
   727  			Name:  "smartSummarize(metric1,'1minute','last','seconds')",
   728  			Step:  60,
   729  			Start: 0,
   730  			Stop:  240,
   731  		},
   732  		{
   733  			Target: "smartSummarize(metric1,'1minute','max','seconds')",
   734  			M: map[parser.MetricRequest][]*types.MetricData{
   735  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   736  			},
   737  			Want:  []float64{59, 119, 179, 239},
   738  			From:  0,
   739  			Until: 240,
   740  			Name:  "smartSummarize(metric1,'1minute','max','seconds')",
   741  			Step:  60,
   742  			Start: 0,
   743  			Stop:  240,
   744  		},
   745  		{
   746  			Target: "smartSummarize(metric1,'1minute','min','seconds')",
   747  			M: map[parser.MetricRequest][]*types.MetricData{
   748  				{Metric: "metric1", From: 0, Until: 240}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   749  			},
   750  			Want:  []float64{0, 60, 120, 180},
   751  			From:  0,
   752  			Until: 240,
   753  			Name:  "smartSummarize(metric1,'1minute','min','seconds')",
   754  			Step:  60,
   755  			Start: 0,
   756  			Stop:  240,
   757  		},
   758  	}
   759  
   760  	for _, tt := range tests {
   761  		eval := th.EvaluatorFromFunc(md[0].F)
   762  		th.TestSummarizeEvalExpr(t, eval, &tt)
   763  	}
   764  }
   765  
   766  func TestFunctionUseNameWithWildcards(t *testing.T) {
   767  	tests := []th.MultiReturnEvalTestItem{
   768  		{
   769  			"smartSummarize(metric1.*,'1minute','last')",
   770  			map[parser.MetricRequest][]*types.MetricData{
   771  				{Metric: "metric1.*", From: 0, Until: 1}: {
   772  					types.MakeMetricData("metric1.foo", generateValues(0, 240, 1), 1, 0),
   773  					types.MakeMetricData("metric1.bar", generateValues(0, 240, 1), 1, 0),
   774  				},
   775  			},
   776  			"smartSummarize",
   777  			map[string][]*types.MetricData{
   778  				"smartSummarize(metric1.foo,'1minute','last')": {types.MakeMetricData("smartSummarize(metric1.foo,'1minute','last')",
   779  					[]float64{59, 119, 179, 239}, 60, 0).SetTag("smartSummarize", "60").SetTag("smartSummarizeFunction", "last")},
   780  				"smartSummarize(metric1.bar,'1minute','last')": {types.MakeMetricData("smartSummarize(metric1.bar,'1minute','last')",
   781  					[]float64{59, 119, 179, 239}, 60, 0).SetTag("smartSummarize", "60").SetTag("smartSummarizeFunction", "last")},
   782  			},
   783  		},
   784  	}
   785  
   786  	for _, tt := range tests {
   787  		testName := tt.Target
   788  		t.Run(testName, func(t *testing.T) {
   789  			eval := th.EvaluatorFromFunc(md[0].F)
   790  			th.TestMultiReturnEvalExpr(t, eval, &tt)
   791  		})
   792  	}
   793  }
   794  
   795  func TestSmartSummarizeErrors(t *testing.T) {
   796  	tests := []th.EvalTestItemWithError{
   797  		{
   798  			Target: "smartSummarize(metric1,'-1minute','sum','minute')", // Test to make sure error occurs when a negative interval is used
   799  			M: map[parser.MetricRequest][]*types.MetricData{
   800  				{Metric: "metric1", From: 0, Until: 1}: {types.MakeMetricData("metric1", generateValues(0, 240, 1), 1, 0)},
   801  			},
   802  			Error: parser.ErrInvalidInterval,
   803  		},
   804  	}
   805  
   806  	for n, tt := range tests {
   807  		testName := tt.Target
   808  		t.Run(testName+"#"+strconv.Itoa(n), func(t *testing.T) {
   809  			eval := th.EvaluatorFromFunc(md[0].F)
   810  			th.TestEvalExprWithError(t, eval, &tt)
   811  		})
   812  	}
   813  }
   814  
   815  func generateValues(start, stop, step int64) (values []float64) {
   816  	for i := start; i < stop; i += step {
   817  		values = append(values, float64(i))
   818  	}
   819  	return
   820  }