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
3.8 KiB

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