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  }