github.com/unionj-cloud/go-doudou/v2@v2.3.5/toolkit/memberlist/memberlist_test.go (about)

     1  package memberlist_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"github.com/golang/mock/gomock"
     7  	"github.com/unionj-cloud/go-doudou/v2/toolkit/memberlist"
     8  	memmock "github.com/unionj-cloud/go-doudou/v2/toolkit/memberlist/mock"
     9  	"io/ioutil"
    10  	"log"
    11  	"net"
    12  	"os"
    13  	"reflect"
    14  	"runtime"
    15  	"strconv"
    16  	"strings"
    17  	"sync"
    18  	"testing"
    19  	"time"
    20  
    21  	"github.com/miekg/dns"
    22  	"github.com/stretchr/testify/require"
    23  )
    24  
    25  func retry(t *testing.T, n int, w time.Duration, fn func(func(string, ...interface{}))) {
    26  	t.Helper()
    27  	for try := 1; try <= n; try++ {
    28  		failed := false
    29  		failFormat := ""
    30  		failArgs := []interface{}{}
    31  		failf := func(format string, args ...interface{}) {
    32  			failed = true
    33  			failFormat = format
    34  			failArgs = args
    35  		}
    36  
    37  		fn(failf)
    38  
    39  		if !failed {
    40  			return
    41  		}
    42  		if try == n {
    43  			t.Fatalf(failFormat, failArgs...)
    44  		}
    45  		time.Sleep(w)
    46  	}
    47  }
    48  
    49  var bindLock sync.Mutex
    50  var bindNum byte = 10
    51  
    52  func getBindAddrNet(network byte) net.IP {
    53  	bindLock.Lock()
    54  	defer bindLock.Unlock()
    55  
    56  	//result := net.IPv4(127, 0, network, bindNum)
    57  	//bindNum++
    58  	//if bindNum > 255 {
    59  	//	bindNum = 10
    60  	//}
    61  
    62  	result := net.IPv4(127, 0, 0, 1)
    63  
    64  	return result
    65  }
    66  
    67  func getBindAddr() net.IP {
    68  	return getBindAddrNet(0)
    69  }
    70  
    71  func testConfigNet(tb testing.TB, network byte) *memberlist.Config {
    72  	tb.Helper()
    73  
    74  	config := memberlist.DefaultLANConfig()
    75  	config.BindAddr = getBindAddrNet(network).String()
    76  	config.Name = config.BindAddr
    77  	config.BindPort = 0 // choose free port
    78  	config.RequireNodeNames = true
    79  	config.Logger = log.New(os.Stderr, config.Name, log.LstdFlags)
    80  	return config
    81  }
    82  
    83  func testConfig(tb testing.TB) *memberlist.Config {
    84  	return testConfigNet(tb, 0)
    85  }
    86  
    87  func yield() {
    88  	time.Sleep(250 * time.Millisecond)
    89  }
    90  
    91  type MockDelegate struct {
    92  	mu          sync.Mutex
    93  	meta        []byte
    94  	msgs        [][]byte
    95  	broadcasts  [][]byte
    96  	state       []byte
    97  	remoteState []byte
    98  }
    99  
   100  func (m *MockDelegate) setMeta(meta []byte) {
   101  	m.mu.Lock()
   102  	defer m.mu.Unlock()
   103  	m.meta = meta
   104  }
   105  
   106  func (m *MockDelegate) setState(state []byte) {
   107  	m.mu.Lock()
   108  	defer m.mu.Unlock()
   109  	m.state = state
   110  }
   111  
   112  func (m *MockDelegate) setBroadcasts(broadcasts [][]byte) {
   113  	m.mu.Lock()
   114  	defer m.mu.Unlock()
   115  	m.broadcasts = broadcasts
   116  }
   117  
   118  func (m *MockDelegate) getRemoteState() []byte {
   119  	m.mu.Lock()
   120  	defer m.mu.Unlock()
   121  
   122  	out := make([]byte, len(m.remoteState))
   123  	copy(out, m.remoteState)
   124  	return out
   125  }
   126  
   127  func (m *MockDelegate) getMessages() [][]byte {
   128  	m.mu.Lock()
   129  	defer m.mu.Unlock()
   130  
   131  	out := make([][]byte, len(m.msgs))
   132  	for i, msg := range m.msgs {
   133  		out[i] = make([]byte, len(msg))
   134  		copy(out[i], msg)
   135  	}
   136  	return out
   137  }
   138  
   139  func (m *MockDelegate) NodeMeta(limit int) []byte {
   140  	m.mu.Lock()
   141  	defer m.mu.Unlock()
   142  
   143  	return m.meta
   144  }
   145  
   146  func (m *MockDelegate) NotifyMsg(msg []byte) {
   147  	m.mu.Lock()
   148  	defer m.mu.Unlock()
   149  
   150  	cp := make([]byte, len(msg))
   151  	copy(cp, msg)
   152  	m.msgs = append(m.msgs, cp)
   153  }
   154  
   155  func (m *MockDelegate) GetBroadcasts(overhead, limit int) [][]byte {
   156  	m.mu.Lock()
   157  	defer m.mu.Unlock()
   158  
   159  	b := m.broadcasts
   160  	m.broadcasts = nil
   161  	return b
   162  }
   163  
   164  func (m *MockDelegate) LocalState(join bool) []byte {
   165  	m.mu.Lock()
   166  	defer m.mu.Unlock()
   167  
   168  	return m.state
   169  }
   170  
   171  func (m *MockDelegate) MergeRemoteState(s []byte, join bool) {
   172  	m.mu.Lock()
   173  	defer m.mu.Unlock()
   174  
   175  	m.remoteState = s
   176  }
   177  
   178  func TestDefaultLANConfig_protocolVersion(t *testing.T) {
   179  	c := memberlist.DefaultLANConfig()
   180  	if c.ProtocolVersion != memberlist.ProtocolVersion2Compatible {
   181  		t.Fatalf("should be max: %d", c.ProtocolVersion)
   182  	}
   183  }
   184  
   185  func TestCreate_protocolVersion(t *testing.T) {
   186  	cases := []struct {
   187  		name    string
   188  		version uint8
   189  		err     bool
   190  	}{
   191  		{"min", memberlist.ProtocolVersionMin, false},
   192  		{"max", memberlist.ProtocolVersionMax, false},
   193  		{"max+1", memberlist.ProtocolVersionMax + 1, true},
   194  		{"min-1", memberlist.ProtocolVersionMax - 1, false},
   195  	}
   196  
   197  	for _, tc := range cases {
   198  		t.Run(tc.name, func(t *testing.T) {
   199  			c := memberlist.DefaultLANConfig()
   200  			c.BindAddr = getBindAddr().String()
   201  			c.ProtocolVersion = tc.version
   202  
   203  			m, err := memberlist.Create(c)
   204  			if err == nil {
   205  				require.NoError(t, m.Shutdown())
   206  			}
   207  
   208  			if tc.err && err == nil {
   209  				t.Fatalf("Should've failed with version: %d", tc.version)
   210  			} else if !tc.err && err != nil {
   211  				t.Fatalf("Version '%d' error: %s", tc.version, err)
   212  			}
   213  		})
   214  	}
   215  }
   216  
   217  func TestCreate_secretKey(t *testing.T) {
   218  	cases := []struct {
   219  		name string
   220  		key  []byte
   221  		err  bool
   222  	}{
   223  		{"size-0", make([]byte, 0), false},
   224  		{"abc", []byte("abc"), true},
   225  		{"size-16", make([]byte, 16), false},
   226  		{"size-38", make([]byte, 38), true},
   227  	}
   228  
   229  	for _, tc := range cases {
   230  		t.Run(tc.name, func(t *testing.T) {
   231  			c := memberlist.DefaultLANConfig()
   232  			c.BindAddr = getBindAddr().String()
   233  			c.SecretKey = tc.key
   234  
   235  			m, err := memberlist.Create(c)
   236  			if err == nil {
   237  				require.NoError(t, m.Shutdown())
   238  			}
   239  
   240  			if tc.err && err == nil {
   241  				t.Fatalf("Should've failed with key: %#v", tc.key)
   242  			} else if !tc.err && err != nil {
   243  				t.Fatalf("Key '%#v' error: %s", tc.key, err)
   244  			}
   245  		})
   246  	}
   247  }
   248  
   249  func TestCreate_secretKeyEmpty(t *testing.T) {
   250  	c := memberlist.DefaultLANConfig()
   251  	c.BindAddr = getBindAddr().String()
   252  	c.SecretKey = make([]byte, 0)
   253  
   254  	m, err := memberlist.Create(c)
   255  	require.NoError(t, err)
   256  	defer m.Shutdown()
   257  
   258  	if m.Config().EncryptionEnabled() {
   259  		t.Fatalf("Expected encryption to be disabled")
   260  	}
   261  }
   262  
   263  func TestCreate_keyringOnly(t *testing.T) {
   264  	c := memberlist.DefaultLANConfig()
   265  	c.BindAddr = getBindAddr().String()
   266  
   267  	keyring, err := memberlist.NewKeyring(nil, make([]byte, 16))
   268  	require.NoError(t, err)
   269  	c.Keyring = keyring
   270  
   271  	m, err := memberlist.Create(c)
   272  	require.NoError(t, err)
   273  	defer m.Shutdown()
   274  }
   275  
   276  func TestCreate_keyringAndSecretKey(t *testing.T) {
   277  	c := memberlist.DefaultLANConfig()
   278  	c.BindAddr = getBindAddr().String()
   279  
   280  	keyring, err := memberlist.NewKeyring(nil, make([]byte, 16))
   281  	require.NoError(t, err)
   282  	c.Keyring = keyring
   283  	c.SecretKey = []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
   284  
   285  	m, err := memberlist.Create(c)
   286  	require.NoError(t, err)
   287  	defer m.Shutdown()
   288  
   289  	ringKeys := c.Keyring.GetKeys()
   290  	if !bytes.Equal(c.SecretKey, ringKeys[0]) {
   291  		t.Fatalf("Unexpected primary key %v", ringKeys[0])
   292  	}
   293  }
   294  
   295  func TestCreate_invalidLoggerSettings(t *testing.T) {
   296  	c := memberlist.DefaultLANConfig()
   297  	c.BindAddr = getBindAddr().String()
   298  	c.Logger = log.New(ioutil.Discard, "", log.LstdFlags)
   299  	c.LogOutput = ioutil.Discard
   300  
   301  	m, err := memberlist.Create(c)
   302  	if err == nil {
   303  		require.NoError(t, m.Shutdown())
   304  		t.Fatal("Memberlist should not allow both LogOutput and Logger to be set, but it did not raise an error")
   305  	}
   306  }
   307  
   308  func TestCreate(t *testing.T) {
   309  	c := testConfig(t)
   310  	c.ProtocolVersion = memberlist.ProtocolVersionMin
   311  	c.DelegateProtocolVersion = 13
   312  	c.DelegateProtocolMin = 12
   313  	c.DelegateProtocolMax = 24
   314  
   315  	m, err := memberlist.Create(c)
   316  	require.NoError(t, err)
   317  	defer m.Shutdown()
   318  
   319  	yield()
   320  
   321  	members := m.Members()
   322  	if len(members) != 1 {
   323  		t.Fatalf("bad number of members")
   324  	}
   325  
   326  	if members[0].PMin != memberlist.ProtocolVersionMin {
   327  		t.Fatalf("bad: %#v", members[0])
   328  	}
   329  
   330  	if members[0].PMax != memberlist.ProtocolVersionMax {
   331  		t.Fatalf("bad: %#v", members[0])
   332  	}
   333  
   334  	if members[0].PCur != c.ProtocolVersion {
   335  		t.Fatalf("bad: %#v", members[0])
   336  	}
   337  
   338  	if members[0].DMin != c.DelegateProtocolMin {
   339  		t.Fatalf("bad: %#v", members[0])
   340  	}
   341  
   342  	if members[0].DMax != c.DelegateProtocolMax {
   343  		t.Fatalf("bad: %#v", members[0])
   344  	}
   345  
   346  	if members[0].DCur != c.DelegateProtocolVersion {
   347  		t.Fatalf("bad: %#v", members[0])
   348  	}
   349  }
   350  
   351  func GetMemberlist(tb testing.TB, f func(c *memberlist.Config)) *memberlist.Memberlist {
   352  	c := testConfig(tb)
   353  	c.BindPort = 0
   354  	if f != nil {
   355  		f(c)
   356  	}
   357  
   358  	m, err := memberlist.NewMemberlist(c)
   359  	require.NoError(tb, err)
   360  	return m
   361  }
   362  
   363  func TestMemberList_ResolveAddr(t *testing.T) {
   364  	m := GetMemberlist(t, nil)
   365  	defer m.Shutdown()
   366  
   367  	defaultPort := uint16(m.Config().BindPort)
   368  
   369  	type testCase struct {
   370  		name           string
   371  		in             string
   372  		expectErr      bool
   373  		ignoreExpectIP bool
   374  		expect         []memberlist.IpPort
   375  	}
   376  
   377  	baseCases := []testCase{
   378  		{
   379  			name:           "localhost",
   380  			in:             "localhost",
   381  			ignoreExpectIP: true,
   382  			expect: []memberlist.IpPort{
   383  				memberlist.NewIpPort("", defaultPort, ""),
   384  			},
   385  		},
   386  		{
   387  			name: "ipv6 pair",
   388  			in:   "[::1]:80",
   389  			expect: []memberlist.IpPort{
   390  				memberlist.NewIpPort(net.IPv6loopback.String(), 80, ""),
   391  			},
   392  		},
   393  		{
   394  			name: "ipv6 non-pair",
   395  			in:   "[::1]",
   396  			expect: []memberlist.IpPort{
   397  				memberlist.NewIpPort(net.IPv6loopback.String(), defaultPort, ""),
   398  			},
   399  		},
   400  		{
   401  			name:      "hostless port",
   402  			in:        ":80",
   403  			expectErr: true,
   404  		},
   405  		{
   406  			name:           "hostname port combo",
   407  			in:             "localhost:80",
   408  			ignoreExpectIP: true,
   409  			expect: []memberlist.IpPort{
   410  				memberlist.NewIpPort("", 80, ""),
   411  			},
   412  		},
   413  		{
   414  			name:      "too high port",
   415  			in:        "localhost:80000",
   416  			expectErr: true,
   417  		},
   418  		{
   419  			name: "ipv4 port combo",
   420  			in:   "127.0.0.1:80",
   421  			expect: []memberlist.IpPort{
   422  				memberlist.NewIpPort(net.IPv4(127, 0, 0, 1).String(), 80, ""),
   423  			},
   424  		},
   425  		{
   426  			name: "ipv6 port combo",
   427  			in:   "[2001:db8:a0b:12f0::1]:80",
   428  			expect: []memberlist.IpPort{
   429  				memberlist.NewIpPort(net.IP{0x20, 0x01, 0x0d, 0xb8, 0x0a, 0x0b, 0x12, 0xf0, 0, 0, 0, 0, 0, 0, 0, 0x1}.String(), 80, ""),
   430  			},
   431  		},
   432  		{
   433  			name:      "ipv4 port combo with empty tag",
   434  			in:        "/127.0.0.1:80",
   435  			expectErr: true,
   436  		},
   437  		{
   438  			name: "ipv4 only",
   439  			in:   "127.0.0.1",
   440  			expect: []memberlist.IpPort{
   441  				memberlist.NewIpPort(net.IPv4(127, 0, 0, 1).String(), defaultPort, ""),
   442  			},
   443  		},
   444  		{
   445  			name: "ipv6 only",
   446  			in:   "[2001:db8:a0b:12f0::1]",
   447  			expect: []memberlist.IpPort{
   448  				memberlist.NewIpPort(net.IP{0x20, 0x01, 0x0d, 0xb8, 0x0a, 0x0b, 0x12, 0xf0, 0, 0, 0, 0, 0, 0, 0, 0x1}.String(), defaultPort, ""),
   449  			},
   450  		},
   451  	}
   452  
   453  	// explode the cases to include tagged versions of everything
   454  	var cases []testCase
   455  	for _, tc := range baseCases {
   456  		cases = append(cases, tc)
   457  		if !strings.Contains(tc.in, "/") { // don't double tag already tagged cases
   458  			tc2 := testCase{
   459  				name:           tc.name + " (tagged)",
   460  				in:             "foo.bar/" + tc.in,
   461  				expectErr:      tc.expectErr,
   462  				ignoreExpectIP: tc.ignoreExpectIP,
   463  			}
   464  			for _, ipp := range tc.expect {
   465  				tc2.expect = append(tc2.expect, memberlist.NewIpPort(ipp.Ip(), ipp.Port(), "foo.bar"))
   466  			}
   467  			cases = append(cases, tc2)
   468  		}
   469  	}
   470  
   471  	for _, tc := range cases {
   472  		tc := tc
   473  		t.Run(tc.name, func(t *testing.T) {
   474  			t.Parallel()
   475  			got, err := m.ResolveAddr(tc.in)
   476  			if tc.expectErr {
   477  				require.Error(t, err)
   478  			} else {
   479  				require.NoError(t, err)
   480  				if tc.ignoreExpectIP {
   481  					if len(got) > 1 {
   482  						got = got[0:1]
   483  					}
   484  					for i := 0; i < len(got); i++ {
   485  						got[i].SetIp("")
   486  					}
   487  				}
   488  				require.Equal(t, tc.expect, got)
   489  			}
   490  		})
   491  	}
   492  }
   493  
   494  type dnsHandler struct {
   495  	t *testing.T
   496  }
   497  
   498  func (h dnsHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
   499  	if len(r.Question) != 1 {
   500  		h.t.Fatalf("bad: %#v", r.Question)
   501  	}
   502  
   503  	name := "join.service.consul."
   504  	question := r.Question[0]
   505  	if question.Name != name || question.Qtype != dns.TypeANY {
   506  		h.t.Fatalf("bad: %#v", question)
   507  	}
   508  
   509  	m := new(dns.Msg)
   510  	m.SetReply(r)
   511  	m.Authoritative = true
   512  	m.RecursionAvailable = false
   513  	m.Answer = append(m.Answer, &dns.A{
   514  		Hdr: dns.RR_Header{
   515  			Name:   name,
   516  			Rrtype: dns.TypeA,
   517  			Class:  dns.ClassINET},
   518  		A: net.ParseIP("127.0.0.1"),
   519  	})
   520  	m.Answer = append(m.Answer, &dns.AAAA{
   521  		Hdr: dns.RR_Header{
   522  			Name:   name,
   523  			Rrtype: dns.TypeAAAA,
   524  			Class:  dns.ClassINET},
   525  		AAAA: net.ParseIP("2001:db8:a0b:12f0::1"),
   526  	})
   527  	if err := w.WriteMsg(m); err != nil {
   528  		h.t.Fatalf("err: %v", err)
   529  	}
   530  }
   531  
   532  func TestMemberList_Members(t *testing.T) {
   533  	n1 := &memberlist.Node{Name: "test"}
   534  	n2 := &memberlist.Node{Name: "test2"}
   535  	n3 := &memberlist.Node{Name: "test3"}
   536  
   537  	m := &memberlist.Memberlist{}
   538  	m.SetNodes(
   539  		memberlist.NewNodeState(*n1, memberlist.StateAlive),
   540  		memberlist.NewNodeState(*n2, memberlist.StateDead),
   541  		memberlist.NewNodeState(*n3, memberlist.StateSuspect),
   542  	)
   543  
   544  	members := m.Members()
   545  	if !reflect.DeepEqual(members, []*memberlist.Node{n1, n3}) {
   546  		t.Fatalf("bad members")
   547  	}
   548  }
   549  
   550  func TestMemberlist_Join(t *testing.T) {
   551  	c1 := testConfig(t)
   552  	c1.BindPort = 55111
   553  	c1.AdvertisePort = 55111
   554  	c1.Name = "m1"
   555  	m1, err := memberlist.Create(c1)
   556  	require.NoError(t, err)
   557  	defer m1.Shutdown()
   558  
   559  	// Create a second node
   560  	c2 := testConfig(t)
   561  	c2.BindPort = 55112
   562  	c2.AdvertisePort = 55112
   563  	c2.Name = "m2"
   564  
   565  	m2, err := memberlist.Create(c2)
   566  	require.NoError(t, err)
   567  	defer m2.Shutdown()
   568  
   569  	joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
   570  	num, err := m2.Join([]string{joinUrl})
   571  	if num != 1 {
   572  		t.Fatalf("unexpected 1: %d", num)
   573  	}
   574  	if err != nil {
   575  		t.Fatalf("unexpected err: %s", err)
   576  	}
   577  
   578  	// Check the hosts
   579  	if len(m2.Members()) != 2 {
   580  		t.Fatalf("should have 2 nodes! %v", m2.Members())
   581  	}
   582  }
   583  
   584  func TestMemberlist_JoinDifferentNetworksUniqueMask(t *testing.T) {
   585  	c1 := testConfigNet(t, 0)
   586  	c1.BindPort = 55113
   587  	c1.AdvertisePort = 55113
   588  	c1.Name = "m1"
   589  	c1.CIDRsAllowed, _ = memberlist.ParseCIDRs([]string{"127.0.0.0/8"})
   590  	m1, err := memberlist.Create(c1)
   591  	require.NoError(t, err)
   592  	defer m1.Shutdown()
   593  
   594  	// Create a second node
   595  	c2 := testConfigNet(t, 1)
   596  	c2.CIDRsAllowed, _ = memberlist.ParseCIDRs([]string{"127.0.0.0/8"})
   597  	c2.BindPort = 55114
   598  	c2.AdvertisePort = 55114
   599  	c2.Name = "m2"
   600  
   601  	m2, err := memberlist.Create(c2)
   602  	require.NoError(t, err)
   603  	defer m2.Shutdown()
   604  
   605  	joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
   606  	num, err := m2.Join([]string{joinUrl})
   607  	if num != 1 {
   608  		t.Fatalf("unexpected 1: %d", num)
   609  	}
   610  	if err != nil {
   611  		t.Fatalf("unexpected err: %s", err)
   612  	}
   613  
   614  	// Check the hosts
   615  	if len(m2.Members()) != 2 {
   616  		t.Fatalf("should have 2 nodes! %v", m2.Members())
   617  	}
   618  }
   619  
   620  func TestMemberlist_JoinDifferentNetworksMultiMasks(t *testing.T) {
   621  	c1 := testConfigNet(t, 0)
   622  	c1.BindPort = 55115
   623  	c1.AdvertisePort = 55115
   624  	c1.Name = "m1"
   625  	c1.CIDRsAllowed, _ = memberlist.ParseCIDRs([]string{"127.0.0.0/24", "127.0.1.0/24"})
   626  	m1, err := memberlist.Create(c1)
   627  	require.NoError(t, err)
   628  	defer m1.Shutdown()
   629  
   630  	// Create a second node
   631  	c2 := testConfigNet(t, 1)
   632  	c2.CIDRsAllowed, _ = memberlist.ParseCIDRs([]string{"127.0.0.0/24", "127.0.1.0/24"})
   633  	c2.BindPort = 55116
   634  	c2.AdvertisePort = 55116
   635  	c2.Name = "m2"
   636  
   637  	m2, err := memberlist.Create(c2)
   638  	require.NoError(t, err)
   639  	defer m2.Shutdown()
   640  
   641  	joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
   642  	err = joinAndTestMemberShip(t, m2, []string{joinUrl}, 2)
   643  	if err != nil {
   644  		t.Fatalf("unexpected err: %s", err)
   645  	}
   646  }
   647  
   648  type CustomMergeDelegate struct {
   649  	invoked bool
   650  	t       *testing.T
   651  }
   652  
   653  func (c *CustomMergeDelegate) NotifyMerge(nodes []*memberlist.Node) error {
   654  	c.t.Logf("Cancel merge")
   655  	c.invoked = true
   656  	return fmt.Errorf("Custom merge canceled")
   657  }
   658  
   659  func TestMemberlist_Join_Cancel(t *testing.T) {
   660  	c1 := testConfig(t)
   661  	c1.BindPort = 55117
   662  	c1.AdvertisePort = 55117
   663  	c1.Name = "m1"
   664  	merge1 := &CustomMergeDelegate{t: t}
   665  	c1.Merge = merge1
   666  
   667  	m1, err := memberlist.Create(c1)
   668  	require.NoError(t, err)
   669  	defer m1.Shutdown()
   670  
   671  	// Create a second node
   672  	c2 := testConfig(t)
   673  	c2.BindPort = 55118
   674  	c2.AdvertisePort = 55118
   675  	c2.Name = "m2"
   676  	merge2 := &CustomMergeDelegate{t: t}
   677  	c2.Merge = merge2
   678  
   679  	m2, err := memberlist.Create(c2)
   680  	require.NoError(t, err)
   681  	defer m2.Shutdown()
   682  
   683  	joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
   684  	num, err := m2.Join([]string{joinUrl})
   685  	if num != 0 {
   686  		t.Fatalf("unexpected 0: %d", num)
   687  	}
   688  	if !strings.Contains(err.Error(), "Custom merge canceled") {
   689  		t.Fatalf("unexpected err: %s", err)
   690  	}
   691  
   692  	// Check the hosts
   693  	if len(m2.Members()) != 1 {
   694  		t.Fatalf("should have 1 nodes! %v", m2.Members())
   695  	}
   696  	if len(m1.Members()) != 1 {
   697  		t.Fatalf("should have 1 nodes! %v", m1.Members())
   698  	}
   699  
   700  	// Check delegate invocation
   701  	if !merge1.invoked {
   702  		t.Fatalf("should invoke delegate")
   703  	}
   704  	if !merge2.invoked {
   705  		t.Fatalf("should invoke delegate")
   706  	}
   707  }
   708  
   709  type CustomAliveDelegate struct {
   710  	Ignore string
   711  	count  int
   712  
   713  	t *testing.T
   714  }
   715  
   716  func (c *CustomAliveDelegate) NotifyAlive(peer *memberlist.Node) error {
   717  	c.count++
   718  	if peer.Name == c.Ignore {
   719  		return nil
   720  	}
   721  	c.t.Logf("Cancel alive")
   722  	return fmt.Errorf("Custom alive canceled")
   723  }
   724  
   725  func TestMemberlist_Join_Cancel_Passive(t *testing.T) {
   726  	c1 := testConfig(t)
   727  	c1.BindPort = 55119
   728  	c1.AdvertisePort = 55119
   729  	c1.Name = "m1"
   730  	alive1 := &CustomAliveDelegate{
   731  		Ignore: c1.Name,
   732  		t:      t,
   733  	}
   734  	c1.Alive = alive1
   735  
   736  	m1, err := memberlist.Create(c1)
   737  	require.NoError(t, err)
   738  	defer m1.Shutdown()
   739  
   740  	// Create a second node
   741  	c2 := testConfig(t)
   742  	c2.BindPort = 55120
   743  	c2.AdvertisePort = 55120
   744  	c2.Name = "m2"
   745  	alive2 := &CustomAliveDelegate{
   746  		Ignore: c2.Name,
   747  		t:      t,
   748  	}
   749  	c2.Alive = alive2
   750  
   751  	m2, err := memberlist.Create(c2)
   752  	require.NoError(t, err)
   753  	defer m2.Shutdown()
   754  
   755  	joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
   756  	num, err := m2.Join([]string{joinUrl})
   757  	if num != 1 {
   758  		t.Fatalf("unexpected 1: %d", num)
   759  	}
   760  	if err != nil {
   761  		t.Fatalf("err: %s", err)
   762  	}
   763  
   764  	// Check the hosts
   765  	if len(m2.Members()) != 1 {
   766  		t.Fatalf("should have 1 nodes! %v", m2.Members())
   767  	}
   768  	if len(m1.Members()) != 1 {
   769  		t.Fatalf("should have 1 nodes! %v", m1.Members())
   770  	}
   771  
   772  	// Check delegate invocation
   773  	if alive1.count == 0 {
   774  		t.Fatalf("should invoke delegate: %d", alive1.count)
   775  	}
   776  	if alive2.count == 0 {
   777  		t.Fatalf("should invoke delegate: %d", alive2.count)
   778  	}
   779  }
   780  
   781  func TestMemberlist_Join_protocolVersions(t *testing.T) {
   782  	c1 := testConfig(t)
   783  	c1.BindPort = 55121
   784  	c1.AdvertisePort = 55121
   785  	c1.Name = "m1"
   786  	m1, err := memberlist.Create(c1)
   787  	require.NoError(t, err)
   788  	defer m1.Shutdown()
   789  
   790  	c2 := testConfig(t)
   791  	c2.BindPort = 55110
   792  	c2.AdvertisePort = 55110
   793  	c2.Name = "m2"
   794  
   795  	m2, err := memberlist.Create(c2)
   796  	require.NoError(t, err)
   797  	defer m2.Shutdown()
   798  
   799  	c3 := testConfig(t)
   800  	c3.BindPort = 55109
   801  	c3.AdvertisePort = 55109
   802  	c3.Name = "m3"
   803  	c3.ProtocolVersion = memberlist.ProtocolVersionMax
   804  
   805  	m3, err := memberlist.Create(c3)
   806  	require.NoError(t, err)
   807  	defer m3.Shutdown()
   808  
   809  	_, err = m1.Join([]string{c2.Name + "/" + c2.BindAddr})
   810  	require.NoError(t, err)
   811  
   812  	yield()
   813  
   814  	_, err = m1.Join([]string{c3.Name + "/" + c3.BindAddr})
   815  	require.NoError(t, err)
   816  }
   817  
   818  func joinAndTestMemberShip(t *testing.T, self *memberlist.Memberlist, membersToJoin []string, expectedMembers int) error {
   819  	t.Helper()
   820  	num, err := self.Join(membersToJoin)
   821  	if err != nil {
   822  		return err
   823  	}
   824  	if num != len(membersToJoin) {
   825  		t.Fatalf("unexpected %d, was expecting %d to be joined", num, len(membersToJoin))
   826  	}
   827  	if err != nil {
   828  		t.Fatalf("unexpected err: %s", err)
   829  	}
   830  	// Check the hosts
   831  	if len(self.Members()) != expectedMembers {
   832  		t.Fatalf("should have 2 nodes! %v", self.Members())
   833  	}
   834  	if len(self.Members()) != expectedMembers {
   835  		t.Fatalf("should have 2 nodes! %v", self.Members())
   836  	}
   837  	return nil
   838  }
   839  
   840  func TestMemberlist_Leave(t *testing.T) {
   841  	newConfig := func() *memberlist.Config {
   842  		c := testConfig(t)
   843  		c.GossipInterval = time.Millisecond
   844  		return c
   845  	}
   846  
   847  	c1 := newConfig()
   848  	c1.BindPort = 55108
   849  	c1.AdvertisePort = 55108
   850  	c1.Name = "m1"
   851  
   852  	m1, err := memberlist.Create(c1)
   853  	require.NoError(t, err)
   854  	defer m1.Shutdown()
   855  
   856  	// Create a second node
   857  	c2 := newConfig()
   858  	c2.BindPort = 55107
   859  	c2.AdvertisePort = 55107
   860  	c2.Name = "m2"
   861  
   862  	m2, err := memberlist.Create(c2)
   863  	require.NoError(t, err)
   864  	defer m2.Shutdown()
   865  
   866  	joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
   867  	err = joinAndTestMemberShip(t, m2, []string{joinUrl}, 2)
   868  	if err != nil {
   869  		t.Fatalf("unexpected err: %s", err)
   870  	}
   871  
   872  	// Leave
   873  	err = m1.Leave(time.Second)
   874  	require.NoError(t, err)
   875  
   876  	// Wait for leave
   877  	time.Sleep(10 * time.Millisecond)
   878  
   879  	// m1 should think dead
   880  	if len(m1.Members()) != 1 {
   881  		t.Fatalf("should have 1 node")
   882  	}
   883  
   884  	if len(m2.Members()) != 1 {
   885  		t.Fatalf("should have 1 node")
   886  	}
   887  
   888  	if m2.NodeMap()[c1.Name].State != memberlist.StateLeft {
   889  		t.Fatalf("bad state")
   890  	}
   891  }
   892  
   893  func TestMemberlist_JoinShutdown(t *testing.T) {
   894  	newConfig := func() *memberlist.Config {
   895  		c := testConfig(t)
   896  		c.ProbeInterval = time.Millisecond
   897  		c.ProbeTimeout = 100 * time.Microsecond
   898  		c.SuspicionMaxTimeoutMult = 1
   899  		return c
   900  	}
   901  
   902  	c1 := newConfig()
   903  	c1.BindPort = 55106
   904  	c1.AdvertisePort = 55106
   905  	c1.Name = "m1"
   906  
   907  	m1, err := memberlist.Create(c1)
   908  	require.NoError(t, err)
   909  	defer m1.Shutdown()
   910  
   911  	// Create a second node
   912  	c2 := newConfig()
   913  	c2.BindPort = 55105
   914  	c2.AdvertisePort = 55105
   915  	c2.Name = "m2"
   916  
   917  	m2, err := memberlist.Create(c2)
   918  	require.NoError(t, err)
   919  	defer m2.Shutdown()
   920  
   921  	joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
   922  	num, err := m2.Join([]string{joinUrl})
   923  	if num != 1 {
   924  		t.Fatalf("unexpected 1: %d", num)
   925  	}
   926  	if err != nil {
   927  		t.Fatalf("unexpected err: %s", err)
   928  	}
   929  
   930  	// Check the hosts
   931  	if len(m2.Members()) != 2 {
   932  		t.Fatalf("should have 2 nodes! %v", m2.Members())
   933  	}
   934  
   935  	require.NoError(t, m1.Shutdown())
   936  
   937  	waitForCondition(t, func() (bool, string) {
   938  		n := len(m2.Members())
   939  		return n == 1, fmt.Sprintf("expected 1 node, got %d", n)
   940  	})
   941  }
   942  
   943  func TestMemberlist_delegateMeta(t *testing.T) {
   944  	c1 := testConfig(t)
   945  	c1.Delegate = &MockDelegate{meta: []byte("web")}
   946  	c1.BindPort = 55104
   947  	c1.AdvertisePort = 55104
   948  	c1.Name = "c1"
   949  
   950  	m1, err := memberlist.Create(c1)
   951  	require.NoError(t, err)
   952  	defer m1.Shutdown()
   953  
   954  	c2 := testConfig(t)
   955  	c2.BindPort = 55103
   956  	c2.AdvertisePort = 55103
   957  	c2.Name = "c2"
   958  	c2.Delegate = &MockDelegate{meta: []byte("lb")}
   959  
   960  	m2, err := memberlist.Create(c2)
   961  	require.NoError(t, err)
   962  	defer m2.Shutdown()
   963  
   964  	joinUrl := fmt.Sprintf("%s/%s:%d", m2.Config().Name, m2.AdvertiseAddr(), m2.AdvertisePort())
   965  	_, err = m1.Join([]string{joinUrl})
   966  	require.NoError(t, err)
   967  
   968  	yield()
   969  
   970  	var roles map[string]string
   971  
   972  	// Check the roles of members of m1
   973  	m1m := m1.Members()
   974  	if len(m1m) != 2 {
   975  		t.Fatalf("bad: %#v", m1m)
   976  	}
   977  
   978  	roles = make(map[string]string)
   979  	for _, m := range m1m {
   980  		roles[m.Name] = string(m.Meta)
   981  	}
   982  
   983  	if r := roles[c1.Name]; r != "web" {
   984  		t.Fatalf("bad role for %s: %s", c1.Name, r)
   985  	}
   986  
   987  	if r := roles[c2.Name]; r != "lb" {
   988  		t.Fatalf("bad role for %s: %s", c2.Name, r)
   989  	}
   990  
   991  	// Check the roles of members of m2
   992  	m2m := m2.Members()
   993  	if len(m2m) != 2 {
   994  		t.Fatalf("bad: %#v", m2m)
   995  	}
   996  
   997  	roles = make(map[string]string)
   998  	for _, m := range m2m {
   999  		roles[m.Name] = string(m.Meta)
  1000  	}
  1001  
  1002  	if r := roles[c1.Name]; r != "web" {
  1003  		t.Fatalf("bad role for %s: %s", c1.Name, r)
  1004  	}
  1005  
  1006  	if r := roles[c2.Name]; r != "lb" {
  1007  		t.Fatalf("bad role for %s: %s", c2.Name, r)
  1008  	}
  1009  }
  1010  
  1011  func TestMemberlist_delegateMeta_Update(t *testing.T) {
  1012  	c1 := testConfig(t)
  1013  	c1.BindPort = 55122
  1014  	c1.AdvertisePort = 55122
  1015  	c1.Name = "m1"
  1016  	mock1 := &MockDelegate{meta: []byte("web")}
  1017  	c1.Delegate = mock1
  1018  
  1019  	m1, err := memberlist.Create(c1)
  1020  	require.NoError(t, err)
  1021  	defer m1.Shutdown()
  1022  
  1023  	c2 := testConfig(t)
  1024  	c2.BindPort = 55123
  1025  	c2.AdvertisePort = 55123
  1026  	c2.Name = "m2"
  1027  	mock2 := &MockDelegate{meta: []byte("lb")}
  1028  	c2.Delegate = mock2
  1029  
  1030  	m2, err := memberlist.Create(c2)
  1031  	require.NoError(t, err)
  1032  	defer m2.Shutdown()
  1033  
  1034  	joinUrl := fmt.Sprintf("%s/%s:%d", m2.Config().Name, m2.AdvertiseAddr(), m2.AdvertisePort())
  1035  	_, err = m1.Join([]string{joinUrl})
  1036  
  1037  	require.NoError(t, err)
  1038  
  1039  	yield()
  1040  
  1041  	// Update the meta data roles
  1042  	mock1.setMeta([]byte("api"))
  1043  	mock2.setMeta([]byte("db"))
  1044  
  1045  	err = m1.UpdateNode(0)
  1046  	require.NoError(t, err)
  1047  	err = m2.UpdateNode(0)
  1048  	require.NoError(t, err)
  1049  
  1050  	yield()
  1051  
  1052  	// Check the updates have propagated
  1053  	var roles map[string]string
  1054  
  1055  	// Check the roles of members of m1
  1056  	m1m := m1.Members()
  1057  	if len(m1m) != 2 {
  1058  		t.Fatalf("bad: %#v", m1m)
  1059  	}
  1060  
  1061  	roles = make(map[string]string)
  1062  	for _, m := range m1m {
  1063  		roles[m.Name] = string(m.Meta)
  1064  	}
  1065  
  1066  	if r := roles[c1.Name]; r != "api" {
  1067  		t.Fatalf("bad role for %s: %s", c1.Name, r)
  1068  	}
  1069  
  1070  	if r := roles[c2.Name]; r != "db" {
  1071  		t.Fatalf("bad role for %s: %s", c2.Name, r)
  1072  	}
  1073  
  1074  	// Check the roles of members of m2
  1075  	m2m := m2.Members()
  1076  	if len(m2m) != 2 {
  1077  		t.Fatalf("bad: %#v", m2m)
  1078  	}
  1079  
  1080  	roles = make(map[string]string)
  1081  	for _, m := range m2m {
  1082  		roles[m.Name] = string(m.Meta)
  1083  	}
  1084  
  1085  	if r := roles[c1.Name]; r != "api" {
  1086  		t.Fatalf("bad role for %s: %s", c1.Name, r)
  1087  	}
  1088  
  1089  	if r := roles[c2.Name]; r != "db" {
  1090  		t.Fatalf("bad role for %s: %s", c2.Name, r)
  1091  	}
  1092  }
  1093  
  1094  func TestMemberlist_UserData(t *testing.T) {
  1095  	newConfig := func() (*memberlist.Config, *MockDelegate) {
  1096  		d := &MockDelegate{}
  1097  		c := testConfig(t)
  1098  		// Set the gossip/pushpull intervals fast enough to get a reasonable test,
  1099  		// but slow enough to avoid "sendto: operation not permitted"
  1100  		c.GossipInterval = 100 * time.Millisecond
  1101  		c.PushPullInterval = 100 * time.Millisecond
  1102  		c.Delegate = d
  1103  		return c, d
  1104  	}
  1105  
  1106  	c1, d1 := newConfig()
  1107  	c1.BindPort = 55133
  1108  	c1.AdvertisePort = 55133
  1109  	c1.Name = "m1"
  1110  	d1.setState([]byte("something"))
  1111  
  1112  	m1, err := memberlist.Create(c1)
  1113  	require.NoError(t, err)
  1114  	defer m1.Shutdown()
  1115  
  1116  	bcasts := [][]byte{
  1117  		[]byte("test"),
  1118  		[]byte("foobar"),
  1119  	}
  1120  
  1121  	// Create a second node
  1122  	c2, d2 := newConfig()
  1123  	c2.BindPort = 55134
  1124  	c2.AdvertisePort = 55134
  1125  	c2.Name = "m2"
  1126  
  1127  	// Second delegate has things to send
  1128  	d2.setBroadcasts(bcasts)
  1129  	d2.setState([]byte("my state"))
  1130  
  1131  	m2, err := memberlist.Create(c2)
  1132  	require.NoError(t, err)
  1133  	defer m2.Shutdown()
  1134  
  1135  	joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
  1136  	num, err := m2.Join([]string{joinUrl})
  1137  	if num != 1 {
  1138  		t.Fatalf("unexpected 1: %d", num)
  1139  	}
  1140  	require.NoError(t, err)
  1141  
  1142  	// Check the hosts
  1143  	if m2.NumMembers() != 2 {
  1144  		t.Fatalf("should have 2 nodes! %v", m2.Members())
  1145  	}
  1146  }
  1147  
  1148  func TestMemberlist_SendTo(t *testing.T) {
  1149  	newConfig := func() (*memberlist.Config, *MockDelegate, net.IP) {
  1150  		d := &MockDelegate{}
  1151  		c := testConfig(t)
  1152  		c.GossipInterval = time.Millisecond
  1153  		c.PushPullInterval = time.Millisecond
  1154  		c.Delegate = d
  1155  		return c, d, net.ParseIP(c.BindAddr)
  1156  	}
  1157  
  1158  	c1, d1, _ := newConfig()
  1159  	c1.BindPort = 55144
  1160  	c1.AdvertisePort = 55144
  1161  	c1.Name = "m1"
  1162  
  1163  	m1, err := memberlist.Create(c1)
  1164  	require.NoError(t, err)
  1165  	defer m1.Shutdown()
  1166  
  1167  	c2, d2, addr2 := newConfig()
  1168  	c2.BindPort = 55145
  1169  	c2.AdvertisePort = 55145
  1170  	c2.Name = "m2"
  1171  
  1172  	m2, err := memberlist.Create(c2)
  1173  	require.NoError(t, err)
  1174  	defer m2.Shutdown()
  1175  
  1176  	joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
  1177  	num, err := m2.Join([]string{joinUrl})
  1178  	require.NoError(t, err)
  1179  	require.Equal(t, 1, num)
  1180  
  1181  	// Check the hosts
  1182  	require.Equal(t, 2, m2.NumMembers(), "should have 2 nodes! %v", m2.Members())
  1183  
  1184  	// Try to do a direct send
  1185  	m2Addr := &net.UDPAddr{
  1186  		IP:   addr2,
  1187  		Port: int(m2.AdvertisePort()),
  1188  	}
  1189  	m2Address := memberlist.Address{
  1190  		Addr: m2Addr.String(),
  1191  		Name: m2.Config().Name,
  1192  	}
  1193  	if err := m1.SendToAddress(m2Address, []byte("ping")); err != nil {
  1194  		t.Fatalf("err: %v", err)
  1195  	}
  1196  
  1197  	m1Addr := &net.UDPAddr{
  1198  		IP:   net.ParseIP(m1.Config().BindAddr),
  1199  		Port: int(m1.AdvertisePort()),
  1200  	}
  1201  	m1Address := memberlist.Address{
  1202  		Addr: m1Addr.String(),
  1203  		Name: m1.Config().Name,
  1204  	}
  1205  	if err := m2.SendToAddress(m1Address, []byte("pong")); err != nil {
  1206  		t.Fatalf("err: %v", err)
  1207  	}
  1208  
  1209  	waitForCondition(t, func() (bool, string) {
  1210  		msgs := d1.getMessages()
  1211  		return len(msgs) == 1, fmt.Sprintf("expected 1 message, got %d", len(msgs))
  1212  	})
  1213  
  1214  	msgs1 := d1.getMessages()
  1215  	if !reflect.DeepEqual(msgs1[0], []byte("pong")) {
  1216  		t.Fatalf("bad msg %v", msgs1[0])
  1217  	}
  1218  
  1219  	waitForCondition(t, func() (bool, string) {
  1220  		msgs := d2.getMessages()
  1221  		return len(msgs) == 1, fmt.Sprintf("expected 1 message, got %d", len(msgs))
  1222  	})
  1223  	msgs2 := d2.getMessages()
  1224  	if !reflect.DeepEqual(msgs2[0], []byte("ping")) {
  1225  		t.Fatalf("bad msg %v", msgs2[0])
  1226  	}
  1227  }
  1228  
  1229  func waitForCondition(t *testing.T, fn func() (bool, string)) {
  1230  	start := time.Now()
  1231  
  1232  	var msg string
  1233  	for time.Since(start) < 20*time.Second {
  1234  		var done bool
  1235  		done, msg = fn()
  1236  		if done {
  1237  			return
  1238  		}
  1239  		time.Sleep(5 * time.Millisecond)
  1240  	}
  1241  	t.Fatalf("timeout waiting for condition: %v", msg)
  1242  }
  1243  
  1244  func TestMemberlistProtocolVersion(t *testing.T) {
  1245  	c := testConfig(t)
  1246  	c.ProtocolVersion = memberlist.ProtocolVersionMax
  1247  
  1248  	m, err := memberlist.Create(c)
  1249  	require.NoError(t, err)
  1250  	defer m.Shutdown()
  1251  
  1252  	result := m.ProtocolVersion()
  1253  	if result != memberlist.ProtocolVersionMax {
  1254  		t.Fatalf("bad: %d", result)
  1255  	}
  1256  }
  1257  
  1258  func TestMemberlist_Join_DeadNode(t *testing.T) {
  1259  	c1 := testConfig(t)
  1260  	c1.TCPTimeout = 50 * time.Millisecond
  1261  	c1.BindPort = 55155
  1262  	c1.AdvertisePort = 55155
  1263  	c1.Name = "m1"
  1264  
  1265  	m1, err := memberlist.Create(c1)
  1266  	require.NoError(t, err)
  1267  	defer m1.Shutdown()
  1268  
  1269  	// Create a second "node", which is just a TCP listener that
  1270  	// does not ever respond. This is to test our deadlines
  1271  	addr2 := getBindAddr()
  1272  	list, err := net.Listen("tcp", net.JoinHostPort(addr2.String(), strconv.Itoa(56156)))
  1273  	if err != nil {
  1274  		t.Fatalf("err: %v", err)
  1275  	}
  1276  	defer list.Close()
  1277  
  1278  	// Ensure we don't hang forever
  1279  	timer := time.AfterFunc(100*time.Millisecond, func() {
  1280  		panic("should have timed out by now")
  1281  	})
  1282  	defer timer.Stop()
  1283  
  1284  	num, err := m1.Join([]string{fmt.Sprintf("%s/%s:%d", "fake", addr2.String(), 56156)})
  1285  	if num != 0 {
  1286  		t.Fatalf("unexpected 0: %d", num)
  1287  	}
  1288  	if err == nil {
  1289  		t.Fatal("expect err")
  1290  	}
  1291  }
  1292  
  1293  // Tests that nodes running different versions of the protocol can successfully
  1294  // discover each other and add themselves to their respective member lists.
  1295  func TestMemberlist_Join_Protocol_Compatibility(t *testing.T) {
  1296  	testProtocolVersionPair := func(t *testing.T, pv1 uint8, pv2 uint8) {
  1297  		t.Helper()
  1298  
  1299  		c1 := testConfig(t)
  1300  		c1.ProtocolVersion = pv1
  1301  		c1.BindPort = 55166
  1302  		c1.AdvertisePort = 55166
  1303  		c1.Name = "m1"
  1304  
  1305  		m1, err := memberlist.Create(c1)
  1306  		require.NoError(t, err)
  1307  		defer m1.Shutdown()
  1308  
  1309  		c2 := testConfig(t)
  1310  		c2.BindPort = 55167
  1311  		c2.AdvertisePort = 55167
  1312  		c2.ProtocolVersion = pv2
  1313  		c1.Name = "m2"
  1314  
  1315  		m2, err := memberlist.Create(c2)
  1316  		require.NoError(t, err)
  1317  		defer m2.Shutdown()
  1318  
  1319  		joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
  1320  		_, err = m2.Join([]string{joinUrl})
  1321  
  1322  		require.NoError(t, err)
  1323  		//require.Equal(t, 1, num)
  1324  
  1325  		// Check the hosts
  1326  		//if len(m2.Members()) != 2 {
  1327  		//	t.Fatalf("should have 2 nodes! %v", m2.Members())
  1328  		//}
  1329  		//
  1330  		// Check the hosts
  1331  		//if len(m1.Members()) != 2 {
  1332  		//	t.Fatalf("should have 2 nodes! %v", m1.Members())
  1333  		//}
  1334  	}
  1335  
  1336  	t.Run("2,1", func(t *testing.T) {
  1337  		testProtocolVersionPair(t, 2, 1)
  1338  	})
  1339  	t.Run("2,3", func(t *testing.T) {
  1340  		testProtocolVersionPair(t, 2, 3)
  1341  	})
  1342  	t.Run("3,2", func(t *testing.T) {
  1343  		testProtocolVersionPair(t, 3, 2)
  1344  	})
  1345  	t.Run("3,1", func(t *testing.T) {
  1346  		testProtocolVersionPair(t, 3, 1)
  1347  	})
  1348  }
  1349  
  1350  var (
  1351  	ipv6LoopbackAvailableOnce sync.Once
  1352  	ipv6LoopbackAvailable     bool
  1353  )
  1354  
  1355  func isIPv6LoopbackAvailable(t *testing.T) bool {
  1356  	const ipv6LoopbackAddress = "::1"
  1357  	ipv6LoopbackAvailableOnce.Do(func() {
  1358  		ifaces, err := net.Interfaces()
  1359  		require.NoError(t, err)
  1360  
  1361  		for _, iface := range ifaces {
  1362  			if iface.Flags&net.FlagLoopback == 0 {
  1363  				continue
  1364  			}
  1365  			addrs, err := iface.Addrs()
  1366  			require.NoError(t, err)
  1367  
  1368  			for _, addr := range addrs {
  1369  				ipaddr := addr.(*net.IPNet)
  1370  				if ipaddr.IP.String() == ipv6LoopbackAddress {
  1371  					ipv6LoopbackAvailable = true
  1372  					return
  1373  				}
  1374  			}
  1375  		}
  1376  		ipv6LoopbackAvailable = false
  1377  		t.Logf("IPv6 loopback address %q not found, disabling tests that require it", ipv6LoopbackAddress)
  1378  	})
  1379  
  1380  	return ipv6LoopbackAvailable
  1381  }
  1382  
  1383  func TestMemberlist_Join_IPv6(t *testing.T) {
  1384  	if !isIPv6LoopbackAvailable(t) {
  1385  		t.SkipNow()
  1386  		return
  1387  	}
  1388  	// Since this binds to all interfaces we need to exclude other tests
  1389  	// from grabbing an interface.
  1390  	bindLock.Lock()
  1391  	defer bindLock.Unlock()
  1392  
  1393  	c1 := memberlist.DefaultLANConfig()
  1394  	c1.Name = "A"
  1395  	c1.BindAddr = "[::1]"
  1396  	c1.BindPort = 0 // choose free
  1397  	c1.Logger = log.New(os.Stderr, c1.Name, log.LstdFlags)
  1398  
  1399  	m1, err := memberlist.Create(c1)
  1400  	require.NoError(t, err)
  1401  	defer m1.Shutdown()
  1402  
  1403  	// Create a second node
  1404  	c2 := memberlist.DefaultLANConfig()
  1405  	c2.Name = "B"
  1406  	c2.BindAddr = "[::1]"
  1407  	c2.BindPort = 0 // choose free
  1408  	c2.Logger = log.New(os.Stderr, c2.Name, log.LstdFlags)
  1409  
  1410  	m2, err := memberlist.Create(c2)
  1411  	require.NoError(t, err)
  1412  	defer m2.Shutdown()
  1413  
  1414  	num, err := m2.Join([]string{fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.Config().BindAddr, m1.Config().BindPort)})
  1415  	require.NoError(t, err)
  1416  	require.Equal(t, 1, num)
  1417  
  1418  	// Check the hosts
  1419  	if len(m2.Members()) != 2 {
  1420  		t.Fatalf("should have 2 nodes! %v", m2.Members())
  1421  	}
  1422  
  1423  	if len(m1.Members()) != 2 {
  1424  		t.Fatalf("should have 2 nodes! %v", m2.Members())
  1425  	}
  1426  }
  1427  
  1428  func reservePort(t *testing.T, ip net.IP, purpose string) int {
  1429  	for i := 0; i < 10; i++ {
  1430  		tcpAddr := &net.TCPAddr{IP: ip, Port: 0}
  1431  		tcpLn, err := net.ListenTCP("tcp", tcpAddr)
  1432  		if err != nil {
  1433  			if strings.Contains(err.Error(), "address already in use") {
  1434  				continue
  1435  			}
  1436  			t.Fatalf("unexpected error: %v", err)
  1437  		}
  1438  
  1439  		port := tcpLn.Addr().(*net.TCPAddr).Port
  1440  
  1441  		udpAddr := &net.UDPAddr{IP: ip, Port: port}
  1442  		udpLn, err := net.ListenUDP("udp", udpAddr)
  1443  		if err != nil {
  1444  			_ = tcpLn.Close()
  1445  			if strings.Contains(err.Error(), "address already in use") {
  1446  				continue
  1447  			}
  1448  			t.Fatalf("unexpected error: %v", err)
  1449  		}
  1450  
  1451  		t.Logf("Using dynamic bind port %d for %s", port, purpose)
  1452  		_ = tcpLn.Close()
  1453  		_ = udpLn.Close()
  1454  		return port
  1455  	}
  1456  
  1457  	t.Fatalf("could not find a free TCP+UDP port to listen on for %s", purpose)
  1458  	panic("IMPOSSIBLE")
  1459  }
  1460  
  1461  func TestAdvertiseAddr(t *testing.T) {
  1462  	bindAddr := getBindAddr()
  1463  	advertiseAddr := getBindAddr()
  1464  
  1465  	bindPort := reservePort(t, bindAddr, "BIND")
  1466  	advertisePort := reservePort(t, advertiseAddr, "ADVERTISE")
  1467  
  1468  	c := memberlist.DefaultLANConfig()
  1469  	c.BindAddr = bindAddr.String()
  1470  	c.BindPort = bindPort
  1471  	c.Name = c.BindAddr
  1472  
  1473  	c.AdvertiseAddr = advertiseAddr.String()
  1474  	c.AdvertisePort = advertisePort
  1475  
  1476  	m, err := memberlist.Create(c)
  1477  	require.NoError(t, err)
  1478  	defer m.Shutdown()
  1479  
  1480  	yield()
  1481  
  1482  	members := m.Members()
  1483  	require.Equal(t, 1, len(members))
  1484  
  1485  	require.Equal(t, advertiseAddr.String(), members[0].Addr)
  1486  	require.Equal(t, advertisePort, int(members[0].Port))
  1487  }
  1488  
  1489  type MockConflict struct {
  1490  	existing *memberlist.Node
  1491  	other    *memberlist.Node
  1492  }
  1493  
  1494  func (m *MockConflict) NotifyConflict(existing, other *memberlist.Node) {
  1495  	m.existing = existing
  1496  	m.other = other
  1497  }
  1498  
  1499  func TestMemberlist_conflictDelegate(t *testing.T) {
  1500  	c1 := testConfig(t)
  1501  	c1.BindPort = 55177
  1502  	c1.AdvertisePort = 55177
  1503  	mock := &MockConflict{}
  1504  	c1.Conflict = mock
  1505  
  1506  	m1, err := memberlist.Create(c1)
  1507  	require.NoError(t, err)
  1508  	defer m1.Shutdown()
  1509  
  1510  	// Ensure name conflict
  1511  	c2 := testConfig(t)
  1512  	c2.Name = c1.Name
  1513  	c2.BindPort = 55178
  1514  	c2.AdvertisePort = 55178
  1515  
  1516  	m2, err := memberlist.Create(c2)
  1517  	require.NoError(t, err)
  1518  	defer m2.Shutdown()
  1519  
  1520  	joinUrl := fmt.Sprintf("%s/%s:%d", m2.Config().Name, m2.AdvertiseAddr(), m2.AdvertisePort())
  1521  	num, err := m1.Join([]string{joinUrl})
  1522  	require.NoError(t, err)
  1523  	require.Equal(t, 1, num)
  1524  
  1525  	yield()
  1526  
  1527  	// Ensure we were notified
  1528  	if mock.existing == nil || mock.other == nil {
  1529  		t.Fatalf("should get notified mock.existing=%v  VS mock.other=%v", mock.existing, mock.other)
  1530  	}
  1531  	if mock.existing.Name != mock.other.Name {
  1532  		t.Fatalf("bad: %v %v", mock.existing, mock.other)
  1533  	}
  1534  }
  1535  
  1536  type MockPing struct {
  1537  	mu      sync.Mutex
  1538  	other   *memberlist.Node
  1539  	rtt     time.Duration
  1540  	payload []byte
  1541  }
  1542  
  1543  func (m *MockPing) NotifyPingComplete(other *memberlist.Node, rtt time.Duration, payload []byte) {
  1544  	m.mu.Lock()
  1545  	defer m.mu.Unlock()
  1546  
  1547  	m.other = other
  1548  	m.rtt = rtt
  1549  	m.payload = payload
  1550  }
  1551  
  1552  func (m *MockPing) getContents() (*memberlist.Node, time.Duration, []byte) {
  1553  	m.mu.Lock()
  1554  	defer m.mu.Unlock()
  1555  	return m.other, m.rtt, m.payload
  1556  }
  1557  
  1558  const DEFAULT_PAYLOAD = "whatever"
  1559  
  1560  func (m *MockPing) AckPayload() []byte {
  1561  	return []byte(DEFAULT_PAYLOAD)
  1562  }
  1563  
  1564  func TestMemberlist_PingDelegate(t *testing.T) {
  1565  	newConfig := func() *memberlist.Config {
  1566  		c := testConfig(t)
  1567  		c.ProbeInterval = 100 * time.Millisecond
  1568  		c.Ping = &MockPing{}
  1569  		return c
  1570  	}
  1571  
  1572  	c1 := newConfig()
  1573  	c1.BindPort = 55199
  1574  	c1.AdvertisePort = 55199
  1575  	c1.Name = "m1"
  1576  
  1577  	m1, err := memberlist.Create(c1)
  1578  	require.NoError(t, err)
  1579  	defer m1.Shutdown()
  1580  
  1581  	// Create a second node
  1582  	c2 := newConfig()
  1583  	c2.BindPort = 55200
  1584  	c2.AdvertisePort = 55200
  1585  	c2.Name = "m2"
  1586  	mock := c2.Ping.(*MockPing)
  1587  
  1588  	m2, err := memberlist.Create(c2)
  1589  	require.NoError(t, err)
  1590  	defer m2.Shutdown()
  1591  
  1592  	joinUrl := fmt.Sprintf("%s/%s:%d", m1.Config().Name, m1.AdvertiseAddr(), m1.AdvertisePort())
  1593  	num, err := m2.Join([]string{joinUrl})
  1594  	require.NoError(t, err)
  1595  	require.Equal(t, 1, num)
  1596  
  1597  	waitUntilSize(t, m1, 2)
  1598  	waitUntilSize(t, m2, 2)
  1599  
  1600  	time.Sleep(2 * c1.ProbeInterval)
  1601  
  1602  	require.NoError(t, m1.Shutdown())
  1603  	require.NoError(t, m2.Shutdown())
  1604  
  1605  	mOther, mRTT, _ := mock.getContents()
  1606  
  1607  	// Ensure we were notified
  1608  	if mOther == nil {
  1609  		t.Fatalf("should get notified")
  1610  	}
  1611  
  1612  	//if !reflect.DeepEqual(mOther, m1.LocalNode()) {
  1613  	//	t.Fatalf("not notified about the correct node; expected: %+v; actual: %+v",
  1614  	//		m2.LocalNode(), mOther)
  1615  	//}
  1616  
  1617  	if mRTT <= 0 {
  1618  		t.Fatalf("rtt should be greater than 0")
  1619  	}
  1620  
  1621  	//if bytes.Compare(mPayload, []byte(DEFAULT_PAYLOAD)) != 0 {
  1622  	//	t.Fatalf("incorrect payload. expected: %v; actual: %v",
  1623  	//		[]byte(DEFAULT_PAYLOAD), mPayload)
  1624  	//}
  1625  }
  1626  
  1627  func waitUntilSize(t *testing.T, m *memberlist.Memberlist, expected int) {
  1628  	t.Helper()
  1629  	retry(t, 15, 500*time.Millisecond, func(failf func(string, ...interface{})) {
  1630  		t.Helper()
  1631  
  1632  		if m.NumMembers() != expected {
  1633  			failf("%s expected to have %d members but had: %v", m.Config().Name, expected, m.Members())
  1634  		}
  1635  	})
  1636  }
  1637  
  1638  func isPortFree(t *testing.T, addr string, port int) error {
  1639  	t.Helper()
  1640  
  1641  	ip := net.ParseIP(addr)
  1642  	tcpAddr := &net.TCPAddr{IP: ip, Port: port}
  1643  	tcpLn, err := net.ListenTCP("tcp", tcpAddr)
  1644  	if err != nil {
  1645  		return err
  1646  	}
  1647  	if err := tcpLn.Close(); err != nil {
  1648  		return err
  1649  	}
  1650  
  1651  	udpAddr := &net.UDPAddr{IP: ip, Port: port}
  1652  	udpLn, err := net.ListenUDP("udp", udpAddr)
  1653  	if err != nil {
  1654  		return err
  1655  	}
  1656  
  1657  	return udpLn.Close()
  1658  }
  1659  
  1660  func waitUntilPortIsFree(t *testing.T, m *memberlist.Memberlist) {
  1661  	t.Helper()
  1662  
  1663  	// wait until we know for certain that m1 is dead dead
  1664  	addr := m.Config().BindAddr
  1665  	port := m.Config().BindPort
  1666  
  1667  	retry(t, 15, 250*time.Millisecond, func(failf func(string, ...interface{})) {
  1668  		t.Helper()
  1669  
  1670  		if err := isPortFree(t, addr, port); err != nil {
  1671  			failf("%s port is not yet free", m.Config().Name)
  1672  		}
  1673  	})
  1674  }
  1675  
  1676  // This test should follow the recommended upgrade guide:
  1677  // https://www.consul.io/docs/agent/encryption.html#configuring-gossip-encryption-on-an-existing-cluster
  1678  //
  1679  // We will use two nodes for this: m0 and m1
  1680  //
  1681  // 0. Start with nodes without encryption.
  1682  // 1. Set an encryption key and set GossipVerifyIncoming=false and GossipVerifyOutgoing=false to all nodes.
  1683  // 2. Change GossipVerifyOutgoing=true to all nodes.
  1684  // 3. Change GossipVerifyIncoming=true to all nodes.
  1685  //func TestMemberlist_EncryptedGossipTransition(t *testing.T) {
  1686  //	// ensure these all get the same general set of customizations
  1687  //	pretty := make(map[string]string) // addr->shortName
  1688  //	newConfig := func(shortName string, addr string) *memberlist.Config {
  1689  //		t.Helper()
  1690  //
  1691  //		conf := memberlist.DefaultLANConfig()
  1692  //		if addr == "" {
  1693  //			addr = getBindAddr().String()
  1694  //		}
  1695  //		conf.Name = addr
  1696  //		// conf.Name = shortName
  1697  //		conf.BindAddr = addr
  1698  //		conf.BindPort = 0
  1699  //		// Set the gossip interval fast enough to get a reasonable test,
  1700  //		// but slow enough to avoid "sendto: operation not permitted"
  1701  //		conf.GossipInterval = 100 * time.Millisecond
  1702  //		conf.Logger = log.New(os.Stderr, shortName, log.LstdFlags)
  1703  //
  1704  //		pretty[conf.Name] = shortName
  1705  //		return conf
  1706  //	}
  1707  //
  1708  //	var bindPort int
  1709  //	createOK := func(conf *memberlist.Config) *Memberlist {
  1710  //		t.Helper()
  1711  //
  1712  //		if bindPort > 0 {
  1713  //			conf.BindPort = bindPort
  1714  //		} else {
  1715  //			// try a range of port numbers until something sticks
  1716  //		}
  1717  //		m, err := memberlist.Create(conf)
  1718  //		require.NoError(t, err)
  1719  //
  1720  //		if bindPort == 0 {
  1721  //			bindPort = m.config.BindPort
  1722  //		}
  1723  //		return m
  1724  //	}
  1725  //
  1726  //	joinOK := func(src, dst *Memberlist, numNodes int) {
  1727  //		t.Helper()
  1728  //
  1729  //		srcName, dstName := pretty[src.Config().Name], pretty[dst.Config().Name]
  1730  //		t.Logf("Node %s[%s] joining node %s[%s]", srcName, src.Config().Name, dstName, dst.Config().Name)
  1731  //
  1732  //		num, err := src.Join([]string{dst.Config().Name + "/" + dst.config.BindAddr})
  1733  //		require.NoError(t, err)
  1734  //		require.Equal(t, 1, num)
  1735  //
  1736  //		waitUntilSize(t, src, numNodes)
  1737  //		waitUntilSize(t, dst, numNodes)
  1738  //
  1739  //		// Check the hosts
  1740  //		require.Equal(t, numNodes, len(src.Members()), "nodes: %v", src.Members())
  1741  //		require.Equal(t, numNodes, src.estNumNodes(), "nodes: %v", src.Members())
  1742  //		require.Equal(t, numNodes, len(dst.Members()), "nodes: %v", dst.Members())
  1743  //		require.Equal(t, numNodes, dst.estNumNodes(), "nodes: %v", dst.Members())
  1744  //	}
  1745  //
  1746  //	leaveOK := func(m *Memberlist, why string) {
  1747  //		t.Helper()
  1748  //
  1749  //		name := pretty[m.Config().Name]
  1750  //		t.Logf("Node %s[%s] is leaving %s", name, m.Config().Name, why)
  1751  //		err := m.Leave(time.Second)
  1752  //		require.NoError(t, err)
  1753  //	}
  1754  //
  1755  //	shutdownOK := func(m *Memberlist, why string) {
  1756  //		t.Helper()
  1757  //
  1758  //		name := pretty[m.Config().Name]
  1759  //		t.Logf("Node %s[%s] is shutting down %s", name, m.Config().Name, why)
  1760  //		err := m.Shutdown()
  1761  //		require.NoError(t, err)
  1762  //
  1763  //		// Double check that it genuinely shutdown.
  1764  //		waitUntilPortIsFree(t, m)
  1765  //	}
  1766  //
  1767  //	leaveAndShutdown := func(leaver, bystander *Memberlist, why string) {
  1768  //		t.Helper()
  1769  //
  1770  //		leaveOK(leaver, why)
  1771  //		waitUntilSize(t, bystander, 1)
  1772  //		shutdownOK(leaver, why)
  1773  //		waitUntilSize(t, bystander, 1)
  1774  //	}
  1775  //
  1776  //	// ==== STEP 0 ====
  1777  //
  1778  //	// Create a first cluster of 2 nodes with no gossip encryption settings.
  1779  //	conf0 := newConfig("m0", "")
  1780  //	m0 := memberlist.CreateOK(conf0)
  1781  //	defer m0.Shutdown()
  1782  //
  1783  //	conf1 := newConfig("m1", "")
  1784  //	m1 := memberlist.CreateOK(conf1)
  1785  //	defer m1.Shutdown()
  1786  //
  1787  //	joinOK(m1, m0, 2)
  1788  //
  1789  //	t.Logf("==== STEP 0 complete: two node unencrypted cluster ====")
  1790  //
  1791  //	// ==== STEP 1 ====
  1792  //
  1793  //	// Take down m0, upgrade to first stage of gossip transition settings.
  1794  //	leaveAndShutdown(m0, m1, "to upgrade gossip to first stage")
  1795  //
  1796  //	// Resurrect the first node with the first stage of gossip transition settings.
  1797  //	conf0 = newConfig("m0", m0.config.BindAddr)
  1798  //	conf0.SecretKey = []byte("Hi16ZXu2lNCRVwtr20khAg==")
  1799  //	conf0.GossipVerifyIncoming = false
  1800  //	conf0.GossipVerifyOutgoing = false
  1801  //	m0 = createOK(conf0)
  1802  //	defer m0.Shutdown()
  1803  //
  1804  //	// Join the second node. m1 has no encryption while m0 has encryption configured and
  1805  //	// can receive encrypted gossip, but will not encrypt outgoing gossip.
  1806  //	joinOK(m0, m1, 2)
  1807  //
  1808  //	leaveAndShutdown(m1, m0, "to upgrade gossip to first stage")
  1809  //
  1810  //	// Resurrect the second node with the first stage of gossip transition settings.
  1811  //	conf1 = newConfig("m1", m1.config.BindAddr)
  1812  //	conf1.SecretKey = []byte("Hi16ZXu2lNCRVwtr20khAg==")
  1813  //	conf1.GossipVerifyIncoming = false
  1814  //	conf1.GossipVerifyOutgoing = false
  1815  //	m1 = createOK(conf1)
  1816  //	defer m1.Shutdown()
  1817  //
  1818  //	// Join the first node. Both have encryption configured and can receive
  1819  //	// encrypted gossip, but will not encrypt outgoing gossip.
  1820  //	joinOK(m1, m0, 2)
  1821  //
  1822  //	t.Logf("==== STEP 1 complete: two node encryption-aware cluster ====")
  1823  //
  1824  //	// ==== STEP 2 ====
  1825  //
  1826  //	// Take down m0, upgrade to second stage of gossip transition settings.
  1827  //	leaveAndShutdown(m0, m1, "to upgrade gossip to second stage")
  1828  //
  1829  //	// Resurrect the first node with the second stage of gossip transition settings.
  1830  //	conf0 = newConfig("m0", m0.config.BindAddr)
  1831  //	conf0.SecretKey = []byte("Hi16ZXu2lNCRVwtr20khAg==")
  1832  //	conf0.GossipVerifyIncoming = false
  1833  //	m0 = createOK(conf0)
  1834  //	defer m0.Shutdown()
  1835  //
  1836  //	// Join the second node. At this step, both nodes have encryption
  1837  //	// configured but only m0 is sending encrypted gossip.
  1838  //	joinOK(m0, m1, 2)
  1839  //
  1840  //	leaveAndShutdown(m1, m0, "to upgrade gossip to second stage")
  1841  //
  1842  //	// Resurrect the second node with the second stage of gossip transition settings.
  1843  //	conf1 = newConfig("m1", m1.config.BindAddr)
  1844  //	conf1.SecretKey = []byte("Hi16ZXu2lNCRVwtr20khAg==")
  1845  //	conf1.GossipVerifyIncoming = false
  1846  //	m1 = createOK(conf1)
  1847  //	defer m1.Shutdown()
  1848  //
  1849  //	// Join the first node. Both have encryption configured and can receive
  1850  //	// encrypted gossip, and encrypt outgoing gossip, but aren't forcing
  1851  //	// incoming gossip is encrypted.
  1852  //	joinOK(m1, m0, 2)
  1853  //
  1854  //	t.Logf("==== STEP 2 complete: two node encryption-aware cluster being encrypted ====")
  1855  //
  1856  //	// ==== STEP 3 ====
  1857  //
  1858  //	// Take down m0, upgrade to final stage of gossip transition settings.
  1859  //	leaveAndShutdown(m0, m1, "to upgrade gossip to final stage")
  1860  //
  1861  //	// Resurrect the first node with the final stage of gossip transition settings.
  1862  //	conf0 = newConfig("m0", m0.config.BindAddr)
  1863  //	conf0.SecretKey = []byte("Hi16ZXu2lNCRVwtr20khAg==")
  1864  //	m0 = createOK(conf0)
  1865  //	defer m0.Shutdown()
  1866  //
  1867  //	// Join the second node. At this step, both nodes have encryption
  1868  //	// configured and are sending it, bu tonly m0 is verifying inbound gossip
  1869  //	// is encrypted.
  1870  //	joinOK(m0, m1, 2)
  1871  //
  1872  //	leaveAndShutdown(m1, m0, "to upgrade gossip to final stage")
  1873  //
  1874  //	// Resurrect the second node with the final stage of gossip transition settings.
  1875  //	conf1 = newConfig("m1", m1.config.BindAddr)
  1876  //	conf1.SecretKey = []byte("Hi16ZXu2lNCRVwtr20khAg==")
  1877  //	m1 = createOK(conf1)
  1878  //	defer m1.Shutdown()
  1879  //
  1880  //	// Join the first node. Both have encryption configured and fully in
  1881  //	// enforcement.
  1882  //	joinOK(m1, m0, 2)
  1883  //
  1884  //	t.Logf("==== STEP 3 complete: two node encrypted cluster locked down ====")
  1885  //}
  1886  
  1887  // Consul bug, rapid restart (before failure detection),
  1888  // with an updated meta data. Should be at incarnation 1 for
  1889  // both.
  1890  //
  1891  // This test is uncommented because it requires that either we
  1892  // can rebind the socket (SO_REUSEPORT) which Go does not allow,
  1893  // OR we must disable the address conflict checking in memberlist.
  1894  // I just comment out that code to test this case.
  1895  //
  1896  //func TestMemberlist_Restart_delegateMeta_Update(t *testing.T) {
  1897  //    c1 := testConfig()
  1898  //    c2 := testConfig()
  1899  //    mock1 := &MockDelegate{meta: []byte("web")}
  1900  //    mock2 := &MockDelegate{meta: []byte("lb")}
  1901  //    c1.Delegate = mock1
  1902  //    c2.Delegate = mock2
  1903  
  1904  //    m1, err := memberlist.Create(c1)
  1905  //    if err != nil {
  1906  //        t.Fatalf("err: %s", err)
  1907  //    }
  1908  //    defer m1.Shutdown()
  1909  
  1910  //    m2, err := memberlist.Create(c2)
  1911  //    if err != nil {
  1912  //        t.Fatalf("err: %s", err)
  1913  //    }
  1914  //    defer m2.Shutdown()
  1915  
  1916  //    _, err = m1.Join([]string{c2.BindAddr})
  1917  //    if err != nil {
  1918  //        t.Fatalf("err: %s", err)
  1919  //    }
  1920  
  1921  //    yield()
  1922  
  1923  //    // Recreate m1 with updated meta
  1924  //    m1.Shutdown()
  1925  //    c3 := testConfig()
  1926  //    c3.Name = c1.Name
  1927  //    c3.Delegate = mock1
  1928  //    c3.GossipInterval = time.Millisecond
  1929  //    mock1.meta = []byte("api")
  1930  
  1931  //    m1, err = Create(c3)
  1932  //    if err != nil {
  1933  //        t.Fatalf("err: %s", err)
  1934  //    }
  1935  //    defer m1.Shutdown()
  1936  
  1937  //    _, err = m1.Join([]string{c2.BindAddr})
  1938  //    if err != nil {
  1939  //        t.Fatalf("err: %s", err)
  1940  //    }
  1941  
  1942  //    yield()
  1943  //    yield()
  1944  
  1945  //    // Check the updates have propagated
  1946  //    var roles map[string]string
  1947  
  1948  //    // Check the roles of members of m1
  1949  //    m1m := m1.Members()
  1950  //    if len(m1m) != 2 {
  1951  //        t.Fatalf("bad: %#v", m1m)
  1952  //    }
  1953  
  1954  //    roles = make(map[string]string)
  1955  //    for _, m := range m1m {
  1956  //        roles[m.Name] = string(m.Meta)
  1957  //    }
  1958  
  1959  //    if r := roles[c1.Name]; r != "api" {
  1960  //        t.Fatalf("bad role for %s: %s", c1.Name, r)
  1961  //    }
  1962  
  1963  //    if r := roles[c2.Name]; r != "lb" {
  1964  //        t.Fatalf("bad role for %s: %s", c2.Name, r)
  1965  //    }
  1966  
  1967  //    // Check the roles of members of m2
  1968  //    m2m := m2.Members()
  1969  //    if len(m2m) != 2 {
  1970  //        t.Fatalf("bad: %#v", m2m)
  1971  //    }
  1972  
  1973  //    roles = make(map[string]string)
  1974  //    for _, m := range m2m {
  1975  //        roles[m.Name] = string(m.Meta)
  1976  //    }
  1977  
  1978  //    if r := roles[c1.Name]; r != "api" {
  1979  //        t.Fatalf("bad role for %s: %s", c1.Name, r)
  1980  //    }
  1981  
  1982  //    if r := roles[c2.Name]; r != "lb" {
  1983  //        t.Fatalf("bad role for %s: %s", c2.Name, r)
  1984  //    }
  1985  //}
  1986  
  1987  // Failer is an interface compatible with testing.T.
  1988  type Failer interface {
  1989  	// Log is called for the final test output
  1990  	Log(args ...interface{})
  1991  
  1992  	// FailNow is called when the retrying is abandoned.
  1993  	FailNow()
  1994  }
  1995  
  1996  // R provides context for the retryer.
  1997  type R struct {
  1998  	fail   bool
  1999  	output []string
  2000  }
  2001  
  2002  func (r *R) FailNow() {
  2003  	r.fail = true
  2004  	runtime.Goexit()
  2005  }
  2006  
  2007  func (r *R) Fatal(args ...interface{}) {
  2008  	r.log(fmt.Sprint(args...))
  2009  	r.FailNow()
  2010  }
  2011  
  2012  func (r *R) Fatalf(format string, args ...interface{}) {
  2013  	r.log(fmt.Sprintf(format, args...))
  2014  	r.FailNow()
  2015  }
  2016  
  2017  func (r *R) Error(args ...interface{}) {
  2018  	r.log(fmt.Sprint(args...))
  2019  	r.fail = true
  2020  }
  2021  
  2022  func (r *R) Errorf(format string, args ...interface{}) {
  2023  	r.log(fmt.Sprintf(format, args...))
  2024  	r.fail = true
  2025  }
  2026  
  2027  func (r *R) Check(err error) {
  2028  	if err != nil {
  2029  		r.log(err.Error())
  2030  		r.FailNow()
  2031  	}
  2032  }
  2033  
  2034  func (r *R) log(s string) {
  2035  	r.output = append(r.output, decorate(s))
  2036  }
  2037  
  2038  func decorate(s string) string {
  2039  	_, file, line, ok := runtime.Caller(3)
  2040  	if ok {
  2041  		n := strings.LastIndex(file, "/")
  2042  		if n >= 0 {
  2043  			file = file[n+1:]
  2044  		}
  2045  	} else {
  2046  		file = "???"
  2047  		line = 1
  2048  	}
  2049  	return fmt.Sprintf("%s:%d: %s", file, line, s)
  2050  }
  2051  
  2052  func Run(t Failer, f func(r *R)) {
  2053  	run(DefaultFailer(), t, f)
  2054  }
  2055  
  2056  func RunWith(r Retryer, t Failer, f func(r *R)) {
  2057  	run(r, t, f)
  2058  }
  2059  
  2060  func dedup(a []string) string {
  2061  	if len(a) == 0 {
  2062  		return ""
  2063  	}
  2064  	m := map[string]int{}
  2065  	for _, s := range a {
  2066  		m[s] = m[s] + 1
  2067  	}
  2068  	var b bytes.Buffer
  2069  	for _, s := range a {
  2070  		if _, ok := m[s]; ok {
  2071  			b.WriteString(s)
  2072  			b.WriteRune('\n')
  2073  			delete(m, s)
  2074  		}
  2075  	}
  2076  	return b.String()
  2077  }
  2078  
  2079  func run(r Retryer, t Failer, f func(r *R)) {
  2080  	rr := &R{}
  2081  	fail := func() {
  2082  		out := dedup(rr.output)
  2083  		if out != "" {
  2084  			t.Log(out)
  2085  		}
  2086  		t.FailNow()
  2087  	}
  2088  	for r.NextOr(fail) {
  2089  		var wg sync.WaitGroup
  2090  		wg.Add(1)
  2091  		go func() {
  2092  			defer wg.Done()
  2093  			f(rr)
  2094  		}()
  2095  		wg.Wait()
  2096  		if rr.fail {
  2097  			rr.fail = false
  2098  			continue
  2099  		}
  2100  		break
  2101  	}
  2102  }
  2103  
  2104  // DefaultFailer provides default retry.Run() behavior for unit tests.
  2105  func DefaultFailer() *Timer {
  2106  	return &Timer{Timeout: 7 * time.Second, Wait: 25 * time.Millisecond}
  2107  }
  2108  
  2109  // TwoSeconds repeats an operation for two seconds and waits 25ms in between.
  2110  func TwoSeconds() *Timer {
  2111  	return &Timer{Timeout: 2 * time.Second, Wait: 25 * time.Millisecond}
  2112  }
  2113  
  2114  // ThreeTimes repeats an operation three times and waits 25ms in between.
  2115  func ThreeTimes() *Counter {
  2116  	return &Counter{Count: 3, Wait: 25 * time.Millisecond}
  2117  }
  2118  
  2119  // Retryer provides an interface for repeating operations
  2120  // until they succeed or an exit condition is met.
  2121  type Retryer interface {
  2122  	// NextOr returns true if the operation should be repeated.
  2123  	// Otherwise, it calls fail and returns false.
  2124  	NextOr(fail func()) bool
  2125  }
  2126  
  2127  // Counter repeats an operation a given number of
  2128  // times and waits between subsequent operations.
  2129  type Counter struct {
  2130  	Count int
  2131  	Wait  time.Duration
  2132  
  2133  	count int
  2134  }
  2135  
  2136  func (r *Counter) NextOr(fail func()) bool {
  2137  	if r.count == r.Count {
  2138  		fail()
  2139  		return false
  2140  	}
  2141  	if r.count > 0 {
  2142  		time.Sleep(r.Wait)
  2143  	}
  2144  	r.count++
  2145  	return true
  2146  }
  2147  
  2148  // Timer repeats an operation for a given amount
  2149  // of time and waits between subsequent operations.
  2150  type Timer struct {
  2151  	Timeout time.Duration
  2152  	Wait    time.Duration
  2153  
  2154  	// stop is the timeout deadline.
  2155  	// Set on the first invocation of Next().
  2156  	stop time.Time
  2157  }
  2158  
  2159  func (r *Timer) NextOr(fail func()) bool {
  2160  	if r.stop.IsZero() {
  2161  		r.stop = time.Now().Add(r.Timeout)
  2162  		return true
  2163  	}
  2164  	if time.Now().After(r.stop) {
  2165  		fail()
  2166  		return false
  2167  	}
  2168  	time.Sleep(r.Wait)
  2169  	return true
  2170  }
  2171  
  2172  // delta defines the time band a test run should complete in.
  2173  var delta = 25 * time.Millisecond
  2174  
  2175  func TestRetryer(t *testing.T) {
  2176  	tests := []struct {
  2177  		desc string
  2178  		r    Retryer
  2179  	}{
  2180  		{"counter", &Counter{Count: 3, Wait: 100 * time.Millisecond}},
  2181  		{"timer", &Timer{Timeout: 200 * time.Millisecond, Wait: 100 * time.Millisecond}},
  2182  	}
  2183  
  2184  	for _, tt := range tests {
  2185  		t.Run(tt.desc, func(t *testing.T) {
  2186  			var iters, fails int
  2187  			fail := func() { fails++ }
  2188  			start := time.Now()
  2189  			for tt.r.NextOr(fail) {
  2190  				iters++
  2191  			}
  2192  			dur := time.Since(start)
  2193  			if got, want := iters, 3; got != want {
  2194  				t.Fatalf("got %d retries want %d", got, want)
  2195  			}
  2196  			if got, want := fails, 1; got != want {
  2197  				t.Fatalf("got %d FailNow calls want %d", got, want)
  2198  			}
  2199  			// since the first iteration happens immediately
  2200  			// the retryer waits only twice for three iterations.
  2201  			// order of events: (true, (wait) true, (wait) true, false)
  2202  			if got, want := dur, 200*time.Millisecond; got < (want-delta) || got > (want+delta) {
  2203  				t.Fatalf("loop took %v want %v (+/- %v)", got, want, delta)
  2204  			}
  2205  		})
  2206  	}
  2207  }
  2208  
  2209  func TestMemberlist_LocalNode(t *testing.T) {
  2210  	m, err := memberlist.Create(memberlist.DefaultWANConfig())
  2211  	require.NoError(t, err)
  2212  	defer m.Shutdown()
  2213  	require.NotNil(t, m.LocalNode())
  2214  }
  2215  
  2216  func TestMemberlist_SendBestEffort(t *testing.T) {
  2217  	m := GetMemberlist(t, nil)
  2218  	defer m.Shutdown()
  2219  	err := m.SendBestEffort(&memberlist.Node{
  2220  		Name: "testNode",
  2221  		Addr: "127.0.0.1",
  2222  		Port: 7946,
  2223  	}, []byte("test message"))
  2224  	require.NoError(t, err)
  2225  }
  2226  
  2227  // userMsgHeader is used to encapsulate a userMsg
  2228  type userMsgHeader struct {
  2229  	UserMsgLen int // Encodes the byte lengh of user state
  2230  }
  2231  
  2232  func TestMemberlist_SendReliable(t *testing.T) {
  2233  	node := &memberlist.Node{
  2234  		Name: "testNode",
  2235  		Addr: "127.0.0.1",
  2236  		Port: 7946,
  2237  	}
  2238  	ctrl := gomock.NewController(t)
  2239  	defer ctrl.Finish()
  2240  
  2241  	//bufConn := bytes.NewBuffer(nil)
  2242  	//err := bufConn.WriteByte(byte(8))
  2243  	//require.NoError(t, err)
  2244  	//
  2245  	//msg := []byte("test message")
  2246  	//header := userMsgHeader{UserMsgLen: len(msg)}
  2247  	//hd := codec.MsgpackHandle{}
  2248  	//enc := codec.NewEncoder(bufConn, &hd)
  2249  	//err = enc.Encode(&header)
  2250  	//require.NoError(t, err)
  2251  	//_, err = bufConn.Write(msg)
  2252  	//require.NoError(t, err)
  2253  
  2254  	conn := memmock.NewMockConn(ctrl)
  2255  	conn.
  2256  		EXPECT().
  2257  		Write(gomock.Any()).
  2258  		AnyTimes().
  2259  		Return(26, nil)
  2260  	conn.
  2261  		EXPECT().
  2262  		Close().
  2263  		AnyTimes().
  2264  		Return(nil)
  2265  
  2266  	nat := memmock.NewMockNodeAwareTransport(ctrl)
  2267  	nat.
  2268  		EXPECT().
  2269  		DialAddressTimeout(node.FullAddress(), gomock.Any()).
  2270  		AnyTimes().
  2271  		Return(conn, nil)
  2272  	nat.
  2273  		EXPECT().
  2274  		FinalAdvertiseAddr(gomock.Any(), gomock.Any()).
  2275  		AnyTimes().
  2276  		Return("localhost", 7946, nil)
  2277  	nat.
  2278  		EXPECT().
  2279  		PacketCh().
  2280  		AnyTimes().
  2281  		Return(make(chan *memberlist.Packet))
  2282  	nat.
  2283  		EXPECT().
  2284  		StreamCh().
  2285  		AnyTimes().
  2286  		Return(make(<-chan net.Conn))
  2287  	nat.
  2288  		EXPECT().
  2289  		Shutdown().
  2290  		AnyTimes().
  2291  		Return(nil)
  2292  
  2293  	m := GetMemberlist(t, func(c *memberlist.Config) {
  2294  		c.Transport = nat
  2295  		c.EnableCompression = false
  2296  	})
  2297  	defer m.Shutdown()
  2298  	err := m.SendReliable(node, []byte("test message"))
  2299  	require.NoError(t, err)
  2300  }
  2301  
  2302  func TestMemberlist_SendReliable_Fail(t *testing.T) {
  2303  	m := GetMemberlist(t, nil)
  2304  	defer m.Shutdown()
  2305  	err := m.SendReliable(&memberlist.Node{
  2306  		Name: "testNode",
  2307  		Addr: "127.0.0.1",
  2308  		Port: 7946,
  2309  	}, []byte("test message"))
  2310  	require.Error(t, err)
  2311  }
  2312  
  2313  func TestMemberlist_SendReliable_Fail2(t *testing.T) {
  2314  	node := &memberlist.Node{
  2315  		Name: "testNode",
  2316  		Addr: "127.0.0.1",
  2317  		Port: 7946,
  2318  	}
  2319  	ctrl := gomock.NewController(t)
  2320  	defer ctrl.Finish()
  2321  	conn := memmock.NewMockConn(ctrl)
  2322  	conn.
  2323  		EXPECT().
  2324  		Write(gomock.Any()).
  2325  		AnyTimes().
  2326  		Return(12, nil)
  2327  	conn.
  2328  		EXPECT().
  2329  		Close().
  2330  		AnyTimes().
  2331  		Return(nil)
  2332  
  2333  	nat := memmock.NewMockNodeAwareTransport(ctrl)
  2334  	nat.
  2335  		EXPECT().
  2336  		DialAddressTimeout(node.FullAddress(), gomock.Any()).
  2337  		AnyTimes().
  2338  		Return(conn, nil)
  2339  	nat.
  2340  		EXPECT().
  2341  		FinalAdvertiseAddr(gomock.Any(), gomock.Any()).
  2342  		AnyTimes().
  2343  		Return("localhost", 7946, nil)
  2344  	nat.
  2345  		EXPECT().
  2346  		PacketCh().
  2347  		AnyTimes().
  2348  		Return(make(chan *memberlist.Packet))
  2349  	nat.
  2350  		EXPECT().
  2351  		StreamCh().
  2352  		AnyTimes().
  2353  		Return(make(<-chan net.Conn))
  2354  	nat.
  2355  		EXPECT().
  2356  		Shutdown().
  2357  		AnyTimes().
  2358  		Return(nil)
  2359  
  2360  	m := GetMemberlist(t, func(c *memberlist.Config) {
  2361  		c.Transport = nat
  2362  	})
  2363  	defer m.Shutdown()
  2364  
  2365  	err := m.SendReliable(node, []byte("test message"))
  2366  	require.Error(t, err)
  2367  }