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.

162 lines
4.4 KiB

  1. package e2e_test
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "math/rand"
  7. "testing"
  8. "time"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. "github.com/tendermint/tendermint/rpc/client/http"
  12. e2e "github.com/tendermint/tendermint/test/e2e/pkg"
  13. "github.com/tendermint/tendermint/types"
  14. )
  15. // Tests that any initial state given in genesis has made it into the app.
  16. func TestApp_InitialState(t *testing.T) {
  17. testNode(t, func(t *testing.T, node e2e.Node) {
  18. if len(node.Testnet.InitialState) == 0 {
  19. return
  20. }
  21. client, err := node.Client()
  22. require.NoError(t, err)
  23. for k, v := range node.Testnet.InitialState {
  24. resp, err := client.ABCIQuery(ctx, "", []byte(k))
  25. require.NoError(t, err)
  26. assert.Equal(t, k, string(resp.Response.Key))
  27. assert.Equal(t, v, string(resp.Response.Value))
  28. }
  29. })
  30. }
  31. // Tests that the app hash (as reported by the app) matches the last
  32. // block and the node sync status.
  33. func TestApp_Hash(t *testing.T) {
  34. testNode(t, func(t *testing.T, node e2e.Node) {
  35. client, err := node.Client()
  36. require.NoError(t, err)
  37. info, err := client.ABCIInfo(ctx)
  38. require.NoError(t, err)
  39. require.NotEmpty(t, info.Response.LastBlockAppHash, "expected app to return app hash")
  40. status, err := client.Status(ctx)
  41. require.NoError(t, err)
  42. block, err := client.Block(ctx, &info.Response.LastBlockHeight)
  43. require.NoError(t, err)
  44. if info.Response.LastBlockHeight == block.Block.Height {
  45. require.EqualValues(t, info.Response.LastBlockAppHash, block.Block.AppHash.Bytes(),
  46. "app hash does not match last block's app hash")
  47. }
  48. require.True(t, status.SyncInfo.LatestBlockHeight >= info.Response.LastBlockHeight,
  49. "status out of sync with application")
  50. })
  51. }
  52. // Tests that we can set a value and retrieve it.
  53. func TestApp_Tx(t *testing.T) {
  54. type broadcastFunc func(context.Context, types.Tx) error
  55. testCases := []struct {
  56. Name string
  57. WaitTime time.Duration
  58. BroadcastTx func(client *http.HTTP) broadcastFunc
  59. ShouldSkip bool
  60. }{
  61. {
  62. Name: "Sync",
  63. WaitTime: time.Minute,
  64. BroadcastTx: func(client *http.HTTP) broadcastFunc {
  65. return func(ctx context.Context, tx types.Tx) error {
  66. _, err := client.BroadcastTxSync(ctx, tx)
  67. return err
  68. }
  69. },
  70. },
  71. {
  72. Name: "Commit",
  73. WaitTime: 15 * time.Second,
  74. // TODO: turn this check back on if it can
  75. // return reliably. Currently these calls have
  76. // a hard timeout of 10s (server side
  77. // configured). The Sync check is probably
  78. // safe.
  79. ShouldSkip: true,
  80. BroadcastTx: func(client *http.HTTP) broadcastFunc {
  81. return func(ctx context.Context, tx types.Tx) error {
  82. _, err := client.BroadcastTxCommit(ctx, tx)
  83. return err
  84. }
  85. },
  86. },
  87. {
  88. Name: "Async",
  89. WaitTime: 90 * time.Second,
  90. // TODO: turn this check back on if there's a
  91. // way to avoid failures in the case that the
  92. // transaction doesn't make it into the
  93. // mempool. (retries?)
  94. ShouldSkip: true,
  95. BroadcastTx: func(client *http.HTTP) broadcastFunc {
  96. return func(ctx context.Context, tx types.Tx) error {
  97. _, err := client.BroadcastTxAsync(ctx, tx)
  98. return err
  99. }
  100. },
  101. },
  102. }
  103. for idx, test := range testCases {
  104. if test.ShouldSkip {
  105. continue
  106. }
  107. t.Run(test.Name, func(t *testing.T) {
  108. // testNode calls t.Parallel as well, so we should
  109. // have a copy of the
  110. test := testCases[idx]
  111. testNode(t, func(t *testing.T, node e2e.Node) {
  112. client, err := node.Client()
  113. require.NoError(t, err)
  114. // Generate a random value, to prevent duplicate tx errors when
  115. // manually running the test multiple times for a testnet.
  116. bz := make([]byte, 32)
  117. _, err = rand.Read(bz)
  118. require.NoError(t, err)
  119. key := fmt.Sprintf("testapp-tx-%v", node.Name)
  120. value := fmt.Sprintf("%x", bz)
  121. tx := types.Tx(fmt.Sprintf("%v=%v", key, value))
  122. require.NoError(t, test.BroadcastTx(client)(ctx, tx))
  123. hash := tx.Hash()
  124. require.Eventuallyf(t, func() bool {
  125. txResp, err := client.Tx(ctx, hash, false)
  126. return err == nil && bytes.Equal(txResp.Tx, tx)
  127. },
  128. test.WaitTime, // timeout
  129. time.Second, // interval
  130. "submitted tx %X wasn't committed after %v",
  131. hash, test.WaitTime,
  132. )
  133. abciResp, err := client.ABCIQuery(ctx, "", []byte(key))
  134. require.NoError(t, err)
  135. assert.Equal(t, key, string(abciResp.Response.Key))
  136. assert.Equal(t, value, string(abciResp.Response.Value))
  137. })
  138. })
  139. }
  140. }