You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

150 lines
3.7 KiB

7 years ago
7 years ago
8 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
  1. package rpctest
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "path/filepath"
  7. "strings"
  8. "time"
  9. "github.com/tendermint/tendermint/libs/log"
  10. abci "github.com/tendermint/tendermint/abci/types"
  11. cfg "github.com/tendermint/tendermint/config"
  12. cmn "github.com/tendermint/tendermint/libs/common"
  13. nm "github.com/tendermint/tendermint/node"
  14. "github.com/tendermint/tendermint/p2p"
  15. "github.com/tendermint/tendermint/privval"
  16. "github.com/tendermint/tendermint/proxy"
  17. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  18. core_grpc "github.com/tendermint/tendermint/rpc/grpc"
  19. rpcclient "github.com/tendermint/tendermint/rpc/lib/client"
  20. )
  21. var globalConfig *cfg.Config
  22. func waitForRPC() {
  23. laddr := GetConfig().RPC.ListenAddress
  24. client := rpcclient.NewJSONRPCClient(laddr)
  25. ctypes.RegisterAmino(client.Codec())
  26. result := new(ctypes.ResultStatus)
  27. for {
  28. _, err := client.Call("status", map[string]interface{}{}, result)
  29. if err == nil {
  30. return
  31. } else {
  32. fmt.Println("error", err)
  33. time.Sleep(time.Millisecond)
  34. }
  35. }
  36. }
  37. func waitForGRPC() {
  38. client := GetGRPCClient()
  39. for {
  40. _, err := client.Ping(context.Background(), &core_grpc.RequestPing{})
  41. if err == nil {
  42. return
  43. }
  44. }
  45. }
  46. // f**ing long, but unique for each test
  47. func makePathname() string {
  48. // get path
  49. p, err := os.Getwd()
  50. if err != nil {
  51. panic(err)
  52. }
  53. // fmt.Println(p)
  54. sep := string(filepath.Separator)
  55. return strings.Replace(p, sep, "_", -1)
  56. }
  57. func randPort() int {
  58. port, err := cmn.GetFreePort()
  59. if err != nil {
  60. panic(err)
  61. }
  62. return port
  63. }
  64. func makeAddrs() (string, string, string) {
  65. return fmt.Sprintf("tcp://0.0.0.0:%d", randPort()),
  66. fmt.Sprintf("tcp://0.0.0.0:%d", randPort()),
  67. fmt.Sprintf("tcp://0.0.0.0:%d", randPort())
  68. }
  69. // GetConfig returns a config for the test cases as a singleton
  70. func GetConfig() *cfg.Config {
  71. if globalConfig == nil {
  72. pathname := makePathname()
  73. globalConfig = cfg.ResetTestRoot(pathname)
  74. // and we use random ports to run in parallel
  75. tm, rpc, grpc := makeAddrs()
  76. globalConfig.P2P.ListenAddress = tm
  77. globalConfig.RPC.ListenAddress = rpc
  78. globalConfig.RPC.CORSAllowedOrigins = []string{"https://tendermint.com/"}
  79. globalConfig.RPC.GRPCListenAddress = grpc
  80. globalConfig.TxIndex.IndexTags = "app.creator,tx.height" // see kvstore application
  81. }
  82. return globalConfig
  83. }
  84. func GetGRPCClient() core_grpc.BroadcastAPIClient {
  85. grpcAddr := globalConfig.RPC.GRPCListenAddress
  86. return core_grpc.StartGRPCClient(grpcAddr)
  87. }
  88. // StartTendermint starts a test tendermint server in a go routine and returns when it is initialized
  89. func StartTendermint(app abci.Application) *nm.Node {
  90. node := NewTendermint(app)
  91. err := node.Start()
  92. if err != nil {
  93. panic(err)
  94. }
  95. // wait for rpc
  96. waitForRPC()
  97. waitForGRPC()
  98. fmt.Println("Tendermint running!")
  99. return node
  100. }
  101. // StopTendermint stops a test tendermint server, waits until it's stopped and
  102. // cleans up test/config files.
  103. func StopTendermint(node *nm.Node) {
  104. node.Stop()
  105. node.Wait()
  106. os.RemoveAll(node.Config().RootDir)
  107. }
  108. // NewTendermint creates a new tendermint server and sleeps forever
  109. func NewTendermint(app abci.Application) *nm.Node {
  110. // Create & start node
  111. config := GetConfig()
  112. logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
  113. logger = log.NewFilter(logger, log.AllowError())
  114. pvKeyFile := config.PrivValidatorKeyFile()
  115. pvKeyStateFile := config.PrivValidatorStateFile()
  116. pv := privval.LoadOrGenFilePV(pvKeyFile, pvKeyStateFile)
  117. papp := proxy.NewLocalClientCreator(app)
  118. nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
  119. if err != nil {
  120. panic(err)
  121. }
  122. node, err := nm.NewNode(config, pv, nodeKey, papp,
  123. nm.DefaultGenesisDocProviderFunc(config),
  124. nm.DefaultDBProvider,
  125. nm.DefaultMetricsProvider(config.Instrumentation),
  126. logger)
  127. if err != nil {
  128. panic(err)
  129. }
  130. return node
  131. }