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.

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