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.

258 lines
6.8 KiB

9 years ago
  1. package rpctest
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "net/http"
  7. "testing"
  8. "time"
  9. "github.com/tendermint/tendermint/Godeps/_workspace/src/github.com/gorilla/websocket"
  10. "github.com/tendermint/tendermint/binary"
  11. _ "github.com/tendermint/tendermint/config/tendermint_test"
  12. "github.com/tendermint/tendermint/rpc/types"
  13. "github.com/tendermint/tendermint/types"
  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.WSRequest{
  31. Type: "subscribe",
  32. Event: eventid,
  33. })
  34. if err != nil {
  35. t.Fatal(err)
  36. }
  37. }
  38. // unsubscribe from an event
  39. func unsubscribe(t *testing.T, con *websocket.Conn, eventid string) {
  40. err := con.WriteJSON(rpctypes.WSRequest{
  41. Type: "unsubscribe",
  42. Event: eventid,
  43. })
  44. if err != nil {
  45. t.Fatal(err)
  46. }
  47. }
  48. // wait for an event; do things that might trigger events, and check them when they are received
  49. func waitForEvent(t *testing.T, con *websocket.Conn, eventid string, dieOnTimeout bool, f func(), check func(string, []byte) error) {
  50. // go routine to wait for webscoket msg
  51. gch := make(chan []byte) // good channel
  52. ech := make(chan error) // error channel
  53. go func() {
  54. for {
  55. _, p, err := con.ReadMessage()
  56. if err != nil {
  57. ech <- err
  58. break
  59. } else {
  60. // if the event id isnt what we're waiting on
  61. // ignore it
  62. var response struct {
  63. Event string `json:"event"`
  64. }
  65. if err := json.Unmarshal(p, &response); err != nil {
  66. ech <- err
  67. break
  68. }
  69. if response.Event == eventid {
  70. gch <- p
  71. break
  72. }
  73. }
  74. }
  75. }()
  76. // do stuff (transactions)
  77. f()
  78. // wait for an event or 10 seconds
  79. ticker := time.Tick(10 * time.Second)
  80. select {
  81. case <-ticker:
  82. if dieOnTimeout {
  83. con.Close()
  84. t.Fatalf("%s event was not received in time", eventid)
  85. }
  86. // else that's great, we didn't hear the event
  87. // and we shouldn't have
  88. case p := <-gch:
  89. if dieOnTimeout {
  90. // message was received and expected
  91. // run the check
  92. err := check(eventid, p)
  93. if err != nil {
  94. t.Fatal(err)
  95. }
  96. } else {
  97. con.Close()
  98. t.Fatalf("%s event was not expected", eventid)
  99. }
  100. case err := <-ech:
  101. t.Fatal(err)
  102. }
  103. }
  104. //--------------------------------------------------------------------------------
  105. func unmarshalResponseNewBlock(b []byte) (*types.Block, error) {
  106. // unmarshall and assert somethings
  107. var response struct {
  108. Event string `json:"event"`
  109. Data *types.Block `json:"data"`
  110. Error string `json:"error"`
  111. }
  112. var err error
  113. binary.ReadJSON(&response, b, &err)
  114. if err != nil {
  115. return nil, err
  116. }
  117. if response.Error != "" {
  118. return nil, fmt.Errorf(response.Error)
  119. }
  120. block := response.Data
  121. return block, nil
  122. }
  123. func unmarshalValidateBlockchain(t *testing.T, con *websocket.Conn, eid string) {
  124. var initBlockN uint
  125. for i := 0; i < 2; i++ {
  126. waitForEvent(t, con, eid, true, func() {}, func(eid string, b []byte) error {
  127. block, err := unmarshalResponseNewBlock(b)
  128. if err != nil {
  129. return err
  130. }
  131. if i == 0 {
  132. initBlockN = block.Header.Height
  133. } else {
  134. if block.Header.Height != initBlockN+uint(i) {
  135. return fmt.Errorf("Expected block %d, got block %d", i, block.Header.Height)
  136. }
  137. }
  138. return nil
  139. })
  140. }
  141. }
  142. func unmarshalValidateSend(amt uint64, toAddr []byte) func(string, []byte) error {
  143. return func(eid string, b []byte) error {
  144. // unmarshal and assert correctness
  145. var response struct {
  146. Event string `json:"event"`
  147. Data types.SendTx `json:"data"`
  148. Error string `json:"error"`
  149. }
  150. var err error
  151. binary.ReadJSON(&response, b, &err)
  152. if err != nil {
  153. return err
  154. }
  155. if response.Error != "" {
  156. return fmt.Errorf(response.Error)
  157. }
  158. if eid != response.Event {
  159. return fmt.Errorf("Eventid is not correct. Got %s, expected %s", response.Event, eid)
  160. }
  161. tx := response.Data
  162. if bytes.Compare(tx.Inputs[0].Address, user[0].Address) != 0 {
  163. return fmt.Errorf("Senders do not match up! Got %x, expected %x", tx.Inputs[0].Address, user[0].Address)
  164. }
  165. if tx.Inputs[0].Amount != amt {
  166. return fmt.Errorf("Amt does not match up! Got %d, expected %d", tx.Inputs[0].Amount, amt)
  167. }
  168. if bytes.Compare(tx.Outputs[0].Address, toAddr) != 0 {
  169. return fmt.Errorf("Receivers do not match up! Got %x, expected %x", tx.Outputs[0].Address, user[0].Address)
  170. }
  171. return nil
  172. }
  173. }
  174. func unmarshalValidateCall(amt uint64, returnCode []byte) func(string, []byte) error {
  175. return func(eid string, b []byte) error {
  176. // unmarshall and assert somethings
  177. var response struct {
  178. Event string `json:"event"`
  179. Data struct {
  180. Tx types.CallTx `json:"tx"`
  181. Return []byte `json:"return"`
  182. Exception string `json:"exception"`
  183. } `json:"data"`
  184. Error string `json:"error"`
  185. }
  186. var err error
  187. binary.ReadJSON(&response, b, &err)
  188. if err != nil {
  189. return err
  190. }
  191. if response.Error != "" {
  192. return fmt.Errorf(response.Error)
  193. }
  194. if response.Data.Exception != "" {
  195. return fmt.Errorf(response.Data.Exception)
  196. }
  197. tx := response.Data.Tx
  198. if bytes.Compare(tx.Input.Address, user[0].Address) != 0 {
  199. return fmt.Errorf("Senders do not match up! Got %x, expected %x", tx.Input.Address, user[0].Address)
  200. }
  201. if tx.Input.Amount != amt {
  202. return fmt.Errorf("Amt does not match up! Got %d, expected %d", tx.Input.Amount, amt)
  203. }
  204. ret := response.Data.Return
  205. if bytes.Compare(ret, returnCode) != 0 {
  206. return fmt.Errorf("Call did not return correctly. Got %x, expected %x", ret, returnCode)
  207. }
  208. return nil
  209. }
  210. }
  211. func unmarshalValidateCallCall(origin, returnCode []byte, txid *[]byte) func(string, []byte) error {
  212. return func(eid string, b []byte) error {
  213. // unmarshall and assert somethings
  214. var response struct {
  215. Event string `json:"event"`
  216. Data types.EventMsgCall `json:"data"`
  217. Error string `json:"error"`
  218. }
  219. var err error
  220. binary.ReadJSON(&response, b, &err)
  221. if err != nil {
  222. return err
  223. }
  224. if response.Error != "" {
  225. return fmt.Errorf(response.Error)
  226. }
  227. if response.Data.Exception != "" {
  228. return fmt.Errorf(response.Data.Exception)
  229. }
  230. if bytes.Compare(response.Data.Origin, origin) != 0 {
  231. return fmt.Errorf("Origin does not match up! Got %x, expected %x", response.Data.Origin, origin)
  232. }
  233. ret := response.Data.Return
  234. if bytes.Compare(ret, returnCode) != 0 {
  235. return fmt.Errorf("Call did not return correctly. Got %x, expected %x", ret, returnCode)
  236. }
  237. if bytes.Compare(response.Data.TxId, *txid) != 0 {
  238. return fmt.Errorf("TxIds do not match up! Got %x, expected %x", response.Data.TxId, *txid)
  239. }
  240. return nil
  241. }
  242. }