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