github.com/m3db/m3@v1.5.1-0.20231129193456-75a402aa583b/src/m3ninx/search/proptest/prop_test.go (about) 1 // +build big 2 3 // Copyright (c) 2018 Uber Technologies, Inc. 4 // 5 // Permission is hereby granted, free of charge, to any person obtaining a copy 6 // of this software and associated documentation files (the "Software"), to deal 7 // in the Software without restriction, including without limitation the rights 8 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 // copies of the Software, and to permit persons to whom the Software is 10 // furnished to do so, subject to the following conditions: 11 // 12 // The above copyright notice and this permission notice shall be included in 13 // all copies or substantial portions of the Software. 14 // 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 // THE SOFTWARE. 22 23 package proptest 24 25 import ( 26 "math/rand" 27 "os" 28 "testing" 29 "time" 30 31 "github.com/m3db/m3/src/x/context" 32 33 "github.com/m3db/m3/src/m3ninx/index" 34 "github.com/m3db/m3/src/m3ninx/index/segment/fst" 35 "github.com/m3db/m3/src/m3ninx/search" 36 "github.com/m3db/m3/src/m3ninx/search/executor" 37 38 "github.com/leanovate/gopter" 39 "github.com/leanovate/gopter/prop" 40 "github.com/stretchr/testify/require" 41 ) 42 43 func TestSegmentDistributionDoesNotAffectQuery(t *testing.T) { 44 parameters := gopter.DefaultTestParameters() 45 seed := time.Now().UnixNano() 46 parameters.MinSuccessfulTests = 100 47 parameters.MaxSize = 20 48 parameters.Rng = rand.New(rand.NewSource(seed)) 49 properties := gopter.NewProperties(parameters) 50 51 simpleSeg := newTestMemSegment(t, lotsTestDocuments) 52 properties.Property("Any distribution of test documents in segments does not affect query results", prop.ForAll( 53 func(i propTestInput, q search.Query) (bool, error) { 54 ctx := context.NewBackground() 55 r, err := simpleSeg.Reader() 56 require.NoError(t, err) 57 eOrg := executor.NewExecutor([]index.Reader{r}) 58 dOrg, err := eOrg.Execute(ctx, q) 59 if err != nil { 60 return false, err 61 } 62 matchedDocs, err := collectDocs(dOrg) 63 require.NoError(t, err) 64 docMatcher, err := newDocumentIteratorMatcher(t, matchedDocs...) 65 require.NoError(t, err) 66 67 segments := i.generate(t, lotsTestDocuments) 68 readers := make([]index.Reader, 0, len(segments)) 69 for _, s := range segments { 70 r, err := s.Reader() 71 if err != nil { 72 return false, err 73 } 74 readers = append(readers, r) 75 } 76 77 e := executor.NewExecutor(readers) 78 d, err := e.Execute(ctx, q) 79 if err != nil { 80 return false, err 81 } 82 83 if err := docMatcher.Matches(d); err != nil { 84 return false, err 85 } 86 87 return true, nil 88 }, 89 genPropTestInput(len(lotsTestDocuments)), 90 GenQuery(lotsTestDocuments), 91 )) 92 93 reporter := gopter.NewFormatedReporter(true, 160, os.Stdout) 94 if !properties.Run(reporter) { 95 t.Errorf("failed with initial seed: %d", seed) 96 } 97 } 98 99 func TestFSTSimpleSegmentsQueryTheSame(t *testing.T) { 100 parameters := gopter.DefaultTestParameters() 101 seed := time.Now().UnixNano() 102 parameters.MinSuccessfulTests = 100 103 parameters.MaxSize = 20 104 parameters.Rng = rand.New(rand.NewSource(seed)) 105 properties := gopter.NewProperties(parameters) 106 107 simpleSeg := newTestMemSegment(t, lotsTestDocuments) 108 fstSeg := fst.ToTestSegment(t, simpleSeg, fstOptions) 109 110 properties.Property("Simple & FST Segments Query the same results", prop.ForAll( 111 func(q search.Query) (bool, error) { 112 ctx := context.NewBackground() 113 r, err := simpleSeg.Reader() 114 require.NoError(t, err) 115 eOrg := executor.NewExecutor([]index.Reader{r}) 116 dOrg, err := eOrg.Execute(ctx, q) 117 if err != nil { 118 return false, err 119 } 120 matchedDocs, err := collectDocs(dOrg) 121 require.NoError(t, err) 122 docMatcher, err := newDocumentIteratorMatcher(t, matchedDocs...) 123 require.NoError(t, err) 124 125 rFst, err := fstSeg.Reader() 126 require.NoError(t, err) 127 e := executor.NewExecutor([]index.Reader{rFst}) 128 d, err := e.Execute(ctx, q) 129 if err != nil { 130 return false, err 131 } 132 133 if err := docMatcher.Matches(d); err != nil { 134 return false, err 135 } 136 137 return true, nil 138 }, 139 GenQuery(lotsTestDocuments), 140 )) 141 142 reporter := gopter.NewFormatedReporter(true, 160, os.Stdout) 143 if !properties.Run(reporter) { 144 t.Errorf("failed with initial seed: %d", seed) 145 } 146 }