github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/query/graphite/common/aggregation_test.go (about)

     1  // Copyright (c) 2019 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package common
    22  
    23  import (
    24  	"fmt"
    25  	"math"
    26  	"testing"
    27  	"time"
    28  
    29  	"github.com/m3db/m3/src/query/graphite/ts"
    30  
    31  	"github.com/stretchr/testify/require"
    32  )
    33  
    34  func TestRangeOfSeries(t *testing.T) {
    35  	ctx, input := NewConsolidationTestSeries(consolidationStartTime, consolidationEndTime, 30*time.Second)
    36  	defer ctx.Close()
    37  
    38  	in := ts.SeriesList{Values: input}
    39  
    40  	expectedStart := ctx.StartTime.Add(-30 * time.Second)
    41  	expectedStep := 10000
    42  	rangeSeries, err := Range(ctx, in, func(series ts.SeriesList) string {
    43  		return "woot"
    44  	})
    45  	require.Nil(t, err)
    46  
    47  	expected := TestSeries{
    48  		Name: "woot",
    49  		Data: []float64{0, 0, 0, 12, 12, 12, 14, 14, 14, 0, 0, 0},
    50  	}
    51  
    52  	CompareOutputsAndExpected(t, expectedStep, expectedStart, []TestSeries{expected}, []*ts.Series{rangeSeries})
    53  }
    54  
    55  func TestAggregationFunctions(t *testing.T) {
    56  	type input struct {
    57  		functionName string
    58  		values       []float64
    59  	}
    60  
    61  	type output struct {
    62  		aggregatedValue float64
    63  		nans            int
    64  	}
    65  
    66  	tests := []struct {
    67  		input  input
    68  		output output
    69  	}{
    70  		{
    71  			input: input{
    72  				"sum",
    73  				[]float64{1, 2, 3, math.NaN()},
    74  			},
    75  			output: output{
    76  				6,
    77  				1,
    78  			},
    79  		},
    80  		{
    81  			input: input{
    82  				"avg",
    83  				[]float64{1, 2, 3, math.NaN()},
    84  			},
    85  			output: output{
    86  				2,
    87  				1,
    88  			},
    89  		},
    90  		{
    91  			input: input{
    92  				"max",
    93  				[]float64{1, 2, 3, math.NaN()},
    94  			},
    95  			output: output{
    96  				3,
    97  				1,
    98  			},
    99  		},
   100  		{
   101  			input: input{
   102  				"min",
   103  				[]float64{1, 2, 3, math.NaN()},
   104  			},
   105  			output: output{
   106  				1,
   107  				1,
   108  			},
   109  		},
   110  		{
   111  			input: input{
   112  				"median",
   113  				[]float64{1, 2, 3, math.NaN()},
   114  			},
   115  			output: output{
   116  				2,
   117  				1,
   118  			},
   119  		},
   120  		{
   121  			input: input{
   122  				"diff",
   123  				[]float64{1, 2, 3, math.NaN()},
   124  			},
   125  			output: output{
   126  				-4,
   127  				1,
   128  			},
   129  		},
   130  		{
   131  			input: input{
   132  				"stddev",
   133  				[]float64{1, 2, 3, math.NaN()},
   134  			},
   135  			output: output{
   136  				math.Sqrt(float64(2) / float64(3)),
   137  				1,
   138  			},
   139  		},
   140  		{
   141  			input: input{
   142  				"range",
   143  				[]float64{1, 2, 3, math.NaN()},
   144  			},
   145  			output: output{
   146  				2,
   147  				1,
   148  			},
   149  		},
   150  		{
   151  			input: input{
   152  				"multiply",
   153  				[]float64{1, 2, 3, math.NaN()},
   154  			},
   155  			output: output{
   156  				1 * 2 * 3,
   157  				1,
   158  			},
   159  		},
   160  		{
   161  			input: input{
   162  				"last",
   163  				[]float64{1, 2, 3, math.NaN()},
   164  			},
   165  			output: output{
   166  				3,
   167  				1,
   168  			},
   169  		},
   170  		{
   171  			input: input{
   172  				"count",
   173  				[]float64{1, 2, 3, math.NaN()},
   174  			},
   175  			output: output{
   176  				3,
   177  				1,
   178  			},
   179  		},
   180  	}
   181  
   182  	for _, test := range tests {
   183  		safeAggFn, ok := SafeAggregationFns[test.input.functionName]
   184  		require.True(t, ok)
   185  		aggregatedValue, nans, ok := safeAggFn(test.input.values)
   186  		require.True(t, ok)
   187  		require.Equal(t, test.output.aggregatedValue, aggregatedValue,
   188  			fmt.Sprintf("aggregation result for %v should be equal", test.input.functionName))
   189  		require.Equal(t, test.output.nans, nans)
   190  	}
   191  }