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