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  }