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 }