vitess.io/vitess@v0.16.2/go/vt/vtgate/engine/fuzz.go (about) 1 //go:build gofuzz 2 // +build gofuzz 3 4 /* 5 Copyright 2021 The Vitess Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 */ 19 20 /* 21 DEPENDENCIES: 22 This fuzzer relies heavily on 23 $VTROOT/go/vt/vtgate/engine/fake_vcursor_test.go, 24 and in order to run it, it is required to rename: 25 $VTROOT/go/vt/vtgate/engine/fake_vcursor_test.go 26 to 27 $VTROOT/go/vt/vtgate/engine/fake_vcursor.go 28 29 This is handled by the OSS-fuzz build script and 30 is only important to make note of if the fuzzer 31 is run locally. 32 33 STATUS: 34 The fuzzer does not currently implement executions 35 for all possible API's in the engine package, and 36 it can be considered experimental, as I (@AdamKorcz) 37 am interested in its performance when being run 38 continuously by OSS-fuzz. Needless to say, more 39 APIs can be added with ease. 40 */ 41 42 package engine 43 44 import ( 45 fuzz "github.com/AdaLogics/go-fuzz-headers" 46 47 querypb "vitess.io/vitess/go/vt/proto/query" 48 topodatapb "vitess.io/vitess/go/vt/proto/topodata" 49 ) 50 51 // FuzzEngine implements the fuzzer 52 func FuzzEngine(data []byte) int { 53 c := fuzz.NewConsumer(data) 54 55 index, err := c.GetInt() 56 if err != nil { 57 return 0 58 } 59 switch i := index % 3; i { 60 case 0: 61 execUpdate(c) 62 case 1: 63 execInsert(c) 64 case 2: 65 execRoute(c) 66 default: 67 return 0 68 } 69 return 1 70 } 71 72 // execUpdate implements a wrapper to fuzz Update.Tryexecute() 73 func execUpdate(f *fuzz.ConsumeFuzzer) { 74 upd := &Update{} 75 err := f.GenerateStruct(upd) 76 if err != nil { 77 return 78 } 79 vc := &loggingVCursor{} 80 _, _ = upd.TryExecute(ctx, vc, map[string]*querypb.BindVariable{}, false) 81 } 82 83 // execUpdate implements a wrapper to fuzz Insert.Tryexecute() 84 func execInsert(f *fuzz.ConsumeFuzzer) { 85 ins := &Insert{} 86 err := f.GenerateStruct(ins) 87 if err != nil { 88 return 89 } 90 vc := &loggingVCursor{} 91 _, _ = ins.TryExecute(ctx, vc, map[string]*querypb.BindVariable{}, false) 92 } 93 94 // execUpdate implements a wrapper to fuzz Route.Tryexecute() 95 func execRoute(f *fuzz.ConsumeFuzzer) { 96 sel := &Route{} 97 err := f.GenerateStruct(sel) 98 if err != nil { 99 return 100 } 101 vc := newFuzzDMLTestVCursor("0") 102 _, _ = sel.TryExecute(ctx, vc, map[string]*querypb.BindVariable{}, false) 103 } 104 105 func newFuzzDMLTestVCursor(shards ...string) *loggingVCursor { 106 return &loggingVCursor{shards: shards, resolvedTargetTabletType: topodatapb.TabletType_PRIMARY} 107 }