github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/gossip/resolver/resolver_test.go (about)

     1  // Copyright 2015 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  package resolver
    12  
    13  import (
    14  	"context"
    15  	"net"
    16  	"testing"
    17  
    18  	"github.com/cockroachdb/cockroach/pkg/base"
    19  	"github.com/cockroachdb/errors"
    20  	"github.com/stretchr/testify/require"
    21  )
    22  
    23  func TestParseResolverAddress(t *testing.T) {
    24  	def := ensureHostPort(":", base.DefaultPort)
    25  	testCases := []struct {
    26  		input           string
    27  		success         bool
    28  		resolverType    string
    29  		resolverAddress string
    30  	}{
    31  		// Ports are not checked at parsing time. They are at GetAddress time though.
    32  		{"127.0.0.1:26222", true, "tcp", "127.0.0.1:26222"},
    33  		{":" + base.DefaultPort, true, "tcp", def},
    34  		{"127.0.0.1", true, "tcp", "127.0.0.1:" + base.DefaultPort},
    35  		{"", false, "", ""},
    36  		{"", false, "tcp", ""},
    37  		{":", true, "tcp", def},
    38  	}
    39  
    40  	for tcNum, tc := range testCases {
    41  		resolver, err := NewResolver(tc.input)
    42  		if (err == nil) != tc.success {
    43  			t.Errorf("#%d: expected success=%t, got err=%v", tcNum, tc.success, err)
    44  		}
    45  		if err != nil {
    46  			continue
    47  		}
    48  		if resolver.Type() != tc.resolverType {
    49  			t.Errorf("#%d: expected resolverType=%s, got %+v", tcNum, tc.resolverType, resolver)
    50  		}
    51  		if resolver.Addr() != tc.resolverAddress {
    52  			t.Errorf("#%d: expected resolverAddress=%s, got %+v", tcNum, tc.resolverAddress, resolver)
    53  		}
    54  	}
    55  }
    56  
    57  func TestGetAddress(t *testing.T) {
    58  	testCases := []struct {
    59  		address      string
    60  		success      bool
    61  		addressType  string
    62  		addressValue string
    63  	}{
    64  		{"127.0.0.1:26222", true, "tcp", "127.0.0.1:26222"},
    65  		{"127.0.0.1", true, "tcp", "127.0.0.1:" + base.DefaultPort},
    66  		{"localhost:80", true, "tcp", "localhost:80"},
    67  	}
    68  
    69  	for tcNum, tc := range testCases {
    70  		resolver, err := NewResolver(tc.address)
    71  		if err != nil {
    72  			t.Fatal(err)
    73  		}
    74  		address, err := resolver.GetAddress()
    75  		if (err == nil) != tc.success {
    76  			t.Errorf("#%d: expected success=%t, got err=%v", tcNum, tc.success, err)
    77  		}
    78  		if err != nil {
    79  			continue
    80  		}
    81  		if address.Network() != tc.addressType {
    82  			t.Errorf("#%d: expected address type=%s, got %+v", tcNum, tc.addressType, address)
    83  		}
    84  		if address.String() != tc.addressValue {
    85  			t.Errorf("#%d: expected address value=%s, got %+v", tcNum, tc.addressValue, address)
    86  		}
    87  	}
    88  }
    89  
    90  func TestSRV(t *testing.T) {
    91  	type lookupFunc func(service, proto, name string) (string, []*net.SRV, error)
    92  
    93  	lookupWithErr := func(err error) lookupFunc {
    94  		return func(service, proto, name string) (string, []*net.SRV, error) {
    95  			if service != "" || proto != "" {
    96  				t.Errorf("unexpected params in erroring LookupSRV() call")
    97  			}
    98  			return "", nil, err
    99  		}
   100  	}
   101  
   102  	dnsErr := &net.DNSError{Err: "no such host", Name: "", Server: "", IsTimeout: false}
   103  
   104  	lookupSuccess := func(service, proto, name string) (string, []*net.SRV, error) {
   105  		if service != "" || proto != "" {
   106  			t.Errorf("unexpected params in successful LookupSRV() call")
   107  		}
   108  
   109  		srvs := []*net.SRV{
   110  			{Target: "node1", Port: 26222},
   111  			{Target: "node2", Port: 35222},
   112  			{Target: "node3", Port: 0},
   113  		}
   114  
   115  		return "cluster", srvs, nil
   116  	}
   117  
   118  	expectedAddrs := []string{"node1:26222", "node2:35222"}
   119  
   120  	testCases := []struct {
   121  		address  string
   122  		lookuper lookupFunc
   123  		want     []string
   124  	}{
   125  		{":26222", nil, nil},
   126  		{"some.host", lookupWithErr(dnsErr), nil},
   127  		{"some.host", lookupWithErr(errors.New("another error")), nil},
   128  		{"some.host", lookupSuccess, expectedAddrs},
   129  		{"some.host:26222", lookupSuccess, expectedAddrs},
   130  		// "real" `lookupSRV` returns "no such host" when resolving IP addresses
   131  		{"127.0.0.1", lookupWithErr(dnsErr), nil},
   132  		{"127.0.0.1:26222", lookupWithErr(dnsErr), nil},
   133  		{"[2001:0db8:85a3:0000:0000:8a2e:0370:7334]", lookupWithErr(dnsErr), nil},
   134  		{"[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:26222", lookupWithErr(dnsErr), nil},
   135  	}
   136  
   137  	for tcNum, tc := range testCases {
   138  		func() {
   139  			defer TestingOverrideSRVLookupFn(tc.lookuper)()
   140  
   141  			resolvers, err := SRV(context.Background(), tc.address)
   142  
   143  			if err != nil {
   144  				t.Errorf("#%d: expected success, got err=%v", tcNum, err)
   145  			}
   146  
   147  			require.Equal(t, tc.want, resolvers, "Test #%d failed", tcNum)
   148  
   149  		}()
   150  	}
   151  }