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.

294 lines
8.1 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. package client_test
  2. import (
  3. "strings"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/stretchr/testify/require"
  7. "github.com/tendermint/merkleeyes/iavl" //TODO use tendermint/iavl ?
  8. "github.com/tendermint/tendermint/rpc/client"
  9. rpctest "github.com/tendermint/tendermint/rpc/test"
  10. "github.com/tendermint/tendermint/types"
  11. )
  12. func getHTTPClient() *client.HTTP {
  13. rpcAddr := rpctest.GetConfig().RPC.ListenAddress
  14. return client.NewHTTP(rpcAddr, "/websocket")
  15. }
  16. func getLocalClient() client.Local {
  17. return client.NewLocal(node)
  18. }
  19. // GetClients returns a slice of clients for table-driven tests
  20. func GetClients() []client.Client {
  21. return []client.Client{
  22. getHTTPClient(),
  23. getLocalClient(),
  24. }
  25. }
  26. // Make sure status is correct (we connect properly)
  27. func TestStatus(t *testing.T) {
  28. for i, c := range GetClients() {
  29. moniker := rpctest.GetConfig().Moniker
  30. status, err := c.Status()
  31. require.Nil(t, err, "%d: %+v", i, err)
  32. assert.Equal(t, moniker, status.NodeInfo.Moniker)
  33. }
  34. }
  35. // Make sure info is correct (we connect properly)
  36. func TestInfo(t *testing.T) {
  37. for i, c := range GetClients() {
  38. // status, err := c.Status()
  39. // require.Nil(t, err, "%+v", err)
  40. info, err := c.ABCIInfo()
  41. require.Nil(t, err, "%d: %+v", i, err)
  42. // TODO: this is not correct - fix merkleeyes!
  43. // assert.EqualValues(t, status.LatestBlockHeight, info.Response.LastBlockHeight)
  44. assert.True(t, strings.Contains(info.Response.Data, "size"))
  45. }
  46. }
  47. func TestNetInfo(t *testing.T) {
  48. for i, c := range GetClients() {
  49. nc, ok := c.(client.NetworkClient)
  50. require.True(t, ok, "%d", i)
  51. netinfo, err := nc.NetInfo()
  52. require.Nil(t, err, "%d: %+v", i, err)
  53. assert.True(t, netinfo.Listening)
  54. assert.Equal(t, 0, len(netinfo.Peers))
  55. }
  56. }
  57. func TestDumpConsensusState(t *testing.T) {
  58. for i, c := range GetClients() {
  59. // FIXME: fix server so it doesn't panic on invalid input
  60. nc, ok := c.(client.NetworkClient)
  61. require.True(t, ok, "%d", i)
  62. cons, err := nc.DumpConsensusState()
  63. require.Nil(t, err, "%d: %+v", i, err)
  64. assert.NotEmpty(t, cons.RoundState)
  65. assert.Empty(t, cons.PeerRoundStates)
  66. }
  67. }
  68. func TestGenesisAndValidators(t *testing.T) {
  69. for i, c := range GetClients() {
  70. // make sure this is the right genesis file
  71. gen, err := c.Genesis()
  72. require.Nil(t, err, "%d: %+v", i, err)
  73. // get the genesis validator
  74. require.Equal(t, 1, len(gen.Genesis.Validators))
  75. gval := gen.Genesis.Validators[0]
  76. // get the current validators
  77. vals, err := c.Validators(nil)
  78. require.Nil(t, err, "%d: %+v", i, err)
  79. require.Equal(t, 1, len(vals.Validators))
  80. val := vals.Validators[0]
  81. // make sure the current set is also the genesis set
  82. assert.Equal(t, gval.Power, val.VotingPower)
  83. assert.Equal(t, gval.PubKey, val.PubKey)
  84. }
  85. }
  86. func TestABCIQuery(t *testing.T) {
  87. for i, c := range GetClients() {
  88. // write something
  89. k, v, tx := MakeTxKV()
  90. bres, err := c.BroadcastTxCommit(tx)
  91. require.Nil(t, err, "%d: %+v", i, err)
  92. apph := bres.Height + 1 // this is where the tx will be applied to the state
  93. // wait before querying
  94. client.WaitForHeight(c, apph, nil)
  95. qres, err := c.ABCIQuery("/key", k)
  96. if assert.Nil(t, err) && assert.True(t, qres.Code.IsOK()) {
  97. assert.EqualValues(t, v, qres.Value)
  98. }
  99. }
  100. }
  101. // Make some app checks
  102. func TestAppCalls(t *testing.T) {
  103. assert, require := assert.New(t), require.New(t)
  104. for i, c := range GetClients() {
  105. // get an offset of height to avoid racing and guessing
  106. s, err := c.Status()
  107. require.Nil(err, "%d: %+v", i, err)
  108. // sh is start height or status height
  109. sh := s.LatestBlockHeight
  110. // look for the future
  111. h := sh + 2
  112. _, err = c.Block(&h)
  113. assert.NotNil(err) // no block yet
  114. // write something
  115. k, v, tx := MakeTxKV()
  116. bres, err := c.BroadcastTxCommit(tx)
  117. require.Nil(err, "%d: %+v", i, err)
  118. require.True(bres.DeliverTx.Code.IsOK())
  119. txh := bres.Height
  120. apph := txh + 1 // this is where the tx will be applied to the state
  121. // wait before querying
  122. client.WaitForHeight(c, apph, nil)
  123. qres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Trusted: true})
  124. if assert.Nil(err) && assert.True(qres.Code.IsOK()) {
  125. // assert.Equal(k, data.GetKey()) // only returned for proofs
  126. assert.EqualValues(v, qres.Value)
  127. }
  128. // make sure we can lookup the tx with proof
  129. // ptx, err := c.Tx(bres.Hash, true)
  130. ptx, err := c.Tx(bres.Hash, true)
  131. require.Nil(err, "%d: %+v", i, err)
  132. assert.Equal(txh, ptx.Height)
  133. assert.EqualValues(tx, ptx.Tx)
  134. // and we can even check the block is added
  135. block, err := c.Block(&apph)
  136. require.Nil(err, "%d: %+v", i, err)
  137. appHash := block.BlockMeta.Header.AppHash
  138. assert.True(len(appHash) > 0)
  139. assert.EqualValues(apph, block.BlockMeta.Header.Height)
  140. // check blockchain info, now that we know there is info
  141. // TODO: is this commented somewhere that they are returned
  142. // in order of descending height???
  143. info, err := c.BlockchainInfo(apph, apph)
  144. require.Nil(err, "%d: %+v", i, err)
  145. assert.True(info.LastHeight >= apph)
  146. if assert.Equal(1, len(info.BlockMetas)) {
  147. lastMeta := info.BlockMetas[0]
  148. assert.EqualValues(apph, lastMeta.Header.Height)
  149. bMeta := block.BlockMeta
  150. assert.Equal(bMeta.Header.AppHash, lastMeta.Header.AppHash)
  151. assert.Equal(bMeta.BlockID, lastMeta.BlockID)
  152. }
  153. // and get the corresponding commit with the same apphash
  154. commit, err := c.Commit(&apph)
  155. require.Nil(err, "%d: %+v", i, err)
  156. cappHash := commit.Header.AppHash
  157. assert.Equal(appHash, cappHash)
  158. assert.NotNil(commit.Commit)
  159. // compare the commits (note Commit(2) has commit from Block(3))
  160. h = apph - 1
  161. commit2, err := c.Commit(&h)
  162. require.Nil(err, "%d: %+v", i, err)
  163. assert.Equal(block.Block.LastCommit, commit2.Commit)
  164. // and we got a proof that works!
  165. pres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Trusted: false})
  166. if assert.Nil(err) && assert.True(pres.Code.IsOK()) {
  167. proof, err := iavl.ReadProof(pres.Proof)
  168. if assert.Nil(err) {
  169. key := pres.Key
  170. value := pres.Value
  171. assert.EqualValues(appHash, proof.RootHash)
  172. valid := proof.Verify(key, value, appHash)
  173. assert.True(valid)
  174. }
  175. }
  176. }
  177. }
  178. func TestBroadcastTxSync(t *testing.T) {
  179. require := require.New(t)
  180. mempool := node.MempoolReactor().Mempool
  181. initMempoolSize := mempool.Size()
  182. for i, c := range GetClients() {
  183. _, _, tx := MakeTxKV()
  184. bres, err := c.BroadcastTxSync(tx)
  185. require.Nil(err, "%d: %+v", i, err)
  186. require.True(bres.Code.IsOK())
  187. require.Equal(initMempoolSize+1, mempool.Size())
  188. txs := mempool.Reap(1)
  189. require.EqualValues(tx, txs[0])
  190. mempool.Flush()
  191. }
  192. }
  193. func TestBroadcastTxCommit(t *testing.T) {
  194. require := require.New(t)
  195. mempool := node.MempoolReactor().Mempool
  196. for i, c := range GetClients() {
  197. _, _, tx := MakeTxKV()
  198. bres, err := c.BroadcastTxCommit(tx)
  199. require.Nil(err, "%d: %+v", i, err)
  200. require.True(bres.CheckTx.Code.IsOK())
  201. require.True(bres.DeliverTx.Code.IsOK())
  202. require.Equal(0, mempool.Size())
  203. }
  204. }
  205. func TestTx(t *testing.T) {
  206. assert, require := assert.New(t), require.New(t)
  207. // first we broadcast a tx
  208. c := getHTTPClient()
  209. _, _, tx := MakeTxKV()
  210. bres, err := c.BroadcastTxCommit(tx)
  211. require.Nil(err, "%+v", err)
  212. txHeight := bres.Height
  213. txHash := bres.Hash
  214. anotherTxHash := types.Tx("a different tx").Hash()
  215. cases := []struct {
  216. valid bool
  217. hash []byte
  218. prove bool
  219. }{
  220. // only valid if correct hash provided
  221. {true, txHash, false},
  222. {true, txHash, true},
  223. {false, anotherTxHash, false},
  224. {false, anotherTxHash, true},
  225. {false, nil, false},
  226. {false, nil, true},
  227. }
  228. for i, c := range GetClients() {
  229. for j, tc := range cases {
  230. t.Logf("client %d, case %d", i, j)
  231. // now we query for the tx.
  232. // since there's only one tx, we know index=0.
  233. ptx, err := c.Tx(tc.hash, tc.prove)
  234. if !tc.valid {
  235. require.NotNil(err)
  236. } else {
  237. require.Nil(err, "%+v", err)
  238. assert.Equal(txHeight, ptx.Height)
  239. assert.EqualValues(tx, ptx.Tx)
  240. assert.Equal(0, ptx.Index)
  241. assert.True(ptx.TxResult.Code.IsOK())
  242. // time to verify the proof
  243. proof := ptx.Proof
  244. if tc.prove && assert.EqualValues(tx, proof.Data) {
  245. assert.True(proof.Proof.Verify(proof.Index, proof.Total, txHash, proof.RootHash))
  246. }
  247. }
  248. }
  249. }
  250. }