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.

316 lines
8.3 KiB

8 years ago
8 years ago
8 years ago
  1. package rpctest
  2. import (
  3. "bytes"
  4. crand "crypto/rand"
  5. "fmt"
  6. "math/rand"
  7. "testing"
  8. "time"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. abci "github.com/tendermint/abci/types"
  12. . "github.com/tendermint/go-common"
  13. rpc "github.com/tendermint/go-rpc/client"
  14. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  15. "github.com/tendermint/tendermint/types"
  16. )
  17. //--------------------------------------------------------------------------------
  18. // Test the HTTP client
  19. // These tests assume the dummy app
  20. //--------------------------------------------------------------------------------
  21. //--------------------------------------------------------------------------------
  22. // status
  23. func TestURIStatus(t *testing.T) {
  24. testStatus(t, GetURIClient())
  25. }
  26. func TestJSONStatus(t *testing.T) {
  27. testStatus(t, GetJSONClient())
  28. }
  29. func testStatus(t *testing.T, client rpc.HTTPClient) {
  30. chainID := GetConfig().GetString("chain_id")
  31. tmResult := new(ctypes.TMResult)
  32. _, err := client.Call("status", map[string]interface{}{}, tmResult)
  33. require.Nil(t, err)
  34. status := (*tmResult).(*ctypes.ResultStatus)
  35. assert.Equal(t, chainID, status.NodeInfo.Network)
  36. }
  37. //--------------------------------------------------------------------------------
  38. // broadcast tx sync
  39. // random bytes (excluding byte('='))
  40. func randBytes(t *testing.T) []byte {
  41. n := rand.Intn(10) + 2
  42. buf := make([]byte, n)
  43. _, err := crand.Read(buf)
  44. require.Nil(t, err)
  45. return bytes.Replace(buf, []byte("="), []byte{100}, -1)
  46. }
  47. func TestURIBroadcastTxSync(t *testing.T) {
  48. testBroadcastTxSync(t, GetURIClient())
  49. }
  50. func TestJSONBroadcastTxSync(t *testing.T) {
  51. testBroadcastTxSync(t, GetJSONClient())
  52. }
  53. func testBroadcastTxSync(t *testing.T, client rpc.HTTPClient) {
  54. config.Set("block_size", 0)
  55. defer config.Set("block_size", -1)
  56. tmResult := new(ctypes.TMResult)
  57. tx := randBytes(t)
  58. _, err := client.Call("broadcast_tx_sync", map[string]interface{}{"tx": tx}, tmResult)
  59. require.Nil(t, err)
  60. res := (*tmResult).(*ctypes.ResultBroadcastTx)
  61. require.Equal(t, abci.CodeType_OK, res.Code)
  62. mem := node.MempoolReactor().Mempool
  63. require.Equal(t, 1, mem.Size())
  64. txs := mem.Reap(1)
  65. require.EqualValues(t, tx, txs[0])
  66. mem.Flush()
  67. }
  68. //--------------------------------------------------------------------------------
  69. // query
  70. func testTxKV(t *testing.T) ([]byte, []byte, []byte) {
  71. k := randBytes(t)
  72. v := randBytes(t)
  73. return k, v, []byte(Fmt("%s=%s", k, v))
  74. }
  75. func sendTx(t *testing.T, client rpc.HTTPClient) ([]byte, []byte) {
  76. tmResult := new(ctypes.TMResult)
  77. k, v, tx := testTxKV(t)
  78. _, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, tmResult)
  79. require.Nil(t, err)
  80. return k, v
  81. }
  82. func TestURIABCIQuery(t *testing.T) {
  83. testABCIQuery(t, GetURIClient())
  84. }
  85. func TestJSONABCIQuery(t *testing.T) {
  86. testABCIQuery(t, GetURIClient())
  87. }
  88. func testABCIQuery(t *testing.T, client rpc.HTTPClient) {
  89. k, _ := sendTx(t, client)
  90. time.Sleep(time.Millisecond * 100)
  91. tmResult := new(ctypes.TMResult)
  92. _, err := client.Call("abci_query",
  93. map[string]interface{}{"path": "", "data": k, "prove": false}, tmResult)
  94. require.Nil(t, err)
  95. resQuery := (*tmResult).(*ctypes.ResultABCIQuery)
  96. require.EqualValues(t, 0, resQuery.Response.Code)
  97. // XXX: specific to value returned by the dummy
  98. require.NotEqual(t, 0, len(resQuery.Response.Value))
  99. }
  100. //--------------------------------------------------------------------------------
  101. // broadcast tx commit
  102. func TestURIBroadcastTxCommit(t *testing.T) {
  103. testBroadcastTxCommit(t, GetURIClient())
  104. }
  105. func TestJSONBroadcastTxCommit(t *testing.T) {
  106. testBroadcastTxCommit(t, GetJSONClient())
  107. }
  108. func testBroadcastTxCommit(t *testing.T, client rpc.HTTPClient) {
  109. require := require.New(t)
  110. tmResult := new(ctypes.TMResult)
  111. tx := randBytes(t)
  112. _, err := client.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, tmResult)
  113. require.Nil(err)
  114. res := (*tmResult).(*ctypes.ResultBroadcastTxCommit)
  115. checkTx := res.CheckTx
  116. require.Equal(abci.CodeType_OK, checkTx.Code)
  117. deliverTx := res.DeliverTx
  118. require.Equal(abci.CodeType_OK, deliverTx.Code)
  119. mem := node.MempoolReactor().Mempool
  120. require.Equal(0, mem.Size())
  121. // TODO: find tx in block
  122. }
  123. //--------------------------------------------------------------------------------
  124. // Test the websocket service
  125. var wsTyp = "JSONRPC"
  126. // make a simple connection to the server
  127. func TestWSConnect(t *testing.T) {
  128. wsc := GetWSClient()
  129. wsc.Stop()
  130. }
  131. // receive a new block message
  132. func TestWSNewBlock(t *testing.T) {
  133. wsc := GetWSClient()
  134. eid := types.EventStringNewBlock()
  135. require.Nil(t, wsc.Subscribe(eid))
  136. defer func() {
  137. require.Nil(t, wsc.Unsubscribe(eid))
  138. wsc.Stop()
  139. }()
  140. waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error {
  141. // fmt.Println("Check:", b)
  142. return nil
  143. })
  144. }
  145. // receive a few new block messages in a row, with increasing height
  146. func TestWSBlockchainGrowth(t *testing.T) {
  147. if testing.Short() {
  148. t.Skip("skipping test in short mode.")
  149. }
  150. wsc := GetWSClient()
  151. eid := types.EventStringNewBlock()
  152. require.Nil(t, wsc.Subscribe(eid))
  153. defer func() {
  154. require.Nil(t, wsc.Unsubscribe(eid))
  155. wsc.Stop()
  156. }()
  157. // listen for NewBlock, ensure height increases by 1
  158. var initBlockN int
  159. for i := 0; i < 3; i++ {
  160. waitForEvent(t, wsc, eid, true, func() {}, func(eid string, eventData interface{}) error {
  161. block := eventData.(types.EventDataNewBlock).Block
  162. if i == 0 {
  163. initBlockN = block.Header.Height
  164. } else {
  165. if block.Header.Height != initBlockN+i {
  166. return fmt.Errorf("Expected block %d, got block %d", initBlockN+i, block.Header.Height)
  167. }
  168. }
  169. return nil
  170. })
  171. }
  172. }
  173. func TestWSTxEvent(t *testing.T) {
  174. require := require.New(t)
  175. wsc := GetWSClient()
  176. tx := randBytes(t)
  177. // listen for the tx I am about to submit
  178. eid := types.EventStringTx(types.Tx(tx))
  179. require.Nil(wsc.Subscribe(eid))
  180. defer func() {
  181. require.Nil(wsc.Unsubscribe(eid))
  182. wsc.Stop()
  183. }()
  184. // send an tx
  185. tmResult := new(ctypes.TMResult)
  186. _, err := GetJSONClient().Call("broadcast_tx_sync", map[string]interface{}{"tx": tx}, tmResult)
  187. require.Nil(err)
  188. waitForEvent(t, wsc, eid, true, func() {}, func(eid string, b interface{}) error {
  189. evt, ok := b.(types.EventDataTx)
  190. require.True(ok, "Got wrong event type: %#v", b)
  191. require.Equal(tx, []byte(evt.Tx), "Returned different tx")
  192. require.Equal(abci.CodeType_OK, evt.Code)
  193. return nil
  194. })
  195. }
  196. /* TODO: this with dummy app..
  197. func TestWSDoubleFire(t *testing.T) {
  198. if testing.Short() {
  199. t.Skip("skipping test in short mode.")
  200. }
  201. con := newWSCon(t)
  202. eid := types.EventStringAccInput(user[0].Address)
  203. subscribe(t, con, eid)
  204. defer func() {
  205. unsubscribe(t, con, eid)
  206. con.Close()
  207. }()
  208. amt := int64(100)
  209. toAddr := user[1].Address
  210. // broadcast the transaction, wait to hear about it
  211. waitForEvent(t, con, eid, true, func() {
  212. tx := makeDefaultSendTxSigned(t, wsTyp, toAddr, amt)
  213. broadcastTx(t, wsTyp, tx)
  214. }, func(eid string, b []byte) error {
  215. return nil
  216. })
  217. // but make sure we don't hear about it twice
  218. waitForEvent(t, con, eid, false, func() {
  219. }, func(eid string, b []byte) error {
  220. return nil
  221. })
  222. }*/
  223. //--------------------------------------------------------------------------------
  224. // unsafe_set_config
  225. var stringVal = "my string"
  226. var intVal = 987654321
  227. var boolVal = true
  228. // don't change these
  229. var testCasesUnsafeSetConfig = [][]string{
  230. []string{"string", "key1", stringVal},
  231. []string{"int", "key2", fmt.Sprintf("%v", intVal)},
  232. []string{"bool", "key3", fmt.Sprintf("%v", boolVal)},
  233. }
  234. func TestURIUnsafeSetConfig(t *testing.T) {
  235. for _, testCase := range testCasesUnsafeSetConfig {
  236. tmResult := new(ctypes.TMResult)
  237. _, err := GetURIClient().Call("unsafe_set_config", map[string]interface{}{
  238. "type": testCase[0],
  239. "key": testCase[1],
  240. "value": testCase[2],
  241. }, tmResult)
  242. require.Nil(t, err)
  243. }
  244. testUnsafeSetConfig(t)
  245. }
  246. func TestJSONUnsafeSetConfig(t *testing.T) {
  247. for _, testCase := range testCasesUnsafeSetConfig {
  248. tmResult := new(ctypes.TMResult)
  249. _, err := GetJSONClient().Call("unsafe_set_config",
  250. map[string]interface{}{"type": testCase[0], "key": testCase[1], "value": testCase[2]},
  251. tmResult)
  252. require.Nil(t, err)
  253. }
  254. testUnsafeSetConfig(t)
  255. }
  256. func testUnsafeSetConfig(t *testing.T) {
  257. require := require.New(t)
  258. s := config.GetString("key1")
  259. require.Equal(stringVal, s)
  260. i := config.GetInt("key2")
  261. require.Equal(intVal, i)
  262. b := config.GetBool("key3")
  263. require.Equal(boolVal, b)
  264. }