github.com/DerekStrickland/consul@v1.4.5/agent/consul/util_test.go (about)

     1  package consul
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net"
     7  	"regexp"
     8  	"testing"
     9  
    10  	"github.com/hashicorp/go-version"
    11  	"github.com/hashicorp/serf/serf"
    12  )
    13  
    14  func TestGetPrivateIP(t *testing.T) {
    15  	t.Parallel()
    16  	ip, _, err := net.ParseCIDR("10.1.2.3/32")
    17  	if err != nil {
    18  		t.Fatalf("failed to parse private cidr: %v", err)
    19  	}
    20  
    21  	pubIP, _, err := net.ParseCIDR("8.8.8.8/32")
    22  	if err != nil {
    23  		t.Fatalf("failed to parse public cidr: %v", err)
    24  	}
    25  
    26  	tests := []struct {
    27  		addrs    []net.Addr
    28  		expected net.IP
    29  		err      error
    30  	}{
    31  		{
    32  			addrs: []net.Addr{
    33  				&net.IPAddr{
    34  					IP: ip,
    35  				},
    36  				&net.IPAddr{
    37  					IP: pubIP,
    38  				},
    39  			},
    40  			expected: ip,
    41  		},
    42  		{
    43  			addrs: []net.Addr{
    44  				&net.IPAddr{
    45  					IP: pubIP,
    46  				},
    47  			},
    48  			err: errors.New("No private IP address found"),
    49  		},
    50  		{
    51  			addrs: []net.Addr{
    52  				&net.IPAddr{
    53  					IP: ip,
    54  				},
    55  				&net.IPAddr{
    56  					IP: ip,
    57  				},
    58  				&net.IPAddr{
    59  					IP: pubIP,
    60  				},
    61  			},
    62  			err: errors.New("Multiple private IPs found. Please configure one."),
    63  		},
    64  	}
    65  
    66  	for _, test := range tests {
    67  		ip, err := getPrivateIP(test.addrs)
    68  		switch {
    69  		case test.err != nil && err != nil:
    70  			if err.Error() != test.err.Error() {
    71  				t.Fatalf("unexpected error: %v != %v", test.err, err)
    72  			}
    73  		case (test.err == nil && err != nil) || (test.err != nil && err == nil):
    74  			t.Fatalf("unexpected error: %v != %v", test.err, err)
    75  		default:
    76  			if !test.expected.Equal(ip) {
    77  				t.Fatalf("unexpected ip: %v != %v", ip, test.expected)
    78  			}
    79  		}
    80  	}
    81  }
    82  
    83  func TestIsPrivateIP(t *testing.T) {
    84  	t.Parallel()
    85  	if !isPrivateIP("192.168.1.1") {
    86  		t.Fatalf("bad")
    87  	}
    88  	if !isPrivateIP("172.16.45.100") {
    89  		t.Fatalf("bad")
    90  	}
    91  	if !isPrivateIP("10.1.2.3") {
    92  		t.Fatalf("bad")
    93  	}
    94  	if !isPrivateIP("100.115.110.19") {
    95  		t.Fatalf("bad")
    96  	}
    97  	if isPrivateIP("8.8.8.8") {
    98  		t.Fatalf("bad")
    99  	}
   100  	if !isPrivateIP("127.0.0.1") {
   101  		t.Fatalf("bad")
   102  	}
   103  }
   104  
   105  func TestUtil_CanServersUnderstandProtocol(t *testing.T) {
   106  	t.Parallel()
   107  	var members []serf.Member
   108  
   109  	// All empty list cases should return false.
   110  	for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
   111  		grok, err := CanServersUnderstandProtocol(members, v)
   112  		if err != nil {
   113  			t.Fatalf("err: %v", err)
   114  		}
   115  		if grok {
   116  			t.Fatalf("empty list should always return false")
   117  		}
   118  	}
   119  
   120  	// Add a non-server member.
   121  	members = append(members, serf.Member{
   122  		Tags: map[string]string{
   123  			"vsn_min": fmt.Sprintf("%d", ProtocolVersionMin),
   124  			"vsn_max": fmt.Sprintf("%d", ProtocolVersionMax),
   125  		},
   126  	})
   127  
   128  	// Make sure it doesn't get counted.
   129  	for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
   130  		grok, err := CanServersUnderstandProtocol(members, v)
   131  		if err != nil {
   132  			t.Fatalf("err: %v", err)
   133  		}
   134  		if grok {
   135  			t.Fatalf("non-server members should not be counted")
   136  		}
   137  	}
   138  
   139  	// Add a server member.
   140  	members = append(members, serf.Member{
   141  		Tags: map[string]string{
   142  			"role":    "consul",
   143  			"vsn_min": fmt.Sprintf("%d", ProtocolVersionMin),
   144  			"vsn_max": fmt.Sprintf("%d", ProtocolVersionMax),
   145  		},
   146  	})
   147  
   148  	// Now it should report that it understands.
   149  	for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
   150  		grok, err := CanServersUnderstandProtocol(members, v)
   151  		if err != nil {
   152  			t.Fatalf("err: %v", err)
   153  		}
   154  		if !grok {
   155  			t.Fatalf("server should grok")
   156  		}
   157  	}
   158  
   159  	// Nobody should understand anything from the future.
   160  	for v := uint8(ProtocolVersionMax + 1); v <= uint8(ProtocolVersionMax+10); v++ {
   161  		grok, err := CanServersUnderstandProtocol(members, v)
   162  		if err != nil {
   163  			t.Fatalf("err: %v", err)
   164  		}
   165  		if grok {
   166  			t.Fatalf("server should not grok")
   167  		}
   168  	}
   169  
   170  	// Add an older server.
   171  	members = append(members, serf.Member{
   172  		Tags: map[string]string{
   173  			"role":    "consul",
   174  			"vsn_min": fmt.Sprintf("%d", ProtocolVersionMin),
   175  			"vsn_max": fmt.Sprintf("%d", ProtocolVersionMax-1),
   176  		},
   177  	})
   178  
   179  	// The servers should no longer understand the max version.
   180  	for v := ProtocolVersionMin; v <= ProtocolVersionMax; v++ {
   181  		grok, err := CanServersUnderstandProtocol(members, v)
   182  		if err != nil {
   183  			t.Fatalf("err: %v", err)
   184  		}
   185  		expected := v < ProtocolVersionMax
   186  		if grok != expected {
   187  			t.Fatalf("bad: %v != %v", grok, expected)
   188  		}
   189  	}
   190  
   191  	// Try a version that's too low for the minimum.
   192  	{
   193  		grok, err := CanServersUnderstandProtocol(members, 0)
   194  		if err != nil {
   195  			t.Fatalf("err: %v", err)
   196  		}
   197  		if grok {
   198  			t.Fatalf("server should not grok")
   199  		}
   200  	}
   201  }
   202  
   203  func TestIsConsulNode(t *testing.T) {
   204  	t.Parallel()
   205  	m := serf.Member{
   206  		Tags: map[string]string{
   207  			"role": "node",
   208  			"dc":   "east-aws",
   209  		},
   210  	}
   211  	valid, dc := isConsulNode(m)
   212  	if !valid || dc != "east-aws" {
   213  		t.Fatalf("bad: %v %v", valid, dc)
   214  	}
   215  }
   216  
   217  func TestByteConversion(t *testing.T) {
   218  	t.Parallel()
   219  	var val uint64 = 2 << 50
   220  	raw := uint64ToBytes(val)
   221  	if bytesToUint64(raw) != val {
   222  		t.Fatalf("no match")
   223  	}
   224  }
   225  
   226  func TestGenerateUUID(t *testing.T) {
   227  	t.Parallel()
   228  	prev := generateUUID()
   229  	for i := 0; i < 100; i++ {
   230  		id := generateUUID()
   231  		if prev == id {
   232  			t.Fatalf("Should get a new ID!")
   233  		}
   234  
   235  		matched, err := regexp.MatchString(
   236  			"[\\da-f]{8}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{4}-[\\da-f]{12}", id)
   237  		if !matched || err != nil {
   238  			t.Fatalf("expected match %s %v %s", id, matched, err)
   239  		}
   240  	}
   241  }
   242  
   243  func TestGetPublicIPv6(t *testing.T) {
   244  	t.Parallel()
   245  	ip, _, err := net.ParseCIDR("fe80::1/128")
   246  	if err != nil {
   247  		t.Fatalf("failed to parse link-local cidr: %v", err)
   248  	}
   249  
   250  	ip2, _, err := net.ParseCIDR("::1/128")
   251  	if err != nil {
   252  		t.Fatalf("failed to parse loopback cidr: %v", err)
   253  	}
   254  
   255  	ip3, _, err := net.ParseCIDR("fc00::1/128")
   256  	if err != nil {
   257  		t.Fatalf("failed to parse ULA cidr: %v", err)
   258  	}
   259  
   260  	pubIP, _, err := net.ParseCIDR("2001:0db8:85a3::8a2e:0370:7334/128")
   261  	if err != nil {
   262  		t.Fatalf("failed to parse public cidr: %v", err)
   263  	}
   264  
   265  	tests := []struct {
   266  		addrs    []net.Addr
   267  		expected net.IP
   268  		err      error
   269  	}{
   270  		{
   271  			addrs: []net.Addr{
   272  				&net.IPAddr{
   273  					IP: ip,
   274  				},
   275  				&net.IPAddr{
   276  					IP: ip2,
   277  				},
   278  				&net.IPAddr{
   279  					IP: ip3,
   280  				},
   281  				&net.IPAddr{
   282  					IP: pubIP,
   283  				},
   284  			},
   285  			expected: pubIP,
   286  		},
   287  		{
   288  			addrs: []net.Addr{
   289  				&net.IPAddr{
   290  					IP: ip,
   291  				},
   292  				&net.IPAddr{
   293  					IP: ip2,
   294  				},
   295  				&net.IPAddr{
   296  					IP: ip3,
   297  				},
   298  			},
   299  			err: errors.New("No public IPv6 address found"),
   300  		},
   301  		{
   302  			addrs: []net.Addr{
   303  				&net.IPAddr{
   304  					IP: ip,
   305  				},
   306  				&net.IPAddr{
   307  					IP: ip,
   308  				},
   309  				&net.IPAddr{
   310  					IP: pubIP,
   311  				},
   312  				&net.IPAddr{
   313  					IP: pubIP,
   314  				},
   315  			},
   316  			err: errors.New("Multiple public IPv6 addresses found. Please configure one."),
   317  		},
   318  	}
   319  
   320  	for _, test := range tests {
   321  		ip, err := getPublicIPv6(test.addrs)
   322  		switch {
   323  		case test.err != nil && err != nil:
   324  			if err.Error() != test.err.Error() {
   325  				t.Fatalf("unexpected error: %v != %v", test.err, err)
   326  			}
   327  		case (test.err == nil && err != nil) || (test.err != nil && err == nil):
   328  			t.Fatalf("unexpected error: %v != %v", test.err, err)
   329  		default:
   330  			if !test.expected.Equal(ip) {
   331  				t.Fatalf("unexpected ip: %v != %v", ip, test.expected)
   332  			}
   333  		}
   334  	}
   335  }
   336  
   337  func TestServersMeetMinimumVersion(t *testing.T) {
   338  	t.Parallel()
   339  	makeMember := func(version string) serf.Member {
   340  		return serf.Member{
   341  			Name: "foo",
   342  			Addr: net.IP([]byte{127, 0, 0, 1}),
   343  			Tags: map[string]string{
   344  				"role":          "consul",
   345  				"id":            "asdf",
   346  				"dc":            "east-aws",
   347  				"port":          "10000",
   348  				"build":         version,
   349  				"wan_join_port": "1234",
   350  				"vsn":           "1",
   351  				"expect":        "3",
   352  				"raft_vsn":      "3",
   353  			},
   354  			Status: serf.StatusAlive,
   355  		}
   356  	}
   357  
   358  	cases := []struct {
   359  		members  []serf.Member
   360  		ver      *version.Version
   361  		expected bool
   362  	}{
   363  		// One server, meets reqs
   364  		{
   365  			members: []serf.Member{
   366  				makeMember("0.7.5"),
   367  			},
   368  			ver:      version.Must(version.NewVersion("0.7.5")),
   369  			expected: true,
   370  		},
   371  		// One server, doesn't meet reqs
   372  		{
   373  			members: []serf.Member{
   374  				makeMember("0.7.5"),
   375  			},
   376  			ver:      version.Must(version.NewVersion("0.8.0")),
   377  			expected: false,
   378  		},
   379  		// Multiple servers, meets req version
   380  		{
   381  			members: []serf.Member{
   382  				makeMember("0.7.5"),
   383  				makeMember("0.8.0"),
   384  			},
   385  			ver:      version.Must(version.NewVersion("0.7.5")),
   386  			expected: true,
   387  		},
   388  		// Multiple servers, doesn't meet req version
   389  		{
   390  			members: []serf.Member{
   391  				makeMember("0.7.5"),
   392  				makeMember("0.8.0"),
   393  			},
   394  			ver:      version.Must(version.NewVersion("0.8.0")),
   395  			expected: false,
   396  		},
   397  	}
   398  
   399  	for _, tc := range cases {
   400  		result := ServersMeetMinimumVersion(tc.members, tc.ver)
   401  		if result != tc.expected {
   402  			t.Fatalf("bad: %v, %v, %v", result, tc.ver.String(), tc)
   403  		}
   404  	}
   405  }