github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/x/time/ranges_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 time
    22  
    23  import (
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/stretchr/testify/require"
    28  )
    29  
    30  func validateIter(t *testing.T, it *RangeIter, expected []Range) {
    31  	idx := 0
    32  	for it.Next() {
    33  		r := it.Value()
    34  		require.Equal(t, expected[idx], r)
    35  		idx++
    36  	}
    37  }
    38  
    39  func getRangesToAdd() []Range {
    40  	return []Range{
    41  		{Start: testStart, End: testStart.Add(time.Second)},
    42  		{Start: testStart.Add(10 * time.Second), End: testStart.Add(15 * time.Second)},
    43  		{Start: testStart.Add(-3 * time.Second), End: testStart.Add(-1 * time.Second)},
    44  		{Start: testStart.Add(-8 * time.Second), End: testStart.Add(-5 * time.Second)},
    45  		{Start: testStart.Add(-1 * time.Second), End: testStart},
    46  		{Start: testStart.Add(time.Second), End: testStart.Add(8 * time.Second)},
    47  		{Start: testStart.Add(-10 * time.Second), End: testStart.Add(12 * time.Second)},
    48  	}
    49  }
    50  
    51  func getRangesToRemove() []Range {
    52  	return []Range{
    53  		{Start: testStart.Add(-5 * time.Second), End: testStart.Add(-3 * time.Second)},
    54  		{Start: testStart.Add(-6 * time.Second), End: testStart.Add(8 * time.Second)},
    55  		{Start: testStart.Add(12 * time.Second), End: testStart.Add(13 * time.Second)},
    56  		{Start: testStart.Add(10 * time.Second), End: testStart.Add(12 * time.Second)},
    57  	}
    58  }
    59  
    60  func getPopulatedRanges(ranges []Range, start, end int) Ranges {
    61  	tr := NewRanges()
    62  	for _, r := range ranges[start:end] {
    63  		tr.AddRange(r)
    64  	}
    65  	return tr
    66  }
    67  
    68  func TestIsEmpty(t *testing.T) {
    69  	tr := NewRanges()
    70  	require.True(t, tr.IsEmpty())
    71  
    72  	tr.AddRange(getRangesToAdd()[0])
    73  	require.False(t, tr.IsEmpty())
    74  }
    75  
    76  func TestNewRanges(t *testing.T) {
    77  	rangesToAdd := getRangesToAdd()
    78  	exp := getPopulatedRanges(rangesToAdd, 0, len(rangesToAdd))
    79  	clone := exp.Clone()
    80  	obs := NewRanges(rangesToAdd...)
    81  	exp.RemoveRanges(clone)
    82  	require.True(t, exp.IsEmpty())
    83  	obs.RemoveRanges(clone)
    84  	require.True(t, obs.IsEmpty())
    85  }
    86  
    87  func TestClone(t *testing.T) {
    88  	rangesToAdd := getRangesToAdd()
    89  	tr := getPopulatedRanges(rangesToAdd, 0, 4)
    90  
    91  	expectedResults := []Range{rangesToAdd[3], rangesToAdd[2], rangesToAdd[0], rangesToAdd[1]}
    92  	validateIter(t, tr.Iter(), expectedResults)
    93  
    94  	cloned := tr.Clone()
    95  	tr.RemoveRange(rangesToAdd[0])
    96  	validateIter(t, cloned.Iter(), expectedResults)
    97  	validateIter(t, tr.Iter(), []Range{rangesToAdd[3], rangesToAdd[2], rangesToAdd[1]})
    98  }
    99  
   100  func TestAddRange(t *testing.T) {
   101  	tr := NewRanges()
   102  	tr.AddRange(Range{})
   103  	validateIter(t, tr.Iter(), []Range{})
   104  
   105  	rangestoAdd := getRangesToAdd()
   106  	expectedResults := [][]Range{
   107  		{rangestoAdd[0]},
   108  		{rangestoAdd[0], rangestoAdd[1]},
   109  		{rangestoAdd[2], rangestoAdd[0], rangestoAdd[1]},
   110  		{rangestoAdd[3], rangestoAdd[2], rangestoAdd[0], rangestoAdd[1]},
   111  		{rangestoAdd[3], rangestoAdd[2], rangestoAdd[4], rangestoAdd[0], rangestoAdd[1]},
   112  		{rangestoAdd[3], rangestoAdd[2], rangestoAdd[4], rangestoAdd[0], rangestoAdd[5], rangestoAdd[1]},
   113  		{{Start: testStart.Add(-10 * time.Second), End: testStart.Add(15 * time.Second)}},
   114  	}
   115  
   116  	saved := tr.Clone()
   117  	for i, r := range rangestoAdd {
   118  		tr.AddRange(r)
   119  		validateIter(t, tr.Iter(), expectedResults[i])
   120  	}
   121  	validateIter(t, saved.Iter(), []Range{})
   122  }
   123  
   124  func TestAddRanges(t *testing.T) {
   125  	rangesToAdd := getRangesToAdd()
   126  
   127  	tr := getPopulatedRanges(rangesToAdd, 0, 4)
   128  	tr.AddRanges(NewRanges())
   129  
   130  	expectedResults := []Range{rangesToAdd[3], rangesToAdd[2], rangesToAdd[0], rangesToAdd[1]}
   131  	validateIter(t, tr.Iter(), expectedResults)
   132  
   133  	tr2 := getPopulatedRanges(rangesToAdd, 4, 7)
   134  	saved := tr.Clone()
   135  	tr.AddRanges(tr2)
   136  
   137  	expectedResults2 := []Range{{Start: testStart.Add(-10 * time.Second), End: testStart.Add(15 * time.Second)}}
   138  	validateIter(t, tr.Iter(), expectedResults2)
   139  	validateIter(t, saved.Iter(), expectedResults)
   140  }
   141  
   142  func TestRemoveRange(t *testing.T) {
   143  	tr := getPopulatedRanges(getRangesToAdd(), 0, 4)
   144  
   145  	rangesToRemove := getRangesToRemove()
   146  	expectedResults := [][]Range{
   147  		{
   148  			{Start: testStart.Add(-8 * time.Second), End: testStart.Add(-5 * time.Second)},
   149  			{Start: testStart.Add(-3 * time.Second), End: testStart.Add(-1 * time.Second)},
   150  			{Start: testStart, End: testStart.Add(time.Second)},
   151  			{Start: testStart.Add(10 * time.Second), End: testStart.Add(15 * time.Second)},
   152  		},
   153  		{
   154  			{Start: testStart.Add(-8 * time.Second), End: testStart.Add(-6 * time.Second)},
   155  			{Start: testStart.Add(10 * time.Second), End: testStart.Add(15 * time.Second)},
   156  		},
   157  		{
   158  			{Start: testStart.Add(-8 * time.Second), End: testStart.Add(-6 * time.Second)},
   159  			{Start: testStart.Add(10 * time.Second), End: testStart.Add(12 * time.Second)},
   160  			{Start: testStart.Add(13 * time.Second), End: testStart.Add(15 * time.Second)},
   161  		},
   162  		{
   163  			{Start: testStart.Add(-8 * time.Second), End: testStart.Add(-6 * time.Second)},
   164  			{Start: testStart.Add(13 * time.Second), End: testStart.Add(15 * time.Second)},
   165  		},
   166  	}
   167  
   168  	saved := tr.Clone()
   169  	for i, r := range rangesToRemove {
   170  		tr.RemoveRange(r)
   171  		validateIter(t, tr.Iter(), expectedResults[i])
   172  	}
   173  
   174  	tr.RemoveRange(Range{})
   175  	validateIter(t, tr.Iter(), expectedResults[3])
   176  
   177  	tr.RemoveRange(Range{
   178  		Start: testStart.Add(-10 * time.Second),
   179  		End:   testStart.Add(15 * time.Second),
   180  	})
   181  	require.True(t, tr.IsEmpty())
   182  	validateIter(t, saved.Iter(), expectedResults[0])
   183  }
   184  
   185  func TestRemoveRanges(t *testing.T) {
   186  	tr := getPopulatedRanges(getRangesToAdd(), 0, 4)
   187  	tr.RemoveRanges(NewRanges())
   188  
   189  	expectedResults := []Range{
   190  		{Start: testStart.Add(-8 * time.Second), End: testStart.Add(-5 * time.Second)},
   191  		{Start: testStart.Add(-3 * time.Second), End: testStart.Add(-1 * time.Second)},
   192  		{Start: testStart, End: testStart.Add(time.Second)},
   193  		{Start: testStart.Add(10 * time.Second), End: testStart.Add(15 * time.Second)},
   194  	}
   195  	validateIter(t, tr.Iter(), expectedResults)
   196  
   197  	saved := tr.Clone()
   198  	tr2 := getPopulatedRanges(getRangesToRemove(), 0, 4)
   199  	tr.RemoveRanges(tr2)
   200  
   201  	expectedResults2 := []Range{
   202  		{Start: testStart.Add(-8 * time.Second), End: testStart.Add(-6 * time.Second)},
   203  		{Start: testStart.Add(13 * time.Second), End: testStart.Add(15 * time.Second)},
   204  	}
   205  	validateIter(t, tr.Iter(), expectedResults2)
   206  	validateIter(t, saved.Iter(), expectedResults)
   207  }
   208  
   209  func TestOverlaps(t *testing.T) {
   210  	tr := getPopulatedRanges(getRangesToAdd(), 0, 4)
   211  	require.True(t, tr.Overlaps(Range{Start: testStart, End: testStart.Add(time.Second)}))
   212  	require.True(t, tr.Overlaps(Range{Start: testStart.Add(-7 * time.Second), End: testStart.Add(-5 * time.Second)}))
   213  	require.True(t, tr.Overlaps(Range{Start: testStart.Add(-7 * time.Second), End: testStart.Add(-4 * time.Second)}))
   214  	require.True(t, tr.Overlaps(Range{Start: testStart.Add(-3 * time.Second), End: testStart.Add(1 * time.Second)}))
   215  	require.True(t, tr.Overlaps(Range{Start: testStart.Add(9 * time.Second), End: testStart.Add(15 * time.Second)}))
   216  	require.True(t, tr.Overlaps(Range{Start: testStart.Add(12 * time.Second), End: testStart.Add(13 * time.Second)}))
   217  	require.False(t, tr.Overlaps(Range{Start: testStart, End: testStart}))
   218  	require.False(t, tr.Overlaps(Range{Start: testStart.Add(time.Second), End: testStart.Add(2 * time.Second)}))
   219  }
   220  
   221  func TestRangesIter(t *testing.T) {
   222  	rangesToAdd := getRangesToAdd()
   223  	tr := getPopulatedRanges(rangesToAdd, 0, 4)
   224  	expectedResults := []Range{
   225  		{Start: testStart.Add(-8 * time.Second), End: testStart.Add(-5 * time.Second)},
   226  		{Start: testStart.Add(-3 * time.Second), End: testStart.Add(-1 * time.Second)},
   227  		{Start: testStart, End: testStart.Add(time.Second)},
   228  		{Start: testStart.Add(10 * time.Second), End: testStart.Add(15 * time.Second)},
   229  	}
   230  	validateIter(t, tr.Iter(), expectedResults)
   231  	tr.RemoveRange(rangesToAdd[2])
   232  	validateIter(t, tr.Iter(), append(expectedResults[:1], expectedResults[2:]...))
   233  }
   234  
   235  func TestRangesString(t *testing.T) {
   236  	tr := NewRanges()
   237  	require.Equal(t, "[]", tr.String())
   238  	start := ToUnixNano(time.Unix(1465430400, 0).UTC())
   239  	tr.AddRanges(NewRanges(
   240  		Range{Start: start, End: start.Add(2 * time.Hour)},
   241  		Range{Start: start.Add(4 * time.Hour), End: start.Add(5 * time.Hour)}))
   242  	require.Equal(
   243  		t, "[(2016-06-09 00:00:00 +0000 UTC,2016-06-09 02:00:00 +0000 UTC),"+
   244  			"(2016-06-09 04:00:00 +0000 UTC,2016-06-09 05:00:00 +0000 UTC)]", tr.String())
   245  }