github.com/vipernet-xyz/tm@v0.34.24/abci/example/example_test.go (about)

     1  package example
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"net"
     7  	"os"
     8  	"reflect"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/require"
    13  
    14  	"google.golang.org/grpc"
    15  
    16  	"golang.org/x/net/context"
    17  
    18  	"github.com/vipernet-xyz/tm/libs/log"
    19  	tmnet "github.com/vipernet-xyz/tm/libs/net"
    20  
    21  	abcicli "github.com/vipernet-xyz/tm/abci/client"
    22  	"github.com/vipernet-xyz/tm/abci/example/code"
    23  	"github.com/vipernet-xyz/tm/abci/example/kvstore"
    24  	abciserver "github.com/vipernet-xyz/tm/abci/server"
    25  	"github.com/vipernet-xyz/tm/abci/types"
    26  )
    27  
    28  func init() {
    29  	rand.Seed(time.Now().UnixNano())
    30  }
    31  
    32  func TestKVStore(t *testing.T) {
    33  	fmt.Println("### Testing KVStore")
    34  	testStream(t, kvstore.NewApplication())
    35  }
    36  
    37  func TestBaseApp(t *testing.T) {
    38  	fmt.Println("### Testing BaseApp")
    39  	testStream(t, types.NewBaseApplication())
    40  }
    41  
    42  func TestGRPC(t *testing.T) {
    43  	fmt.Println("### Testing GRPC")
    44  	testGRPCSync(t, types.NewGRPCApplication(types.NewBaseApplication()))
    45  }
    46  
    47  func testStream(t *testing.T, app types.Application) {
    48  	numDeliverTxs := 20000
    49  	socketFile := fmt.Sprintf("test-%08x.sock", rand.Int31n(1<<30))
    50  	defer os.Remove(socketFile)
    51  	socket := fmt.Sprintf("unix://%v", socketFile)
    52  
    53  	// Start the listener
    54  	server := abciserver.NewSocketServer(socket, app)
    55  	server.SetLogger(log.TestingLogger().With("module", "abci-server"))
    56  	if err := server.Start(); err != nil {
    57  		require.NoError(t, err, "Error starting socket server")
    58  	}
    59  	t.Cleanup(func() {
    60  		if err := server.Stop(); err != nil {
    61  			t.Error(err)
    62  		}
    63  	})
    64  
    65  	// Connect to the socket
    66  	client := abcicli.NewSocketClient(socket, false)
    67  	client.SetLogger(log.TestingLogger().With("module", "abci-client"))
    68  	if err := client.Start(); err != nil {
    69  		t.Fatalf("Error starting socket client: %v", err.Error())
    70  	}
    71  	t.Cleanup(func() {
    72  		if err := client.Stop(); err != nil {
    73  			t.Error(err)
    74  		}
    75  	})
    76  
    77  	done := make(chan struct{})
    78  	counter := 0
    79  	client.SetResponseCallback(func(req *types.Request, res *types.Response) {
    80  		// Process response
    81  		switch r := res.Value.(type) {
    82  		case *types.Response_DeliverTx:
    83  			counter++
    84  			if r.DeliverTx.Code != code.CodeTypeOK {
    85  				t.Error("DeliverTx failed with ret_code", r.DeliverTx.Code)
    86  			}
    87  			if counter > numDeliverTxs {
    88  				t.Fatalf("Too many DeliverTx responses. Got %d, expected %d", counter, numDeliverTxs)
    89  			}
    90  			if counter == numDeliverTxs {
    91  				go func() {
    92  					time.Sleep(time.Second * 1) // Wait for a bit to allow counter overflow
    93  					close(done)
    94  				}()
    95  				return
    96  			}
    97  		case *types.Response_Flush:
    98  			// ignore
    99  		default:
   100  			t.Error("Unexpected response type", reflect.TypeOf(res.Value))
   101  		}
   102  	})
   103  
   104  	// Write requests
   105  	for counter := 0; counter < numDeliverTxs; counter++ {
   106  		// Send request
   107  		reqRes := client.DeliverTxAsync(types.RequestDeliverTx{Tx: []byte("test")})
   108  		_ = reqRes
   109  		// check err ?
   110  
   111  		// Sometimes send flush messages
   112  		if counter%123 == 0 {
   113  			client.FlushAsync()
   114  			// check err ?
   115  		}
   116  	}
   117  
   118  	// Send final flush message
   119  	client.FlushAsync()
   120  
   121  	<-done
   122  }
   123  
   124  //-------------------------
   125  // test grpc
   126  
   127  func dialerFunc(ctx context.Context, addr string) (net.Conn, error) {
   128  	return tmnet.Connect(addr)
   129  }
   130  
   131  func testGRPCSync(t *testing.T, app types.ABCIApplicationServer) {
   132  	numDeliverTxs := 2000
   133  	socketFile := fmt.Sprintf("/tmp/test-%08x.sock", rand.Int31n(1<<30))
   134  	defer os.Remove(socketFile)
   135  	socket := fmt.Sprintf("unix://%v", socketFile)
   136  
   137  	// Start the listener
   138  	server := abciserver.NewGRPCServer(socket, app)
   139  	server.SetLogger(log.TestingLogger().With("module", "abci-server"))
   140  	if err := server.Start(); err != nil {
   141  		t.Fatalf("Error starting GRPC server: %v", err.Error())
   142  	}
   143  
   144  	t.Cleanup(func() {
   145  		if err := server.Stop(); err != nil {
   146  			t.Error(err)
   147  		}
   148  	})
   149  
   150  	// Connect to the socket
   151  	//nolint:staticcheck // SA1019 Existing use of deprecated but supported dial option.
   152  	conn, err := grpc.Dial(socket, grpc.WithInsecure(), grpc.WithContextDialer(dialerFunc))
   153  	if err != nil {
   154  		t.Fatalf("Error dialing GRPC server: %v", err.Error())
   155  	}
   156  
   157  	t.Cleanup(func() {
   158  		if err := conn.Close(); err != nil {
   159  			t.Error(err)
   160  		}
   161  	})
   162  
   163  	client := types.NewABCIApplicationClient(conn)
   164  
   165  	// Write requests
   166  	for counter := 0; counter < numDeliverTxs; counter++ {
   167  		// Send request
   168  		response, err := client.DeliverTx(context.Background(), &types.RequestDeliverTx{Tx: []byte("test")})
   169  		if err != nil {
   170  			t.Fatalf("Error in GRPC DeliverTx: %v", err.Error())
   171  		}
   172  		counter++
   173  		if response.Code != code.CodeTypeOK {
   174  			t.Error("DeliverTx failed with ret_code", response.Code)
   175  		}
   176  		if counter > numDeliverTxs {
   177  			t.Fatal("Too many DeliverTx responses")
   178  		}
   179  		t.Log("response", counter)
   180  		if counter == numDeliverTxs {
   181  			go func() {
   182  				time.Sleep(time.Second * 1) // Wait for a bit to allow counter overflow
   183  			}()
   184  		}
   185  
   186  	}
   187  }