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.

366 lines
10 KiB

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