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.

163 lines
4.1 KiB

  1. package rpctest
  2. import (
  3. "testing"
  4. "time"
  5. . "github.com/tendermint/go-common"
  6. cfg "github.com/tendermint/go-config"
  7. "github.com/tendermint/go-p2p"
  8. "github.com/tendermint/go-wire"
  9. client "github.com/tendermint/go-rpc/client"
  10. "github.com/tendermint/tendermint/config/tendermint_test"
  11. nm "github.com/tendermint/tendermint/node"
  12. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  13. "github.com/tendermint/tendermint/types"
  14. )
  15. // global variables for use across all tests
  16. var (
  17. config cfg.Config
  18. node *nm.Node
  19. mempoolCount = 0
  20. chainID string
  21. rpcAddr string
  22. requestAddr string
  23. websocketAddr string
  24. websocketEndpoint string
  25. clientURI *client.ClientURI
  26. clientJSON *client.ClientJSONRPC
  27. )
  28. // initialize config and create new node
  29. func init() {
  30. config = tendermint_test.ResetConfig("rpc_test_client_test")
  31. chainID = config.GetString("chain_id")
  32. rpcAddr = config.GetString("rpc_laddr")
  33. requestAddr = rpcAddr
  34. websocketAddr = rpcAddr
  35. websocketEndpoint = "/websocket"
  36. clientURI = client.NewClientURI(requestAddr)
  37. clientJSON = client.NewClientJSONRPC(requestAddr)
  38. // TODO: change consensus/state.go timeouts to be shorter
  39. // start a node
  40. ready := make(chan struct{})
  41. go newNode(ready)
  42. <-ready
  43. }
  44. // create a new node and sleep forever
  45. func newNode(ready chan struct{}) {
  46. // Create & start node
  47. privValidatorFile := config.GetString("priv_validator_file")
  48. privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
  49. node = nm.NewNode(config, privValidator, nm.GetProxyApp)
  50. l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), true)
  51. node.AddListener(l)
  52. node.Start()
  53. // Run the RPC server.
  54. node.StartRPC()
  55. ready <- struct{}{}
  56. // Sleep forever
  57. ch := make(chan struct{})
  58. <-ch
  59. }
  60. //--------------------------------------------------------------------------------
  61. // Utilities for testing the websocket service
  62. // create a new connection
  63. func newWSClient(t *testing.T) *client.WSClient {
  64. wsc := client.NewWSClient(websocketAddr, websocketEndpoint)
  65. if _, err := wsc.Start(); err != nil {
  66. t.Fatal(err)
  67. }
  68. return wsc
  69. }
  70. // subscribe to an event
  71. func subscribe(t *testing.T, wsc *client.WSClient, eventid string) {
  72. if err := wsc.Subscribe(eventid); err != nil {
  73. t.Fatal(err)
  74. }
  75. }
  76. // unsubscribe from an event
  77. func unsubscribe(t *testing.T, wsc *client.WSClient, eventid string) {
  78. if err := wsc.Unsubscribe(eventid); err != nil {
  79. t.Fatal(err)
  80. }
  81. }
  82. // wait for an event; do things that might trigger events, and check them when they are received
  83. // the check function takes an event id and the byte slice read off the ws
  84. func waitForEvent(t *testing.T, wsc *client.WSClient, eventid string, dieOnTimeout bool, f func(), check func(string, interface{}) error) {
  85. // go routine to wait for webscoket msg
  86. goodCh := make(chan interface{})
  87. errCh := make(chan error)
  88. // Read message
  89. go func() {
  90. var err error
  91. LOOP:
  92. for {
  93. select {
  94. case r := <-wsc.ResultsCh:
  95. result := new(ctypes.TMResult)
  96. wire.ReadJSONPtr(result, r, &err)
  97. if err != nil {
  98. errCh <- err
  99. break LOOP
  100. }
  101. event, ok := (*result).(*ctypes.ResultEvent)
  102. if ok && event.Name == eventid {
  103. goodCh <- event.Data
  104. break LOOP
  105. }
  106. case err := <-wsc.ErrorsCh:
  107. errCh <- err
  108. break LOOP
  109. case <-wsc.Quit:
  110. break LOOP
  111. }
  112. }
  113. }()
  114. // do stuff (transactions)
  115. f()
  116. // wait for an event or timeout
  117. timeout := time.NewTimer(10 * time.Second)
  118. select {
  119. case <-timeout.C:
  120. if dieOnTimeout {
  121. wsc.Stop()
  122. t.Fatalf("%s event was not received in time", eventid)
  123. }
  124. // else that's great, we didn't hear the event
  125. // and we shouldn't have
  126. case eventData := <-goodCh:
  127. if dieOnTimeout {
  128. // message was received and expected
  129. // run the check
  130. if err := check(eventid, eventData); err != nil {
  131. t.Fatal(err) // Show the stack trace.
  132. }
  133. } else {
  134. wsc.Stop()
  135. t.Fatalf("%s event was not expected", eventid)
  136. }
  137. case err := <-errCh:
  138. t.Fatal(err)
  139. panic(err) // Show the stack trace.
  140. }
  141. }
  142. //--------------------------------------------------------------------------------