github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/core/ip/cached_resolver_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 ip
    19  
    20  import (
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/stretchr/testify/assert"
    25  )
    26  
    27  func TestCachedResolverCachesPublicIP(t *testing.T) {
    28  	tests := []struct {
    29  		name              string
    30  		cacheDuration     time.Duration
    31  		sleepAfterCall    time.Duration
    32  		expectedIP        string
    33  		expectedIPFetches int
    34  	}{
    35  		{
    36  			name:              "Test ip is fetch and cache",
    37  			cacheDuration:     50 * time.Millisecond,
    38  			sleepAfterCall:    time.Microsecond,
    39  			expectedIP:        "1.1.1.1",
    40  			expectedIPFetches: 1,
    41  		},
    42  		{
    43  			name:              "Test ip cache update when cache duration has passed",
    44  			cacheDuration:     time.Microsecond,
    45  			sleepAfterCall:    time.Millisecond,
    46  			expectedIP:        "1.1.1.1",
    47  			expectedIPFetches: 5,
    48  		},
    49  	}
    50  
    51  	for _, test := range tests {
    52  		t.Run(test.name, func(t *testing.T) {
    53  			mr := &mockRealResolver{}
    54  			cr := NewCachedResolver(mr, test.cacheDuration)
    55  
    56  			var actualIP string
    57  			var err error
    58  			for i := 0; i < 5; i++ {
    59  				actualIP, err = cr.GetPublicIP()
    60  				assert.NoError(t, err)
    61  				time.Sleep(test.sleepAfterCall)
    62  			}
    63  
    64  			assert.Equal(t, test.expectedIP, actualIP)
    65  			assert.Equal(t, test.expectedIPFetches, mr.getPublicIPCalls)
    66  		})
    67  	}
    68  }
    69  
    70  func TestCachedResolverCachesOutboundIP(t *testing.T) {
    71  	tests := []struct {
    72  		name              string
    73  		cacheDuration     time.Duration
    74  		ipCheckInterval   time.Duration
    75  		expectedIP        string
    76  		expectedIPFetches int
    77  	}{
    78  		{
    79  			name: "Test ip is fetch and cache",
    80  			// monotonic time resolution is fairly low on some OS'es, such as 15ms on Windows 2008
    81  			cacheDuration:     50 * time.Millisecond,
    82  			ipCheckInterval:   time.Microsecond,
    83  			expectedIP:        "192.168.1.2",
    84  			expectedIPFetches: 1,
    85  		},
    86  		{
    87  			name:              "Test ip cache update when cache duration has passed",
    88  			cacheDuration:     time.Microsecond,
    89  			ipCheckInterval:   time.Millisecond,
    90  			expectedIP:        "192.168.1.2",
    91  			expectedIPFetches: 5,
    92  		},
    93  	}
    94  
    95  	for _, test := range tests {
    96  		t.Run(test.name, func(t *testing.T) {
    97  			mr := &mockRealResolver{}
    98  			cr := NewCachedResolver(mr, test.cacheDuration)
    99  
   100  			var actualIP string
   101  			var err error
   102  			for i := 0; i < 5; i++ {
   103  				actualIP, err = cr.GetOutboundIP()
   104  				assert.NoError(t, err)
   105  				time.Sleep(test.ipCheckInterval)
   106  			}
   107  
   108  			assert.Equal(t, test.expectedIP, actualIP)
   109  			assert.Equal(t, test.expectedIPFetches, mr.getOutboundIPCalls)
   110  		})
   111  	}
   112  }
   113  
   114  type mockRealResolver struct {
   115  	getOutboundIPCalls int
   116  	getPublicIPCalls   int
   117  }
   118  
   119  func (m *mockRealResolver) GetOutboundIP() (string, error) {
   120  	m.getOutboundIPCalls++
   121  	return "192.168.1.2", nil
   122  }
   123  
   124  func (m *mockRealResolver) GetPublicIP() (string, error) {
   125  	m.getPublicIPCalls++
   126  	return "1.1.1.1", nil
   127  }
   128  
   129  func (m *mockRealResolver) GetProxyIP(_ int) (string, error) {
   130  	return m.GetPublicIP()
   131  }