github.com/m3db/m3@v1.5.0/src/dbnode/encoding/iterators_test.go (about) 1 // Copyright (c) 2018 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 encoding 22 23 import ( 24 "testing" 25 "time" 26 27 "github.com/m3db/m3/src/dbnode/ts" 28 xtime "github.com/m3db/m3/src/x/time" 29 30 "github.com/stretchr/testify/require" 31 ) 32 33 var ( 34 at = xtime.Now().Truncate(time.Hour) 35 firstAnnotation = []byte{1, 2, 3} 36 commonTestValues = [][]testValue{ 37 { 38 {t: at, value: 2.0, unit: xtime.Second, annotation: firstAnnotation}, 39 {t: at.Add(time.Second), value: 6.0, unit: xtime.Second, annotation: []byte{2}}, 40 {t: at.Add(2 * time.Second), value: 7.0, unit: xtime.Second, annotation: []byte{3}}, 41 }, 42 { 43 {t: at, value: 1.0, unit: xtime.Second, annotation: firstAnnotation}, 44 {t: at.Add(time.Second), value: 5.0, unit: xtime.Second}, 45 {t: at.Add(2 * time.Second), value: 9.0, unit: xtime.Second, annotation: []byte{4}}, 46 }, 47 { 48 {t: at, value: 3.0, unit: xtime.Second, annotation: firstAnnotation}, 49 {t: at.Add(time.Second), value: 4.0, unit: xtime.Second}, 50 {t: at.Add(2 * time.Second), value: 8.0, unit: xtime.Second, annotation: []byte{5}}, 51 }, 52 } 53 ) 54 55 func TestIteratorsIterateEqualTimestampStrategy(t *testing.T) { 56 testValues := commonTestValues 57 lastTestValues := commonTestValues[len(commonTestValues)-1] 58 59 iters := &iterators{equalTimesStrategy: IterateLastPushed} 60 iters.reset() 61 62 assertIteratorsValues(t, iters, testValues, lastTestValues, firstAnnotation, true) 63 } 64 65 func TestIteratorsNoCloseIters(t *testing.T) { 66 testValues := commonTestValues 67 lastTestValues := commonTestValues[len(commonTestValues)-1] 68 69 iters := &iterators{equalTimesStrategy: IterateLastPushed} 70 iters.reset() 71 72 assertIteratorsValues(t, iters, testValues, lastTestValues, firstAnnotation, false) 73 } 74 75 func TestIteratorsIterateHighestValue(t *testing.T) { 76 testValues := commonTestValues 77 lastTestValues := []testValue{ 78 testValues[2][0], 79 testValues[0][1], 80 testValues[1][2], 81 } 82 83 iters := &iterators{equalTimesStrategy: IterateHighestValue} 84 iters.reset() 85 86 assertIteratorsValues(t, iters, testValues, lastTestValues, firstAnnotation, true) 87 } 88 89 func TestIteratorsIterateLowestValue(t *testing.T) { 90 testValues := commonTestValues 91 lastTestValues := []testValue{ 92 testValues[1][0], 93 testValues[2][1], 94 testValues[0][2], 95 } 96 97 iters := &iterators{equalTimesStrategy: IterateLowestValue} 98 iters.reset() 99 100 assertIteratorsValues(t, iters, testValues, lastTestValues, firstAnnotation, true) 101 } 102 103 func TestIteratorsIterateHighestFrequencyValue(t *testing.T) { 104 testValues := [][]testValue{ 105 { 106 {t: at, value: 2.0, unit: xtime.Second}, 107 {t: at.Add(time.Second), value: 6.0, unit: xtime.Second}, 108 {t: at.Add(2 * time.Second), value: 8.0, unit: xtime.Second}, 109 }, 110 { 111 {t: at, value: 2.0, unit: xtime.Second}, 112 {t: at.Add(time.Second), value: 6.0, unit: xtime.Second}, 113 {t: at.Add(2 * time.Second), value: 9.0, unit: xtime.Second}, 114 }, 115 { 116 {t: at, value: 3.0, unit: xtime.Second}, 117 {t: at.Add(time.Second), value: 5.0, unit: xtime.Second}, 118 {t: at.Add(2 * time.Second), value: 8.0, unit: xtime.Second}, 119 120 // Also test just a single value without any other frequencies 121 {t: at.Add(3 * time.Second), value: 10.0, unit: xtime.Second}, 122 }, 123 } 124 lastTestValues := []testValue{ 125 testValues[0][0], 126 testValues[1][1], 127 testValues[2][2], 128 testValues[2][3], 129 } 130 131 iters := &iterators{equalTimesStrategy: IterateHighestFrequencyValue} 132 iters.reset() 133 134 assertIteratorsValues(t, iters, testValues, lastTestValues, nil, true) 135 } 136 137 func TestIteratorsReuse(t *testing.T) { 138 var ( 139 testValues1 = [][]testValue{ 140 { 141 {t: at, value: 1.0, unit: xtime.Second, annotation: []byte{1}}, 142 }, 143 } 144 testValues2 = [][]testValue{ 145 { 146 {t: at.Add(time.Hour), value: 2.0, unit: xtime.Second, annotation: nil}, 147 }, 148 } 149 ) 150 151 iters := &iterators{equalTimesStrategy: IterateLastPushed} 152 iters.reset() 153 154 assertIteratorsValues(t, iters, testValues1, testValues1[0], []byte{1}, true) 155 iters.reset() 156 assertIteratorsValues(t, iters, testValues2, testValues2[0], nil, true) 157 } 158 159 func assertIteratorsValues( 160 t *testing.T, 161 iters *iterators, 162 testValues [][]testValue, 163 expectedValues []testValue, 164 expectedFirstAnnotation ts.Annotation, 165 closeIters bool, 166 ) { 167 iters.closeIters = closeIters 168 require.Equal(t, 0, len(iters.values)) 169 170 var testIters []Iterator 171 for _, values := range testValues { 172 testIters = append(testIters, newTestIterator(values)) 173 } 174 175 for _, iter := range testIters { 176 require.True(t, iters.push(iter)) 177 } 178 179 for _, expectedValue := range expectedValues { 180 ok, err := iters.moveToValidNext() 181 require.NoError(t, err) 182 require.True(t, ok) 183 184 dp, unit, annotation := iters.current() 185 require.Equal(t, expectedValue.t, dp.TimestampNanos) 186 require.Equal(t, expectedValue.value, dp.Value) 187 require.Equal(t, expectedValue.unit, unit) 188 require.Equal(t, expectedValue.annotation, annotation) 189 require.Equal(t, expectedFirstAnnotation, iters.firstAnnotation()) 190 } 191 ok, err := iters.moveToValidNext() 192 require.NoError(t, err) 193 require.False(t, ok) 194 195 for _, testIter := range testIters { 196 require.Equal(t, closeIters, testIter.(*testIterator).closed) 197 } 198 }