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