github.com/homburg/packer@v0.6.1-0.20140528012651-1dcaf1716848/packer/rpc/muxconn_test.go (about) 1 package rpc 2 3 import ( 4 "io" 5 "net" 6 "sync" 7 "testing" 8 ) 9 10 func readStream(t *testing.T, s io.Reader) string { 11 var data [1024]byte 12 n, err := s.Read(data[:]) 13 if err != nil { 14 t.Fatalf("err: %s", err) 15 } 16 17 return string(data[0:n]) 18 } 19 20 func testMux(t *testing.T) (client *MuxConn, server *MuxConn) { 21 l, err := net.Listen("tcp", "127.0.0.1:0") 22 if err != nil { 23 t.Fatalf("err: %s", err) 24 } 25 26 // Server side 27 doneCh := make(chan struct{}) 28 go func() { 29 defer close(doneCh) 30 conn, err := l.Accept() 31 l.Close() 32 if err != nil { 33 t.Fatalf("err: %s", err) 34 } 35 36 server = NewMuxConn(conn) 37 }() 38 39 // Client side 40 conn, err := net.Dial("tcp", l.Addr().String()) 41 if err != nil { 42 t.Fatalf("err: %s", err) 43 } 44 client = NewMuxConn(conn) 45 46 // Wait for the server 47 <-doneCh 48 49 return 50 } 51 52 func TestMuxConn(t *testing.T) { 53 client, server := testMux(t) 54 defer client.Close() 55 defer server.Close() 56 57 // When the server is done 58 doneCh := make(chan struct{}) 59 60 // The server side 61 go func() { 62 defer close(doneCh) 63 64 s0, err := server.Accept(0) 65 if err != nil { 66 t.Fatalf("err: %s", err) 67 } 68 69 s1, err := server.Dial(1) 70 if err != nil { 71 t.Fatalf("err: %s", err) 72 } 73 74 var wg sync.WaitGroup 75 wg.Add(2) 76 77 go func() { 78 defer wg.Done() 79 defer s1.Close() 80 data := readStream(t, s1) 81 if data != "another" { 82 t.Fatalf("bad: %#v", data) 83 } 84 }() 85 86 go func() { 87 defer wg.Done() 88 defer s0.Close() 89 data := readStream(t, s0) 90 if data != "hello" { 91 t.Fatalf("bad: %#v", data) 92 } 93 }() 94 95 wg.Wait() 96 }() 97 98 s0, err := client.Dial(0) 99 if err != nil { 100 t.Fatalf("err: %s", err) 101 } 102 103 s1, err := client.Accept(1) 104 if err != nil { 105 t.Fatalf("err: %s", err) 106 } 107 108 if _, err := s0.Write([]byte("hello")); err != nil { 109 t.Fatalf("err: %s", err) 110 } 111 if _, err := s1.Write([]byte("another")); err != nil { 112 t.Fatalf("err: %s", err) 113 } 114 115 s0.Close() 116 s1.Close() 117 118 // Wait for the server to be done 119 <-doneCh 120 } 121 122 func TestMuxConn_lotsOfData(t *testing.T) { 123 client, server := testMux(t) 124 defer client.Close() 125 defer server.Close() 126 127 // When the server is done 128 doneCh := make(chan struct{}) 129 130 // The server side 131 go func() { 132 defer close(doneCh) 133 134 s0, err := server.Accept(0) 135 if err != nil { 136 t.Fatalf("err: %s", err) 137 } 138 139 var data [1024]byte 140 for { 141 n, err := s0.Read(data[:]) 142 if err == io.EOF { 143 break 144 } 145 146 dataString := string(data[0:n]) 147 if dataString != "hello" { 148 t.Fatalf("bad: %#v", dataString) 149 } 150 } 151 152 s0.Close() 153 }() 154 155 s0, err := client.Dial(0) 156 if err != nil { 157 t.Fatalf("err: %s", err) 158 } 159 160 for i := 0; i < 4096*4; i++ { 161 if _, err := s0.Write([]byte("hello")); err != nil { 162 t.Fatalf("err: %s", err) 163 } 164 } 165 166 if err := s0.Close(); err != nil { 167 t.Fatalf("err: %s", err) 168 } 169 170 // Wait for the server to be done 171 <-doneCh 172 } 173 174 // This tests that even when the client end is closed, data can be 175 // read from the server. 176 func TestMuxConn_clientCloseRead(t *testing.T) { 177 client, server := testMux(t) 178 defer client.Close() 179 defer server.Close() 180 181 // This channel will be closed when we close 182 waitCh := make(chan struct{}) 183 184 go func() { 185 conn, err := server.Accept(0) 186 if err != nil { 187 t.Fatalf("err: %s", err) 188 } 189 190 <-waitCh 191 192 _, err = conn.Write([]byte("foo")) 193 if err != nil { 194 t.Fatalf("err: %s", err) 195 } 196 197 conn.Close() 198 }() 199 200 s0, err := client.Dial(0) 201 if err != nil { 202 t.Fatalf("err: %s", err) 203 } 204 205 if err := s0.Close(); err != nil { 206 t.Fatalf("bad: %s", err) 207 } 208 209 // Close this to continue on on the server-side 210 close(waitCh) 211 212 var data [1024]byte 213 n, err := s0.Read(data[:]) 214 if string(data[:n]) != "foo" { 215 t.Fatalf("bad: %#v", string(data[:n])) 216 } 217 } 218 219 func TestMuxConn_socketClose(t *testing.T) { 220 client, server := testMux(t) 221 defer client.Close() 222 defer server.Close() 223 224 go func() { 225 _, err := server.Accept(0) 226 if err != nil { 227 t.Fatalf("err: %s", err) 228 } 229 230 server.rwc.Close() 231 }() 232 233 s0, err := client.Dial(0) 234 if err != nil { 235 t.Fatalf("err: %s", err) 236 } 237 238 var data [1024]byte 239 _, err = s0.Read(data[:]) 240 if err != io.EOF { 241 t.Fatalf("err: %s", err) 242 } 243 } 244 245 func TestMuxConn_clientClosesStreams(t *testing.T) { 246 client, server := testMux(t) 247 defer client.Close() 248 defer server.Close() 249 250 go func() { 251 conn, err := server.Accept(0) 252 if err != nil { 253 t.Fatalf("err: %s", err) 254 } 255 conn.Close() 256 }() 257 258 s0, err := client.Dial(0) 259 if err != nil { 260 t.Fatalf("err: %s", err) 261 } 262 263 var data [1024]byte 264 _, err = s0.Read(data[:]) 265 if err != io.EOF { 266 t.Fatalf("err: %s", err) 267 } 268 } 269 270 func TestMuxConn_serverClosesStreams(t *testing.T) { 271 client, server := testMux(t) 272 defer client.Close() 273 defer server.Close() 274 go server.Accept(0) 275 276 s0, err := client.Dial(0) 277 if err != nil { 278 t.Fatalf("err: %s", err) 279 } 280 281 if err := server.Close(); err != nil { 282 t.Fatalf("err: %s", err) 283 } 284 285 // This should block forever since we never write onto this stream. 286 var data [1024]byte 287 _, err = s0.Read(data[:]) 288 if err != io.EOF { 289 t.Fatalf("err: %s", err) 290 } 291 } 292 293 func TestMuxConnNextId(t *testing.T) { 294 client, server := testMux(t) 295 defer client.Close() 296 defer server.Close() 297 298 a := client.NextId() 299 b := client.NextId() 300 301 if a != 1 || b != 2 { 302 t.Fatalf("IDs should increment") 303 } 304 305 a = server.NextId() 306 b = server.NextId() 307 308 if a != 1 || b != 2 { 309 t.Fatalf("IDs should increment: %d %d", a, b) 310 } 311 }