github.com/micro/go-micro/v2@v2.9.1/tunnel/tunnel_test.go (about) 1 package tunnel 2 3 import ( 4 "os" 5 "sync" 6 "testing" 7 "time" 8 9 "github.com/micro/go-micro/v2/transport" 10 ) 11 12 func testBrokenTunAccept(t *testing.T, tun Tunnel, wait chan bool, wg *sync.WaitGroup) { 13 defer wg.Done() 14 15 // listen on some virtual address 16 tl, err := tun.Listen("test-tunnel") 17 if err != nil { 18 t.Fatal(err) 19 } 20 21 // receiver ready; notify sender 22 wait <- true 23 24 // accept a connection 25 c, err := tl.Accept() 26 if err != nil { 27 t.Fatal(err) 28 } 29 30 // accept the message and close the tunnel 31 // we do this to simulate loss of network connection 32 m := new(transport.Message) 33 if err := c.Recv(m); err != nil { 34 t.Fatal(err) 35 } 36 37 // close all the links 38 for _, link := range tun.Links() { 39 link.Close() 40 } 41 42 // receiver ready; notify sender 43 wait <- true 44 45 // accept the message 46 m = new(transport.Message) 47 if err := c.Recv(m); err != nil { 48 t.Fatal(err) 49 } 50 51 // notify the sender we have received 52 wait <- true 53 } 54 55 func testBrokenTunSend(t *testing.T, tun Tunnel, wait chan bool, wg *sync.WaitGroup, reconnect time.Duration) { 56 defer wg.Done() 57 58 // wait for the listener to get ready 59 <-wait 60 61 // dial a new session 62 c, err := tun.Dial("test-tunnel") 63 if err != nil { 64 t.Fatal(err) 65 } 66 defer c.Close() 67 68 m := transport.Message{ 69 Header: map[string]string{ 70 "test": "send", 71 }, 72 } 73 74 // send the message 75 if err := c.Send(&m); err != nil { 76 t.Fatal(err) 77 } 78 79 // wait for the listener to get ready 80 <-wait 81 82 // give it time to reconnect 83 time.Sleep(reconnect) 84 85 // send the message 86 if err := c.Send(&m); err != nil { 87 t.Fatal(err) 88 } 89 90 // wait for the listener to receive the message 91 // c.Send merely enqueues the message to the link send queue and returns 92 // in order to verify it was received we wait for the listener to tell us 93 <-wait 94 } 95 96 // testAccept will accept connections on the transport, create a new link and tunnel on top 97 func testAccept(t *testing.T, tun Tunnel, wait chan bool, wg *sync.WaitGroup) { 98 defer wg.Done() 99 100 // listen on some virtual address 101 tl, err := tun.Listen("test-tunnel") 102 if err != nil { 103 t.Fatal(err) 104 } 105 106 // receiver ready; notify sender 107 wait <- true 108 109 // accept a connection 110 c, err := tl.Accept() 111 if err != nil { 112 t.Fatal(err) 113 } 114 115 // get a message 116 for { 117 // accept the message 118 m := new(transport.Message) 119 if err := c.Recv(m); err != nil { 120 t.Fatal(err) 121 } 122 123 if v := m.Header["test"]; v != "send" { 124 t.Fatalf("Accept side expected test:send header. Received: %s", v) 125 } 126 127 // now respond 128 m.Header["test"] = "accept" 129 if err := c.Send(m); err != nil { 130 t.Fatal(err) 131 } 132 133 wait <- true 134 135 return 136 } 137 } 138 139 // testSend will create a new link to an address and then a tunnel on top 140 func testSend(t *testing.T, tun Tunnel, wait chan bool, wg *sync.WaitGroup) { 141 defer wg.Done() 142 143 // wait for the listener to get ready 144 <-wait 145 146 // dial a new session 147 c, err := tun.Dial("test-tunnel") 148 if err != nil { 149 t.Fatal(err) 150 } 151 defer c.Close() 152 153 m := transport.Message{ 154 Header: map[string]string{ 155 "test": "send", 156 }, 157 } 158 159 // send the message 160 if err := c.Send(&m); err != nil { 161 t.Fatal(err) 162 } 163 164 // now wait for the response 165 mr := new(transport.Message) 166 if err := c.Recv(mr); err != nil { 167 t.Fatal(err) 168 } 169 170 <-wait 171 172 if v := mr.Header["test"]; v != "accept" { 173 t.Fatalf("Message not received from accepted side. Received: %s", v) 174 } 175 } 176 177 func TestTunnel(t *testing.T) { 178 // create a new tunnel client 179 tunA := NewTunnel( 180 Address("127.0.0.1:9096"), 181 Nodes("127.0.0.1:9097"), 182 ) 183 184 // create a new tunnel server 185 tunB := NewTunnel( 186 Address("127.0.0.1:9097"), 187 ) 188 189 // start tunB 190 err := tunB.Connect() 191 if err != nil { 192 t.Fatal(err) 193 } 194 defer tunB.Close() 195 196 // start tunA 197 err = tunA.Connect() 198 if err != nil { 199 t.Fatal(err) 200 } 201 defer tunA.Close() 202 203 wait := make(chan bool) 204 205 var wg sync.WaitGroup 206 207 wg.Add(1) 208 // start the listener 209 go testAccept(t, tunB, wait, &wg) 210 211 wg.Add(1) 212 // start the client 213 go testSend(t, tunA, wait, &wg) 214 215 // wait until done 216 wg.Wait() 217 } 218 219 func TestLoopbackTunnel(t *testing.T) { 220 // create a new tunnel 221 tun := NewTunnel( 222 Address("127.0.0.1:9096"), 223 Nodes("127.0.0.1:9096"), 224 ) 225 226 // start tunnel 227 err := tun.Connect() 228 if err != nil { 229 t.Fatal(err) 230 } 231 defer tun.Close() 232 233 time.Sleep(500 * time.Millisecond) 234 235 wait := make(chan bool) 236 237 var wg sync.WaitGroup 238 239 wg.Add(1) 240 // start the listener 241 go testAccept(t, tun, wait, &wg) 242 243 wg.Add(1) 244 // start the client 245 go testSend(t, tun, wait, &wg) 246 247 // wait until done 248 wg.Wait() 249 } 250 251 func TestTunnelRTTRate(t *testing.T) { 252 // create a new tunnel client 253 tunA := NewTunnel( 254 Address("127.0.0.1:9096"), 255 Nodes("127.0.0.1:9097"), 256 ) 257 258 // create a new tunnel server 259 tunB := NewTunnel( 260 Address("127.0.0.1:9097"), 261 ) 262 263 // start tunB 264 err := tunB.Connect() 265 if err != nil { 266 t.Fatal(err) 267 } 268 defer tunB.Close() 269 270 // start tunA 271 err = tunA.Connect() 272 if err != nil { 273 t.Fatal(err) 274 } 275 defer tunA.Close() 276 277 wait := make(chan bool) 278 279 var wg sync.WaitGroup 280 281 wg.Add(1) 282 // start the listener 283 go testAccept(t, tunB, wait, &wg) 284 285 wg.Add(1) 286 // start the client 287 go testSend(t, tunA, wait, &wg) 288 289 // wait until done 290 wg.Wait() 291 292 if len(os.Getenv("IN_TRAVIS_CI")) == 0 { 293 // only needed for debug 294 for _, link := range tunA.Links() { 295 t.Logf("Link %s length %v rate %v", link.Id(), link.Length(), link.Rate()) 296 } 297 298 for _, link := range tunB.Links() { 299 t.Logf("Link %s length %v rate %v", link.Id(), link.Length(), link.Rate()) 300 } 301 } 302 } 303 304 func TestReconnectTunnel(t *testing.T) { 305 // we manually override the tunnel.ReconnectTime value here 306 // this is so that we make the reconnects faster than the default 5s 307 ReconnectTime = 200 * time.Millisecond 308 309 // create a new tunnel client 310 tunA := NewTunnel( 311 Address("127.0.0.1:9098"), 312 Nodes("127.0.0.1:9099"), 313 ) 314 315 // create a new tunnel server 316 tunB := NewTunnel( 317 Address("127.0.0.1:9099"), 318 ) 319 320 // start tunnel 321 err := tunB.Connect() 322 if err != nil { 323 t.Fatal(err) 324 } 325 defer tunB.Close() 326 327 // start tunnel 328 err = tunA.Connect() 329 if err != nil { 330 t.Fatal(err) 331 } 332 defer tunA.Close() 333 334 wait := make(chan bool) 335 336 var wg sync.WaitGroup 337 338 wg.Add(1) 339 // start tunnel listener 340 go testBrokenTunAccept(t, tunB, wait, &wg) 341 342 wg.Add(1) 343 // start tunnel sender 344 go testBrokenTunSend(t, tunA, wait, &wg, ReconnectTime*5) 345 346 // wait until done 347 wg.Wait() 348 }