github.com/Tyktechnologies/tyk@v2.9.5+incompatible/dnscache/manager_test.go (about)

     1  package dnscache
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/TykTechnologies/tyk/config"
    11  )
    12  
    13  func TestWrapDialerDialContextFunc(t *testing.T) {
    14  	tearDownTestStorageFetchItem := setupTestStorageFetchItem(&configTestStorageFetchItem{t, etcHostsMap, etcHostsErrorMap})
    15  	defer tearDownTestStorageFetchItem()
    16  
    17  	expectedHost := "orig-host.com"
    18  	expectedSingleIpHost := "single.orig-host.com"
    19  	hostWithPort := expectedHost + ":8078"
    20  	singleIpHostWithPort := expectedSingleIpHost + ":8078"
    21  	dialerContext, cancel := context.WithCancel(context.TODO())
    22  	cancel() //Manually disable connection establishment
    23  
    24  	cases := []struct {
    25  		name string
    26  
    27  		address          string
    28  		multiIPsStrategy config.IPsHandleStrategy
    29  		initStorage      bool
    30  
    31  		shouldCallFetchItem bool
    32  		shouldCallDelete    bool
    33  		expectedHostname    string
    34  		expectedError       string
    35  	}{
    36  		{
    37  			"PickFirstStrategy(1 ip): Should parse address, call storage.FetchItem, cache ip, call storage.Delete on DialContext error",
    38  			singleIpHostWithPort, config.PickFirstStrategy, true,
    39  			true, true, expectedSingleIpHost, "operation was canceled",
    40  		},
    41  		{
    42  			"PickFirstStrategy(>1 ip): Should parse address, call storage.FetchItem, cache all ips, call storage.Delete on DialContext error",
    43  			hostWithPort, config.PickFirstStrategy, true,
    44  			true, true, expectedHost, "operation was canceled",
    45  		},
    46  		{
    47  			"NoCacheStrategy(1 ip): Should parse address, call storage.FetchItem, cache ip, call storage.Delete on DialContext error",
    48  			singleIpHostWithPort, config.NoCacheStrategy, true,
    49  			true, true, expectedSingleIpHost, "operation was canceled",
    50  		},
    51  		{
    52  			"NoCacheStrategy(>1 ip): Should parse address, call storage.FetchItem, remove ips caching",
    53  			hostWithPort, config.NoCacheStrategy, true,
    54  			true, true, expectedHost, "operation was canceled",
    55  		},
    56  		{
    57  			"RandomStrategy(>1 ip): Should parse address, call storage.FetchItem, cache all ips, connect to random ip, call storage.Delete on DialContext error",
    58  			hostWithPort, config.RandomStrategy, true,
    59  			true, true, expectedHost, "operation was canceled",
    60  		},
    61  		{
    62  			"Shouldn't call FetchItem when caching is disabled(storage == nil)",
    63  			hostWithPort, config.NoCacheStrategy, false,
    64  			false, false, "", "",
    65  		},
    66  		{
    67  			"Shouldn't cache ipv4 address",
    68  			"192.0.2.10:80", config.NoCacheStrategy, true,
    69  			false, false, "", "operation was canceled",
    70  		},
    71  		{
    72  			"Should faifast on address without port(accept only address with port)",
    73  			expectedHost, config.NoCacheStrategy, true,
    74  			false, false, "", "missing port in address",
    75  		},
    76  	}
    77  
    78  	for _, tc := range cases {
    79  		t.Run(tc.name, func(t *testing.T) {
    80  			var fetchItemCall, deleteCall struct {
    81  				called bool
    82  				key    string
    83  			}
    84  
    85  			storage := &MockStorage{func(key string) ([]string, error) {
    86  				fetchItemCall.called = true
    87  				fetchItemCall.key = key
    88  				return etcHostsMap[key+"."], nil
    89  			}, func(key string) (DnsCacheItem, bool) {
    90  				if _, ok := etcHostsMap[key]; ok {
    91  					return DnsCacheItem{}, true
    92  				}
    93  
    94  				return DnsCacheItem{}, false
    95  			}, func(key string, addrs []string) {},
    96  				func(key string) {
    97  					deleteCall.called = true
    98  					deleteCall.key = key
    99  				}, func() {}}
   100  
   101  			dnsManager := NewDnsCacheManager(tc.multiIPsStrategy)
   102  			if tc.initStorage {
   103  				dnsManager.SetCacheStorage(storage)
   104  			}
   105  
   106  			_, err := dnsManager.WrapDialer(&net.Dialer{
   107  				Timeout:   1 * time.Second,
   108  				KeepAlive: 0,
   109  			})(dialerContext, "tcp", tc.address)
   110  
   111  			if tc.expectedError != "" {
   112  				if err != nil && !strings.Contains(err.Error(), tc.expectedError) {
   113  					t.Fatalf("wanted error '%s', got '%s'", tc.expectedError, err.Error())
   114  				}
   115  			}
   116  
   117  			if tc.shouldCallFetchItem != fetchItemCall.called {
   118  				t.Fatalf("wanted fetchItemCall.called to be %v, got %v", tc.shouldCallFetchItem, fetchItemCall.called)
   119  			}
   120  
   121  			if tc.shouldCallFetchItem {
   122  				if fetchItemCall.key != tc.expectedHostname {
   123  					t.Fatalf("wanted fetchItemCall.key to be %v, got %v", tc.expectedHostname, fetchItemCall.key)
   124  				}
   125  			}
   126  
   127  			if tc.shouldCallDelete != deleteCall.called {
   128  				t.Fatalf("wanted deleteCall.called to be %v, got %v", tc.shouldCallDelete, deleteCall.called)
   129  			}
   130  			if tc.shouldCallDelete {
   131  				if deleteCall.key != tc.expectedHostname {
   132  					t.Fatalf("wanted deleteCall.key to be %v, got %v", tc.expectedHostname, deleteCall.key)
   133  				}
   134  			}
   135  
   136  			if tc.initStorage {
   137  				dnsManager.DisposeCache()
   138  			}
   139  		})
   140  	}
   141  }