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.

122 lines
2.8 KiB

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