github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/metrics/policy/resolution_test.go (about)

     1  // Copyright (c) 2016 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 policy
    22  
    23  import (
    24  	"testing"
    25  	"time"
    26  
    27  	xtime "github.com/m3db/m3/src/x/time"
    28  
    29  	"github.com/stretchr/testify/require"
    30  )
    31  
    32  func TestValidResolutionValue(t *testing.T) {
    33  	inputs := []ResolutionValue{
    34  		OneSecond,
    35  		TenSeconds,
    36  		OneMinute,
    37  		FiveMinutes,
    38  		TenMinutes,
    39  	}
    40  	expected := []Resolution{
    41  		Resolution{Window: time.Second, Precision: xtime.Second},
    42  		Resolution{Window: 10 * time.Second, Precision: xtime.Second},
    43  		Resolution{Window: time.Minute, Precision: xtime.Minute},
    44  		Resolution{Window: 5 * time.Minute, Precision: xtime.Minute},
    45  		Resolution{Window: 10 * time.Minute, Precision: xtime.Minute},
    46  	}
    47  	for i, value := range inputs {
    48  		resolution, err := value.Resolution()
    49  		require.NoError(t, err)
    50  		require.Equal(t, resolution, expected[i])
    51  		require.True(t, value.IsValid())
    52  	}
    53  }
    54  
    55  func TestInvalidResolutionValue(t *testing.T) {
    56  	inputs := []ResolutionValue{
    57  		UnknownResolutionValue,
    58  		ResolutionValue(100),
    59  	}
    60  	for _, value := range inputs {
    61  		_, err := value.Resolution()
    62  		require.Equal(t, errUnknownResolutionValue, err)
    63  		require.False(t, value.IsValid())
    64  	}
    65  }
    66  
    67  func TestValidResolution(t *testing.T) {
    68  	inputs := []Resolution{
    69  		{Window: time.Second, Precision: xtime.Second},
    70  		{Window: 10 * time.Second, Precision: xtime.Second},
    71  		{Window: time.Minute, Precision: xtime.Minute},
    72  		{Window: 5 * time.Minute, Precision: xtime.Minute},
    73  		{Window: 10 * time.Minute, Precision: xtime.Minute},
    74  	}
    75  	expected := []ResolutionValue{
    76  		OneSecond,
    77  		TenSeconds,
    78  		OneMinute,
    79  		FiveMinutes,
    80  		TenMinutes,
    81  	}
    82  	for i, input := range inputs {
    83  		resolutionValue, err := ValueFromResolution(input)
    84  		require.NoError(t, err)
    85  		require.Equal(t, expected[i], resolutionValue)
    86  	}
    87  }
    88  
    89  func TestInvalidResolution(t *testing.T) {
    90  	inputs := []Resolution{
    91  		{Window: 2 * time.Second, Precision: xtime.Second},
    92  		{Window: time.Second, Precision: xtime.None},
    93  	}
    94  	for _, resolution := range inputs {
    95  		_, err := ValueFromResolution(resolution)
    96  		require.Equal(t, errUnknownResolution, err)
    97  	}
    98  }
    99  
   100  func TestParseResolution(t *testing.T) {
   101  	inputs := []struct {
   102  		str      string
   103  		expected Resolution
   104  	}{
   105  		{
   106  			str:      "10s",
   107  			expected: Resolution{Window: 10 * time.Second, Precision: xtime.Second},
   108  		},
   109  		{
   110  			str:      "120m",
   111  			expected: Resolution{Window: 2 * time.Hour, Precision: xtime.Hour},
   112  		},
   113  		{
   114  			str:      "130m",
   115  			expected: Resolution{Window: 130 * time.Minute, Precision: xtime.Minute},
   116  		},
   117  		{
   118  			str:      "3ms",
   119  			expected: Resolution{Window: 3 * time.Millisecond, Precision: xtime.Millisecond},
   120  		},
   121  		{
   122  			str:      "10s@1s",
   123  			expected: Resolution{Window: 10 * time.Second, Precision: xtime.Second},
   124  		},
   125  		{
   126  			str:      "120m@1m",
   127  			expected: Resolution{Window: 2 * time.Hour, Precision: xtime.Minute},
   128  		},
   129  		{
   130  			str:      "130m@1m",
   131  			expected: Resolution{Window: 130 * time.Minute, Precision: xtime.Minute},
   132  		},
   133  		{
   134  			str:      "3ms@1ms",
   135  			expected: Resolution{Window: 3 * time.Millisecond, Precision: xtime.Millisecond},
   136  		},
   137  	}
   138  	for _, input := range inputs {
   139  		res, err := ParseResolution(input.str)
   140  		require.NoError(t, err)
   141  		require.Equal(t, input.expected, res)
   142  	}
   143  }
   144  
   145  func TestResolutionString(t *testing.T) {
   146  	inputs := []struct {
   147  		resolution Resolution
   148  		expected   string
   149  	}{
   150  		{
   151  			resolution: Resolution{Window: time.Second, Precision: xtime.Second},
   152  			expected:   "1s",
   153  		},
   154  		{
   155  			resolution: Resolution{Window: 10 * time.Second, Precision: xtime.Second},
   156  			expected:   "10s",
   157  		},
   158  		{
   159  			resolution: Resolution{Window: time.Minute, Precision: xtime.Minute},
   160  			expected:   "1m",
   161  		},
   162  		{
   163  			resolution: Resolution{Window: 10 * time.Minute, Precision: xtime.Minute},
   164  			expected:   "10m",
   165  		},
   166  		{
   167  			resolution: Resolution{Window: time.Hour, Precision: xtime.Hour},
   168  			expected:   "1h",
   169  		},
   170  		{
   171  			resolution: Resolution{Window: 10 * time.Minute, Precision: xtime.Second},
   172  			expected:   "10m@1s",
   173  		},
   174  	}
   175  	for _, input := range inputs {
   176  		require.Equal(t, input.expected, input.resolution.String())
   177  	}
   178  }
   179  
   180  func TestResolutionRoundTrip(t *testing.T) {
   181  	inputs := []Resolution{
   182  		Resolution{Window: time.Second, Precision: xtime.Second},
   183  		Resolution{Window: 10 * time.Second, Precision: xtime.Second},
   184  		Resolution{Window: time.Minute, Precision: xtime.Minute},
   185  		Resolution{Window: 10 * time.Minute, Precision: xtime.Minute},
   186  		Resolution{Window: time.Hour, Precision: xtime.Hour},
   187  		Resolution{Window: 10 * time.Minute, Precision: xtime.Second},
   188  		Resolution{Window: 23491929834 * time.Nanosecond, Precision: xtime.Nanosecond},
   189  	}
   190  
   191  	for _, input := range inputs {
   192  		res, err := ParseResolution(input.String())
   193  		require.NoError(t, err)
   194  		require.Equal(t, input, res)
   195  	}
   196  }
   197  
   198  func TestParseResolutionNoPrecisionErrors(t *testing.T) {
   199  	inputs := []string{
   200  		"10seconds",
   201  		"0.1s",
   202  		"10seconds@1s",
   203  		"10s@2s",
   204  		"10s@",
   205  	}
   206  	for _, input := range inputs {
   207  		_, err := ParseResolution(input)
   208  		require.Error(t, err)
   209  	}
   210  }