github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/network/tunnel/mucp/mucp_test.go (about)

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