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.

271 lines
7.3 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. package rpctest
  2. import (
  3. "bytes"
  4. "fmt"
  5. "net/http"
  6. "testing"
  7. "time"
  8. "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/gorilla/websocket"
  9. _ "github.com/tendermint/tendermint/config/tendermint_test"
  10. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  11. "github.com/tendermint/tendermint/rpc/types"
  12. "github.com/tendermint/tendermint/types"
  13. "github.com/tendermint/tendermint/wire"
  14. )
  15. //--------------------------------------------------------------------------------
  16. // Utilities for testing the websocket service
  17. // create a new connection
  18. func newWSCon(t *testing.T) *websocket.Conn {
  19. dialer := websocket.DefaultDialer
  20. rHeader := http.Header{}
  21. con, r, err := dialer.Dial(websocketAddr, rHeader)
  22. fmt.Println("response", r)
  23. if err != nil {
  24. t.Fatal(err)
  25. }
  26. return con
  27. }
  28. // subscribe to an event
  29. func subscribe(t *testing.T, con *websocket.Conn, eventid string) {
  30. err := con.WriteJSON(rpctypes.RPCRequest{
  31. JSONRPC: "2.0",
  32. ID: "",
  33. Method: "subscribe",
  34. Params: []interface{}{eventid},
  35. })
  36. if err != nil {
  37. t.Fatal(err)
  38. }
  39. }
  40. // unsubscribe from an event
  41. func unsubscribe(t *testing.T, con *websocket.Conn, eventid string) {
  42. err := con.WriteJSON(rpctypes.RPCRequest{
  43. JSONRPC: "2.0",
  44. ID: "",
  45. Method: "unsubscribe",
  46. Params: []interface{}{eventid},
  47. })
  48. if err != nil {
  49. t.Fatal(err)
  50. }
  51. }
  52. // wait for an event; do things that might trigger events, and check them when they are received
  53. // the check function takes an event id and the byte slice read off the ws
  54. func waitForEvent(t *testing.T, con *websocket.Conn, eventid string, dieOnTimeout bool, f func(), check func(string, []byte) error) {
  55. // go routine to wait for webscoket msg
  56. goodCh := make(chan []byte)
  57. errCh := make(chan error)
  58. quitCh := make(chan struct{})
  59. defer close(quitCh)
  60. // Read message
  61. go func() {
  62. for {
  63. _, p, err := con.ReadMessage()
  64. if err != nil {
  65. errCh <- err
  66. break
  67. } else {
  68. // if the event id isnt what we're waiting on
  69. // ignore it
  70. var response ctypes.Response
  71. var err error
  72. wire.ReadJSON(&response, p, &err)
  73. if err != nil {
  74. errCh <- err
  75. break
  76. }
  77. event, ok := response.Result.(*ctypes.ResultEvent)
  78. if ok && event.Event == eventid {
  79. goodCh <- p
  80. break
  81. }
  82. }
  83. }
  84. }()
  85. // do stuff (transactions)
  86. f()
  87. // wait for an event or timeout
  88. timeout := time.NewTimer(10 * time.Second)
  89. select {
  90. case <-timeout.C:
  91. if dieOnTimeout {
  92. con.Close()
  93. t.Fatalf("%s event was not received in time", eventid)
  94. }
  95. // else that's great, we didn't hear the event
  96. // and we shouldn't have
  97. case p := <-goodCh:
  98. if dieOnTimeout {
  99. // message was received and expected
  100. // run the check
  101. err := check(eventid, p)
  102. if err != nil {
  103. t.Fatal(err)
  104. panic(err) // Show the stack trace.
  105. }
  106. } else {
  107. con.Close()
  108. t.Fatalf("%s event was not expected", eventid)
  109. }
  110. case err := <-errCh:
  111. t.Fatal(err)
  112. panic(err) // Show the stack trace.
  113. }
  114. }
  115. //--------------------------------------------------------------------------------
  116. func unmarshalResponseNewBlock(b []byte) (*types.Block, error) {
  117. // unmarshall and assert somethings
  118. var response ctypes.Response
  119. var err error
  120. wire.ReadJSON(&response, b, &err)
  121. if err != nil {
  122. return nil, err
  123. }
  124. if response.Error != "" {
  125. return nil, fmt.Errorf(response.Error)
  126. }
  127. block := response.Result.(*ctypes.ResultEvent).Data.(types.EventDataNewBlock).Block
  128. return block, nil
  129. }
  130. func unmarshalResponseNameReg(b []byte) (*types.NameTx, error) {
  131. // unmarshall and assert somethings
  132. var response ctypes.Response
  133. var err error
  134. wire.ReadJSON(&response, b, &err)
  135. if err != nil {
  136. return nil, err
  137. }
  138. if response.Error != "" {
  139. return nil, fmt.Errorf(response.Error)
  140. }
  141. tx := response.Result.(*ctypes.ResultEvent).Data.(types.EventDataTx).Tx.(*types.NameTx)
  142. return tx, nil
  143. }
  144. func unmarshalValidateBlockchain(t *testing.T, con *websocket.Conn, eid string) {
  145. var initBlockN int
  146. for i := 0; i < 2; i++ {
  147. waitForEvent(t, con, eid, true, func() {}, func(eid string, b []byte) error {
  148. block, err := unmarshalResponseNewBlock(b)
  149. if err != nil {
  150. return err
  151. }
  152. if i == 0 {
  153. initBlockN = block.Header.Height
  154. } else {
  155. if block.Header.Height != initBlockN+i {
  156. return fmt.Errorf("Expected block %d, got block %d", i, block.Header.Height)
  157. }
  158. }
  159. return nil
  160. })
  161. }
  162. }
  163. func unmarshalValidateSend(amt int64, toAddr []byte) func(string, []byte) error {
  164. return func(eid string, b []byte) error {
  165. // unmarshal and assert correctness
  166. var response ctypes.Response
  167. var err error
  168. wire.ReadJSON(&response, b, &err)
  169. if err != nil {
  170. return err
  171. }
  172. if response.Error != "" {
  173. return fmt.Errorf(response.Error)
  174. }
  175. if eid != response.Result.(*ctypes.ResultEvent).Event {
  176. return fmt.Errorf("Eventid is not correct. Got %s, expected %s", response.Result.(*ctypes.ResultEvent).Event, eid)
  177. }
  178. tx := response.Result.(*ctypes.ResultEvent).Data.(types.EventDataTx).Tx.(*types.SendTx)
  179. if !bytes.Equal(tx.Inputs[0].Address, user[0].Address) {
  180. return fmt.Errorf("Senders do not match up! Got %x, expected %x", tx.Inputs[0].Address, user[0].Address)
  181. }
  182. if tx.Inputs[0].Amount != amt {
  183. return fmt.Errorf("Amt does not match up! Got %d, expected %d", tx.Inputs[0].Amount, amt)
  184. }
  185. if !bytes.Equal(tx.Outputs[0].Address, toAddr) {
  186. return fmt.Errorf("Receivers do not match up! Got %x, expected %x", tx.Outputs[0].Address, user[0].Address)
  187. }
  188. return nil
  189. }
  190. }
  191. func unmarshalValidateTx(amt int64, returnCode []byte) func(string, []byte) error {
  192. return func(eid string, b []byte) error {
  193. // unmarshall and assert somethings
  194. var response ctypes.Response
  195. var err error
  196. wire.ReadJSON(&response, b, &err)
  197. if err != nil {
  198. return err
  199. }
  200. if response.Error != "" {
  201. return fmt.Errorf(response.Error)
  202. }
  203. var data = response.Result.(*ctypes.ResultEvent).Data.(types.EventDataTx)
  204. if data.Exception != "" {
  205. return fmt.Errorf(data.Exception)
  206. }
  207. tx := data.Tx.(*types.CallTx)
  208. if !bytes.Equal(tx.Input.Address, user[0].Address) {
  209. return fmt.Errorf("Senders do not match up! Got %x, expected %x",
  210. tx.Input.Address, user[0].Address)
  211. }
  212. if tx.Input.Amount != amt {
  213. return fmt.Errorf("Amt does not match up! Got %d, expected %d",
  214. tx.Input.Amount, amt)
  215. }
  216. ret := data.Return
  217. if !bytes.Equal(ret, returnCode) {
  218. return fmt.Errorf("Tx did not return correctly. Got %x, expected %x", ret, returnCode)
  219. }
  220. return nil
  221. }
  222. }
  223. func unmarshalValidateCall(origin, returnCode []byte, txid *[]byte) func(string, []byte) error {
  224. return func(eid string, b []byte) error {
  225. // unmarshall and assert somethings
  226. var response ctypes.Response
  227. var err error
  228. wire.ReadJSON(&response, b, &err)
  229. if err != nil {
  230. return err
  231. }
  232. if response.Error != "" {
  233. return fmt.Errorf(response.Error)
  234. }
  235. var data = response.Result.(*ctypes.ResultEvent).Data.(types.EventDataCall)
  236. if data.Exception != "" {
  237. return fmt.Errorf(data.Exception)
  238. }
  239. if !bytes.Equal(data.Origin, origin) {
  240. return fmt.Errorf("Origin does not match up! Got %x, expected %x",
  241. data.Origin, origin)
  242. }
  243. ret := data.Return
  244. if !bytes.Equal(ret, returnCode) {
  245. return fmt.Errorf("Call did not return correctly. Got %x, expected %x", ret, returnCode)
  246. }
  247. if !bytes.Equal(data.TxID, *txid) {
  248. return fmt.Errorf("TxIDs do not match up! Got %x, expected %x",
  249. data.TxID, *txid)
  250. }
  251. return nil
  252. }
  253. }