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.

159 lines
3.9 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. )
  14. // global variables for use across all tests
  15. var (
  16. config cfg.Config
  17. node *nm.Node
  18. chainID string
  19. rpcAddr string
  20. requestAddr string
  21. websocketAddr string
  22. websocketEndpoint string
  23. clientURI *client.ClientURI
  24. clientJSON *client.ClientJSONRPC
  25. )
  26. // initialize config and create new node
  27. func init() {
  28. config = tendermint_test.ResetConfig("rpc_test_client_test")
  29. chainID = config.GetString("chain_id")
  30. rpcAddr = config.GetString("rpc_laddr")
  31. requestAddr = rpcAddr
  32. websocketAddr = rpcAddr
  33. websocketEndpoint = "/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. node = nm.NewNodeDefault(config)
  46. protocol, address := nm.ProtocolAndAddress(config.GetString("node_laddr"))
  47. l := p2p.NewDefaultListener(protocol, address, true)
  48. node.AddListener(l)
  49. node.Start()
  50. // Run the RPC server.
  51. node.StartRPC()
  52. ready <- struct{}{}
  53. // Sleep forever
  54. ch := make(chan struct{})
  55. <-ch
  56. }
  57. //--------------------------------------------------------------------------------
  58. // Utilities for testing the websocket service
  59. // create a new connection
  60. func newWSClient(t *testing.T) *client.WSClient {
  61. wsc := client.NewWSClient(websocketAddr, websocketEndpoint)
  62. if _, err := wsc.Start(); err != nil {
  63. panic(err)
  64. }
  65. return wsc
  66. }
  67. // subscribe to an event
  68. func subscribe(t *testing.T, wsc *client.WSClient, eventid string) {
  69. if err := wsc.Subscribe(eventid); err != nil {
  70. panic(err)
  71. }
  72. }
  73. // unsubscribe from an event
  74. func unsubscribe(t *testing.T, wsc *client.WSClient, eventid string) {
  75. if err := wsc.Unsubscribe(eventid); err != nil {
  76. panic(err)
  77. }
  78. }
  79. // wait for an event; do things that might trigger events, and check them when they are received
  80. // the check function takes an event id and the byte slice read off the ws
  81. func waitForEvent(t *testing.T, wsc *client.WSClient, eventid string, dieOnTimeout bool, f func(), check func(string, interface{}) error) {
  82. // go routine to wait for webscoket msg
  83. goodCh := make(chan interface{})
  84. errCh := make(chan error)
  85. // Read message
  86. go func() {
  87. var err error
  88. LOOP:
  89. for {
  90. select {
  91. case r := <-wsc.ResultsCh:
  92. result := new(ctypes.TMResult)
  93. wire.ReadJSONPtr(result, r, &err)
  94. if err != nil {
  95. errCh <- err
  96. break LOOP
  97. }
  98. event, ok := (*result).(*ctypes.ResultEvent)
  99. if ok && event.Name == eventid {
  100. goodCh <- event.Data
  101. break LOOP
  102. }
  103. case err := <-wsc.ErrorsCh:
  104. errCh <- err
  105. break LOOP
  106. case <-wsc.Quit:
  107. break LOOP
  108. }
  109. }
  110. }()
  111. // do stuff (transactions)
  112. f()
  113. // wait for an event or timeout
  114. timeout := time.NewTimer(10 * time.Second)
  115. select {
  116. case <-timeout.C:
  117. if dieOnTimeout {
  118. wsc.Stop()
  119. panic(Fmt("%s event was not received in time", eventid))
  120. }
  121. // else that's great, we didn't hear the event
  122. // and we shouldn't have
  123. case eventData := <-goodCh:
  124. if dieOnTimeout {
  125. // message was received and expected
  126. // run the check
  127. if err := check(eventid, eventData); err != nil {
  128. panic(err) // Show the stack trace.
  129. }
  130. } else {
  131. wsc.Stop()
  132. panic(Fmt("%s event was not expected", eventid))
  133. }
  134. case err := <-errCh:
  135. panic(err) // Show the stack trace.
  136. }
  137. }
  138. //--------------------------------------------------------------------------------