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.

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