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 }