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.

238 lines
6.8 KiB

  1. package client_test
  2. import (
  3. "encoding/json"
  4. "strings"
  5. "testing"
  6. "time"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/require"
  9. merkle "github.com/tendermint/go-merkle"
  10. merktest "github.com/tendermint/merkleeyes/testutil"
  11. "github.com/tendermint/tendermint/rpc/client"
  12. ctypes "github.com/tendermint/tendermint/rpc/core/types"
  13. rpctest "github.com/tendermint/tendermint/rpc/test"
  14. "github.com/tendermint/tendermint/types"
  15. )
  16. func getHTTPClient() *client.HTTP {
  17. rpcAddr := rpctest.GetConfig().GetString("rpc_laddr")
  18. return client.NewHTTP(rpcAddr, "/websocket")
  19. }
  20. func getLocalClient() client.Local {
  21. return client.NewLocal(node)
  22. }
  23. // GetClients returns a slice of clients for table-driven tests
  24. func GetClients() []client.Client {
  25. return []client.Client{
  26. getHTTPClient(),
  27. getLocalClient(),
  28. }
  29. }
  30. // Make sure status is correct (we connect properly)
  31. func TestStatus(t *testing.T) {
  32. for i, c := range GetClients() {
  33. chainID := rpctest.GetConfig().GetString("chain_id")
  34. status, err := c.Status()
  35. require.Nil(t, err, "%d: %+v", i, err)
  36. assert.Equal(t, chainID, status.NodeInfo.Network)
  37. }
  38. }
  39. // Make sure info is correct (we connect properly)
  40. func TestInfo(t *testing.T) {
  41. for i, c := range GetClients() {
  42. // status, err := c.Status()
  43. // require.Nil(t, err, "%+v", err)
  44. info, err := c.ABCIInfo()
  45. require.Nil(t, err, "%d: %+v", i, err)
  46. // TODO: this is not correct - fix merkleeyes!
  47. // assert.EqualValues(t, status.LatestBlockHeight, info.Response.LastBlockHeight)
  48. assert.True(t, strings.HasPrefix(info.Response.Data, "size"))
  49. }
  50. }
  51. func TestNetInfo(t *testing.T) {
  52. for i, c := range GetClients() {
  53. nc, ok := c.(client.NetworkClient)
  54. require.True(t, ok, "%d", i)
  55. netinfo, err := nc.NetInfo()
  56. require.Nil(t, err, "%d: %+v", i, err)
  57. assert.True(t, netinfo.Listening)
  58. assert.Equal(t, 0, len(netinfo.Peers))
  59. }
  60. }
  61. func TestDumpConsensusState(t *testing.T) {
  62. for i, c := range GetClients() {
  63. // FIXME: fix server so it doesn't panic on invalid input
  64. nc, ok := c.(client.NetworkClient)
  65. require.True(t, ok, "%d", i)
  66. cons, err := nc.DumpConsensusState()
  67. require.Nil(t, err, "%d: %+v", i, err)
  68. assert.NotEmpty(t, cons.RoundState)
  69. assert.Empty(t, cons.PeerRoundStates)
  70. }
  71. }
  72. func TestGenesisAndValidators(t *testing.T) {
  73. for i, c := range GetClients() {
  74. chainID := rpctest.GetConfig().GetString("chain_id")
  75. // make sure this is the right genesis file
  76. gen, err := c.Genesis()
  77. require.Nil(t, err, "%d: %+v", i, err)
  78. assert.Equal(t, chainID, gen.Genesis.ChainID)
  79. // get the genesis validator
  80. require.Equal(t, 1, len(gen.Genesis.Validators))
  81. gval := gen.Genesis.Validators[0]
  82. // get the current validators
  83. vals, err := c.Validators()
  84. require.Nil(t, err, "%d: %+v", i, err)
  85. require.Equal(t, 1, len(vals.Validators))
  86. val := vals.Validators[0]
  87. // make sure the current set is also the genesis set
  88. assert.Equal(t, gval.Amount, val.VotingPower)
  89. assert.Equal(t, gval.PubKey, val.PubKey)
  90. }
  91. }
  92. // Make some app checks
  93. func TestAppCalls(t *testing.T) {
  94. assert, require := assert.New(t), require.New(t)
  95. for i, c := range GetClients() {
  96. // get an offset of height to avoid racing and guessing
  97. s, err := c.Status()
  98. require.Nil(err, "%d: %+v", i, err)
  99. // sh is start height or status height
  100. sh := s.LatestBlockHeight
  101. // look for the future
  102. _, err = c.Block(sh + 2)
  103. assert.NotNil(err) // no block yet
  104. // write something
  105. k, v, tx := merktest.MakeTxKV()
  106. _, err = c.BroadcastTxCommit(tx)
  107. require.Nil(err, "%d: %+v", i, err)
  108. // wait before querying
  109. time.Sleep(time.Second * 1)
  110. qres, err := c.ABCIQuery("/key", k, false)
  111. if assert.Nil(err) && assert.True(qres.Response.Code.IsOK()) {
  112. data := qres.Response
  113. // assert.Equal(k, data.GetKey()) // only returned for proofs
  114. assert.Equal(v, data.GetValue())
  115. }
  116. // +/- 1 making my head hurt
  117. h := int(qres.Response.Height) - 1
  118. // and we can even check the block is added
  119. block, err := c.Block(h)
  120. require.Nil(err, "%d: %+v", i, err)
  121. appHash := block.BlockMeta.Header.AppHash
  122. assert.True(len(appHash) > 0)
  123. assert.EqualValues(h, block.BlockMeta.Header.Height)
  124. // check blockchain info, now that we know there is info
  125. // TODO: is this commented somewhere that they are returned
  126. // in order of descending height???
  127. info, err := c.BlockchainInfo(h-2, h)
  128. require.Nil(err, "%d: %+v", i, err)
  129. assert.True(info.LastHeight > 2)
  130. if assert.Equal(3, len(info.BlockMetas)) {
  131. lastMeta := info.BlockMetas[0]
  132. assert.EqualValues(h, lastMeta.Header.Height)
  133. bMeta := block.BlockMeta
  134. assert.Equal(bMeta.Header.AppHash, lastMeta.Header.AppHash)
  135. assert.Equal(bMeta.BlockID, lastMeta.BlockID)
  136. }
  137. // and get the corresponding commit with the same apphash
  138. commit, err := c.Commit(h)
  139. require.Nil(err, "%d: %+v", i, err)
  140. cappHash := commit.Header.AppHash
  141. assert.Equal(appHash, cappHash)
  142. assert.NotNil(commit.Commit)
  143. // compare the commits (note Commit(2) has commit from Block(3))
  144. commit2, err := c.Commit(h - 1)
  145. require.Nil(err, "%d: %+v", i, err)
  146. assert.Equal(block.Block.LastCommit, commit2.Commit)
  147. // and we got a proof that works!
  148. pres, err := c.ABCIQuery("/key", k, true)
  149. if assert.Nil(err) && assert.True(pres.Response.Code.IsOK()) {
  150. proof, err := merkle.ReadProof(pres.Response.GetProof())
  151. if assert.Nil(err) {
  152. key := pres.Response.GetKey()
  153. value := pres.Response.GetValue()
  154. assert.Equal(appHash, proof.RootHash)
  155. valid := proof.Verify(key, value, appHash)
  156. assert.True(valid)
  157. }
  158. }
  159. }
  160. }
  161. // TestSubscriptions only works for HTTPClient
  162. //
  163. // TODO: generalize this functionality -> Local and Client
  164. func TestSubscriptions(t *testing.T) {
  165. require := require.New(t)
  166. c := getHTTPClient()
  167. err := c.StartWebsocket()
  168. require.Nil(err)
  169. defer c.StopWebsocket()
  170. // subscribe to a transaction event
  171. _, _, tx := merktest.MakeTxKV()
  172. eventType := types.EventStringTx(types.Tx(tx))
  173. c.Subscribe(eventType)
  174. // set up a listener
  175. r, e := c.GetEventChannels()
  176. go func() {
  177. // send a tx and wait for it to propogate
  178. _, err = c.BroadcastTxCommit(tx)
  179. require.Nil(err, string(tx))
  180. }()
  181. checkData := func(data []byte, kind byte) {
  182. x := []interface{}{}
  183. err := json.Unmarshal(data, &x)
  184. require.Nil(err)
  185. // gotta love wire's json format
  186. require.EqualValues(kind, x[0])
  187. }
  188. res := <-r
  189. checkData(res, ctypes.ResultTypeSubscribe)
  190. // read one event, must be success
  191. select {
  192. case res := <-r:
  193. checkData(res, ctypes.ResultTypeEvent)
  194. // this is good.. let's get the data... ugh...
  195. // result := new(ctypes.TMResult)
  196. // wire.ReadJSON(result, res, &err)
  197. // require.Nil(err, "%+v", err)
  198. // event, ok := (*result).(*ctypes.ResultEvent)
  199. // require.True(ok)
  200. // assert.Equal("foo", event.Name)
  201. // data, ok := event.Data.(types.EventDataTx)
  202. // require.True(ok)
  203. // assert.EqualValues(0, data.Code)
  204. // assert.EqualValues(tx, data.Tx)
  205. case err := <-e:
  206. // this is a failure
  207. require.Nil(err)
  208. }
  209. }