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.

198 lines
5.7 KiB

  1. package rpctest
  2. import (
  3. "fmt"
  4. "testing"
  5. "github.com/tendermint/tendermint/account"
  6. _ "github.com/tendermint/tendermint/config/tendermint_test"
  7. "github.com/tendermint/tendermint/types"
  8. )
  9. var wsTyp = "JSONRPC"
  10. //--------------------------------------------------------------------------------
  11. // Test the websocket service
  12. // make a simple connection to the server
  13. func TestWSConnect(t *testing.T) {
  14. con := newWSCon(t)
  15. con.Close()
  16. }
  17. // receive a new block message
  18. func _TestWSNewBlock(t *testing.T) {
  19. con := newWSCon(t)
  20. eid := types.EventStringNewBlock()
  21. subscribe(t, con, eid)
  22. defer func() {
  23. unsubscribe(t, con, eid)
  24. con.Close()
  25. }()
  26. waitForEvent(t, con, eid, true, func() {}, func(eid string, b []byte) error {
  27. fmt.Println("Check:", string(b))
  28. return nil
  29. })
  30. }
  31. // receive a few new block messages in a row, with increasing height
  32. func TestWSBlockchainGrowth(t *testing.T) {
  33. con := newWSCon(t)
  34. eid := types.EventStringNewBlock()
  35. subscribe(t, con, eid)
  36. defer func() {
  37. unsubscribe(t, con, eid)
  38. con.Close()
  39. }()
  40. // listen for NewBlock, ensure height increases by 1
  41. unmarshalValidateBlockchain(t, con, eid)
  42. }
  43. // send a transaction and validate the events from listening for both sender and receiver
  44. func TestWSSend(t *testing.T) {
  45. toAddr := user[1].Address
  46. amt := int64(100)
  47. con := newWSCon(t)
  48. eidInput := types.EventStringAccInput(user[0].Address)
  49. eidOutput := types.EventStringAccOutput(toAddr)
  50. subscribe(t, con, eidInput)
  51. subscribe(t, con, eidOutput)
  52. defer func() {
  53. unsubscribe(t, con, eidInput)
  54. unsubscribe(t, con, eidOutput)
  55. con.Close()
  56. }()
  57. waitForEvent(t, con, eidInput, true, func() {
  58. tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt)
  59. broadcastTx(t, wsTyp, tx)
  60. }, unmarshalValidateSend(amt, toAddr))
  61. waitForEvent(t, con, eidOutput, true, func() {}, unmarshalValidateSend(amt, toAddr))
  62. }
  63. // ensure events are only fired once for a given transaction
  64. func TestWSDoubleFire(t *testing.T) {
  65. con := newWSCon(t)
  66. eid := types.EventStringAccInput(user[0].Address)
  67. subscribe(t, con, eid)
  68. defer func() {
  69. unsubscribe(t, con, eid)
  70. con.Close()
  71. }()
  72. amt := int64(100)
  73. toAddr := user[1].Address
  74. // broadcast the transaction, wait to hear about it
  75. waitForEvent(t, con, eid, true, func() {
  76. tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt)
  77. broadcastTx(t, wsTyp, tx)
  78. }, func(eid string, b []byte) error {
  79. return nil
  80. })
  81. // but make sure we don't hear about it twice
  82. waitForEvent(t, con, eid, false, func() {
  83. }, func(eid string, b []byte) error {
  84. return nil
  85. })
  86. }
  87. // create a contract, wait for the event, and send it a msg, validate the return
  88. func TestWSCallWait(t *testing.T) {
  89. con := newWSCon(t)
  90. eid1 := types.EventStringAccInput(user[0].Address)
  91. subscribe(t, con, eid1)
  92. defer func() {
  93. unsubscribe(t, con, eid1)
  94. con.Close()
  95. }()
  96. amt, gasLim, fee := int64(10000), int64(1000), int64(1000)
  97. code, returnCode, returnVal := simpleContract()
  98. var contractAddr []byte
  99. // wait for the contract to be created
  100. waitForEvent(t, con, eid1, true, func() {
  101. tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee)
  102. receipt := broadcastTx(t, wsTyp, tx)
  103. contractAddr = receipt.ContractAddr
  104. }, unmarshalValidateCall(amt, returnCode))
  105. // susbscribe to the new contract
  106. amt = int64(10001)
  107. eid2 := types.EventStringAccOutput(contractAddr)
  108. subscribe(t, con, eid2)
  109. defer func() {
  110. unsubscribe(t, con, eid2)
  111. }()
  112. // get the return value from a call
  113. data := []byte{0x1}
  114. waitForEvent(t, con, eid2, true, func() {
  115. tx := makeDefaultCallTx(t, wsTyp, contractAddr, data, amt, gasLim, fee)
  116. receipt := broadcastTx(t, wsTyp, tx)
  117. contractAddr = receipt.ContractAddr
  118. }, unmarshalValidateCall(amt, returnVal))
  119. }
  120. // create a contract and send it a msg without waiting. wait for contract event
  121. // and validate return
  122. func TestWSCallNoWait(t *testing.T) {
  123. con := newWSCon(t)
  124. amt, gasLim, fee := int64(10000), int64(1000), int64(1000)
  125. code, _, returnVal := simpleContract()
  126. tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee)
  127. receipt := broadcastTx(t, wsTyp, tx)
  128. contractAddr := receipt.ContractAddr
  129. // susbscribe to the new contract
  130. amt = int64(10001)
  131. eid := types.EventStringAccOutput(contractAddr)
  132. subscribe(t, con, eid)
  133. defer func() {
  134. unsubscribe(t, con, eid)
  135. con.Close()
  136. }()
  137. // get the return value from a call
  138. data := []byte{0x1}
  139. waitForEvent(t, con, eid, true, func() {
  140. tx := makeDefaultCallTx(t, wsTyp, contractAddr, data, amt, gasLim, fee)
  141. broadcastTx(t, wsTyp, tx)
  142. }, unmarshalValidateCall(amt, returnVal))
  143. }
  144. // create two contracts, one of which calls the other
  145. func TestWSCallCall(t *testing.T) {
  146. con := newWSCon(t)
  147. amt, gasLim, fee := int64(10000), int64(1000), int64(1000)
  148. code, _, returnVal := simpleContract()
  149. txid := new([]byte)
  150. // deploy the two contracts
  151. tx := makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee)
  152. receipt := broadcastTx(t, wsTyp, tx)
  153. contractAddr1 := receipt.ContractAddr
  154. code, _, _ = simpleCallContract(contractAddr1)
  155. tx = makeDefaultCallTx(t, wsTyp, nil, code, amt, gasLim, fee)
  156. receipt = broadcastTx(t, wsTyp, tx)
  157. contractAddr2 := receipt.ContractAddr
  158. // susbscribe to the new contracts
  159. amt = int64(10001)
  160. eid1 := types.EventStringAccReceive(contractAddr1)
  161. subscribe(t, con, eid1)
  162. defer func() {
  163. unsubscribe(t, con, eid1)
  164. con.Close()
  165. }()
  166. // call contract2, which should call contract1, and wait for ev1
  167. // let the contract get created first
  168. waitForEvent(t, con, eid1, true, func() {
  169. }, func(eid string, b []byte) error {
  170. return nil
  171. })
  172. // call it
  173. waitForEvent(t, con, eid1, true, func() {
  174. tx := makeDefaultCallTx(t, wsTyp, contractAddr2, nil, amt, gasLim, fee)
  175. broadcastTx(t, wsTyp, tx)
  176. *txid = account.HashSignBytes(chainID, tx)
  177. }, unmarshalValidateCallCall(user[0].Address, returnVal, txid))
  178. }