github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+incompatible/plugin/rpcplugin/muxer_test.go (about)

     1  package rpcplugin
     2  
     3  import (
     4  	"io"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  	"github.com/stretchr/testify/require"
     9  )
    10  
    11  func TestMuxer(t *testing.T) {
    12  	r1, w1 := io.Pipe()
    13  	r2, w2 := io.Pipe()
    14  
    15  	alice := NewMuxer(NewReadWriteCloser(r1, w2), false)
    16  	defer func() { assert.NoError(t, alice.Close()) }()
    17  
    18  	bob := NewMuxer(NewReadWriteCloser(r2, w1), true)
    19  	defer func() { assert.NoError(t, bob.Close()) }()
    20  
    21  	id1, alice1 := alice.Serve()
    22  	defer func() { assert.NoError(t, alice1.Close()) }()
    23  
    24  	id2, bob2 := bob.Serve()
    25  	defer func() { assert.NoError(t, bob2.Close()) }()
    26  
    27  	done1 := make(chan bool)
    28  	done2 := make(chan bool)
    29  
    30  	go func() {
    31  		bob1 := bob.Connect(id1)
    32  		defer func() { assert.NoError(t, bob1.Close()) }()
    33  
    34  		n, err := bob1.Write([]byte("ping1.0"))
    35  		require.NoError(t, err)
    36  		assert.Equal(t, n, 7)
    37  
    38  		n, err = bob1.Write([]byte("ping1.1"))
    39  		require.NoError(t, err)
    40  		assert.Equal(t, n, 7)
    41  	}()
    42  
    43  	go func() {
    44  		alice2 := alice.Connect(id2)
    45  		defer func() { assert.NoError(t, alice2.Close()) }()
    46  
    47  		n, err := alice2.Write([]byte("ping2.0"))
    48  		require.NoError(t, err)
    49  		assert.Equal(t, n, 7)
    50  
    51  		buf := make([]byte, 20)
    52  		n, err = alice2.Read(buf)
    53  		require.NoError(t, err)
    54  		assert.Equal(t, n, 7)
    55  		assert.Equal(t, []byte("pong2.0"), buf[:n])
    56  
    57  		done2 <- true
    58  	}()
    59  
    60  	go func() {
    61  		buf := make([]byte, 7)
    62  		n, err := io.ReadFull(alice1, buf)
    63  		require.NoError(t, err)
    64  		assert.Equal(t, n, 7)
    65  		assert.Equal(t, []byte("ping1.0"), buf[:n])
    66  
    67  		n, err = alice1.Read(buf)
    68  		require.NoError(t, err)
    69  		assert.Equal(t, n, 7)
    70  		assert.Equal(t, []byte("ping1.1"), buf[:n])
    71  
    72  		done1 <- true
    73  	}()
    74  
    75  	go func() {
    76  		buf := make([]byte, 20)
    77  		n, err := bob2.Read(buf)
    78  		require.NoError(t, err)
    79  		assert.Equal(t, n, 7)
    80  		assert.Equal(t, []byte("ping2.0"), buf[:n])
    81  
    82  		n, err = bob2.Write([]byte("pong2.0"))
    83  		require.NoError(t, err)
    84  		assert.Equal(t, n, 7)
    85  	}()
    86  
    87  	<-done1
    88  	<-done2
    89  }
    90  
    91  // Closing a muxer during a read should unblock, but return an error.
    92  func TestMuxer_CloseDuringRead(t *testing.T) {
    93  	r1, w1 := io.Pipe()
    94  	r2, w2 := io.Pipe()
    95  
    96  	alice := NewMuxer(NewReadWriteCloser(r1, w2), false)
    97  
    98  	bob := NewMuxer(NewReadWriteCloser(r2, w1), true)
    99  	defer func() { assert.NoError(t, bob.Close()) }()
   100  
   101  	_, s := alice.Serve()
   102  
   103  	go alice.Close()
   104  	buf := make([]byte, 20)
   105  	n, err := s.Read(buf)
   106  	assert.Equal(t, 0, n)
   107  	assert.NotNil(t, err)
   108  	assert.NotEqual(t, io.EOF, err)
   109  }
   110  
   111  // Closing a stream during a read should unblock and return io.EOF since this is the way to
   112  // gracefully close a connection.
   113  func TestMuxer_StreamCloseDuringRead(t *testing.T) {
   114  	r1, w1 := io.Pipe()
   115  	r2, w2 := io.Pipe()
   116  
   117  	alice := NewMuxer(NewReadWriteCloser(r1, w2), false)
   118  	defer func() { assert.NoError(t, alice.Close()) }()
   119  
   120  	bob := NewMuxer(NewReadWriteCloser(r2, w1), true)
   121  	defer func() { assert.NoError(t, bob.Close()) }()
   122  
   123  	_, s := alice.Serve()
   124  
   125  	go s.Close()
   126  	buf := make([]byte, 20)
   127  	n, err := s.Read(buf)
   128  	assert.Equal(t, 0, n)
   129  	assert.Equal(t, io.EOF, err)
   130  }
   131  
   132  // Closing a stream during a read should unblock and return io.EOF since this is the way for the
   133  // remote to gracefully close a connection.
   134  func TestMuxer_RemoteStreamCloseDuringRead(t *testing.T) {
   135  	r1, w1 := io.Pipe()
   136  	r2, w2 := io.Pipe()
   137  
   138  	alice := NewMuxer(NewReadWriteCloser(r1, w2), false)
   139  	defer func() { assert.NoError(t, alice.Close()) }()
   140  
   141  	bob := NewMuxer(NewReadWriteCloser(r2, w1), true)
   142  	defer func() { assert.NoError(t, bob.Close()) }()
   143  
   144  	id, as := alice.Serve()
   145  	bs := bob.Connect(id)
   146  
   147  	go func() {
   148  		as.Write([]byte("foo"))
   149  		as.Close()
   150  	}()
   151  	buf := make([]byte, 20)
   152  	n, err := bs.Read(buf)
   153  	assert.Equal(t, 3, n)
   154  	assert.Equal(t, "foo", string(buf[:n]))
   155  	n, err = bs.Read(buf)
   156  	assert.Equal(t, 0, n)
   157  	assert.Equal(t, io.EOF, err)
   158  }
   159  
   160  // Closing a muxer during a write should unblock, but return an error.
   161  func TestMuxer_CloseDuringWrite(t *testing.T) {
   162  	r1, w1 := io.Pipe()
   163  	r2, w2 := io.Pipe()
   164  
   165  	alice := NewMuxer(NewReadWriteCloser(r1, w2), false)
   166  
   167  	// Don't connect bob to let writes will block forever.
   168  	defer r2.Close()
   169  	defer w1.Close()
   170  
   171  	_, s := alice.Serve()
   172  
   173  	go alice.Close()
   174  	buf := make([]byte, 20)
   175  	n, err := s.Write(buf)
   176  	assert.Equal(t, 0, n)
   177  	assert.NotNil(t, err)
   178  	assert.NotEqual(t, io.EOF, err)
   179  }
   180  
   181  func TestMuxer_ReadWrite(t *testing.T) {
   182  	r1, w1 := io.Pipe()
   183  	r2, w2 := io.Pipe()
   184  
   185  	alice := NewMuxer(NewReadWriteCloser(r1, w2), false)
   186  	defer func() { assert.NoError(t, alice.Close()) }()
   187  
   188  	bob := NewMuxer(NewReadWriteCloser(r2, w1), true)
   189  	defer func() { assert.NoError(t, bob.Close()) }()
   190  
   191  	go alice.Write([]byte("hello"))
   192  	buf := make([]byte, 20)
   193  	n, err := bob.Read(buf)
   194  	assert.Equal(t, 5, n)
   195  	assert.Nil(t, err)
   196  	assert.Equal(t, []byte("hello"), buf[:n])
   197  }