github.com/fiagdao/tendermint@v0.32.11-0.20220824195748-2087fcc480c1/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 defer s.Stop() 47 defer c.Stop() 48 49 resp := make(chan error, 1) 50 go func() { 51 // This is BeginBlockSync unrolled.... 52 reqres := c.BeginBlockAsync(types.RequestBeginBlock{}) 53 c.FlushSync() 54 res := reqres.Response.GetBeginBlock() 55 require.NotNil(t, res) 56 resp <- c.Error() 57 }() 58 59 select { 60 case <-time.After(time.Second): 61 require.Fail(t, "No response arrived") 62 case err, ok := <-resp: 63 require.True(t, ok, "Must not close channel") 64 assert.NoError(t, err, "This should return success") 65 } 66 } 67 68 func TestHangingSyncCalls(t *testing.T) { 69 app := slowApp{} 70 71 s, c := setupClientServer(t, app) 72 defer s.Stop() 73 defer c.Stop() 74 75 resp := make(chan error, 1) 76 go func() { 77 // Start BeginBlock and flush it 78 reqres := c.BeginBlockAsync(types.RequestBeginBlock{}) 79 flush := c.FlushAsync() 80 // wait 20 ms for all events to travel socket, but 81 // no response yet from server 82 time.Sleep(20 * time.Millisecond) 83 // kill the server, so the connections break 84 s.Stop() 85 86 // wait for the response from BeginBlock 87 reqres.Wait() 88 flush.Wait() 89 resp <- c.Error() 90 }() 91 92 select { 93 case <-time.After(time.Second): 94 require.Fail(t, "No response arrived") 95 case err, ok := <-resp: 96 require.True(t, ok, "Must not close channel") 97 assert.Error(t, err, "We should get EOF error") 98 } 99 } 100 101 func setupClientServer(t *testing.T, app types.Application) ( 102 service.Service, abcicli.Client) { 103 // some port between 20k and 30k 104 port := 20000 + tmrand.Int32()%10000 105 addr := fmt.Sprintf("localhost:%d", port) 106 107 s, err := server.NewServer(addr, "socket", app) 108 require.NoError(t, err) 109 err = s.Start() 110 require.NoError(t, err) 111 112 c := abcicli.NewSocketClient(addr, true) 113 err = c.Start() 114 require.NoError(t, err) 115 116 return s, c 117 } 118 119 type slowApp struct { 120 types.BaseApplication 121 } 122 123 func (slowApp) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock { 124 time.Sleep(200 * time.Millisecond) 125 return types.ResponseBeginBlock{} 126 }