github.com/ari-anchor/sei-tendermint@v0.0.0-20230519144642-dc826b7b56bb/rpc/test/helpers.go (about)

     1  package rpctest
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"testing"
     8  	"time"
     9  
    10  	abciclient "github.com/ari-anchor/sei-tendermint/abci/client"
    11  	abci "github.com/ari-anchor/sei-tendermint/abci/types"
    12  	"github.com/ari-anchor/sei-tendermint/config"
    13  	"github.com/ari-anchor/sei-tendermint/libs/log"
    14  	tmnet "github.com/ari-anchor/sei-tendermint/libs/net"
    15  	"github.com/ari-anchor/sei-tendermint/libs/service"
    16  	"github.com/ari-anchor/sei-tendermint/node"
    17  	"github.com/ari-anchor/sei-tendermint/rpc/coretypes"
    18  	rpcclient "github.com/ari-anchor/sei-tendermint/rpc/jsonrpc/client"
    19  	"go.opentelemetry.io/otel/sdk/trace"
    20  )
    21  
    22  // Options helps with specifying some parameters for our RPC testing for greater
    23  // control.
    24  type Options struct {
    25  	suppressStdout bool
    26  }
    27  
    28  // waitForRPC connects to the RPC service and blocks until a /status call succeeds.
    29  func waitForRPC(ctx context.Context, conf *config.Config) {
    30  	laddr := conf.RPC.ListenAddress
    31  	client, err := rpcclient.New(laddr)
    32  	if err != nil {
    33  		panic(err)
    34  	}
    35  	result := new(coretypes.ResultStatus)
    36  	for {
    37  		err := client.Call(ctx, "status", map[string]interface{}{}, result)
    38  		if err == nil {
    39  			return
    40  		}
    41  
    42  		fmt.Println("error", err)
    43  		time.Sleep(time.Millisecond)
    44  	}
    45  }
    46  
    47  func randPort() int {
    48  	port, err := tmnet.GetFreePort()
    49  	if err != nil {
    50  		panic(err)
    51  	}
    52  	return port
    53  }
    54  
    55  // makeAddrs constructs local listener addresses for node services.  This
    56  // implementation uses random ports so test instances can run concurrently.
    57  func makeAddrs() (p2pAddr, rpcAddr string) {
    58  	const addrTemplate = "tcp://127.0.0.1:%d"
    59  	return fmt.Sprintf(addrTemplate, randPort()), fmt.Sprintf(addrTemplate, randPort())
    60  }
    61  
    62  func CreateConfig(t *testing.T, testName string) (*config.Config, error) {
    63  	c, err := config.ResetTestRoot(t.TempDir(), testName)
    64  	if err != nil {
    65  		return nil, err
    66  	}
    67  
    68  	p2pAddr, rpcAddr := makeAddrs()
    69  	c.P2P.ListenAddress = p2pAddr
    70  	c.RPC.ListenAddress = rpcAddr
    71  	c.RPC.EventLogWindowSize = 5 * time.Minute
    72  	c.Consensus.WalPath = "rpc-test"
    73  	c.RPC.CORSAllowedOrigins = []string{"https://tendermint.com/"}
    74  	return c, nil
    75  }
    76  
    77  type ServiceCloser func(context.Context) error
    78  
    79  func StartTendermint(
    80  	ctx context.Context,
    81  	conf *config.Config,
    82  	app abci.Application,
    83  	opts ...func(*Options),
    84  ) (service.Service, ServiceCloser, error) {
    85  	ctx, cancel := context.WithCancel(ctx)
    86  
    87  	nodeOpts := &Options{}
    88  	for _, opt := range opts {
    89  		opt(nodeOpts)
    90  	}
    91  	var logger log.Logger
    92  	if nodeOpts.suppressStdout {
    93  		logger = log.NewNopLogger()
    94  	} else {
    95  		var err error
    96  		logger, err = log.NewDefaultLogger(log.LogFormatPlain, log.LogLevelInfo)
    97  		if err != nil {
    98  			return nil, func(_ context.Context) error { cancel(); return nil }, err
    99  		}
   100  
   101  	}
   102  	papp := abciclient.NewLocalClient(logger, app)
   103  	tmNode, err := node.New(
   104  		ctx,
   105  		conf,
   106  		logger,
   107  		make(chan struct{}),
   108  		papp,
   109  		nil,
   110  		[]trace.TracerProviderOption{},
   111  		node.NoOpMetricsProvider(),
   112  	)
   113  	if err != nil {
   114  		return nil, func(_ context.Context) error { cancel(); return nil }, err
   115  	}
   116  
   117  	err = tmNode.Start(ctx)
   118  	if err != nil {
   119  		return nil, func(_ context.Context) error { cancel(); return nil }, err
   120  	}
   121  
   122  	waitForRPC(ctx, conf)
   123  
   124  	if !nodeOpts.suppressStdout {
   125  		fmt.Println("Tendermint running!")
   126  	}
   127  
   128  	return tmNode, func(ctx context.Context) error {
   129  		cancel()
   130  		tmNode.Wait()
   131  		os.RemoveAll(conf.RootDir)
   132  		return nil
   133  	}, nil
   134  }
   135  
   136  // SuppressStdout is an option that tries to make sure the RPC test Tendermint
   137  // node doesn't log anything to stdout.
   138  func SuppressStdout(o *Options) {
   139  	o.suppressStdout = true
   140  }