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.

162 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. chainID string
  20. rpcAddr string
  21. requestAddr string
  22. websocketAddr string
  23. websocketEndpoint string
  24. clientURI *client.ClientURI
  25. clientJSON *client.ClientJSONRPC
  26. )
  27. // initialize config and create new node
  28. func init() {
  29. config = tendermint_test.ResetConfig("rpc_test_client_test")
  30. chainID = config.GetString("chain_id")
  31. rpcAddr = config.GetString("rpc_laddr")
  32. requestAddr = rpcAddr
  33. websocketAddr = rpcAddr
  34. websocketEndpoint = "/websocket"
  35. clientURI = client.NewClientURI(requestAddr)
  36. clientJSON = client.NewClientJSONRPC(requestAddr)
  37. // TODO: change consensus/state.go timeouts to be shorter
  38. // start a node
  39. ready := make(chan struct{})
  40. go newNode(ready)
  41. <-ready
  42. }
  43. // create a new node and sleep forever
  44. func newNode(ready chan struct{}) {
  45. // Create & start node
  46. privValidatorFile := config.GetString("priv_validator_file")
  47. privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
  48. node = nm.NewNode(config, privValidator, nm.GetProxyApp)
  49. protocol, address := nm.ProtocolAndAddress(config.GetString("node_laddr"))
  50. l := p2p.NewDefaultListener(protocol, address, 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. panic(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. panic(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. panic(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. panic(Fmt("%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. panic(err) // Show the stack trace.
  132. }
  133. } else {
  134. wsc.Stop()
  135. panic(Fmt("%s event was not expected", eventid))
  136. }
  137. case err := <-errCh:
  138. panic(err) // Show the stack trace.
  139. }
  140. }
  141. //--------------------------------------------------------------------------------