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.

135 lines
3.0 KiB

  1. package abciclient_test
  2. import (
  3. "context"
  4. "fmt"
  5. "testing"
  6. "time"
  7. "math/rand"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/require"
  10. abciclient "github.com/tendermint/tendermint/abci/client"
  11. "github.com/tendermint/tendermint/abci/server"
  12. "github.com/tendermint/tendermint/abci/types"
  13. "github.com/tendermint/tendermint/libs/log"
  14. "github.com/tendermint/tendermint/libs/service"
  15. )
  16. var ctx = context.Background()
  17. func TestProperSyncCalls(t *testing.T) {
  18. app := slowApp{}
  19. logger := log.TestingLogger()
  20. s, c := setupClientServer(t, logger, app)
  21. t.Cleanup(func() {
  22. if err := s.Stop(); err != nil {
  23. t.Error(err)
  24. }
  25. })
  26. t.Cleanup(func() {
  27. if err := c.Stop(); err != nil {
  28. t.Error(err)
  29. }
  30. })
  31. resp := make(chan error, 1)
  32. go func() {
  33. // This is BeginBlockSync unrolled....
  34. reqres, err := c.BeginBlockAsync(ctx, types.RequestBeginBlock{})
  35. assert.NoError(t, err)
  36. err = c.FlushSync(context.Background())
  37. assert.NoError(t, err)
  38. res := reqres.Response.GetBeginBlock()
  39. assert.NotNil(t, res)
  40. resp <- c.Error()
  41. }()
  42. select {
  43. case <-time.After(time.Second):
  44. require.Fail(t, "No response arrived")
  45. case err, ok := <-resp:
  46. require.True(t, ok, "Must not close channel")
  47. assert.NoError(t, err, "This should return success")
  48. }
  49. }
  50. func TestHangingSyncCalls(t *testing.T) {
  51. app := slowApp{}
  52. logger := log.TestingLogger()
  53. s, c := setupClientServer(t, logger, app)
  54. t.Cleanup(func() {
  55. if err := s.Stop(); err != nil {
  56. t.Log(err)
  57. }
  58. })
  59. t.Cleanup(func() {
  60. if err := c.Stop(); err != nil {
  61. t.Log(err)
  62. }
  63. })
  64. resp := make(chan error, 1)
  65. go func() {
  66. // Start BeginBlock and flush it
  67. reqres, err := c.BeginBlockAsync(ctx, types.RequestBeginBlock{})
  68. assert.NoError(t, err)
  69. flush, err := c.FlushAsync(ctx)
  70. assert.NoError(t, err)
  71. // wait 20 ms for all events to travel socket, but
  72. // no response yet from server
  73. time.Sleep(20 * time.Millisecond)
  74. // kill the server, so the connections break
  75. err = s.Stop()
  76. assert.NoError(t, err)
  77. // wait for the response from BeginBlock
  78. reqres.Wait()
  79. flush.Wait()
  80. resp <- c.Error()
  81. }()
  82. select {
  83. case <-time.After(time.Second):
  84. require.Fail(t, "No response arrived")
  85. case err, ok := <-resp:
  86. require.True(t, ok, "Must not close channel")
  87. assert.Error(t, err, "We should get EOF error")
  88. }
  89. }
  90. func setupClientServer(
  91. t *testing.T,
  92. logger log.Logger,
  93. app types.Application,
  94. ) (service.Service, abciclient.Client) {
  95. t.Helper()
  96. // some port between 20k and 30k
  97. port := 20000 + rand.Int31()%10000
  98. addr := fmt.Sprintf("localhost:%d", port)
  99. s, err := server.NewServer(logger, addr, "socket", app)
  100. require.NoError(t, err)
  101. err = s.Start()
  102. require.NoError(t, err)
  103. c := abciclient.NewSocketClient(logger, addr, true)
  104. err = c.Start()
  105. require.NoError(t, err)
  106. return s, c
  107. }
  108. type slowApp struct {
  109. types.BaseApplication
  110. }
  111. func (slowApp) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
  112. time.Sleep(200 * time.Millisecond)
  113. return types.ResponseBeginBlock{}
  114. }