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 }