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.

127 lines
2.8 KiB

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