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  }