mirror of
https://github.com/tendermint/tendermint.git
synced 2026-07-20 23:12:44 +00:00
f0db0ff260
In my mind this is "don't make grpc any weirder than it has to be." We definitely don't need to export this type: if you're using gRPC for ABCI you *probably* don't want to also depend on the huge swath of the code that The ideal case is you generate the proto yourself, standup a gRPC service on your own (presumably because your application has other gRPC services that you want to expose,) and then your application doesn't need to interact with the types package at all. This is definitely the case for anyone who uses gRPC and doesn't use Go (which is likely the predominant use case.) If you're using Go, and want to use tendermint's service runner for running your gRPC service, you can, but at this point (as before,) you're already importing the `types` package (and you were before,) I've just eliminated an intermediate type that you shouldn't need to think about. Reviewers: I think the change is pretty rote, but the logic/user-story above would definitely be better for being validated by someone other than me. :)
146 lines
3.9 KiB
Go
146 lines
3.9 KiB
Go
package example
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"math/rand"
|
|
"net"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"google.golang.org/grpc"
|
|
"google.golang.org/grpc/credentials/insecure"
|
|
|
|
"github.com/tendermint/tendermint/libs/log"
|
|
tmnet "github.com/tendermint/tendermint/libs/net"
|
|
|
|
abciclient "github.com/tendermint/tendermint/abci/client"
|
|
"github.com/tendermint/tendermint/abci/example/code"
|
|
"github.com/tendermint/tendermint/abci/example/kvstore"
|
|
abciserver "github.com/tendermint/tendermint/abci/server"
|
|
"github.com/tendermint/tendermint/abci/types"
|
|
)
|
|
|
|
func init() {
|
|
rand.Seed(time.Now().UnixNano())
|
|
}
|
|
|
|
func TestKVStore(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
logger := log.NewNopLogger()
|
|
|
|
t.Log("### Testing KVStore")
|
|
testBulk(ctx, t, logger, kvstore.NewApplication())
|
|
}
|
|
|
|
func TestBaseApp(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
logger := log.NewNopLogger()
|
|
|
|
t.Log("### Testing BaseApp")
|
|
testBulk(ctx, t, logger, types.NewBaseApplication())
|
|
}
|
|
|
|
func TestGRPC(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
|
|
logger := log.NewNopLogger()
|
|
|
|
t.Log("### Testing GRPC")
|
|
testGRPCSync(ctx, t, logger, types.NewBaseApplication())
|
|
}
|
|
|
|
func testBulk(ctx context.Context, t *testing.T, logger log.Logger, app types.Application) {
|
|
t.Helper()
|
|
|
|
const numDeliverTxs = 700000
|
|
socketFile := fmt.Sprintf("test-%08x.sock", rand.Int31n(1<<30))
|
|
defer os.Remove(socketFile)
|
|
socket := fmt.Sprintf("unix://%v", socketFile)
|
|
// Start the listener
|
|
server := abciserver.NewSocketServer(logger.With("module", "abci-server"), socket, app)
|
|
t.Cleanup(server.Wait)
|
|
err := server.Start(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// Connect to the socket
|
|
client := abciclient.NewSocketClient(logger.With("module", "abci-client"), socket, false)
|
|
t.Cleanup(client.Wait)
|
|
|
|
err = client.Start(ctx)
|
|
require.NoError(t, err)
|
|
|
|
// Construct request
|
|
rfb := types.RequestFinalizeBlock{Txs: make([][]byte, numDeliverTxs)}
|
|
for counter := 0; counter < numDeliverTxs; counter++ {
|
|
rfb.Txs[counter] = []byte("test")
|
|
}
|
|
// Send bulk request
|
|
res, err := client.FinalizeBlock(ctx, rfb)
|
|
require.NoError(t, err)
|
|
require.Equal(t, numDeliverTxs, len(res.TxResults), "Number of txs doesn't match")
|
|
for _, tx := range res.TxResults {
|
|
require.Equal(t, tx.Code, code.CodeTypeOK, "Tx failed")
|
|
}
|
|
|
|
// Send final flush message
|
|
err = client.Flush(ctx)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
//-------------------------
|
|
// test grpc
|
|
|
|
func dialerFunc(ctx context.Context, addr string) (net.Conn, error) {
|
|
return tmnet.Connect(addr)
|
|
}
|
|
|
|
func testGRPCSync(ctx context.Context, t *testing.T, logger log.Logger, app types.Application) {
|
|
t.Helper()
|
|
numDeliverTxs := 680000
|
|
socketFile := fmt.Sprintf("/tmp/test-%08x.sock", rand.Int31n(1<<30))
|
|
defer os.Remove(socketFile)
|
|
socket := fmt.Sprintf("unix://%v", socketFile)
|
|
|
|
// Start the listener
|
|
server := abciserver.NewGRPCServer(logger.With("module", "abci-server"), socket, app)
|
|
|
|
require.NoError(t, server.Start(ctx))
|
|
t.Cleanup(server.Wait)
|
|
|
|
// Connect to the socket
|
|
conn, err := grpc.Dial(socket,
|
|
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
|
grpc.WithContextDialer(dialerFunc),
|
|
)
|
|
require.NoError(t, err, "Error dialing GRPC server")
|
|
|
|
t.Cleanup(func() {
|
|
if err := conn.Close(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
})
|
|
|
|
client := types.NewABCIApplicationClient(conn)
|
|
|
|
// Construct request
|
|
rfb := types.RequestFinalizeBlock{Txs: make([][]byte, numDeliverTxs)}
|
|
for counter := 0; counter < numDeliverTxs; counter++ {
|
|
rfb.Txs[counter] = []byte("test")
|
|
}
|
|
|
|
// Send request
|
|
response, err := client.FinalizeBlock(ctx, &rfb)
|
|
require.NoError(t, err, "Error in GRPC FinalizeBlock")
|
|
require.Equal(t, numDeliverTxs, len(response.TxResults), "Number of txs returned via GRPC doesn't match")
|
|
for _, tx := range response.TxResults {
|
|
require.Equal(t, tx.Code, code.CodeTypeOK, "Tx failed")
|
|
}
|
|
}
|