vitess.io/vitess@v0.16.2/go/vt/vtgate/grpcvtgateconn/fuzz_flaky_test.go (about) 1 //go:build gofuzz 2 // +build gofuzz 3 4 /* 5 Copyright 2021 The Vitess Authors. 6 Licensed under the Apache License, Version 2.0 (the "License"); 7 you may not use this file except in compliance with the License. 8 You may obtain a copy of the License at 9 http://www.apache.org/licenses/LICENSE-2.0 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package grpcvtgateconn 18 19 import ( 20 "context" 21 "fmt" 22 "io" 23 "net" 24 "os" 25 "testing" 26 27 "github.com/spf13/pflag" 28 "github.com/stretchr/testify/require" 29 "google.golang.org/grpc" 30 31 "vitess.io/vitess/go/vt/grpcclient" 32 "vitess.io/vitess/go/vt/servenv" 33 "vitess.io/vitess/go/vt/vtgate/grpcvtgateservice" 34 "vitess.io/vitess/go/vt/vtgate/vtgateconn" 35 ) 36 37 func init() { 38 testing.Init() 39 } 40 41 func IsDivisibleBy(n int, divisibleby int) bool { 42 return (n % divisibleby) == 0 43 } 44 45 func Fuzz(data []byte) int { 46 t := &testing.T{} 47 if len(data) < 20 { 48 return -1 49 } 50 if IsDivisibleBy(len(data), 10) == false { 51 return -1 52 } 53 54 var opts []grpc.ServerOption 55 // fake service 56 service := CreateFakeServer(t) 57 58 // listen on a random port 59 listener, err := net.Listen("tcp", "127.0.0.1:0") 60 if err != nil { 61 fmt.Println("Cannot listen") 62 return -1 63 } 64 defer listener.Close() 65 66 // add auth interceptors 67 opts = append(opts, grpc.StreamInterceptor(servenv.FakeAuthStreamInterceptor)) 68 opts = append(opts, grpc.UnaryInterceptor(servenv.FakeAuthUnaryInterceptor)) 69 70 // Create a gRPC server and listen on the port 71 server := grpc.NewServer(opts...) 72 grpcvtgateservice.RegisterForTest(server, service) 73 go server.Serve(listener) 74 defer server.GracefulStop() 75 76 authJSON := `{ 77 "Username": "valid", 78 "Password": "valid" 79 }` 80 81 f, err := os.CreateTemp("", "static_auth_creds.json") 82 if err != nil { 83 return -1 84 } 85 defer os.Remove(f.Name()) 86 if _, err := io.WriteString(f, authJSON); err != nil { 87 return -1 88 } 89 if err := f.Close(); err != nil { 90 return -1 91 } 92 93 // Create a Go RPC client connecting to the server 94 ctx := context.Background() 95 fs := pflag.NewFlagSet("", pflag.ContinueOnError) 96 grpcclient.RegisterFlags(fs) 97 98 err = fs.Parse([]string{ 99 "--grpc_auth_static_client_creds", 100 f.Name(), 101 }) 102 require.NoError(t, err, "failed to set `--grpc_auth_static_client_creds=%s`", f.Name()) 103 client, err := dial(ctx, listener.Addr().String()) 104 if err != nil { 105 fmt.Println("dial failed") 106 return -1 107 } 108 defer client.Close() 109 110 RegisterTestDialProtocol(client) 111 conn, err := vtgateconn.DialProtocol(context.Background(), "test", "") 112 if err != nil { 113 fmt.Println("Got err from vtgateconn.DialProtocol") 114 return -1 115 } 116 session := conn.Session("connection_ks@rdonly", testExecuteOptions) 117 118 // Do the actual fuzzing: 119 // 10 executions per fuzz run 120 ctx = newContext() 121 chunkSize := len(data) / 10 122 for i := 0; i < len(data); i = i + chunkSize { 123 from := i //lower 124 to := i + chunkSize //upper 125 _, _ = session.Execute(ctx, string(data[from:to]), nil) 126 } 127 return 1 128 }