github.com/arcology-network/consensus-engine@v1.9.0/abci/client/socket_client_test.go (about)

     1  package abcicli_test
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/stretchr/testify/assert"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	abcicli "github.com/arcology-network/consensus-engine/abci/client"
    12  	"github.com/arcology-network/consensus-engine/abci/server"
    13  	"github.com/arcology-network/consensus-engine/abci/types"
    14  	tmrand "github.com/arcology-network/consensus-engine/libs/rand"
    15  	"github.com/arcology-network/consensus-engine/libs/service"
    16  )
    17  
    18  func TestProperSyncCalls(t *testing.T) {
    19  	app := slowApp{}
    20  
    21  	s, c := setupClientServer(t, app)
    22  	t.Cleanup(func() {
    23  		if err := s.Stop(); err != nil {
    24  			t.Error(err)
    25  		}
    26  	})
    27  	t.Cleanup(func() {
    28  		if err := c.Stop(); err != nil {
    29  			t.Error(err)
    30  		}
    31  	})
    32  
    33  	resp := make(chan error, 1)
    34  	go func() {
    35  		// This is BeginBlockSync unrolled....
    36  		reqres := c.BeginBlockAsync(types.RequestBeginBlock{})
    37  		err := c.FlushSync()
    38  		require.NoError(t, err)
    39  		res := reqres.Response.GetBeginBlock()
    40  		require.NotNil(t, res)
    41  		resp <- c.Error()
    42  	}()
    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  
    53  func TestHangingSyncCalls(t *testing.T) {
    54  	app := slowApp{}
    55  
    56  	s, c := setupClientServer(t, app)
    57  	t.Cleanup(func() {
    58  		if err := s.Stop(); err != nil {
    59  			t.Log(err)
    60  		}
    61  	})
    62  	t.Cleanup(func() {
    63  		if err := c.Stop(); err != nil {
    64  			t.Log(err)
    65  		}
    66  	})
    67  
    68  	resp := make(chan error, 1)
    69  	go func() {
    70  		// Start BeginBlock and flush it
    71  		reqres := c.BeginBlockAsync(types.RequestBeginBlock{})
    72  		flush := c.FlushAsync()
    73  		// wait 20 ms for all events to travel socket, but
    74  		// no response yet from server
    75  		time.Sleep(20 * time.Millisecond)
    76  		// kill the server, so the connections break
    77  		err := s.Stop()
    78  		require.NoError(t, err)
    79  
    80  		// wait for the response from BeginBlock
    81  		reqres.Wait()
    82  		flush.Wait()
    83  		resp <- c.Error()
    84  	}()
    85  
    86  	select {
    87  	case <-time.After(time.Second):
    88  		require.Fail(t, "No response arrived")
    89  	case err, ok := <-resp:
    90  		require.True(t, ok, "Must not close channel")
    91  		assert.Error(t, err, "We should get EOF error")
    92  	}
    93  }
    94  
    95  func setupClientServer(t *testing.T, app types.Application) (
    96  	service.Service, abcicli.Client) {
    97  	// some port between 20k and 30k
    98  	port := 20000 + tmrand.Int32()%10000
    99  	addr := fmt.Sprintf("localhost:%d", port)
   100  
   101  	s, err := server.NewServer(addr, "socket", app)
   102  	require.NoError(t, err)
   103  	err = s.Start()
   104  	require.NoError(t, err)
   105  
   106  	c := abcicli.NewSocketClient(addr, true)
   107  	err = c.Start()
   108  	require.NoError(t, err)
   109  
   110  	return s, c
   111  }
   112  
   113  type slowApp struct {
   114  	types.BaseApplication
   115  }
   116  
   117  func (slowApp) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
   118  	time.Sleep(200 * time.Millisecond)
   119  	return types.ResponseBeginBlock{}
   120  }