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

10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 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. }