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.0 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. l := p2p.NewDefaultListener("tcp", config.GetString("node_laddr"), true)
  50. node.AddListener(l)
  51. node.Start()
  52. // Run the RPC server.
  53. node.StartRPC()
  54. ready <- struct{}{}
  55. // Sleep forever
  56. ch := make(chan struct{})
  57. <-ch
  58. }
  59. //--------------------------------------------------------------------------------
  60. // Utilities for testing the websocket service
  61. // create a new connection
  62. func newWSClient(t *testing.T) *client.WSClient {
  63. wsc := client.NewWSClient(websocketAddr, websocketEndpoint)
  64. if _, err := wsc.Start(); err != nil {
  65. t.Fatal(err)
  66. }
  67. return wsc
  68. }
  69. // subscribe to an event
  70. func subscribe(t *testing.T, wsc *client.WSClient, eventid string) {
  71. if err := wsc.Subscribe(eventid); err != nil {
  72. t.Fatal(err)
  73. }
  74. }
  75. // unsubscribe from an event
  76. func unsubscribe(t *testing.T, wsc *client.WSClient, eventid string) {
  77. if err := wsc.Unsubscribe(eventid); err != nil {
  78. t.Fatal(err)
  79. }
  80. }
  81. // wait for an event; do things that might trigger events, and check them when they are received
  82. // the check function takes an event id and the byte slice read off the ws
  83. func waitForEvent(t *testing.T, wsc *client.WSClient, eventid string, dieOnTimeout bool, f func(), check func(string, interface{}) error) {
  84. // go routine to wait for webscoket msg
  85. goodCh := make(chan interface{})
  86. errCh := make(chan error)
  87. // Read message
  88. go func() {
  89. var err error
  90. LOOP:
  91. for {
  92. select {
  93. case r := <-wsc.ResultsCh:
  94. result := new(ctypes.TMResult)
  95. wire.ReadJSONPtr(result, r, &err)
  96. if err != nil {
  97. errCh <- err
  98. break LOOP
  99. }
  100. event, ok := (*result).(*ctypes.ResultEvent)
  101. if ok && event.Name == eventid {
  102. goodCh <- event.Data
  103. break LOOP
  104. }
  105. case err := <-wsc.ErrorsCh:
  106. errCh <- err
  107. break LOOP
  108. case <-wsc.Quit:
  109. break LOOP
  110. }
  111. }
  112. }()
  113. // do stuff (transactions)
  114. f()
  115. // wait for an event or timeout
  116. timeout := time.NewTimer(10 * time.Second)
  117. select {
  118. case <-timeout.C:
  119. if dieOnTimeout {
  120. wsc.Stop()
  121. t.Fatalf("%s event was not received in time", eventid)
  122. }
  123. // else that's great, we didn't hear the event
  124. // and we shouldn't have
  125. case eventData := <-goodCh:
  126. if dieOnTimeout {
  127. // message was received and expected
  128. // run the check
  129. if err := check(eventid, eventData); err != nil {
  130. t.Fatal(err) // Show the stack trace.
  131. }
  132. } else {
  133. wsc.Stop()
  134. t.Fatalf("%s event was not expected", eventid)
  135. }
  136. case err := <-errCh:
  137. t.Fatal(err)
  138. panic(err) // Show the stack trace.
  139. }
  140. }
  141. //--------------------------------------------------------------------------------