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