github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/m3ninx/search/executor/iterator_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 executor 22 23 import ( 24 "fmt" 25 "testing" 26 27 "github.com/m3db/m3/src/m3ninx/doc" 28 "github.com/m3db/m3/src/m3ninx/index" 29 "github.com/m3db/m3/src/m3ninx/postings/roaring" 30 "github.com/m3db/m3/src/m3ninx/search" 31 "github.com/m3db/m3/src/x/context" 32 33 "github.com/golang/mock/gomock" 34 "github.com/stretchr/testify/require" 35 ) 36 37 func TestIterator(t *testing.T) { 38 mockCtrl := gomock.NewController(t) 39 defer mockCtrl.Finish() 40 41 // Set up Searcher. 42 firstPL := roaring.NewPostingsList() 43 require.NoError(t, firstPL.Insert(42)) 44 require.NoError(t, firstPL.Insert(47)) 45 secondPL := roaring.NewPostingsList() 46 require.NoError(t, secondPL.Insert(67)) 47 48 // Set up Readers. 49 docs := []doc.Document{ 50 doc.NewDocumentFromEncoded(doc.Encoded{Bytes: []byte("encodedbytes1")}), 51 doc.NewDocumentFromEncoded(doc.Encoded{Bytes: []byte("encodedbytes2")}), 52 doc.NewDocumentFromEncoded(doc.Encoded{Bytes: []byte("encodedbytes3")}), 53 } 54 55 firstDocIter := doc.NewMockIterator(mockCtrl) 56 secondDocIter := doc.NewMockIterator(mockCtrl) 57 gomock.InOrder( 58 firstDocIter.EXPECT().Next().Return(true), 59 firstDocIter.EXPECT().Current().Return(docs[0]), 60 firstDocIter.EXPECT().Next().Return(true), 61 firstDocIter.EXPECT().Current().Return(docs[1]), 62 firstDocIter.EXPECT().Next().Return(false), 63 firstDocIter.EXPECT().Err().Return(nil), 64 firstDocIter.EXPECT().Close().Return(nil), 65 66 secondDocIter.EXPECT().Next().Return(true), 67 secondDocIter.EXPECT().Current().Return(docs[2]), 68 secondDocIter.EXPECT().Next().Return(false), 69 secondDocIter.EXPECT().Err().Return(nil), 70 secondDocIter.EXPECT().Close().Return(nil), 71 ) 72 73 firstReader := index.NewMockReader(mockCtrl) 74 secondReader := index.NewMockReader(mockCtrl) 75 gomock.InOrder( 76 firstReader.EXPECT().Docs(firstPL).Return(firstDocIter, nil), 77 secondReader.EXPECT().Docs(secondPL).Return(secondDocIter, nil), 78 ) 79 80 searcher := search.NewMockSearcher(mockCtrl) 81 gomock.InOrder( 82 searcher.EXPECT().Search(firstReader).Return(firstPL, nil), 83 searcher.EXPECT().Search(secondReader).Return(secondPL, nil), 84 ) 85 86 query := search.NewMockQuery(mockCtrl) 87 query.EXPECT().Searcher().Return(searcher, nil) 88 89 readers := index.Readers{firstReader, secondReader} 90 91 // Construct iterator and run tests. 92 iter, err := newIterator(context.NewBackground(), query, readers) 93 require.NoError(t, err) 94 95 require.False(t, iter.Done()) 96 require.True(t, iter.Next()) 97 require.Equal(t, docs[0], iter.Current()) 98 require.False(t, iter.Done()) 99 require.True(t, iter.Next()) 100 require.Equal(t, docs[1], iter.Current()) 101 require.False(t, iter.Done()) 102 require.True(t, iter.Next()) 103 require.Equal(t, docs[2], iter.Current()) 104 105 require.True(t, iter.Done()) 106 require.False(t, iter.Next()) 107 require.NoError(t, iter.Err()) 108 require.NoError(t, iter.Close()) 109 } 110 111 func TestCloseEarly(t *testing.T) { 112 mockCtrl := gomock.NewController(t) 113 defer mockCtrl.Finish() 114 115 // Set up Searcher. 116 firstPL := roaring.NewPostingsList() 117 require.NoError(t, firstPL.Insert(42)) 118 require.NoError(t, firstPL.Insert(47)) 119 secondPL := roaring.NewPostingsList() 120 require.NoError(t, secondPL.Insert(67)) 121 122 // Set up Readers. 123 docs := []doc.Document{ 124 doc.NewDocumentFromEncoded(doc.Encoded{Bytes: []byte("encodedbytes1")}), 125 doc.NewDocumentFromEncoded(doc.Encoded{Bytes: []byte("encodedbytes2")}), 126 doc.NewDocumentFromEncoded(doc.Encoded{Bytes: []byte("encodedbytes3")}), 127 } 128 129 firstDocIter := doc.NewMockIterator(mockCtrl) 130 secondDocIter := doc.NewMockIterator(mockCtrl) 131 gomock.InOrder( 132 firstDocIter.EXPECT().Next().Return(true), 133 firstDocIter.EXPECT().Current().Return(docs[0]), 134 firstDocIter.EXPECT().Next().Return(true), 135 firstDocIter.EXPECT().Current().Return(docs[1]), 136 firstDocIter.EXPECT().Close().Return(nil), 137 secondDocIter.EXPECT().Close().Return(nil), 138 ) 139 140 firstReader := index.NewMockReader(mockCtrl) 141 secondReader := index.NewMockReader(mockCtrl) 142 gomock.InOrder( 143 firstReader.EXPECT().Docs(firstPL).Return(firstDocIter, nil), 144 secondReader.EXPECT().Docs(secondPL).Return(secondDocIter, nil), 145 ) 146 147 searcher := search.NewMockSearcher(mockCtrl) 148 gomock.InOrder( 149 searcher.EXPECT().Search(firstReader).Return(firstPL, nil), 150 searcher.EXPECT().Search(secondReader).Return(secondPL, nil), 151 ) 152 153 query := search.NewMockQuery(mockCtrl) 154 query.EXPECT().Searcher().Return(searcher, nil) 155 156 readers := index.Readers{firstReader, secondReader} 157 158 // Construct iterator and run tests. 159 iter, err := newIterator(context.NewBackground(), query, readers) 160 require.NoError(t, err) 161 162 require.True(t, iter.Next()) 163 require.Equal(t, docs[0], iter.Current()) 164 require.NoError(t, iter.Close()) 165 } 166 167 func TestErrIterating(t *testing.T) { 168 mockCtrl := gomock.NewController(t) 169 defer mockCtrl.Finish() 170 171 // Set up Searcher. 172 firstPL := roaring.NewPostingsList() 173 secondPL := roaring.NewPostingsList() 174 175 // Set up Readers. 176 docs := []doc.Document{ 177 doc.NewDocumentFromEncoded(doc.Encoded{Bytes: []byte("encodedbytes1")}), 178 doc.NewDocumentFromEncoded(doc.Encoded{Bytes: []byte("encodedbytes2")}), 179 doc.NewDocumentFromEncoded(doc.Encoded{Bytes: []byte("encodedbytes3")}), 180 } 181 182 firstDocIter := doc.NewMockIterator(mockCtrl) 183 secondDocIter := doc.NewMockIterator(mockCtrl) 184 gomock.InOrder( 185 firstDocIter.EXPECT().Next().Return(true), 186 firstDocIter.EXPECT().Current().Return(docs[0]), 187 firstDocIter.EXPECT().Next().Return(false), 188 firstDocIter.EXPECT().Err().Return(fmt.Errorf("failed")), 189 firstDocIter.EXPECT().Close().Return(nil), 190 secondDocIter.EXPECT().Close().Return(nil), 191 ) 192 193 firstReader := index.NewMockReader(mockCtrl) 194 secondReader := index.NewMockReader(mockCtrl) 195 gomock.InOrder( 196 firstReader.EXPECT().Docs(firstPL).Return(firstDocIter, nil), 197 secondReader.EXPECT().Docs(secondPL).Return(secondDocIter, nil), 198 ) 199 200 searcher := search.NewMockSearcher(mockCtrl) 201 gomock.InOrder( 202 searcher.EXPECT().Search(firstReader).Return(firstPL, nil), 203 searcher.EXPECT().Search(secondReader).Return(secondPL, nil), 204 ) 205 206 query := search.NewMockQuery(mockCtrl) 207 query.EXPECT().Searcher().Return(searcher, nil) 208 209 readers := index.Readers{firstReader, secondReader} 210 211 // Construct iterator and run tests. 212 iter, err := newIterator(context.NewBackground(), query, readers) 213 require.NoError(t, err) 214 215 require.False(t, iter.Done()) 216 require.True(t, iter.Next()) 217 require.Equal(t, docs[0], iter.Current()) 218 require.True(t, iter.Done()) 219 require.False(t, iter.Next()) 220 require.Error(t, iter.Err()) 221 require.True(t, iter.Done()) 222 require.NoError(t, iter.Close()) 223 } 224 225 func TestCloseBeforeNext(t *testing.T) { 226 mockCtrl := gomock.NewController(t) 227 defer mockCtrl.Finish() 228 query := search.NewMockQuery(mockCtrl) 229 query.EXPECT().Searcher().Return(nil, nil) 230 231 iter, err := newIterator(context.NewBackground(), query, nil) 232 require.NoError(t, err) 233 require.NoError(t, iter.Close()) 234 } 235 236 func TestNoReaders(t *testing.T) { 237 mockCtrl := gomock.NewController(t) 238 defer mockCtrl.Finish() 239 query := search.NewMockQuery(mockCtrl) 240 query.EXPECT().Searcher().Return(nil, nil) 241 242 iter, err := newIterator(context.NewBackground(), query, index.Readers{}) 243 require.NoError(t, err) 244 require.False(t, iter.Done()) 245 require.False(t, iter.Next()) 246 require.True(t, iter.Done()) 247 require.NoError(t, iter.Close()) 248 } 249 250 func TestEmptyReaders(t *testing.T) { 251 mockCtrl := gomock.NewController(t) 252 defer mockCtrl.Finish() 253 254 // Set up Searcher. 255 firstPL := roaring.NewPostingsList() 256 secondPL := roaring.NewPostingsList() 257 258 // Set up Readers. 259 firstDocIter := doc.NewMockIterator(mockCtrl) 260 secondDocIter := doc.NewMockIterator(mockCtrl) 261 gomock.InOrder( 262 firstDocIter.EXPECT().Next().Return(false), 263 firstDocIter.EXPECT().Err().Return(nil), 264 firstDocIter.EXPECT().Close().Return(nil), 265 266 secondDocIter.EXPECT().Next().Return(false), 267 secondDocIter.EXPECT().Err().Return(nil), 268 secondDocIter.EXPECT().Close().Return(nil), 269 ) 270 271 firstReader := index.NewMockReader(mockCtrl) 272 secondReader := index.NewMockReader(mockCtrl) 273 gomock.InOrder( 274 firstReader.EXPECT().Docs(firstPL).Return(firstDocIter, nil), 275 secondReader.EXPECT().Docs(secondPL).Return(secondDocIter, nil), 276 ) 277 278 searcher := search.NewMockSearcher(mockCtrl) 279 gomock.InOrder( 280 searcher.EXPECT().Search(firstReader).Return(firstPL, nil), 281 searcher.EXPECT().Search(secondReader).Return(secondPL, nil), 282 ) 283 284 query := search.NewMockQuery(mockCtrl) 285 query.EXPECT().Searcher().Return(searcher, nil) 286 287 readers := index.Readers{firstReader, secondReader} 288 289 // Construct iterator and run tests. 290 iter, err := newIterator(context.NewBackground(), query, readers) 291 require.NoError(t, err) 292 require.False(t, iter.Done()) 293 require.False(t, iter.Next()) 294 require.True(t, iter.Done()) 295 require.NoError(t, iter.Close()) 296 }