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