github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/nat/traversal/pinger_test.go (about)

     1  /*
     2   * Copyright (C) 2020 The "MysteriumNetwork/node" Authors.
     3   *
     4   * This program is free software: you can redistribute it and/or modify
     5   * it under the terms of the GNU General Public License as published by
     6   * the Free Software Foundation, either version 3 of the License, or
     7   * (at your option) any later version.
     8   *
     9   * This program is distributed in the hope that it will be useful,
    10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    12   * GNU General Public License for more details.
    13   *
    14   * You should have received a copy of the GNU General Public License
    15   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    16   */
    17  
    18  package traversal
    19  
    20  import (
    21  	"context"
    22  	"fmt"
    23  	"net"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/stretchr/testify/assert"
    28  	"github.com/stretchr/testify/require"
    29  
    30  	"github.com/mysteriumnetwork/node/core/port"
    31  )
    32  
    33  const portCount = 10
    34  
    35  func TestPinger_PingPeer_N_Connections(t *testing.T) {
    36  	pingConfig := &PingConfig{
    37  		Interval:            5 * time.Millisecond,
    38  		SendConnACKInterval: 5 * time.Millisecond,
    39  		Timeout:             5 * time.Second,
    40  	}
    41  	provider := newPinger(pingConfig)
    42  	consumer := newPinger(pingConfig)
    43  	var pPorts, cPorts []int
    44  	ports, err := port.NewFixedRangePool(port.Range{Start: 10000, End: 60000}).AcquireMultiple(portCount * 2)
    45  	assert.NoError(t, err)
    46  	for i := 0; i < portCount; i++ {
    47  		pPorts = append(pPorts, ports[i].Num())
    48  		cPorts = append(cPorts, ports[portCount+i].Num())
    49  	}
    50  	peerConns := make(chan *net.UDPConn, 2)
    51  	go func() {
    52  		conns, err := consumer.PingProviderPeer(context.Background(), "", "127.0.0.1", cPorts, pPorts, 128, 2)
    53  		require.NoError(t, err)
    54  		require.Len(t, conns, 2)
    55  		peerConns <- conns[0]
    56  		peerConns <- conns[1]
    57  	}()
    58  	conns, err := provider.PingConsumerPeer(context.Background(), "id", "127.0.0.1", pPorts, cPorts, 2, 2)
    59  	if err != nil {
    60  		t.Errorf("PingConsumerPeer error: %v", err)
    61  		return
    62  	}
    63  
    64  	if len(conns) != 2 {
    65  		t.Error("Not enough connections received from pinger")
    66  		return
    67  	}
    68  	conn1 := conns[0]
    69  	conn2 := conns[1]
    70  	peerConn1 := <-peerConns
    71  	peerConn2 := <-peerConns
    72  	conn1.Close()
    73  	conn2.Close()
    74  	peerConn1.Close()
    75  	peerConn2.Close()
    76  	assert.Equal(t, conn1.RemoteAddr().(*net.UDPAddr).Port, peerConn1.LocalAddr().(*net.UDPAddr).Port)
    77  	assert.Equal(t, conn2.RemoteAddr().(*net.UDPAddr).Port, peerConn2.LocalAddr().(*net.UDPAddr).Port)
    78  }
    79  
    80  func TestPinger_PingPeer_Not_Enough_Connections_Timeout(t *testing.T) {
    81  	pingConfig := &PingConfig{
    82  		Interval: 10 * time.Millisecond,
    83  		Timeout:  300 * time.Millisecond,
    84  	}
    85  
    86  	provider := newPinger(pingConfig)
    87  	consumer := newPinger(pingConfig)
    88  
    89  	var pPorts, cPorts []int
    90  	ports, err := port.NewFixedRangePool(port.Range{Start: 10000, End: 60000}).AcquireMultiple(10)
    91  	assert.NoError(t, err)
    92  
    93  	for i := 0; i < 5; i++ {
    94  		pPorts = append(pPorts, ports[i].Num())
    95  		cPorts = append(cPorts, ports[5+i].Num())
    96  	}
    97  
    98  	consumerPingErr := make(chan error)
    99  	go func() {
   100  		_, err := consumer.PingProviderPeer(context.Background(), "", "127.0.0.1", cPorts, pPorts, 2, 30)
   101  		consumerPingErr <- err
   102  	}()
   103  	conns, err := provider.PingConsumerPeer(context.Background(), "id", "127.0.0.1", pPorts, cPorts, 2, 30)
   104  	assert.Equal(t, ErrTooFew, err)
   105  	assert.Len(t, conns, 0)
   106  
   107  	consumerErr := <-consumerPingErr
   108  	assert.Equal(t, ErrTooFew, consumerErr)
   109  }
   110  
   111  func TestPinger_PingConsumerPeer_Timeout(t *testing.T) {
   112  	pinger := newPinger(&PingConfig{
   113  		Interval: 1 * time.Millisecond,
   114  		Timeout:  5 * time.Millisecond,
   115  	})
   116  	ports, err := port.NewFixedRangePool(port.Range{Start: 10000, End: 60000}).AcquireMultiple(10)
   117  	assert.NoError(t, err)
   118  
   119  	providerPort := ports[0].Num()
   120  	consumerPort := ports[1].Num()
   121  
   122  	go func() {
   123  		addr, _ := net.ResolveUDPAddr("udp4", fmt.Sprintf("127.0.0.1:%d", providerPort))
   124  		conn, err := net.ListenUDP("udp4", addr)
   125  		assert.NoError(t, err)
   126  		defer conn.Close()
   127  
   128  		select {}
   129  	}()
   130  
   131  	_, err = pinger.PingConsumerPeer(context.Background(), "id", "127.0.0.1", []int{consumerPort}, []int{providerPort}, 2, 2)
   132  
   133  	assert.Equal(t, ErrTooFew, err)
   134  }
   135  
   136  func newPinger(config *PingConfig) NATPinger {
   137  	return NewPinger(config, &mockPublisher{})
   138  }
   139  
   140  type mockPublisher struct{}
   141  
   142  func (p mockPublisher) Publish(topic string, data interface{}) {
   143  }