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.

219 lines
5.1 KiB

  1. package rpctest
  2. import (
  3. "fmt"
  4. "net/http"
  5. "testing"
  6. "time"
  7. "github.com/gorilla/websocket"
  8. . "github.com/tendermint/go-common"
  9. "github.com/tendermint/go-p2p"
  10. "github.com/tendermint/go-wire"
  11. "github.com/tendermint/go-events"
  12. client "github.com/tendermint/go-rpc/client"
  13. "github.com/tendermint/go-rpc/types"
  14. _ "github.com/tendermint/tendermint/config/tendermint_test"
  15. nm "github.com/tendermint/tendermint/node"
  16. "github.com/tendermint/tendermint/types"
  17. )
  18. // global variables for use across all tests
  19. var (
  20. node *nm.Node
  21. mempoolCount = 0
  22. chainID string
  23. rpcAddr, requestAddr, websocketAddr string
  24. clientURI *client.ClientURI
  25. clientJSON *client.ClientJSONRPC
  26. )
  27. // initialize config and create new node
  28. func init() {
  29. initConfig()
  30. chainID = config.GetString("chain_id")
  31. rpcAddr = config.GetString("rpc_laddr")
  32. requestAddr = "http://" + rpcAddr
  33. websocketAddr = "ws://" + rpcAddr + "/websocket"
  34. clientURI = client.NewClientURI(requestAddr)
  35. clientJSON = client.NewClientJSONRPC(requestAddr)
  36. // TODO: change consensus/state.go timeouts to be shorter
  37. // start a node
  38. ready := make(chan struct{})
  39. go newNode(ready)
  40. <-ready
  41. }
  42. // create a new node and sleep forever
  43. func newNode(ready chan struct{}) {
  44. // Create & start node
  45. privValidatorFile := config.GetString("priv_validator_file")
  46. privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
  47. node = nm.NewNode(privValidator)
  48. l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), true)
  49. node.AddListener(l)
  50. node.Start()
  51. // Run the RPC server.
  52. node.StartRPC()
  53. ready <- struct{}{}
  54. // Sleep forever
  55. ch := make(chan struct{})
  56. <-ch
  57. }
  58. //--------------------------------------------------------------------------------
  59. // Utilities for testing the websocket service
  60. // create a new connection
  61. func newWSCon(t *testing.T) *websocket.Conn {
  62. dialer := websocket.DefaultDialer
  63. rHeader := http.Header{}
  64. con, r, err := dialer.Dial(websocketAddr, rHeader)
  65. fmt.Println("response", r)
  66. if err != nil {
  67. t.Fatal(err)
  68. }
  69. return con
  70. }
  71. // subscribe to an event
  72. func subscribe(t *testing.T, con *websocket.Conn, eventid string) {
  73. err := con.WriteJSON(rpctypes.RPCRequest{
  74. JSONRPC: "2.0",
  75. ID: "",
  76. Method: "subscribe",
  77. Params: []interface{}{eventid},
  78. })
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. }
  83. // unsubscribe from an event
  84. func unsubscribe(t *testing.T, con *websocket.Conn, eventid string) {
  85. err := con.WriteJSON(rpctypes.RPCRequest{
  86. JSONRPC: "2.0",
  87. ID: "",
  88. Method: "unsubscribe",
  89. Params: []interface{}{eventid},
  90. })
  91. if err != nil {
  92. t.Fatal(err)
  93. }
  94. }
  95. // wait for an event; do things that might trigger events, and check them when they are received
  96. // the check function takes an event id and the byte slice read off the ws
  97. func waitForEvent(t *testing.T, con *websocket.Conn, eventid string, dieOnTimeout bool, f func(), check func(string, []byte) error) {
  98. // go routine to wait for webscoket msg
  99. goodCh := make(chan []byte)
  100. errCh := make(chan error)
  101. quitCh := make(chan struct{})
  102. defer close(quitCh)
  103. // Read message
  104. go func() {
  105. for {
  106. _, p, err := con.ReadMessage()
  107. if err != nil {
  108. errCh <- err
  109. break
  110. } else {
  111. // if the event id isnt what we're waiting on
  112. // ignore it
  113. var response rpctypes.RPCResponse
  114. var err error
  115. wire.ReadJSON(&response, p, &err)
  116. if err != nil {
  117. errCh <- err
  118. break
  119. }
  120. event, ok := response.Result.(*events.EventResult)
  121. if ok && event.Event == eventid {
  122. goodCh <- p
  123. break
  124. }
  125. }
  126. }
  127. }()
  128. // do stuff (transactions)
  129. f()
  130. // wait for an event or timeout
  131. timeout := time.NewTimer(10 * time.Second)
  132. select {
  133. case <-timeout.C:
  134. if dieOnTimeout {
  135. con.Close()
  136. t.Fatalf("%s event was not received in time", eventid)
  137. }
  138. // else that's great, we didn't hear the event
  139. // and we shouldn't have
  140. case p := <-goodCh:
  141. if dieOnTimeout {
  142. // message was received and expected
  143. // run the check
  144. err := check(eventid, p)
  145. if err != nil {
  146. t.Fatal(err)
  147. panic(err) // Show the stack trace.
  148. }
  149. } else {
  150. con.Close()
  151. t.Fatalf("%s event was not expected", eventid)
  152. }
  153. case err := <-errCh:
  154. t.Fatal(err)
  155. panic(err) // Show the stack trace.
  156. }
  157. }
  158. //--------------------------------------------------------------------------------
  159. func unmarshalResponseNewBlock(b []byte) (*types.Block, error) {
  160. // unmarshall and assert somethings
  161. var response rpctypes.RPCResponse
  162. var err error
  163. wire.ReadJSON(&response, b, &err)
  164. if err != nil {
  165. return nil, err
  166. }
  167. if response.Error != "" {
  168. return nil, fmt.Errorf(response.Error)
  169. }
  170. block := response.Result.(*events.EventResult).Data.(types.EventDataNewBlock).Block
  171. return block, nil
  172. }
  173. func unmarshalValidateBlockchain(t *testing.T, con *websocket.Conn, eid string) {
  174. var initBlockN int
  175. for i := 0; i < 3; i++ {
  176. waitForEvent(t, con, eid, true, func() {}, func(eid string, b []byte) error {
  177. block, err := unmarshalResponseNewBlock(b)
  178. if err != nil {
  179. return err
  180. }
  181. if i == 0 {
  182. initBlockN = block.Header.Height
  183. } else {
  184. if block.Header.Height != initBlockN+i {
  185. return fmt.Errorf("Expected block %d, got block %d", i, block.Header.Height)
  186. }
  187. }
  188. return nil
  189. })
  190. }
  191. }