summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/hashicorp/memberlist
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/hashicorp/memberlist')
-rw-r--r--vendor/github.com/hashicorp/memberlist/awareness_test.go41
-rw-r--r--vendor/github.com/hashicorp/memberlist/broadcast_test.go27
-rw-r--r--vendor/github.com/hashicorp/memberlist/integ_test.go89
-rw-r--r--vendor/github.com/hashicorp/memberlist/keyring_test.go154
-rw-r--r--vendor/github.com/hashicorp/memberlist/logging_test.go47
-rw-r--r--vendor/github.com/hashicorp/memberlist/memberlist_test.go1545
-rw-r--r--vendor/github.com/hashicorp/memberlist/net_test.go814
-rw-r--r--vendor/github.com/hashicorp/memberlist/queue_test.go172
-rw-r--r--vendor/github.com/hashicorp/memberlist/security_test.go70
-rw-r--r--vendor/github.com/hashicorp/memberlist/state_test.go1900
-rw-r--r--vendor/github.com/hashicorp/memberlist/suspicion_test.go198
-rwxr-xr-xvendor/github.com/hashicorp/memberlist/test/setup_subnet.sh28
-rw-r--r--vendor/github.com/hashicorp/memberlist/transport_test.go124
-rw-r--r--vendor/github.com/hashicorp/memberlist/util_test.go358
14 files changed, 0 insertions, 5567 deletions
diff --git a/vendor/github.com/hashicorp/memberlist/awareness_test.go b/vendor/github.com/hashicorp/memberlist/awareness_test.go
deleted file mode 100644
index c6ade10af..000000000
--- a/vendor/github.com/hashicorp/memberlist/awareness_test.go
+++ /dev/null
@@ -1,41 +0,0 @@
-package memberlist
-
-import (
- "testing"
- "time"
-)
-
-func TestAwareness(t *testing.T) {
- cases := []struct {
- delta int
- score int
- timeout time.Duration
- }{
- {0, 0, 1 * time.Second},
- {-1, 0, 1 * time.Second},
- {-10, 0, 1 * time.Second},
- {1, 1, 2 * time.Second},
- {-1, 0, 1 * time.Second},
- {10, 7, 8 * time.Second},
- {-1, 6, 7 * time.Second},
- {-1, 5, 6 * time.Second},
- {-1, 4, 5 * time.Second},
- {-1, 3, 4 * time.Second},
- {-1, 2, 3 * time.Second},
- {-1, 1, 2 * time.Second},
- {-1, 0, 1 * time.Second},
- {-1, 0, 1 * time.Second},
- }
-
- a := newAwareness(8)
- for i, c := range cases {
- a.ApplyDelta(c.delta)
- if a.GetHealthScore() != c.score {
- t.Errorf("case %d: score mismatch %d != %d", i, a.score, c.score)
- }
- if timeout := a.ScaleTimeout(1 * time.Second); timeout != c.timeout {
- t.Errorf("case %d: scaled timeout mismatch %9.6f != %9.6f",
- i, timeout.Seconds(), c.timeout.Seconds())
- }
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/broadcast_test.go b/vendor/github.com/hashicorp/memberlist/broadcast_test.go
deleted file mode 100644
index c6a7302cc..000000000
--- a/vendor/github.com/hashicorp/memberlist/broadcast_test.go
+++ /dev/null
@@ -1,27 +0,0 @@
-package memberlist
-
-import (
- "reflect"
- "testing"
-)
-
-func TestMemberlistBroadcast_Invalidates(t *testing.T) {
- m1 := &memberlistBroadcast{"test", nil, nil}
- m2 := &memberlistBroadcast{"foo", nil, nil}
-
- if m1.Invalidates(m2) || m2.Invalidates(m1) {
- t.Fatalf("unexpected invalidation")
- }
-
- if !m1.Invalidates(m1) {
- t.Fatalf("expected invalidation")
- }
-}
-
-func TestMemberlistBroadcast_Message(t *testing.T) {
- m1 := &memberlistBroadcast{"test", []byte("test"), nil}
- msg := m1.Message()
- if !reflect.DeepEqual(msg, []byte("test")) {
- t.Fatalf("messages do not match")
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/integ_test.go b/vendor/github.com/hashicorp/memberlist/integ_test.go
deleted file mode 100644
index f519c6baa..000000000
--- a/vendor/github.com/hashicorp/memberlist/integ_test.go
+++ /dev/null
@@ -1,89 +0,0 @@
-package memberlist
-
-import (
- "fmt"
- "log"
- "os"
- "testing"
- "time"
-)
-
-// CheckInteg will skip a test if integration testing is not enabled.
-func CheckInteg(t *testing.T) {
- if !IsInteg() {
- t.SkipNow()
- }
-}
-
-// IsInteg returns a boolean telling you if we're in integ testing mode.
-func IsInteg() bool {
- return os.Getenv("INTEG_TESTS") != ""
-}
-
-// Tests the memberlist by creating a cluster of 100 nodes
-// and checking that we get strong convergence of changes.
-func TestMemberlist_Integ(t *testing.T) {
- CheckInteg(t)
-
- num := 16
- var members []*Memberlist
-
- secret := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
- eventCh := make(chan NodeEvent, num)
-
- addr := "127.0.0.1"
- for i := 0; i < num; i++ {
- c := DefaultLANConfig()
- c.Name = fmt.Sprintf("%s:%d", addr, 12345+i)
- c.BindAddr = addr
- c.BindPort = 12345 + i
- c.ProbeInterval = 20 * time.Millisecond
- c.ProbeTimeout = 100 * time.Millisecond
- c.GossipInterval = 20 * time.Millisecond
- c.PushPullInterval = 200 * time.Millisecond
- c.SecretKey = secret
-
- if i == 0 {
- c.Events = &ChannelEventDelegate{eventCh}
- }
-
- m, err := Create(c)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- members = append(members, m)
- defer m.Shutdown()
-
- if i > 0 {
- last := members[i-1]
- num, err := m.Join([]string{last.config.Name})
- if num == 0 || err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- }
- }
-
- // Wait and print debug info
- breakTimer := time.After(250 * time.Millisecond)
-WAIT:
- for {
- select {
- case e := <-eventCh:
- if e.Event == NodeJoin {
- log.Printf("[DEBUG] Node join: %v (%d)", *e.Node, members[0].NumMembers())
- } else {
- log.Printf("[DEBUG] Node leave: %v (%d)", *e.Node, members[0].NumMembers())
- }
- case <-breakTimer:
- break WAIT
- }
- }
-
- for idx, m := range members {
- got := m.NumMembers()
- if got != num {
- t.Errorf("bad num members at idx %d. Expected %d. Got %d.",
- idx, num, got)
- }
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/keyring_test.go b/vendor/github.com/hashicorp/memberlist/keyring_test.go
deleted file mode 100644
index eec699fd0..000000000
--- a/vendor/github.com/hashicorp/memberlist/keyring_test.go
+++ /dev/null
@@ -1,154 +0,0 @@
-package memberlist
-
-import (
- "bytes"
- "testing"
-)
-
-var TestKeys [][]byte = [][]byte{
- []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
- []byte{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0},
- []byte{8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3, 4, 5, 6, 7},
-}
-
-func TestKeyring_EmptyRing(t *testing.T) {
- // Keyrings can be created with no encryption keys (disabled encryption)
- keyring, err := NewKeyring(nil, nil)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- keys := keyring.GetKeys()
- if len(keys) != 0 {
- t.Fatalf("Expected 0 keys but have %d", len(keys))
- }
-}
-
-func TestKeyring_PrimaryOnly(t *testing.T) {
- // Keyrings can be created using only a primary key
- keyring, err := NewKeyring(nil, TestKeys[0])
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- keys := keyring.GetKeys()
- if len(keys) != 1 {
- t.Fatalf("Expected 1 key but have %d", len(keys))
- }
-}
-
-func TestKeyring_GetPrimaryKey(t *testing.T) {
- keyring, err := NewKeyring(TestKeys, TestKeys[1])
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // GetPrimaryKey returns correct key
- primaryKey := keyring.GetPrimaryKey()
- if !bytes.Equal(primaryKey, TestKeys[1]) {
- t.Fatalf("Unexpected primary key: %v", primaryKey)
- }
-}
-
-func TestKeyring_AddRemoveUse(t *testing.T) {
- keyring, err := NewKeyring(nil, TestKeys[1])
- if err != nil {
- t.Fatalf("err :%s", err)
- }
-
- // Use non-existent key throws error
- if err := keyring.UseKey(TestKeys[2]); err == nil {
- t.Fatalf("Expected key not installed error")
- }
-
- // Add key to ring
- if err := keyring.AddKey(TestKeys[2]); err != nil {
- t.Fatalf("err: %s", err)
- }
-
- keys := keyring.GetKeys()
- if !bytes.Equal(keys[0], TestKeys[1]) {
- t.Fatalf("Unexpected primary key change")
- }
-
- if len(keys) != 2 {
- t.Fatalf("Expected 2 keys but have %d", len(keys))
- }
-
- // Use key that exists should succeed
- if err := keyring.UseKey(TestKeys[2]); err != nil {
- t.Fatalf("err: %s", err)
- }
-
- primaryKey := keyring.GetPrimaryKey()
- if !bytes.Equal(primaryKey, TestKeys[2]) {
- t.Fatalf("Unexpected primary key: %v", primaryKey)
- }
-
- // Removing primary key should fail
- if err := keyring.RemoveKey(TestKeys[2]); err == nil {
- t.Fatalf("Expected primary key removal error")
- }
-
- // Removing non-primary key should succeed
- if err := keyring.RemoveKey(TestKeys[1]); err != nil {
- t.Fatalf("err: %s", err)
- }
-
- keys = keyring.GetKeys()
- if len(keys) != 1 {
- t.Fatalf("Expected 1 key but have %d", len(keys))
- }
-}
-
-func TestKeyRing_MultiKeyEncryptDecrypt(t *testing.T) {
- plaintext := []byte("this is a plain text message")
- extra := []byte("random data")
-
- keyring, err := NewKeyring(TestKeys, TestKeys[0])
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // First encrypt using the primary key and make sure we can decrypt
- var buf bytes.Buffer
- err = encryptPayload(1, TestKeys[0], plaintext, extra, &buf)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- msg, err := decryptPayload(keyring.GetKeys(), buf.Bytes(), extra)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- if !bytes.Equal(msg, plaintext) {
- t.Fatalf("bad: %v", msg)
- }
-
- // Now encrypt with a secondary key and try decrypting again.
- buf.Reset()
- err = encryptPayload(1, TestKeys[2], plaintext, extra, &buf)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- msg, err = decryptPayload(keyring.GetKeys(), buf.Bytes(), extra)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- if !bytes.Equal(msg, plaintext) {
- t.Fatalf("bad: %v", msg)
- }
-
- // Remove a key from the ring, and then try decrypting again
- if err := keyring.RemoveKey(TestKeys[2]); err != nil {
- t.Fatalf("err: %s", err)
- }
-
- msg, err = decryptPayload(keyring.GetKeys(), buf.Bytes(), extra)
- if err == nil {
- t.Fatalf("Expected no keys to decrypt message")
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/logging_test.go b/vendor/github.com/hashicorp/memberlist/logging_test.go
deleted file mode 100644
index cc04b8a91..000000000
--- a/vendor/github.com/hashicorp/memberlist/logging_test.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package memberlist
-
-import (
- "fmt"
- "net"
- "testing"
-)
-
-func TestLogging_Address(t *testing.T) {
- s := LogAddress(nil)
- if s != "from=<unknown address>" {
- t.Fatalf("bad: %s", s)
- }
-
- addr, err := net.ResolveIPAddr("ip4", "127.0.0.1")
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- s = LogAddress(addr)
- if s != "from=127.0.0.1" {
- t.Fatalf("bad: %s", s)
- }
-}
-
-func TestLogging_Conn(t *testing.T) {
- s := LogConn(nil)
- if s != "from=<unknown address>" {
- t.Fatalf("bad: %s", s)
- }
-
- ln, err := net.Listen("tcp", ":0")
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- conn, err := net.Dial("tcp", ln.Addr().String())
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- defer conn.Close()
-
- s = LogConn(conn)
- if s != fmt.Sprintf("from=%s", conn.RemoteAddr().String()) {
- t.Fatalf("bad: %s", s)
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/memberlist_test.go b/vendor/github.com/hashicorp/memberlist/memberlist_test.go
deleted file mode 100644
index ee2fc5d52..000000000
--- a/vendor/github.com/hashicorp/memberlist/memberlist_test.go
+++ /dev/null
@@ -1,1545 +0,0 @@
-package memberlist
-
-import (
- "bytes"
- "fmt"
- "io/ioutil"
- "log"
- "net"
- "os"
- "reflect"
- "strings"
- "sync"
- "testing"
- "time"
-
- "github.com/miekg/dns"
-)
-
-var bindLock sync.Mutex
-var bindNum byte = 10
-
-func getBindAddr() net.IP {
- bindLock.Lock()
- defer bindLock.Unlock()
-
- result := net.IPv4(127, 0, 0, bindNum)
- bindNum++
- if bindNum > 255 {
- bindNum = 10
- }
-
- return result
-}
-
-func testConfig() *Config {
- config := DefaultLANConfig()
- config.BindAddr = getBindAddr().String()
- config.Name = config.BindAddr
- return config
-}
-
-func yield() {
- time.Sleep(5 * time.Millisecond)
-}
-
-type MockDelegate struct {
- meta []byte
- msgs [][]byte
- broadcasts [][]byte
- state []byte
- remoteState []byte
-}
-
-func (m *MockDelegate) NodeMeta(limit int) []byte {
- return m.meta
-}
-
-func (m *MockDelegate) NotifyMsg(msg []byte) {
- cp := make([]byte, len(msg))
- copy(cp, msg)
- m.msgs = append(m.msgs, cp)
-}
-
-func (m *MockDelegate) GetBroadcasts(overhead, limit int) [][]byte {
- b := m.broadcasts
- m.broadcasts = nil
- return b
-}
-
-func (m *MockDelegate) LocalState(join bool) []byte {
- return m.state
-}
-
-func (m *MockDelegate) MergeRemoteState(s []byte, join bool) {
- m.remoteState = s
-}
-
-// Returns a new Memberlist on an open port by trying a range of port numbers
-// until something sticks.
-func NewMemberlistOnOpenPort(c *Config) (*Memberlist, error) {
- c.BindPort = 0
- return newMemberlist(c)
-}
-
-func GetMemberlistDelegate(t *testing.T) (*Memberlist, *MockDelegate) {
- d := &MockDelegate{}
-
- c := testConfig()
- c.Delegate = d
-
- m, err := NewMemberlistOnOpenPort(c)
- if err != nil {
- t.Fatalf("failed to start: %v", err)
- return nil, nil
- }
-
- return m, d
-}
-
-func GetMemberlist(t *testing.T) *Memberlist {
- c := testConfig()
-
- m, err := NewMemberlistOnOpenPort(c)
- if err != nil {
- t.Fatalf("failed to start: %v", err)
- return nil
- }
-
- return m
-}
-
-func TestDefaultLANConfig_protocolVersion(t *testing.T) {
- c := DefaultLANConfig()
- if c.ProtocolVersion != ProtocolVersion2Compatible {
- t.Fatalf("should be max: %d", c.ProtocolVersion)
- }
-}
-
-func TestCreate_protocolVersion(t *testing.T) {
- cases := []struct {
- version uint8
- err bool
- }{
- {ProtocolVersionMin, false},
- {ProtocolVersionMax, false},
- // TODO(mitchellh): uncommon when we're over 0
- //{ProtocolVersionMin - 1, true},
- {ProtocolVersionMax + 1, true},
- {ProtocolVersionMax - 1, false},
- }
-
- for _, tc := range cases {
- c := DefaultLANConfig()
- c.BindAddr = getBindAddr().String()
- c.ProtocolVersion = tc.version
- m, err := Create(c)
- if tc.err && err == nil {
- t.Errorf("Should've failed with version: %d", tc.version)
- } else if !tc.err && err != nil {
- t.Errorf("Version '%d' error: %s", tc.version, err)
- }
-
- if err == nil {
- m.Shutdown()
- }
- }
-}
-
-func TestCreate_secretKey(t *testing.T) {
- cases := []struct {
- key []byte
- err bool
- }{
- {make([]byte, 0), false},
- {[]byte("abc"), true},
- {make([]byte, 16), false},
- {make([]byte, 38), true},
- }
-
- for _, tc := range cases {
- c := DefaultLANConfig()
- c.BindAddr = getBindAddr().String()
- c.SecretKey = tc.key
- m, err := Create(c)
- if tc.err && err == nil {
- t.Errorf("Should've failed with key: %#v", tc.key)
- } else if !tc.err && err != nil {
- t.Errorf("Key '%#v' error: %s", tc.key, err)
- }
-
- if err == nil {
- m.Shutdown()
- }
- }
-}
-
-func TestCreate_secretKeyEmpty(t *testing.T) {
- c := DefaultLANConfig()
- c.BindAddr = getBindAddr().String()
- c.SecretKey = make([]byte, 0)
- m, err := Create(c)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m.Shutdown()
-
- if m.config.EncryptionEnabled() {
- t.Fatalf("Expected encryption to be disabled")
- }
-}
-
-func TestCreate_keyringOnly(t *testing.T) {
- c := DefaultLANConfig()
- c.BindAddr = getBindAddr().String()
- keyring, err := NewKeyring(nil, make([]byte, 16))
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- c.Keyring = keyring
-
- m, err := Create(c)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m.Shutdown()
-
- if !m.config.EncryptionEnabled() {
- t.Fatalf("Expected encryption to be enabled")
- }
-}
-
-func TestCreate_keyringAndSecretKey(t *testing.T) {
- c := DefaultLANConfig()
- c.BindAddr = getBindAddr().String()
- keyring, err := NewKeyring(nil, make([]byte, 16))
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- c.Keyring = keyring
- c.SecretKey = []byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
-
- m, err := Create(c)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m.Shutdown()
-
- if !m.config.EncryptionEnabled() {
- t.Fatalf("Expected encryption to be enabled")
- }
-
- ringKeys := c.Keyring.GetKeys()
- if !bytes.Equal(c.SecretKey, ringKeys[0]) {
- t.Fatalf("Unexpected primary key %v", ringKeys[0])
- }
-}
-
-func TestCreate_invalidLoggerSettings(t *testing.T) {
- c := DefaultLANConfig()
- c.BindAddr = getBindAddr().String()
- c.Logger = log.New(ioutil.Discard, "", log.LstdFlags)
- c.LogOutput = ioutil.Discard
-
- _, err := Create(c)
- if err == nil {
- t.Fatal("Memberlist should not allow both LogOutput and Logger to be set, but it did not raise an error")
- }
-}
-
-func TestCreate(t *testing.T) {
- c := testConfig()
- c.ProtocolVersion = ProtocolVersionMin
- c.DelegateProtocolVersion = 13
- c.DelegateProtocolMin = 12
- c.DelegateProtocolMax = 24
-
- m, err := Create(c)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m.Shutdown()
-
- yield()
-
- members := m.Members()
- if len(members) != 1 {
- t.Fatalf("bad number of members")
- }
-
- if members[0].PMin != ProtocolVersionMin {
- t.Fatalf("bad: %#v", members[0])
- }
-
- if members[0].PMax != ProtocolVersionMax {
- t.Fatalf("bad: %#v", members[0])
- }
-
- if members[0].PCur != c.ProtocolVersion {
- t.Fatalf("bad: %#v", members[0])
- }
-
- if members[0].DMin != c.DelegateProtocolMin {
- t.Fatalf("bad: %#v", members[0])
- }
-
- if members[0].DMax != c.DelegateProtocolMax {
- t.Fatalf("bad: %#v", members[0])
- }
-
- if members[0].DCur != c.DelegateProtocolVersion {
- t.Fatalf("bad: %#v", members[0])
- }
-}
-
-func TestMemberList_CreateShutdown(t *testing.T) {
- m := GetMemberlist(t)
- m.schedule()
- if err := m.Shutdown(); err != nil {
- t.Fatalf("failed to shutdown %v", err)
- }
-}
-
-func TestMemberList_ResolveAddr(t *testing.T) {
- m := GetMemberlist(t)
- if _, err := m.resolveAddr("localhost"); err != nil {
- t.Fatalf("Could not resolve localhost: %s", err)
- }
- if _, err := m.resolveAddr("[::1]:80"); err != nil {
- t.Fatalf("Could not understand ipv6 pair: %s", err)
- }
- if _, err := m.resolveAddr("[::1]"); err != nil {
- t.Fatalf("Could not understand ipv6 non-pair")
- }
- if _, err := m.resolveAddr(":80"); err == nil {
- t.Fatalf("Understood hostless port")
- }
- if _, err := m.resolveAddr("localhost:80"); err != nil {
- t.Fatalf("Could not understand hostname port combo: %s", err)
- }
- if _, err := m.resolveAddr("localhost:80000"); err == nil {
- t.Fatalf("Understood too high port")
- }
- if _, err := m.resolveAddr("127.0.0.1:80"); err != nil {
- t.Fatalf("Could not understand hostname port combo: %s", err)
- }
- if _, err := m.resolveAddr("[2001:db8:a0b:12f0::1]:80"); err != nil {
- t.Fatalf("Could not understand hostname port combo: %s", err)
- }
- if _, err := m.resolveAddr("127.0.0.1"); err != nil {
- t.Fatalf("Could not understand IPv4 only %s", err)
- }
- if _, err := m.resolveAddr("[2001:db8:a0b:12f0::1]"); err != nil {
- t.Fatalf("Could not understand IPv6 only %s", err)
- }
-}
-
-type dnsHandler struct {
- t *testing.T
-}
-
-func (h dnsHandler) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
- if len(r.Question) != 1 {
- h.t.Fatalf("bad: %#v", r.Question)
- }
-
- name := "join.service.consul."
- question := r.Question[0]
- if question.Name != name || question.Qtype != dns.TypeANY {
- h.t.Fatalf("bad: %#v", question)
- }
-
- m := new(dns.Msg)
- m.SetReply(r)
- m.Authoritative = true
- m.RecursionAvailable = false
- m.Answer = append(m.Answer, &dns.A{
- Hdr: dns.RR_Header{
- Name: name,
- Rrtype: dns.TypeA,
- Class: dns.ClassINET},
- A: net.ParseIP("127.0.0.1"),
- })
- m.Answer = append(m.Answer, &dns.AAAA{
- Hdr: dns.RR_Header{
- Name: name,
- Rrtype: dns.TypeAAAA,
- Class: dns.ClassINET},
- AAAA: net.ParseIP("2001:db8:a0b:12f0::1"),
- })
- if err := w.WriteMsg(m); err != nil {
- h.t.Fatalf("err: %v", err)
- }
-}
-
-func TestMemberList_ResolveAddr_TCP_First(t *testing.T) {
- bind := "127.0.0.1:8600"
-
- var wg sync.WaitGroup
- wg.Add(1)
- server := &dns.Server{
- Addr: bind,
- Handler: dnsHandler{t},
- Net: "tcp",
- NotifyStartedFunc: wg.Done,
- }
- defer server.Shutdown()
-
- go func() {
- if err := server.ListenAndServe(); err != nil && !strings.Contains(err.Error(), "use of closed network connection") {
- t.Fatalf("err: %v", err)
- }
- }()
- wg.Wait()
-
- tmpFile, err := ioutil.TempFile("", "")
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- defer os.Remove(tmpFile.Name())
-
- content := []byte(fmt.Sprintf("nameserver %s", bind))
- if _, err := tmpFile.Write(content); err != nil {
- t.Fatalf("err: %v", err)
- }
- if err := tmpFile.Close(); err != nil {
- t.Fatalf("err: %v", err)
- }
-
- m := GetMemberlist(t)
- m.config.DNSConfigPath = tmpFile.Name()
- m.setAlive()
- m.schedule()
- defer m.Shutdown()
-
- // Try with and without the trailing dot.
- hosts := []string{
- "join.service.consul.",
- "join.service.consul",
- }
- for _, host := range hosts {
- ips, err := m.resolveAddr(host)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- port := uint16(m.config.BindPort)
- expected := []ipPort{
- ipPort{net.ParseIP("127.0.0.1"), port},
- ipPort{net.ParseIP("2001:db8:a0b:12f0::1"), port},
- }
- if !reflect.DeepEqual(ips, expected) {
- t.Fatalf("bad: %#v expected: %#v", ips, expected)
- }
- }
-}
-
-func TestMemberList_Members(t *testing.T) {
- n1 := &Node{Name: "test"}
- n2 := &Node{Name: "test2"}
- n3 := &Node{Name: "test3"}
-
- m := &Memberlist{}
- nodes := []*nodeState{
- &nodeState{Node: *n1, State: stateAlive},
- &nodeState{Node: *n2, State: stateDead},
- &nodeState{Node: *n3, State: stateSuspect},
- }
- m.nodes = nodes
-
- members := m.Members()
- if !reflect.DeepEqual(members, []*Node{n1, n3}) {
- t.Fatalf("bad members")
- }
-}
-
-func TestMemberlist_Join(t *testing.T) {
- m1 := GetMemberlist(t)
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- // Create a second node
- c := DefaultLANConfig()
- addr1 := getBindAddr()
- c.Name = addr1.String()
- c.BindAddr = addr1.String()
- c.BindPort = m1.config.BindPort
-
- m2, err := Create(c)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m2.Shutdown()
-
- num, err := m2.Join([]string{m1.config.BindAddr})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- // Check the hosts
- if len(m2.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
- if m2.estNumNodes() != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
-}
-
-type CustomMergeDelegate struct {
- invoked bool
-}
-
-func (c *CustomMergeDelegate) NotifyMerge(nodes []*Node) error {
- log.Printf("Cancel merge")
- c.invoked = true
- return fmt.Errorf("Custom merge canceled")
-}
-
-func TestMemberlist_Join_Cancel(t *testing.T) {
- m1 := GetMemberlist(t)
- merge1 := &CustomMergeDelegate{}
- m1.config.Merge = merge1
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- // Create a second node
- c := DefaultLANConfig()
- addr1 := getBindAddr()
- c.Name = addr1.String()
- c.BindAddr = addr1.String()
- c.BindPort = m1.config.BindPort
-
- m2, err := Create(c)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- merge2 := &CustomMergeDelegate{}
- m2.config.Merge = merge2
- defer m2.Shutdown()
-
- num, err := m2.Join([]string{m1.config.BindAddr})
- if num != 0 {
- t.Fatalf("unexpected 0: %d", num)
- }
- if !strings.Contains(err.Error(), "Custom merge canceled") {
- t.Fatalf("unexpected err: %s", err)
- }
-
- // Check the hosts
- if len(m2.Members()) != 1 {
- t.Fatalf("should have 1 nodes! %v", m2.Members())
- }
- if len(m1.Members()) != 1 {
- t.Fatalf("should have 1 nodes! %v", m1.Members())
- }
-
- // Check delegate invocation
- if !merge1.invoked {
- t.Fatalf("should invoke delegate")
- }
- if !merge2.invoked {
- t.Fatalf("should invoke delegate")
- }
-}
-
-type CustomAliveDelegate struct {
- Ignore string
- count int
-}
-
-func (c *CustomAliveDelegate) NotifyAlive(peer *Node) error {
- c.count++
- if peer.Name == c.Ignore {
- return nil
- }
- log.Printf("Cancel alive")
- return fmt.Errorf("Custom alive canceled")
-}
-
-func TestMemberlist_Join_Cancel_Passive(t *testing.T) {
- m1 := GetMemberlist(t)
- alive1 := &CustomAliveDelegate{
- Ignore: m1.config.Name,
- }
- m1.config.Alive = alive1
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- // Create a second node
- c := DefaultLANConfig()
- addr1 := getBindAddr()
- c.Name = addr1.String()
- c.BindAddr = addr1.String()
- c.BindPort = m1.config.BindPort
-
- m2, err := Create(c)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- alive2 := &CustomAliveDelegate{
- Ignore: c.Name,
- }
- m2.config.Alive = alive2
- defer m2.Shutdown()
-
- num, err := m2.Join([]string{m1.config.BindAddr})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- // Check the hosts
- if len(m2.Members()) != 1 {
- t.Fatalf("should have 1 nodes! %v", m2.Members())
- }
- if len(m1.Members()) != 1 {
- t.Fatalf("should have 1 nodes! %v", m1.Members())
- }
-
- // Check delegate invocation
- if alive1.count == 0 {
- t.Fatalf("should invoke delegate: %d", alive1.count)
- }
- if alive2.count == 0 {
- t.Fatalf("should invoke delegate: %d", alive2.count)
- }
-}
-
-func TestMemberlist_Join_protocolVersions(t *testing.T) {
- c1 := testConfig()
- c2 := testConfig()
- c3 := testConfig()
- c3.ProtocolVersion = ProtocolVersionMax
-
- m1, err := Create(c1)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m1.Shutdown()
-
- m2, err := Create(c2)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m2.Shutdown()
-
- m3, err := Create(c3)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m3.Shutdown()
-
- _, err = m1.Join([]string{c2.BindAddr})
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- yield()
-
- _, err = m1.Join([]string{c3.BindAddr})
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-}
-
-func TestMemberlist_Leave(t *testing.T) {
- m1 := GetMemberlist(t)
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- // Create a second node
- c := DefaultLANConfig()
- addr1 := getBindAddr()
- c.Name = addr1.String()
- c.BindAddr = addr1.String()
- c.BindPort = m1.config.BindPort
- c.GossipInterval = time.Millisecond
-
- m2, err := Create(c)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m2.Shutdown()
-
- num, err := m2.Join([]string{m1.config.BindAddr})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- // Check the hosts
- if len(m2.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
- if len(m1.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
-
- // Leave
- m1.Leave(time.Second)
-
- // Wait for leave
- time.Sleep(10 * time.Millisecond)
-
- // m1 should think dead
- if len(m1.Members()) != 1 {
- t.Fatalf("should have 1 node")
- }
-
- if len(m2.Members()) != 1 {
- t.Fatalf("should have 1 node")
- }
-}
-
-func TestMemberlist_JoinShutdown(t *testing.T) {
- m1 := GetMemberlist(t)
- m1.setAlive()
- m1.schedule()
-
- // Create a second node
- c := DefaultLANConfig()
- addr1 := getBindAddr()
- c.Name = addr1.String()
- c.BindAddr = addr1.String()
- c.BindPort = m1.config.BindPort
- c.ProbeInterval = time.Millisecond
- c.ProbeTimeout = 100 * time.Microsecond
- c.SuspicionMaxTimeoutMult = 1
-
- m2, err := Create(c)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m2.Shutdown()
-
- num, err := m2.Join([]string{m1.config.BindAddr})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- // Check the hosts
- if len(m2.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
-
- m1.Shutdown()
-
- time.Sleep(10 * time.Millisecond)
-
- if len(m2.Members()) != 1 {
- t.Fatalf("should have 1 nodes! %v", m2.Members())
- }
-}
-
-func TestMemberlist_delegateMeta(t *testing.T) {
- c1 := testConfig()
- c2 := testConfig()
- c1.Delegate = &MockDelegate{meta: []byte("web")}
- c2.Delegate = &MockDelegate{meta: []byte("lb")}
-
- m1, err := Create(c1)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m1.Shutdown()
-
- m2, err := Create(c2)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m2.Shutdown()
-
- _, err = m1.Join([]string{c2.BindAddr})
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- yield()
-
- var roles map[string]string
-
- // Check the roles of members of m1
- m1m := m1.Members()
- if len(m1m) != 2 {
- t.Fatalf("bad: %#v", m1m)
- }
-
- roles = make(map[string]string)
- for _, m := range m1m {
- roles[m.Name] = string(m.Meta)
- }
-
- if r := roles[c1.Name]; r != "web" {
- t.Fatalf("bad role for %s: %s", c1.Name, r)
- }
-
- if r := roles[c2.Name]; r != "lb" {
- t.Fatalf("bad role for %s: %s", c2.Name, r)
- }
-
- // Check the roles of members of m2
- m2m := m2.Members()
- if len(m2m) != 2 {
- t.Fatalf("bad: %#v", m2m)
- }
-
- roles = make(map[string]string)
- for _, m := range m2m {
- roles[m.Name] = string(m.Meta)
- }
-
- if r := roles[c1.Name]; r != "web" {
- t.Fatalf("bad role for %s: %s", c1.Name, r)
- }
-
- if r := roles[c2.Name]; r != "lb" {
- t.Fatalf("bad role for %s: %s", c2.Name, r)
- }
-}
-
-func TestMemberlist_delegateMeta_Update(t *testing.T) {
- c1 := testConfig()
- c2 := testConfig()
- mock1 := &MockDelegate{meta: []byte("web")}
- mock2 := &MockDelegate{meta: []byte("lb")}
- c1.Delegate = mock1
- c2.Delegate = mock2
-
- m1, err := Create(c1)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m1.Shutdown()
-
- m2, err := Create(c2)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m2.Shutdown()
-
- _, err = m1.Join([]string{c2.BindAddr})
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- yield()
-
- // Update the meta data roles
- mock1.meta = []byte("api")
- mock2.meta = []byte("db")
-
- m1.UpdateNode(0)
- m2.UpdateNode(0)
- yield()
-
- // Check the updates have propagated
- var roles map[string]string
-
- // Check the roles of members of m1
- m1m := m1.Members()
- if len(m1m) != 2 {
- t.Fatalf("bad: %#v", m1m)
- }
-
- roles = make(map[string]string)
- for _, m := range m1m {
- roles[m.Name] = string(m.Meta)
- }
-
- if r := roles[c1.Name]; r != "api" {
- t.Fatalf("bad role for %s: %s", c1.Name, r)
- }
-
- if r := roles[c2.Name]; r != "db" {
- t.Fatalf("bad role for %s: %s", c2.Name, r)
- }
-
- // Check the roles of members of m2
- m2m := m2.Members()
- if len(m2m) != 2 {
- t.Fatalf("bad: %#v", m2m)
- }
-
- roles = make(map[string]string)
- for _, m := range m2m {
- roles[m.Name] = string(m.Meta)
- }
-
- if r := roles[c1.Name]; r != "api" {
- t.Fatalf("bad role for %s: %s", c1.Name, r)
- }
-
- if r := roles[c2.Name]; r != "db" {
- t.Fatalf("bad role for %s: %s", c2.Name, r)
- }
-}
-
-func TestMemberlist_UserData(t *testing.T) {
- m1, d1 := GetMemberlistDelegate(t)
- d1.state = []byte("something")
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- // Create a second delegate with things to send
- d2 := &MockDelegate{}
- d2.broadcasts = [][]byte{
- []byte("test"),
- []byte("foobar"),
- }
- d2.state = []byte("my state")
-
- // Create a second node
- c := DefaultLANConfig()
- addr1 := getBindAddr()
- c.Name = addr1.String()
- c.BindAddr = addr1.String()
- c.BindPort = m1.config.BindPort
- c.GossipInterval = time.Millisecond
- c.PushPullInterval = time.Millisecond
- c.Delegate = d2
-
- m2, err := Create(c)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- num, err := m2.Join([]string{m1.config.BindAddr})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m2.Shutdown()
-
- // Check the hosts
- if m2.NumMembers() != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
-
- // Wait for a little while
- time.Sleep(3 * time.Millisecond)
-
- // Ensure we got the messages
- if len(d1.msgs) != 2 {
- t.Fatalf("should have 2 messages!")
- }
- if !reflect.DeepEqual(d1.msgs[0], []byte("test")) {
- t.Fatalf("bad msg %v", d1.msgs[0])
- }
- if !reflect.DeepEqual(d1.msgs[1], []byte("foobar")) {
- t.Fatalf("bad msg %v", d1.msgs[1])
- }
-
- // Check the push/pull state
- if !reflect.DeepEqual(d1.remoteState, []byte("my state")) {
- t.Fatalf("bad state %s", d1.remoteState)
- }
- if !reflect.DeepEqual(d2.remoteState, []byte("something")) {
- t.Fatalf("bad state %s", d2.remoteState)
- }
-}
-
-func TestMemberlist_SendTo(t *testing.T) {
- m1, d1 := GetMemberlistDelegate(t)
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- // Create a second delegate with things to send
- d2 := &MockDelegate{}
-
- // Create a second node
- c := DefaultLANConfig()
- addr1 := getBindAddr()
- c.Name = addr1.String()
- c.BindAddr = addr1.String()
- c.BindPort = m1.config.BindPort
- c.GossipInterval = time.Millisecond
- c.PushPullInterval = time.Millisecond
- c.Delegate = d2
-
- m2, err := Create(c)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m2.Shutdown()
-
- num, err := m2.Join([]string{m1.config.BindAddr})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- // Check the hosts
- if m2.NumMembers() != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
-
- // Try to do a direct send
- m2Addr := &net.UDPAddr{IP: addr1,
- Port: c.BindPort}
- if err := m1.SendTo(m2Addr, []byte("ping")); err != nil {
- t.Fatalf("err: %v", err)
- }
-
- m1Addr := &net.UDPAddr{IP: net.ParseIP(m1.config.BindAddr),
- Port: m1.config.BindPort}
- if err := m2.SendTo(m1Addr, []byte("pong")); err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Wait for a little while
- time.Sleep(3 * time.Millisecond)
-
- // Ensure we got the messages
- if len(d1.msgs) != 1 {
- t.Fatalf("should have 1 messages!")
- }
- if !reflect.DeepEqual(d1.msgs[0], []byte("pong")) {
- t.Fatalf("bad msg %v", d1.msgs[0])
- }
-
- if len(d2.msgs) != 1 {
- t.Fatalf("should have 1 messages!")
- }
- if !reflect.DeepEqual(d2.msgs[0], []byte("ping")) {
- t.Fatalf("bad msg %v", d2.msgs[0])
- }
-}
-
-func TestMemberlistProtocolVersion(t *testing.T) {
- c := DefaultLANConfig()
- c.BindAddr = getBindAddr().String()
- c.ProtocolVersion = ProtocolVersionMax
- m, err := Create(c)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m.Shutdown()
-
- result := m.ProtocolVersion()
- if result != ProtocolVersionMax {
- t.Fatalf("bad: %d", result)
- }
-}
-
-func TestMemberlist_Join_DeadNode(t *testing.T) {
- m1 := GetMemberlist(t)
- m1.config.TCPTimeout = 50 * time.Millisecond
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- // Create a second "node", which is just a TCP listener that
- // does not ever respond. This is to test our deadliens
- addr1 := getBindAddr()
- list, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr1.String(), m1.config.BindPort))
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- defer list.Close()
-
- // Ensure we don't hang forever
- timer := time.AfterFunc(100*time.Millisecond, func() {
- panic("should have timed out by now")
- })
- defer timer.Stop()
-
- num, err := m1.Join([]string{addr1.String()})
- if num != 0 {
- t.Fatalf("unexpected 0: %d", num)
- }
- if err == nil {
- t.Fatal("expect err")
- }
-}
-
-// Tests that nodes running different versions of the protocol can successfully
-// discover each other and add themselves to their respective member lists.
-func TestMemberlist_Join_Prototocol_Compatibility(t *testing.T) {
- testProtocolVersionPair := func(t *testing.T, pv1 uint8, pv2 uint8) {
- c1 := testConfig()
- c1.ProtocolVersion = pv1
- m1, err := NewMemberlistOnOpenPort(c1)
- if err != nil {
- t.Fatalf("failed to start: %v", err)
- }
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- c2 := DefaultLANConfig()
- addr1 := getBindAddr()
- c2.Name = addr1.String()
- c2.BindAddr = addr1.String()
- c2.BindPort = m1.config.BindPort
- c2.ProtocolVersion = pv2
-
- m2, err := Create(c2)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m2.Shutdown()
-
- num, err := m2.Join([]string{m1.config.BindAddr})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- // Check the hosts
- if len(m2.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
-
- // Check the hosts
- if len(m1.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m1.Members())
- }
- }
-
- testProtocolVersionPair(t, 2, 1)
- testProtocolVersionPair(t, 2, 3)
- testProtocolVersionPair(t, 3, 2)
- testProtocolVersionPair(t, 3, 1)
-}
-
-func TestMemberlist_Join_IPv6(t *testing.T) {
- // Since this binds to all interfaces we need to exclude other tests
- // from grabbing an interface.
- bindLock.Lock()
- defer bindLock.Unlock()
-
- c1 := DefaultLANConfig()
- c1.Name = "A"
- c1.BindAddr = "[::1]"
- var m1 *Memberlist
- var err error
- for i := 0; i < 100; i++ {
- c1.BindPort = 23456 + i
- m1, err = Create(c1)
- if err == nil {
- break
- }
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m1.Shutdown()
-
- // Create a second node
- c2 := DefaultLANConfig()
- c2.Name = "B"
- c2.BindAddr = "[::1]"
- var m2 *Memberlist
- for i := 0; i < 100; i++ {
- c2.BindPort = c1.BindPort + 1 + i
- m2, err = Create(c2)
- if err == nil {
- break
- }
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m2.Shutdown()
-
- num, err := m2.Join([]string{fmt.Sprintf("%s:%d", m1.config.BindAddr, 23456)})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- // Check the hosts
- if len(m2.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
-
- if len(m1.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
-}
-
-func TestAdvertiseAddr(t *testing.T) {
- c := testConfig()
- c.AdvertiseAddr = "127.0.1.100"
- c.AdvertisePort = 23456
-
- m, err := Create(c)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m.Shutdown()
-
- yield()
-
- members := m.Members()
- if len(members) != 1 {
- t.Fatalf("bad number of members")
- }
-
- if bytes.Compare(members[0].Addr, []byte{127, 0, 1, 100}) != 0 {
- t.Fatalf("bad: %#v", members[0])
- }
-
- if members[0].Port != 23456 {
- t.Fatalf("bad: %#v", members[0])
- }
-}
-
-type MockConflict struct {
- existing *Node
- other *Node
-}
-
-func (m *MockConflict) NotifyConflict(existing, other *Node) {
- m.existing = existing
- m.other = other
-}
-
-func TestMemberlist_conflictDelegate(t *testing.T) {
- c1 := testConfig()
- c2 := testConfig()
- mock := &MockConflict{}
- c1.Conflict = mock
-
- // Ensure name conflict
- c2.Name = c1.Name
-
- m1, err := Create(c1)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m1.Shutdown()
-
- m2, err := Create(c2)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m2.Shutdown()
-
- _, err = m1.Join([]string{c2.BindAddr})
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- yield()
-
- // Ensure we were notified
- if mock.existing == nil || mock.other == nil {
- t.Fatalf("should get notified")
- }
- if mock.existing.Name != mock.other.Name {
- t.Fatalf("bad: %v %v", mock.existing, mock.other)
- }
-}
-
-type MockPing struct {
- other *Node
- rtt time.Duration
- payload []byte
-}
-
-func (m *MockPing) NotifyPingComplete(other *Node, rtt time.Duration, payload []byte) {
- m.other = other
- m.rtt = rtt
- m.payload = payload
-}
-
-const DEFAULT_PAYLOAD = "whatever"
-
-func (m *MockPing) AckPayload() []byte {
- return []byte(DEFAULT_PAYLOAD)
-}
-
-func TestMemberlist_PingDelegate(t *testing.T) {
- m1 := GetMemberlist(t)
- m1.config.Ping = &MockPing{}
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- // Create a second node
- c := DefaultLANConfig()
- addr1 := getBindAddr()
- c.Name = addr1.String()
- c.BindAddr = addr1.String()
- c.BindPort = m1.config.BindPort
- c.ProbeInterval = time.Millisecond
- mock := &MockPing{}
- c.Ping = mock
-
- m2, err := Create(c)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m2.Shutdown()
-
- _, err = m2.Join([]string{m1.config.BindAddr})
- if err != nil {
- t.Fatalf("err: %s", err)
- }
-
- yield()
-
- // Ensure we were notified
- if mock.other == nil {
- t.Fatalf("should get notified")
- }
-
- if !reflect.DeepEqual(mock.other, m1.LocalNode()) {
- t.Fatalf("not notified about the correct node; expected: %+v; actual: %+v",
- m2.LocalNode(), mock.other)
- }
-
- if mock.rtt <= 0 {
- t.Fatalf("rtt should be greater than 0")
- }
-
- if bytes.Compare(mock.payload, []byte(DEFAULT_PAYLOAD)) != 0 {
- t.Fatalf("incorrect payload. expected: %v; actual: %v", []byte(DEFAULT_PAYLOAD), mock.payload)
- }
-}
-
-func TestMemberlist_EncryptedGossipTransition(t *testing.T) {
- m1 := GetMemberlist(t)
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- // Create a second node with the first stage of gossip transition settings
- conf2 := DefaultLANConfig()
- addr2 := getBindAddr()
- conf2.Name = addr2.String()
- conf2.BindAddr = addr2.String()
- conf2.BindPort = m1.config.BindPort
- conf2.GossipInterval = time.Millisecond
- conf2.SecretKey = []byte("Hi16ZXu2lNCRVwtr20khAg==")
- conf2.GossipVerifyIncoming = false
- conf2.GossipVerifyOutgoing = false
-
- m2, err := Create(conf2)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m2.Shutdown()
-
- // Join the second node. m1 has no encryption while m2 has encryption configured and
- // can receive encrypted gossip, but will not encrypt outgoing gossip.
- num, err := m2.Join([]string{m1.config.BindAddr})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- // Check the hosts
- if len(m2.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
- if m2.estNumNodes() != 2 {
- t.Fatalf("should have 2 nodes! %v", m2.Members())
- }
-
- // Leave with the first node
- m1.Leave(time.Second)
-
- // Wait for leave
- time.Sleep(10 * time.Millisecond)
-
- // Create a third node that has the second stage of gossip transition settings
- conf3 := DefaultLANConfig()
- addr3 := getBindAddr()
- conf3.Name = addr3.String()
- conf3.BindAddr = addr3.String()
- conf3.BindPort = m1.config.BindPort
- conf3.GossipInterval = time.Millisecond
- conf3.SecretKey = conf2.SecretKey
- conf3.GossipVerifyIncoming = false
-
- m3, err := Create(conf3)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m3.Shutdown()
-
- // Join the third node to the second node. At this step, both nodes have encryption
- // configured but only m3 is sending encrypted gossip.
- num, err = m3.Join([]string{m2.config.BindAddr})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- // Check the hosts
- if len(m3.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m3.Members())
-
- }
- if m3.estNumNodes() != 2 {
- t.Fatalf("should have 2 nodes! %v", m3.Members())
- }
-
- // Leave with the second node
- m2.Leave(time.Second)
-
- // Wait for leave
- time.Sleep(10 * time.Millisecond)
-
- // Create a fourth node that has the second stage of gossip transition settings
- conf4 := DefaultLANConfig()
- addr4 := getBindAddr()
- conf4.Name = addr4.String()
- conf4.BindAddr = addr4.String()
- conf4.BindPort = m3.config.BindPort
- conf4.GossipInterval = time.Millisecond
- conf4.SecretKey = conf2.SecretKey
-
- m4, err := Create(conf4)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- defer m4.Shutdown()
-
- // Join the fourth node to the third node. At this step, both m3 and m4 are speaking
- // encrypted gossip and m3 is still accepting insecure gossip.
- num, err = m4.Join([]string{m3.config.BindAddr})
- if num != 1 {
- t.Fatalf("unexpected 1: %d", num)
- }
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- // Check the hosts
- if len(m4.Members()) != 2 {
- t.Fatalf("should have 2 nodes! %v", m4.Members())
-
- }
- if m4.estNumNodes() != 2 {
- t.Fatalf("should have 2 nodes! %v", m4.Members())
- }
-}
-
-// Consul bug, rapid restart (before failure detection),
-// with an updated meta data. Should be at incarnation 1 for
-// both.
-//
-// This test is uncommented because it requires that either we
-// can rebind the socket (SO_REUSEPORT) which Go does not allow,
-// OR we must disable the address conflict checking in memberlist.
-// I just comment out that code to test this case.
-//
-//func TestMemberlist_Restart_delegateMeta_Update(t *testing.T) {
-// c1 := testConfig()
-// c2 := testConfig()
-// mock1 := &MockDelegate{meta: []byte("web")}
-// mock2 := &MockDelegate{meta: []byte("lb")}
-// c1.Delegate = mock1
-// c2.Delegate = mock2
-
-// m1, err := Create(c1)
-// if err != nil {
-// t.Fatalf("err: %s", err)
-// }
-// defer m1.Shutdown()
-
-// m2, err := Create(c2)
-// if err != nil {
-// t.Fatalf("err: %s", err)
-// }
-// defer m2.Shutdown()
-
-// _, err = m1.Join([]string{c2.BindAddr})
-// if err != nil {
-// t.Fatalf("err: %s", err)
-// }
-
-// yield()
-
-// // Recreate m1 with updated meta
-// m1.Shutdown()
-// c3 := testConfig()
-// c3.Name = c1.Name
-// c3.Delegate = mock1
-// c3.GossipInterval = time.Millisecond
-// mock1.meta = []byte("api")
-
-// m1, err = Create(c3)
-// if err != nil {
-// t.Fatalf("err: %s", err)
-// }
-// defer m1.Shutdown()
-
-// _, err = m1.Join([]string{c2.BindAddr})
-// if err != nil {
-// t.Fatalf("err: %s", err)
-// }
-
-// yield()
-// yield()
-
-// // Check the updates have propagated
-// var roles map[string]string
-
-// // Check the roles of members of m1
-// m1m := m1.Members()
-// if len(m1m) != 2 {
-// t.Fatalf("bad: %#v", m1m)
-// }
-
-// roles = make(map[string]string)
-// for _, m := range m1m {
-// roles[m.Name] = string(m.Meta)
-// }
-
-// if r := roles[c1.Name]; r != "api" {
-// t.Fatalf("bad role for %s: %s", c1.Name, r)
-// }
-
-// if r := roles[c2.Name]; r != "lb" {
-// t.Fatalf("bad role for %s: %s", c2.Name, r)
-// }
-
-// // Check the roles of members of m2
-// m2m := m2.Members()
-// if len(m2m) != 2 {
-// t.Fatalf("bad: %#v", m2m)
-// }
-
-// roles = make(map[string]string)
-// for _, m := range m2m {
-// roles[m.Name] = string(m.Meta)
-// }
-
-// if r := roles[c1.Name]; r != "api" {
-// t.Fatalf("bad role for %s: %s", c1.Name, r)
-// }
-
-// if r := roles[c2.Name]; r != "lb" {
-// t.Fatalf("bad role for %s: %s", c2.Name, r)
-// }
-//}
diff --git a/vendor/github.com/hashicorp/memberlist/net_test.go b/vendor/github.com/hashicorp/memberlist/net_test.go
deleted file mode 100644
index 860535855..000000000
--- a/vendor/github.com/hashicorp/memberlist/net_test.go
+++ /dev/null
@@ -1,814 +0,0 @@
-package memberlist
-
-import (
- "bytes"
- "encoding/binary"
- "fmt"
- "io"
- "log"
- "net"
- "reflect"
- "strings"
- "testing"
- "time"
-
- "github.com/hashicorp/go-msgpack/codec"
-)
-
-// As a regression we left this test very low-level and network-ey, even after
-// we abstracted the transport. We added some basic network-free transport tests
-// in transport_test.go to prove that we didn't hard code some network stuff
-// outside of NetTransport.
-
-func TestHandleCompoundPing(t *testing.T) {
- m := GetMemberlist(t)
- m.config.EnableCompression = false
- defer m.Shutdown()
-
- var udp *net.UDPConn
- for port := 60000; port < 61000; port++ {
- udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
- udpLn, err := net.ListenPacket("udp", udpAddr)
- if err == nil {
- udp = udpLn.(*net.UDPConn)
- break
- }
- }
-
- if udp == nil {
- t.Fatalf("no udp listener")
- }
-
- // Encode a ping
- ping := ping{SeqNo: 42}
- buf, err := encode(pingMsg, ping)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- // Make a compound message
- compound := makeCompoundMessage([][]byte{buf.Bytes(), buf.Bytes(), buf.Bytes()})
-
- // Send compound version
- addr := &net.UDPAddr{IP: net.ParseIP(m.config.BindAddr), Port: m.config.BindPort}
- udp.WriteTo(compound.Bytes(), addr)
-
- // Wait for responses
- doneCh := make(chan struct{}, 1)
- go func() {
- select {
- case <-doneCh:
- case <-time.After(2 * time.Second):
- panic("timeout")
- }
- }()
-
- for i := 0; i < 3; i++ {
- in := make([]byte, 1500)
- n, _, err := udp.ReadFrom(in)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- in = in[0:n]
-
- msgType := messageType(in[0])
- if msgType != ackRespMsg {
- t.Fatalf("bad response %v", in)
- }
-
- var ack ackResp
- if err := decode(in[1:], &ack); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- if ack.SeqNo != 42 {
- t.Fatalf("bad sequence no")
- }
- }
-
- doneCh <- struct{}{}
-}
-
-func TestHandlePing(t *testing.T) {
- m := GetMemberlist(t)
- m.config.EnableCompression = false
- defer m.Shutdown()
-
- var udp *net.UDPConn
- for port := 60000; port < 61000; port++ {
- udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
- udpLn, err := net.ListenPacket("udp", udpAddr)
- if err == nil {
- udp = udpLn.(*net.UDPConn)
- break
- }
- }
-
- if udp == nil {
- t.Fatalf("no udp listener")
- }
-
- // Encode a ping
- ping := ping{SeqNo: 42}
- buf, err := encode(pingMsg, ping)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- // Send
- addr := &net.UDPAddr{IP: net.ParseIP(m.config.BindAddr), Port: m.config.BindPort}
- udp.WriteTo(buf.Bytes(), addr)
-
- // Wait for response
- doneCh := make(chan struct{}, 1)
- go func() {
- select {
- case <-doneCh:
- case <-time.After(2 * time.Second):
- panic("timeout")
- }
- }()
-
- in := make([]byte, 1500)
- n, _, err := udp.ReadFrom(in)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- in = in[0:n]
-
- msgType := messageType(in[0])
- if msgType != ackRespMsg {
- t.Fatalf("bad response %v", in)
- }
-
- var ack ackResp
- if err := decode(in[1:], &ack); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- if ack.SeqNo != 42 {
- t.Fatalf("bad sequence no")
- }
-
- doneCh <- struct{}{}
-}
-
-func TestHandlePing_WrongNode(t *testing.T) {
- m := GetMemberlist(t)
- m.config.EnableCompression = false
- defer m.Shutdown()
-
- var udp *net.UDPConn
- for port := 60000; port < 61000; port++ {
- udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
- udpLn, err := net.ListenPacket("udp", udpAddr)
- if err == nil {
- udp = udpLn.(*net.UDPConn)
- break
- }
- }
-
- if udp == nil {
- t.Fatalf("no udp listener")
- }
-
- // Encode a ping, wrong node!
- ping := ping{SeqNo: 42, Node: m.config.Name + "-bad"}
- buf, err := encode(pingMsg, ping)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- // Send
- addr := &net.UDPAddr{IP: net.ParseIP(m.config.BindAddr), Port: m.config.BindPort}
- udp.WriteTo(buf.Bytes(), addr)
-
- // Wait for response
- udp.SetDeadline(time.Now().Add(50 * time.Millisecond))
- in := make([]byte, 1500)
- _, _, err = udp.ReadFrom(in)
-
- // Should get an i/o timeout
- if err == nil {
- t.Fatalf("expected err %s", err)
- }
-}
-
-func TestHandleIndirectPing(t *testing.T) {
- m := GetMemberlist(t)
- m.config.EnableCompression = false
- defer m.Shutdown()
-
- var udp *net.UDPConn
- for port := 60000; port < 61000; port++ {
- udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
- udpLn, err := net.ListenPacket("udp", udpAddr)
- if err == nil {
- udp = udpLn.(*net.UDPConn)
- break
- }
- }
-
- if udp == nil {
- t.Fatalf("no udp listener")
- }
-
- // Encode an indirect ping
- ind := indirectPingReq{
- SeqNo: 100,
- Target: net.ParseIP(m.config.BindAddr),
- Port: uint16(m.config.BindPort),
- }
- buf, err := encode(indirectPingMsg, &ind)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- // Send
- addr := &net.UDPAddr{IP: net.ParseIP(m.config.BindAddr), Port: m.config.BindPort}
- udp.WriteTo(buf.Bytes(), addr)
-
- // Wait for response
- doneCh := make(chan struct{}, 1)
- go func() {
- select {
- case <-doneCh:
- case <-time.After(2 * time.Second):
- panic("timeout")
- }
- }()
-
- in := make([]byte, 1500)
- n, _, err := udp.ReadFrom(in)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- in = in[0:n]
-
- msgType := messageType(in[0])
- if msgType != ackRespMsg {
- t.Fatalf("bad response %v", in)
- }
-
- var ack ackResp
- if err := decode(in[1:], &ack); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- if ack.SeqNo != 100 {
- t.Fatalf("bad sequence no")
- }
-
- doneCh <- struct{}{}
-}
-
-func TestTCPPing(t *testing.T) {
- var tcp *net.TCPListener
- var tcpAddr *net.TCPAddr
- for port := 60000; port < 61000; port++ {
- tcpAddr = &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: port}
- tcpLn, err := net.ListenTCP("tcp", tcpAddr)
- if err == nil {
- tcp = tcpLn
- break
- }
- }
- if tcp == nil {
- t.Fatalf("no tcp listener")
- }
-
- // Note that tcp gets closed in the last test, so we avoid a deferred
- // Close() call here.
-
- m := GetMemberlist(t)
- defer m.Shutdown()
- pingTimeout := m.config.ProbeInterval
- pingTimeMax := m.config.ProbeInterval + 10*time.Millisecond
-
- // Do a normal round trip.
- pingOut := ping{SeqNo: 23, Node: "mongo"}
- go func() {
- tcp.SetDeadline(time.Now().Add(pingTimeMax))
- conn, err := tcp.AcceptTCP()
- if err != nil {
- t.Fatalf("failed to connect: %s", err)
- }
- defer conn.Close()
-
- msgType, _, dec, err := m.readStream(conn)
- if err != nil {
- t.Fatalf("failed to read ping: %s", err)
- }
-
- if msgType != pingMsg {
- t.Fatalf("expecting ping, got message type (%d)", msgType)
- }
-
- var pingIn ping
- if err := dec.Decode(&pingIn); err != nil {
- t.Fatalf("failed to decode ping: %s", err)
- }
-
- if pingIn.SeqNo != pingOut.SeqNo {
- t.Fatalf("sequence number isn't correct (%d) vs (%d)", pingIn.SeqNo, pingOut.SeqNo)
- }
-
- if pingIn.Node != pingOut.Node {
- t.Fatalf("node name isn't correct (%s) vs (%s)", pingIn.Node, pingOut.Node)
- }
-
- ack := ackResp{pingIn.SeqNo, nil}
- out, err := encode(ackRespMsg, &ack)
- if err != nil {
- t.Fatalf("failed to encode ack: %s", err)
- }
-
- err = m.rawSendMsgStream(conn, out.Bytes())
- if err != nil {
- t.Fatalf("failed to send ack: %s", err)
- }
- }()
- deadline := time.Now().Add(pingTimeout)
- didContact, err := m.sendPingAndWaitForAck(tcpAddr.String(), pingOut, deadline)
- if err != nil {
- t.Fatalf("error trying to ping: %s", err)
- }
- if !didContact {
- t.Fatalf("expected successful ping")
- }
-
- // Make sure a mis-matched sequence number is caught.
- go func() {
- tcp.SetDeadline(time.Now().Add(pingTimeMax))
- conn, err := tcp.AcceptTCP()
- if err != nil {
- t.Fatalf("failed to connect: %s", err)
- }
- defer conn.Close()
-
- _, _, dec, err := m.readStream(conn)
- if err != nil {
- t.Fatalf("failed to read ping: %s", err)
- }
-
- var pingIn ping
- if err := dec.Decode(&pingIn); err != nil {
- t.Fatalf("failed to decode ping: %s", err)
- }
-
- ack := ackResp{pingIn.SeqNo + 1, nil}
- out, err := encode(ackRespMsg, &ack)
- if err != nil {
- t.Fatalf("failed to encode ack: %s", err)
- }
-
- err = m.rawSendMsgStream(conn, out.Bytes())
- if err != nil {
- t.Fatalf("failed to send ack: %s", err)
- }
- }()
- deadline = time.Now().Add(pingTimeout)
- didContact, err = m.sendPingAndWaitForAck(tcpAddr.String(), pingOut, deadline)
- if err == nil || !strings.Contains(err.Error(), "Sequence number") {
- t.Fatalf("expected an error from mis-matched sequence number")
- }
- if didContact {
- t.Fatalf("expected failed ping")
- }
-
- // Make sure an unexpected message type is handled gracefully.
- go func() {
- tcp.SetDeadline(time.Now().Add(pingTimeMax))
- conn, err := tcp.AcceptTCP()
- if err != nil {
- t.Fatalf("failed to connect: %s", err)
- }
- defer conn.Close()
-
- _, _, _, err = m.readStream(conn)
- if err != nil {
- t.Fatalf("failed to read ping: %s", err)
- }
-
- bogus := indirectPingReq{}
- out, err := encode(indirectPingMsg, &bogus)
- if err != nil {
- t.Fatalf("failed to encode bogus msg: %s", err)
- }
-
- err = m.rawSendMsgStream(conn, out.Bytes())
- if err != nil {
- t.Fatalf("failed to send bogus msg: %s", err)
- }
- }()
- deadline = time.Now().Add(pingTimeout)
- didContact, err = m.sendPingAndWaitForAck(tcpAddr.String(), pingOut, deadline)
- if err == nil || !strings.Contains(err.Error(), "Unexpected msgType") {
- t.Fatalf("expected an error from bogus message")
- }
- if didContact {
- t.Fatalf("expected failed ping")
- }
-
- // Make sure failed I/O respects the deadline. In this case we try the
- // common case of the receiving node being totally down.
- tcp.Close()
- deadline = time.Now().Add(pingTimeout)
- startPing := time.Now()
- didContact, err = m.sendPingAndWaitForAck(tcpAddr.String(), pingOut, deadline)
- pingTime := time.Now().Sub(startPing)
- if err != nil {
- t.Fatalf("expected no error during ping on closed socket, got: %s", err)
- }
- if didContact {
- t.Fatalf("expected failed ping")
- }
- if pingTime > pingTimeMax {
- t.Fatalf("took too long to fail ping, %9.6f", pingTime.Seconds())
- }
-}
-
-func TestTCPPushPull(t *testing.T) {
- m := GetMemberlist(t)
- defer m.Shutdown()
- m.nodes = append(m.nodes, &nodeState{
- Node: Node{
- Name: "Test 0",
- Addr: net.ParseIP(m.config.BindAddr),
- Port: uint16(m.config.BindPort),
- },
- Incarnation: 0,
- State: stateSuspect,
- StateChange: time.Now().Add(-1 * time.Second),
- })
-
- addr := fmt.Sprintf("%s:%d", m.config.BindAddr, m.config.BindPort)
- conn, err := net.Dial("tcp", addr)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- defer conn.Close()
-
- localNodes := make([]pushNodeState, 3)
- localNodes[0].Name = "Test 0"
- localNodes[0].Addr = net.ParseIP(m.config.BindAddr)
- localNodes[0].Port = uint16(m.config.BindPort)
- localNodes[0].Incarnation = 1
- localNodes[0].State = stateAlive
- localNodes[1].Name = "Test 1"
- localNodes[1].Addr = net.ParseIP(m.config.BindAddr)
- localNodes[1].Port = uint16(m.config.BindPort)
- localNodes[1].Incarnation = 1
- localNodes[1].State = stateAlive
- localNodes[2].Name = "Test 2"
- localNodes[2].Addr = net.ParseIP(m.config.BindAddr)
- localNodes[2].Port = uint16(m.config.BindPort)
- localNodes[2].Incarnation = 1
- localNodes[2].State = stateAlive
-
- // Send our node state
- header := pushPullHeader{Nodes: 3}
- hd := codec.MsgpackHandle{}
- enc := codec.NewEncoder(conn, &hd)
-
- // Send the push/pull indicator
- conn.Write([]byte{byte(pushPullMsg)})
-
- if err := enc.Encode(&header); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- for i := 0; i < header.Nodes; i++ {
- if err := enc.Encode(&localNodes[i]); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- }
-
- // Read the message type
- var msgType messageType
- if err := binary.Read(conn, binary.BigEndian, &msgType); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- var bufConn io.Reader = conn
- msghd := codec.MsgpackHandle{}
- dec := codec.NewDecoder(bufConn, &msghd)
-
- // Check if we have a compressed message
- if msgType == compressMsg {
- var c compress
- if err := dec.Decode(&c); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- decomp, err := decompressBuffer(&c)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- // Reset the message type
- msgType = messageType(decomp[0])
-
- // Create a new bufConn
- bufConn = bytes.NewReader(decomp[1:])
-
- // Create a new decoder
- dec = codec.NewDecoder(bufConn, &hd)
- }
-
- // Quit if not push/pull
- if msgType != pushPullMsg {
- t.Fatalf("bad message type")
- }
-
- if err := dec.Decode(&header); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- // Allocate space for the transfer
- remoteNodes := make([]pushNodeState, header.Nodes)
-
- // Try to decode all the states
- for i := 0; i < header.Nodes; i++ {
- if err := dec.Decode(&remoteNodes[i]); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- }
-
- if len(remoteNodes) != 1 {
- t.Fatalf("bad response")
- }
-
- n := &remoteNodes[0]
- if n.Name != "Test 0" {
- t.Fatalf("bad name")
- }
- if bytes.Compare(n.Addr, net.ParseIP(m.config.BindAddr)) != 0 {
- t.Fatal("bad addr")
- }
- if n.Incarnation != 0 {
- t.Fatal("bad incarnation")
- }
- if n.State != stateSuspect {
- t.Fatal("bad state")
- }
-}
-
-func TestSendMsg_Piggyback(t *testing.T) {
- m := GetMemberlist(t)
- defer m.Shutdown()
-
- // Add a message to be broadcast
- a := alive{
- Incarnation: 10,
- Node: "rand",
- Addr: []byte{127, 0, 0, 255},
- Meta: nil,
- }
- m.encodeAndBroadcast("rand", aliveMsg, &a)
-
- var udp *net.UDPConn
- for port := 60000; port < 61000; port++ {
- udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
- udpLn, err := net.ListenPacket("udp", udpAddr)
- if err == nil {
- udp = udpLn.(*net.UDPConn)
- break
- }
- }
-
- // Encode a ping
- ping := ping{SeqNo: 42}
- buf, err := encode(pingMsg, ping)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- // Send
- addr := &net.UDPAddr{IP: net.ParseIP(m.config.BindAddr), Port: m.config.BindPort}
- udp.WriteTo(buf.Bytes(), addr)
-
- // Wait for response
- doneCh := make(chan struct{}, 1)
- go func() {
- select {
- case <-doneCh:
- case <-time.After(2 * time.Second):
- panic("timeout")
- }
- }()
-
- in := make([]byte, 1500)
- n, _, err := udp.ReadFrom(in)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- in = in[0:n]
-
- msgType := messageType(in[0])
- if msgType != compoundMsg {
- t.Fatalf("bad response %v", in)
- }
-
- // get the parts
- trunc, parts, err := decodeCompoundMessage(in[1:])
- if trunc != 0 {
- t.Fatalf("unexpected truncation")
- }
- if len(parts) != 2 {
- t.Fatalf("unexpected parts %v", parts)
- }
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- var ack ackResp
- if err := decode(parts[0][1:], &ack); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- if ack.SeqNo != 42 {
- t.Fatalf("bad sequence no")
- }
-
- var aliveout alive
- if err := decode(parts[1][1:], &aliveout); err != nil {
- t.Fatalf("unexpected err %s", err)
- }
-
- if aliveout.Node != "rand" || aliveout.Incarnation != 10 {
- t.Fatalf("bad mesg")
- }
-
- doneCh <- struct{}{}
-}
-
-func TestEncryptDecryptState(t *testing.T) {
- state := []byte("this is our internal state...")
- config := &Config{
- SecretKey: []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
- ProtocolVersion: ProtocolVersionMax,
- }
-
- m, err := Create(config)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m.Shutdown()
-
- crypt, err := m.encryptLocalState(state)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Create reader, seek past the type byte
- buf := bytes.NewReader(crypt)
- buf.Seek(1, 0)
-
- plain, err := m.decryptRemoteState(buf)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- if !reflect.DeepEqual(state, plain) {
- t.Fatalf("Decrypt failed: %v", plain)
- }
-}
-
-func TestRawSendUdp_CRC(t *testing.T) {
- m := GetMemberlist(t)
- m.config.EnableCompression = false
- defer m.Shutdown()
-
- var udp *net.UDPConn
- for port := 60000; port < 61000; port++ {
- udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
- udpLn, err := net.ListenPacket("udp", udpAddr)
- if err == nil {
- udp = udpLn.(*net.UDPConn)
- break
- }
- }
-
- if udp == nil {
- t.Fatalf("no udp listener")
- }
-
- // Pass a nil node with no nodes registered, should result in no checksum
- payload := []byte{3, 3, 3, 3}
- m.rawSendMsgPacket(udp.LocalAddr().String(), nil, payload)
-
- in := make([]byte, 1500)
- n, _, err := udp.ReadFrom(in)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- in = in[0:n]
-
- if len(in) != 4 {
- t.Fatalf("bad: %v", in)
- }
-
- // Pass a non-nil node with PMax >= 5, should result in a checksum
- m.rawSendMsgPacket(udp.LocalAddr().String(), &Node{PMax: 5}, payload)
-
- in = make([]byte, 1500)
- n, _, err = udp.ReadFrom(in)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- in = in[0:n]
-
- if len(in) != 9 {
- t.Fatalf("bad: %v", in)
- }
-
- // Register a node with PMax >= 5 to be looked up, should result in a checksum
- m.nodeMap["127.0.0.1"] = &nodeState{
- Node: Node{PMax: 5},
- }
- m.rawSendMsgPacket(udp.LocalAddr().String(), nil, payload)
-
- in = make([]byte, 1500)
- n, _, err = udp.ReadFrom(in)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- in = in[0:n]
-
- if len(in) != 9 {
- t.Fatalf("bad: %v", in)
- }
-}
-
-func TestIngestPacket_CRC(t *testing.T) {
- m := GetMemberlist(t)
- m.config.EnableCompression = false
- defer m.Shutdown()
-
- var udp *net.UDPConn
- for port := 60000; port < 61000; port++ {
- udpAddr := fmt.Sprintf("127.0.0.1:%d", port)
- udpLn, err := net.ListenPacket("udp", udpAddr)
- if err == nil {
- udp = udpLn.(*net.UDPConn)
- break
- }
- }
-
- if udp == nil {
- t.Fatalf("no udp listener")
- }
-
- // Get a message with a checksum
- payload := []byte{3, 3, 3, 3}
- m.rawSendMsgPacket(udp.LocalAddr().String(), &Node{PMax: 5}, payload)
-
- in := make([]byte, 1500)
- n, _, err := udp.ReadFrom(in)
- if err != nil {
- t.Fatalf("unexpected err %s", err)
- }
- in = in[0:n]
-
- if len(in) != 9 {
- t.Fatalf("bad: %v", in)
- }
-
- // Corrupt the checksum
- in[1] <<= 1
-
- logs := &bytes.Buffer{}
- logger := log.New(logs, "", 0)
- m.logger = logger
- m.ingestPacket(in, udp.LocalAddr(), time.Now())
-
- if !strings.Contains(logs.String(), "invalid checksum") {
- t.Fatalf("bad: %s", logs.String())
- }
-}
-
-func TestGossip_MismatchedKeys(t *testing.T) {
- c1 := testConfig()
- c2 := testConfig()
-
- // Create two agents with different gossip keys
- c1.SecretKey = []byte("4W6DGn2VQVqDEceOdmuRTQ==")
- c2.SecretKey = []byte("XhX/w702/JKKK7/7OtM9Ww==")
-
- m1, err := Create(c1)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m1.Shutdown()
-
- m2, err := Create(c2)
- if err != nil {
- t.Fatalf("err: %s", err)
- }
- defer m2.Shutdown()
-
- // Make sure we get this error on the joining side
- _, err = m2.Join([]string{c1.BindAddr})
- if err == nil || !strings.Contains(err.Error(), "No installed keys could decrypt the message") {
- t.Fatalf("bad: %s", err)
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/queue_test.go b/vendor/github.com/hashicorp/memberlist/queue_test.go
deleted file mode 100644
index 765a3b53d..000000000
--- a/vendor/github.com/hashicorp/memberlist/queue_test.go
+++ /dev/null
@@ -1,172 +0,0 @@
-package memberlist
-
-import (
- "testing"
-)
-
-func TestTransmitLimited_Queue(t *testing.T) {
- q := &TransmitLimitedQueue{RetransmitMult: 1, NumNodes: func() int { return 1 }}
- q.QueueBroadcast(&memberlistBroadcast{"test", nil, nil})
- q.QueueBroadcast(&memberlistBroadcast{"foo", nil, nil})
- q.QueueBroadcast(&memberlistBroadcast{"bar", nil, nil})
-
- if len(q.bcQueue) != 3 {
- t.Fatalf("bad len")
- }
- if q.bcQueue[0].b.(*memberlistBroadcast).node != "test" {
- t.Fatalf("missing test")
- }
- if q.bcQueue[1].b.(*memberlistBroadcast).node != "foo" {
- t.Fatalf("missing foo")
- }
- if q.bcQueue[2].b.(*memberlistBroadcast).node != "bar" {
- t.Fatalf("missing bar")
- }
-
- // Should invalidate previous message
- q.QueueBroadcast(&memberlistBroadcast{"test", nil, nil})
-
- if len(q.bcQueue) != 3 {
- t.Fatalf("bad len")
- }
- if q.bcQueue[0].b.(*memberlistBroadcast).node != "foo" {
- t.Fatalf("missing foo")
- }
- if q.bcQueue[1].b.(*memberlistBroadcast).node != "bar" {
- t.Fatalf("missing bar")
- }
- if q.bcQueue[2].b.(*memberlistBroadcast).node != "test" {
- t.Fatalf("missing test")
- }
-}
-
-func TestTransmitLimited_GetBroadcasts(t *testing.T) {
- q := &TransmitLimitedQueue{RetransmitMult: 3, NumNodes: func() int { return 10 }}
-
- // 18 bytes per message
- q.QueueBroadcast(&memberlistBroadcast{"test", []byte("1. this is a test."), nil})
- q.QueueBroadcast(&memberlistBroadcast{"foo", []byte("2. this is a test."), nil})
- q.QueueBroadcast(&memberlistBroadcast{"bar", []byte("3. this is a test."), nil})
- q.QueueBroadcast(&memberlistBroadcast{"baz", []byte("4. this is a test."), nil})
-
- // 2 byte overhead per message, should get all 4 messages
- all := q.GetBroadcasts(2, 80)
- if len(all) != 4 {
- t.Fatalf("missing messages: %v", all)
- }
-
- // 3 byte overhead, should only get 3 messages back
- partial := q.GetBroadcasts(3, 80)
- if len(partial) != 3 {
- t.Fatalf("missing messages: %v", partial)
- }
-}
-
-func TestTransmitLimited_GetBroadcasts_Limit(t *testing.T) {
- q := &TransmitLimitedQueue{RetransmitMult: 1, NumNodes: func() int { return 10 }}
-
- // 18 bytes per message
- q.QueueBroadcast(&memberlistBroadcast{"test", []byte("1. this is a test."), nil})
- q.QueueBroadcast(&memberlistBroadcast{"foo", []byte("2. this is a test."), nil})
- q.QueueBroadcast(&memberlistBroadcast{"bar", []byte("3. this is a test."), nil})
- q.QueueBroadcast(&memberlistBroadcast{"baz", []byte("4. this is a test."), nil})
-
- // 3 byte overhead, should only get 3 messages back
- partial1 := q.GetBroadcasts(3, 80)
- if len(partial1) != 3 {
- t.Fatalf("missing messages: %v", partial1)
- }
-
- partial2 := q.GetBroadcasts(3, 80)
- if len(partial2) != 3 {
- t.Fatalf("missing messages: %v", partial2)
- }
-
- // Only two not expired
- partial3 := q.GetBroadcasts(3, 80)
- if len(partial3) != 2 {
- t.Fatalf("missing messages: %v", partial3)
- }
-
- // Should get nothing
- partial5 := q.GetBroadcasts(3, 80)
- if len(partial5) != 0 {
- t.Fatalf("missing messages: %v", partial5)
- }
-}
-
-func TestTransmitLimited_Prune(t *testing.T) {
- q := &TransmitLimitedQueue{RetransmitMult: 1, NumNodes: func() int { return 10 }}
-
- ch1 := make(chan struct{}, 1)
- ch2 := make(chan struct{}, 1)
-
- // 18 bytes per message
- q.QueueBroadcast(&memberlistBroadcast{"test", []byte("1. this is a test."), ch1})
- q.QueueBroadcast(&memberlistBroadcast{"foo", []byte("2. this is a test."), ch2})
- q.QueueBroadcast(&memberlistBroadcast{"bar", []byte("3. this is a test."), nil})
- q.QueueBroadcast(&memberlistBroadcast{"baz", []byte("4. this is a test."), nil})
-
- // Keep only 2
- q.Prune(2)
-
- if q.NumQueued() != 2 {
- t.Fatalf("bad len")
- }
-
- // Should notify the first two
- select {
- case <-ch1:
- default:
- t.Fatalf("expected invalidation")
- }
- select {
- case <-ch2:
- default:
- t.Fatalf("expected invalidation")
- }
-
- if q.bcQueue[0].b.(*memberlistBroadcast).node != "bar" {
- t.Fatalf("missing bar")
- }
- if q.bcQueue[1].b.(*memberlistBroadcast).node != "baz" {
- t.Fatalf("missing baz")
- }
-}
-
-func TestLimitedBroadcastSort(t *testing.T) {
- bc := limitedBroadcasts([]*limitedBroadcast{
- &limitedBroadcast{
- transmits: 0,
- },
- &limitedBroadcast{
- transmits: 10,
- },
- &limitedBroadcast{
- transmits: 3,
- },
- &limitedBroadcast{
- transmits: 4,
- },
- &limitedBroadcast{
- transmits: 7,
- },
- })
- bc.Sort()
-
- if bc[0].transmits != 10 {
- t.Fatalf("bad val %v", bc[0])
- }
- if bc[1].transmits != 7 {
- t.Fatalf("bad val %v", bc[7])
- }
- if bc[2].transmits != 4 {
- t.Fatalf("bad val %v", bc[2])
- }
- if bc[3].transmits != 3 {
- t.Fatalf("bad val %v", bc[3])
- }
- if bc[4].transmits != 0 {
- t.Fatalf("bad val %v", bc[4])
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/security_test.go b/vendor/github.com/hashicorp/memberlist/security_test.go
deleted file mode 100644
index 15fa4aa8e..000000000
--- a/vendor/github.com/hashicorp/memberlist/security_test.go
+++ /dev/null
@@ -1,70 +0,0 @@
-package memberlist
-
-import (
- "bytes"
- "reflect"
- "testing"
-)
-
-func TestPKCS7(t *testing.T) {
- for i := 0; i <= 255; i++ {
- // Make a buffer of size i
- buf := []byte{}
- for j := 0; j < i; j++ {
- buf = append(buf, byte(i))
- }
-
- // Copy to bytes buffer
- inp := bytes.NewBuffer(nil)
- inp.Write(buf)
-
- // Pad this out
- pkcs7encode(inp, 0, 16)
-
- // Unpad
- dec := pkcs7decode(inp.Bytes(), 16)
-
- // Ensure equivilence
- if !reflect.DeepEqual(buf, dec) {
- t.Fatalf("mismatch: %v %v", buf, dec)
- }
- }
-
-}
-
-func TestEncryptDecrypt_V0(t *testing.T) {
- encryptDecryptVersioned(0, t)
-}
-
-func TestEncryptDecrypt_V1(t *testing.T) {
- encryptDecryptVersioned(1, t)
-}
-
-func encryptDecryptVersioned(vsn encryptionVersion, t *testing.T) {
- k1 := []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
- plaintext := []byte("this is a plain text message")
- extra := []byte("random data")
-
- var buf bytes.Buffer
- err := encryptPayload(vsn, k1, plaintext, extra, &buf)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- expLen := encryptedLength(vsn, len(plaintext))
- if buf.Len() != expLen {
- t.Fatalf("output length is unexpected %d %d %d", len(plaintext), buf.Len(), expLen)
- }
-
- msg, err := decryptPayload([][]byte{k1}, buf.Bytes(), extra)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- cmp := bytes.Compare(msg, plaintext)
- if cmp != 0 {
- t.Errorf("len %d %v", len(msg), msg)
- t.Errorf("len %d %v", len(plaintext), plaintext)
- t.Fatalf("encrypt/decrypt failed! %d '%s' '%s'", cmp, msg, plaintext)
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/state_test.go b/vendor/github.com/hashicorp/memberlist/state_test.go
deleted file mode 100644
index 71e93ca4e..000000000
--- a/vendor/github.com/hashicorp/memberlist/state_test.go
+++ /dev/null
@@ -1,1900 +0,0 @@
-package memberlist
-
-import (
- "bytes"
- "fmt"
- "net"
- "testing"
- "time"
-)
-
-func HostMemberlist(host string, t *testing.T, f func(*Config)) *Memberlist {
- c := DefaultLANConfig()
- c.Name = host
- c.BindAddr = host
- if f != nil {
- f(c)
- }
-
- m, err := newMemberlist(c)
- if err != nil {
- t.Fatalf("failed to get memberlist: %s", err)
- }
- return m
-}
-
-func TestMemberList_Probe(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = time.Millisecond
- c.ProbeInterval = 10 * time.Millisecond
- })
- m2 := HostMemberlist(addr2.String(), t, nil)
-
- a1 := alive{
- Node: addr1.String(),
- Addr: []byte(addr1),
- Port: uint16(m1.config.BindPort),
- Incarnation: 1,
- }
- m1.aliveNode(&a1, nil, true)
- a2 := alive{
- Node: addr2.String(),
- Addr: []byte(addr2),
- Port: uint16(m2.config.BindPort),
- Incarnation: 1,
- }
- m1.aliveNode(&a2, nil, false)
-
- // should ping addr2
- m1.probe()
-
- // Should not be marked suspect
- n := m1.nodeMap[addr2.String()]
- if n.State != stateAlive {
- t.Fatalf("Expect node to be alive")
- }
-
- // Should increment seqno
- if m1.sequenceNum != 1 {
- t.Fatalf("bad seqno %v", m2.sequenceNum)
- }
-}
-
-func TestMemberList_ProbeNode_Suspect(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- addr3 := getBindAddr()
- addr4 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
- ip3 := []byte(addr3)
- ip4 := []byte(addr4)
-
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = time.Millisecond
- c.ProbeInterval = 10 * time.Millisecond
- })
- m2 := HostMemberlist(addr2.String(), t, nil)
- m3 := HostMemberlist(addr3.String(), t, nil)
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
- a3 := alive{Node: addr3.String(), Addr: ip3, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a3, nil, false)
- a4 := alive{Node: addr4.String(), Addr: ip4, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a4, nil, false)
-
- n := m1.nodeMap[addr4.String()]
- m1.probeNode(n)
-
- // Should be marked suspect.
- if n.State != stateSuspect {
- t.Fatalf("Expect node to be suspect")
- }
- time.Sleep(10 * time.Millisecond)
-
- // One of the peers should have attempted an indirect probe.
- if m2.sequenceNum != 1 && m3.sequenceNum != 1 {
- t.Fatalf("bad seqnos %v, %v", m2.sequenceNum, m3.sequenceNum)
- }
-}
-
-func TestMemberList_ProbeNode_Suspect_Dogpile(t *testing.T) {
- cases := []struct {
- numPeers int
- confirmations int
- expected time.Duration
- }{
- {1, 0, 500 * time.Millisecond}, // n=2, k=3 (max timeout disabled)
- {2, 0, 500 * time.Millisecond}, // n=3, k=3
- {3, 0, 500 * time.Millisecond}, // n=4, k=3
- {4, 0, 1000 * time.Millisecond}, // n=5, k=3 (max timeout starts to take effect)
- {5, 0, 1000 * time.Millisecond}, // n=6, k=3
- {5, 1, 750 * time.Millisecond}, // n=6, k=3 (confirmations start to lower timeout)
- {5, 2, 604 * time.Millisecond}, // n=6, k=3
- {5, 3, 500 * time.Millisecond}, // n=6, k=3 (timeout driven to nominal value)
- {5, 4, 500 * time.Millisecond}, // n=6, k=3
- }
- for i, c := range cases {
- // Create the main memberlist under test.
- addr := getBindAddr()
- m := HostMemberlist(addr.String(), t, func(c *Config) {
- c.ProbeTimeout = time.Millisecond
- c.ProbeInterval = 100 * time.Millisecond
- c.SuspicionMult = 5
- c.SuspicionMaxTimeoutMult = 2
- })
- a := alive{Node: addr.String(), Addr: []byte(addr), Port: 7946, Incarnation: 1}
- m.aliveNode(&a, nil, true)
-
- // Make all but one peer be an real, alive instance.
- var peers []*Memberlist
- for j := 0; j < c.numPeers-1; j++ {
- peerAddr := getBindAddr()
- peers = append(peers, HostMemberlist(peerAddr.String(), t, nil))
- a = alive{Node: peerAddr.String(), Addr: []byte(peerAddr), Port: 7946, Incarnation: 1}
- m.aliveNode(&a, nil, false)
- }
-
- // Just use a bogus address for the last peer so it doesn't respond
- // to pings, but tell the memberlist it's alive.
- badPeerAddr := getBindAddr()
- a = alive{Node: badPeerAddr.String(), Addr: []byte(badPeerAddr), Port: 7946, Incarnation: 1}
- m.aliveNode(&a, nil, false)
-
- // Force a probe, which should start us into the suspect state.
- n := m.nodeMap[badPeerAddr.String()]
- m.probeNode(n)
- if n.State != stateSuspect {
- t.Fatalf("case %d: expected node to be suspect", i)
- }
-
- // Add the requested number of confirmations.
- for j := 0; j < c.confirmations; j++ {
- from := fmt.Sprintf("peer%d", j)
- s := suspect{Node: badPeerAddr.String(), Incarnation: 1, From: from}
- m.suspectNode(&s)
- }
-
- // Wait until right before the timeout and make sure the timer
- // hasn't fired.
- fudge := 25 * time.Millisecond
- time.Sleep(c.expected - fudge)
- if n.State != stateSuspect {
- t.Fatalf("case %d: expected node to still be suspect", i)
- }
-
- // Wait through the timeout and a little after to make sure the
- // timer fires.
- time.Sleep(2 * fudge)
- if n.State != stateDead {
- t.Fatalf("case %d: expected node to be dead", i)
- }
- }
-}
-
-/*
-func TestMemberList_ProbeNode_FallbackTCP(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- addr3 := getBindAddr()
- addr4 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
- ip3 := []byte(addr3)
- ip4 := []byte(addr4)
-
- var probeTimeMax time.Duration
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = 10 * time.Millisecond
- c.ProbeInterval = 200 * time.Millisecond
- probeTimeMax = c.ProbeInterval + 20*time.Millisecond
- })
- defer m1.Shutdown()
-
- m2 := HostMemberlist(addr2.String(), t, nil)
- defer m2.Shutdown()
-
- m3 := HostMemberlist(addr3.String(), t, nil)
- defer m3.Shutdown()
-
- m4 := HostMemberlist(addr4.String(), t, nil)
- defer m4.Shutdown()
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
- a3 := alive{Node: addr3.String(), Addr: ip3, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a3, nil, false)
-
- // Make sure m4 is configured with the same protocol version as m1 so
- // the TCP fallback behavior is enabled.
- a4 := alive{
- Node: addr4.String(),
- Addr: ip4,
- Port: 7946,
- Incarnation: 1,
- Vsn: []uint8{
- ProtocolVersionMin,
- ProtocolVersionMax,
- m1.config.ProtocolVersion,
- m1.config.DelegateProtocolMin,
- m1.config.DelegateProtocolMax,
- m1.config.DelegateProtocolVersion,
- },
- }
- m1.aliveNode(&a4, nil, false)
-
- // Isolate m4 from UDP traffic by re-opening its listener on the wrong
- // port. This should force the TCP fallback path to be used.
- var err error
- if err = m4.udpListener.Close(); err != nil {
- t.Fatalf("err: %v", err)
- }
- udpAddr := &net.UDPAddr{IP: ip4, Port: 9999}
- if m4.udpListener, err = net.ListenUDP("udp", udpAddr); err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Have node m1 probe m4.
- n := m1.nodeMap[addr4.String()]
- startProbe := time.Now()
- m1.probeNode(n)
- probeTime := time.Now().Sub(startProbe)
-
- // Should be marked alive because of the TCP fallback ping.
- if n.State != stateAlive {
- t.Fatalf("expect node to be alive")
- }
-
- // Make sure TCP activity completed in a timely manner.
- if probeTime > probeTimeMax {
- t.Fatalf("took to long to probe, %9.6f", probeTime.Seconds())
- }
-
- // Confirm at least one of the peers attempted an indirect probe.
- time.Sleep(probeTimeMax)
- if m2.sequenceNum != 1 && m3.sequenceNum != 1 {
- t.Fatalf("bad seqnos %v, %v", m2.sequenceNum, m3.sequenceNum)
- }
-
- // Now shutdown all inbound TCP traffic to make sure the TCP fallback
- // path properly fails when the node is really unreachable.
- if err = m4.tcpListener.Close(); err != nil {
- t.Fatalf("err: %v", err)
- }
- tcpAddr := &net.TCPAddr{IP: ip4, Port: 9999}
- if m4.tcpListener, err = net.ListenTCP("tcp", tcpAddr); err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Probe again, this time there should be no contact.
- startProbe = time.Now()
- m1.probeNode(n)
- probeTime = time.Now().Sub(startProbe)
-
- // Node should be reported suspect.
- if n.State != stateSuspect {
- t.Fatalf("expect node to be suspect")
- }
-
- // Make sure TCP activity didn't cause us to wait too long before
- // timing out.
- if probeTime > probeTimeMax {
- t.Fatalf("took to long to probe, %9.6f", probeTime.Seconds())
- }
-
- // Confirm at least one of the peers attempted an indirect probe.
- time.Sleep(probeTimeMax)
- if m2.sequenceNum != 2 && m3.sequenceNum != 2 {
- t.Fatalf("bad seqnos %v, %v", m2.sequenceNum, m3.sequenceNum)
- }
-}
-
-func TestMemberList_ProbeNode_FallbackTCP_Disabled(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- addr3 := getBindAddr()
- addr4 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
- ip3 := []byte(addr3)
- ip4 := []byte(addr4)
-
- var probeTimeMax time.Duration
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = 10 * time.Millisecond
- c.ProbeInterval = 200 * time.Millisecond
- probeTimeMax = c.ProbeInterval + 20*time.Millisecond
- })
- defer m1.Shutdown()
-
- m2 := HostMemberlist(addr2.String(), t, nil)
- defer m2.Shutdown()
-
- m3 := HostMemberlist(addr3.String(), t, nil)
- defer m3.Shutdown()
-
- m4 := HostMemberlist(addr4.String(), t, nil)
- defer m4.Shutdown()
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
- a3 := alive{Node: addr3.String(), Addr: ip3, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a3, nil, false)
-
- // Make sure m4 is configured with the same protocol version as m1 so
- // the TCP fallback behavior is enabled.
- a4 := alive{
- Node: addr4.String(),
- Addr: ip4,
- Port: 7946,
- Incarnation: 1,
- Vsn: []uint8{
- ProtocolVersionMin,
- ProtocolVersionMax,
- m1.config.ProtocolVersion,
- m1.config.DelegateProtocolMin,
- m1.config.DelegateProtocolMax,
- m1.config.DelegateProtocolVersion,
- },
- }
- m1.aliveNode(&a4, nil, false)
-
- // Isolate m4 from UDP traffic by re-opening its listener on the wrong
- // port. This should force the TCP fallback path to be used.
- var err error
- if err = m4.udpListener.Close(); err != nil {
- t.Fatalf("err: %v", err)
- }
- udpAddr := &net.UDPAddr{IP: ip4, Port: 9999}
- if m4.udpListener, err = net.ListenUDP("udp", udpAddr); err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Disable the TCP pings using the config mechanism.
- m1.config.DisableTcpPings = true
-
- // Have node m1 probe m4.
- n := m1.nodeMap[addr4.String()]
- startProbe := time.Now()
- m1.probeNode(n)
- probeTime := time.Now().Sub(startProbe)
-
- // Node should be reported suspect.
- if n.State != stateSuspect {
- t.Fatalf("expect node to be suspect")
- }
-
- // Make sure TCP activity didn't cause us to wait too long before
- // timing out.
- if probeTime > probeTimeMax {
- t.Fatalf("took to long to probe, %9.6f", probeTime.Seconds())
- }
-
- // Confirm at least one of the peers attempted an indirect probe.
- time.Sleep(probeTimeMax)
- if m2.sequenceNum != 1 && m3.sequenceNum != 1 {
- t.Fatalf("bad seqnos %v, %v", m2.sequenceNum, m3.sequenceNum)
- }
-}
-
-func TestMemberList_ProbeNode_FallbackTCP_OldProtocol(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- addr3 := getBindAddr()
- addr4 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
- ip3 := []byte(addr3)
- ip4 := []byte(addr4)
-
- var probeTimeMax time.Duration
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = 10 * time.Millisecond
- c.ProbeInterval = 200 * time.Millisecond
- probeTimeMax = c.ProbeInterval + 20*time.Millisecond
- })
- defer m1.Shutdown()
-
- m2 := HostMemberlist(addr2.String(), t, nil)
- defer m2.Shutdown()
-
- m3 := HostMemberlist(addr3.String(), t, nil)
- defer m3.Shutdown()
-
- m4 := HostMemberlist(addr4.String(), t, nil)
- defer m4.Shutdown()
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
- a3 := alive{Node: addr3.String(), Addr: ip3, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a3, nil, false)
-
- // Set up m4 so that it doesn't understand a version of the protocol
- // that supports TCP pings.
- a4 := alive{
- Node: addr4.String(),
- Addr: ip4,
- Port: 7946,
- Incarnation: 1,
- Vsn: []uint8{
- ProtocolVersionMin,
- ProtocolVersion2Compatible,
- ProtocolVersion2Compatible,
- m1.config.DelegateProtocolMin,
- m1.config.DelegateProtocolMax,
- m1.config.DelegateProtocolVersion,
- },
- }
- m1.aliveNode(&a4, nil, false)
-
- // Isolate m4 from UDP traffic by re-opening its listener on the wrong
- // port. This should force the TCP fallback path to be used.
- var err error
- if err = m4.udpListener.Close(); err != nil {
- t.Fatalf("err: %v", err)
- }
- udpAddr := &net.UDPAddr{IP: ip4, Port: 9999}
- if m4.udpListener, err = net.ListenUDP("udp", udpAddr); err != nil {
- t.Fatalf("err: %v", err)
- }
-
- // Have node m1 probe m4.
- n := m1.nodeMap[addr4.String()]
- startProbe := time.Now()
- m1.probeNode(n)
- probeTime := time.Now().Sub(startProbe)
-
- // Node should be reported suspect.
- if n.State != stateSuspect {
- t.Fatalf("expect node to be suspect")
- }
-
- // Make sure TCP activity didn't cause us to wait too long before
- // timing out.
- if probeTime > probeTimeMax {
- t.Fatalf("took to long to probe, %9.6f", probeTime.Seconds())
- }
-
- // Confirm at least one of the peers attempted an indirect probe.
- time.Sleep(probeTimeMax)
- if m2.sequenceNum != 1 && m3.sequenceNum != 1 {
- t.Fatalf("bad seqnos %v, %v", m2.sequenceNum, m3.sequenceNum)
- }
-}
-*/
-
-func TestMemberList_ProbeNode_Awareness_Degraded(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- addr3 := getBindAddr()
- addr4 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
- ip3 := []byte(addr3)
- ip4 := []byte(addr4)
-
- var probeTimeMin time.Duration
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = 10 * time.Millisecond
- c.ProbeInterval = 200 * time.Millisecond
- probeTimeMin = 2*c.ProbeInterval - 50*time.Millisecond
- })
- defer m1.Shutdown()
-
- m2 := HostMemberlist(addr2.String(), t, func(c *Config) {
- c.ProbeTimeout = 10 * time.Millisecond
- c.ProbeInterval = 200 * time.Millisecond
- })
- defer m2.Shutdown()
-
- m3 := HostMemberlist(addr3.String(), t, func(c *Config) {
- c.ProbeTimeout = 10 * time.Millisecond
- c.ProbeInterval = 200 * time.Millisecond
- })
- defer m3.Shutdown()
-
- // This will enable nacks by invoking the latest protocol version.
- vsn := []uint8{
- ProtocolVersionMin,
- ProtocolVersionMax,
- m1.config.ProtocolVersion,
- m1.config.DelegateProtocolMin,
- m1.config.DelegateProtocolMax,
- m1.config.DelegateProtocolVersion,
- }
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1, Vsn: vsn}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1, Vsn: vsn}
- m1.aliveNode(&a2, nil, false)
- a3 := alive{Node: addr3.String(), Addr: ip3, Port: 7946, Incarnation: 1, Vsn: vsn}
- m1.aliveNode(&a3, nil, false)
-
- // Node 4 never gets started.
- a4 := alive{Node: addr4.String(), Addr: ip4, Port: 7946, Incarnation: 1, Vsn: vsn}
- m1.aliveNode(&a4, nil, false)
-
- // Start the health in a degraded state.
- m1.awareness.ApplyDelta(1)
- if score := m1.GetHealthScore(); score != 1 {
- t.Fatalf("bad: %d", score)
- }
-
- // Have node m1 probe m4.
- n := m1.nodeMap[addr4.String()]
- startProbe := time.Now()
- m1.probeNode(n)
- probeTime := time.Now().Sub(startProbe)
-
- // Node should be reported suspect.
- if n.State != stateSuspect {
- t.Fatalf("expect node to be suspect")
- }
-
- // Make sure we timed out approximately on time (note that we accounted
- // for the slowed-down failure detector in the probeTimeMin calculation.
- if probeTime < probeTimeMin {
- t.Fatalf("probed too quickly, %9.6f", probeTime.Seconds())
- }
-
- // Confirm at least one of the peers attempted an indirect probe.
- if m2.sequenceNum != 1 && m3.sequenceNum != 1 {
- t.Fatalf("bad seqnos %v, %v", m2.sequenceNum, m3.sequenceNum)
- }
-
- // We should have gotten all the nacks, so our score should remain the
- // same, since we didn't get a successful probe.
- if score := m1.GetHealthScore(); score != 1 {
- t.Fatalf("bad: %d", score)
- }
-}
-
-func TestMemberList_ProbeNode_Awareness_Improved(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
-
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = 10 * time.Millisecond
- c.ProbeInterval = 200 * time.Millisecond
- })
- defer m1.Shutdown()
-
- m2 := HostMemberlist(addr2.String(), t, nil)
- defer m2.Shutdown()
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
-
- // Start the health in a degraded state.
- m1.awareness.ApplyDelta(1)
- if score := m1.GetHealthScore(); score != 1 {
- t.Fatalf("bad: %d", score)
- }
-
- // Have node m1 probe m2.
- n := m1.nodeMap[addr2.String()]
- m1.probeNode(n)
-
- // Node should be reported alive.
- if n.State != stateAlive {
- t.Fatalf("expect node to be suspect")
- }
-
- // Our score should have improved since we did a good probe.
- if score := m1.GetHealthScore(); score != 0 {
- t.Fatalf("bad: %d", score)
- }
-}
-
-func TestMemberList_ProbeNode_Awareness_MissedNack(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- addr3 := getBindAddr()
- addr4 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
- ip3 := []byte(addr3)
- ip4 := []byte(addr4)
-
- var probeTimeMax time.Duration
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = 10 * time.Millisecond
- c.ProbeInterval = 200 * time.Millisecond
- probeTimeMax = c.ProbeInterval + 50*time.Millisecond
- })
- defer m1.Shutdown()
-
- m2 := HostMemberlist(addr2.String(), t, func(c *Config) {
- c.ProbeTimeout = 10 * time.Millisecond
- c.ProbeInterval = 200 * time.Millisecond
- })
- defer m2.Shutdown()
-
- // This will enable nacks by invoking the latest protocol version.
- vsn := []uint8{
- ProtocolVersionMin,
- ProtocolVersionMax,
- m1.config.ProtocolVersion,
- m1.config.DelegateProtocolMin,
- m1.config.DelegateProtocolMax,
- m1.config.DelegateProtocolVersion,
- }
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1, Vsn: vsn}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1, Vsn: vsn}
- m1.aliveNode(&a2, nil, false)
-
- // Node 3 and node 4 never get started.
- a3 := alive{Node: addr3.String(), Addr: ip3, Port: 7946, Incarnation: 1, Vsn: vsn}
- m1.aliveNode(&a3, nil, false)
- a4 := alive{Node: addr4.String(), Addr: ip4, Port: 7946, Incarnation: 1, Vsn: vsn}
- m1.aliveNode(&a4, nil, false)
-
- // Make sure health looks good.
- if score := m1.GetHealthScore(); score != 0 {
- t.Fatalf("bad: %d", score)
- }
-
- // Have node m1 probe m4.
- n := m1.nodeMap[addr4.String()]
- startProbe := time.Now()
- m1.probeNode(n)
- probeTime := time.Now().Sub(startProbe)
-
- // Node should be reported suspect.
- if n.State != stateSuspect {
- t.Fatalf("expect node to be suspect")
- }
-
- // Make sure we timed out approximately on time.
- if probeTime > probeTimeMax {
- t.Fatalf("took to long to probe, %9.6f", probeTime.Seconds())
- }
-
- // We should have gotten dinged for the missed nack.
- time.Sleep(probeTimeMax)
- if score := m1.GetHealthScore(); score != 1 {
- t.Fatalf("bad: %d", score)
- }
-}
-
-func TestMemberList_ProbeNode_Awareness_OldProtocol(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- addr3 := getBindAddr()
- addr4 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
- ip3 := []byte(addr3)
- ip4 := []byte(addr4)
-
- var probeTimeMax time.Duration
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = 10 * time.Millisecond
- c.ProbeInterval = 200 * time.Millisecond
- probeTimeMax = c.ProbeInterval + 20*time.Millisecond
- })
- defer m1.Shutdown()
-
- m2 := HostMemberlist(addr2.String(), t, nil)
- defer m2.Shutdown()
-
- m3 := HostMemberlist(addr3.String(), t, nil)
- defer m3.Shutdown()
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
- a3 := alive{Node: addr3.String(), Addr: ip3, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a3, nil, false)
-
- // Node 4 never gets started.
- a4 := alive{Node: addr4.String(), Addr: ip4, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a4, nil, false)
-
- // Make sure health looks good.
- if score := m1.GetHealthScore(); score != 0 {
- t.Fatalf("bad: %d", score)
- }
-
- // Have node m1 probe m4.
- n := m1.nodeMap[addr4.String()]
- startProbe := time.Now()
- m1.probeNode(n)
- probeTime := time.Now().Sub(startProbe)
-
- // Node should be reported suspect.
- if n.State != stateSuspect {
- t.Fatalf("expect node to be suspect")
- }
-
- // Make sure we timed out approximately on time.
- if probeTime > probeTimeMax {
- t.Fatalf("took to long to probe, %9.6f", probeTime.Seconds())
- }
-
- // Confirm at least one of the peers attempted an indirect probe.
- time.Sleep(probeTimeMax)
- if m2.sequenceNum != 1 && m3.sequenceNum != 1 {
- t.Fatalf("bad seqnos %v, %v", m2.sequenceNum, m3.sequenceNum)
- }
-
- // Since we are using the old protocol here, we should have gotten dinged
- // for a failed health check.
- if score := m1.GetHealthScore(); score != 1 {
- t.Fatalf("bad: %d", score)
- }
-}
-
-func TestMemberList_ProbeNode_Buddy(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
-
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = time.Millisecond
- c.ProbeInterval = 10 * time.Millisecond
- })
- m2 := HostMemberlist(addr2.String(), t, nil)
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
-
- m1.aliveNode(&a1, nil, true)
- m1.aliveNode(&a2, nil, false)
- m2.aliveNode(&a2, nil, true)
-
- // Force the state to suspect so we piggyback a suspect message with the ping.
- // We should see this get refuted later, and the ping will succeed.
- n := m1.nodeMap[addr2.String()]
- n.State = stateSuspect
- m1.probeNode(n)
-
- // Make sure a ping was sent.
- if m1.sequenceNum != 1 {
- t.Fatalf("bad seqno %v", m1.sequenceNum)
- }
-
- // Check a broadcast is queued.
- if num := m2.broadcasts.NumQueued(); num != 1 {
- t.Fatalf("expected only one queued message: %d", num)
- }
-
- // Should be alive msg.
- if messageType(m2.broadcasts.bcQueue[0].b.Message()[0]) != aliveMsg {
- t.Fatalf("expected queued alive msg")
- }
-}
-
-func TestMemberList_ProbeNode(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
-
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = time.Millisecond
- c.ProbeInterval = 10 * time.Millisecond
- })
- _ = HostMemberlist(addr2.String(), t, nil)
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
-
- n := m1.nodeMap[addr2.String()]
- m1.probeNode(n)
-
- // Should be marked alive
- if n.State != stateAlive {
- t.Fatalf("Expect node to be alive")
- }
-
- // Should increment seqno
- if m1.sequenceNum != 1 {
- t.Fatalf("bad seqno %v", m1.sequenceNum)
- }
-}
-
-func TestMemberList_Ping(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
-
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.ProbeTimeout = time.Millisecond
- c.ProbeInterval = 10 * time.Second
- })
- _ = HostMemberlist(addr2.String(), t, nil)
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
-
- // Do a legit ping.
- n := m1.nodeMap[addr2.String()]
- addr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(addr2.String(), "7946"))
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- rtt, err := m1.Ping(n.Name, addr)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- if !(rtt > 0) {
- t.Fatalf("bad: %v", rtt)
- }
-
- // This ping has a bad node name so should timeout.
- _, err = m1.Ping("bad", addr)
- if _, ok := err.(NoPingResponseError); !ok || err == nil {
- t.Fatalf("bad: %v", err)
- }
-}
-
-func TestMemberList_ResetNodes(t *testing.T) {
- m := GetMemberlist(t)
- a1 := alive{Node: "test1", Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a1, nil, false)
- a2 := alive{Node: "test2", Addr: []byte{127, 0, 0, 2}, Incarnation: 1}
- m.aliveNode(&a2, nil, false)
- a3 := alive{Node: "test3", Addr: []byte{127, 0, 0, 3}, Incarnation: 1}
- m.aliveNode(&a3, nil, false)
- d := dead{Node: "test2", Incarnation: 1}
- m.deadNode(&d)
-
- m.config.GossipToTheDeadTime = 100 * time.Millisecond
- m.resetNodes()
- if len(m.nodes) != 3 {
- t.Fatalf("Bad length")
- }
- if _, ok := m.nodeMap["test2"]; !ok {
- t.Fatalf("test2 should not be unmapped")
- }
-
- time.Sleep(200 * time.Millisecond)
- m.resetNodes()
- if len(m.nodes) != 2 {
- t.Fatalf("Bad length")
- }
- if _, ok := m.nodeMap["test2"]; ok {
- t.Fatalf("test2 should be unmapped")
- }
-}
-
-func TestMemberList_NextSeq(t *testing.T) {
- m := &Memberlist{}
- if m.nextSeqNo() != 1 {
- t.Fatalf("bad sequence no")
- }
- if m.nextSeqNo() != 2 {
- t.Fatalf("bad sequence no")
- }
-}
-
-func TestMemberList_setProbeChannels(t *testing.T) {
- m := &Memberlist{ackHandlers: make(map[uint32]*ackHandler)}
-
- ch := make(chan ackMessage, 1)
- m.setProbeChannels(0, ch, nil, 10*time.Millisecond)
-
- if _, ok := m.ackHandlers[0]; !ok {
- t.Fatalf("missing handler")
- }
- time.Sleep(20 * time.Millisecond)
-
- if _, ok := m.ackHandlers[0]; ok {
- t.Fatalf("non-reaped handler")
- }
-}
-
-func TestMemberList_setAckHandler(t *testing.T) {
- m := &Memberlist{ackHandlers: make(map[uint32]*ackHandler)}
-
- f := func([]byte, time.Time) {}
- m.setAckHandler(0, f, 10*time.Millisecond)
-
- if _, ok := m.ackHandlers[0]; !ok {
- t.Fatalf("missing handler")
- }
- time.Sleep(20 * time.Millisecond)
-
- if _, ok := m.ackHandlers[0]; ok {
- t.Fatalf("non-reaped handler")
- }
-}
-
-func TestMemberList_invokeAckHandler(t *testing.T) {
- m := &Memberlist{ackHandlers: make(map[uint32]*ackHandler)}
-
- // Does nothing
- m.invokeAckHandler(ackResp{}, time.Now())
-
- var b bool
- f := func(payload []byte, timestamp time.Time) { b = true }
- m.setAckHandler(0, f, 10*time.Millisecond)
-
- // Should set b
- m.invokeAckHandler(ackResp{0, nil}, time.Now())
- if !b {
- t.Fatalf("b not set")
- }
-
- if _, ok := m.ackHandlers[0]; ok {
- t.Fatalf("non-reaped handler")
- }
-}
-
-func TestMemberList_invokeAckHandler_Channel_Ack(t *testing.T) {
- m := &Memberlist{ackHandlers: make(map[uint32]*ackHandler)}
-
- ack := ackResp{0, []byte{0, 0, 0}}
-
- // Does nothing
- m.invokeAckHandler(ack, time.Now())
-
- ackCh := make(chan ackMessage, 1)
- nackCh := make(chan struct{}, 1)
- m.setProbeChannels(0, ackCh, nackCh, 10*time.Millisecond)
-
- // Should send message
- m.invokeAckHandler(ack, time.Now())
-
- select {
- case v := <-ackCh:
- if v.Complete != true {
- t.Fatalf("Bad value")
- }
- if bytes.Compare(v.Payload, ack.Payload) != 0 {
- t.Fatalf("wrong payload. expected: %v; actual: %v", ack.Payload, v.Payload)
- }
-
- case <-nackCh:
- t.Fatalf("should not get a nack")
-
- default:
- t.Fatalf("message not sent")
- }
-
- if _, ok := m.ackHandlers[0]; ok {
- t.Fatalf("non-reaped handler")
- }
-}
-
-func TestMemberList_invokeAckHandler_Channel_Nack(t *testing.T) {
- m := &Memberlist{ackHandlers: make(map[uint32]*ackHandler)}
-
- nack := nackResp{0}
-
- // Does nothing.
- m.invokeNackHandler(nack)
-
- ackCh := make(chan ackMessage, 1)
- nackCh := make(chan struct{}, 1)
- m.setProbeChannels(0, ackCh, nackCh, 10*time.Millisecond)
-
- // Should send message.
- m.invokeNackHandler(nack)
-
- select {
- case <-ackCh:
- t.Fatalf("should not get an ack")
-
- case <-nackCh:
- // Good.
-
- default:
- t.Fatalf("message not sent")
- }
-
- // Getting a nack doesn't reap the handler so that we can still forward
- // an ack up to the reap time, if we get one.
- if _, ok := m.ackHandlers[0]; !ok {
- t.Fatalf("handler should not be reaped")
- }
-
- ack := ackResp{0, []byte{0, 0, 0}}
- m.invokeAckHandler(ack, time.Now())
-
- select {
- case v := <-ackCh:
- if v.Complete != true {
- t.Fatalf("Bad value")
- }
- if bytes.Compare(v.Payload, ack.Payload) != 0 {
- t.Fatalf("wrong payload. expected: %v; actual: %v", ack.Payload, v.Payload)
- }
-
- case <-nackCh:
- t.Fatalf("should not get a nack")
-
- default:
- t.Fatalf("message not sent")
- }
-
- if _, ok := m.ackHandlers[0]; ok {
- t.Fatalf("non-reaped handler")
- }
-}
-
-func TestMemberList_AliveNode_NewNode(t *testing.T) {
- ch := make(chan NodeEvent, 1)
- m := GetMemberlist(t)
- m.config.Events = &ChannelEventDelegate{ch}
-
- a := alive{Node: "test", Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a, nil, false)
-
- if len(m.nodes) != 1 {
- t.Fatalf("should add node")
- }
-
- state, ok := m.nodeMap["test"]
- if !ok {
- t.Fatalf("should map node")
- }
-
- if state.Incarnation != 1 {
- t.Fatalf("bad incarnation")
- }
- if state.State != stateAlive {
- t.Fatalf("bad state")
- }
- if time.Now().Sub(state.StateChange) > time.Second {
- t.Fatalf("bad change delta")
- }
-
- // Check for a join message
- select {
- case e := <-ch:
- if e.Node.Name != "test" {
- t.Fatalf("bad node name")
- }
- default:
- t.Fatalf("no join message")
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 1 {
- t.Fatalf("expected queued message")
- }
-}
-
-func TestMemberList_AliveNode_SuspectNode(t *testing.T) {
- ch := make(chan NodeEvent, 1)
- m := GetMemberlist(t)
-
- a := alive{Node: "test", Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a, nil, false)
-
- // Listen only after first join
- m.config.Events = &ChannelEventDelegate{ch}
-
- // Make suspect
- state := m.nodeMap["test"]
- state.State = stateSuspect
- state.StateChange = state.StateChange.Add(-time.Hour)
-
- // Old incarnation number, should not change
- m.aliveNode(&a, nil, false)
- if state.State != stateSuspect {
- t.Fatalf("update with old incarnation!")
- }
-
- // Should reset to alive now
- a.Incarnation = 2
- m.aliveNode(&a, nil, false)
- if state.State != stateAlive {
- t.Fatalf("no update with new incarnation!")
- }
-
- if time.Now().Sub(state.StateChange) > time.Second {
- t.Fatalf("bad change delta")
- }
-
- // Check for a no join message
- select {
- case <-ch:
- t.Fatalf("got bad join message")
- default:
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 1 {
- t.Fatalf("expected queued message")
- }
-}
-
-func TestMemberList_AliveNode_Idempotent(t *testing.T) {
- ch := make(chan NodeEvent, 1)
- m := GetMemberlist(t)
-
- a := alive{Node: "test", Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a, nil, false)
-
- // Listen only after first join
- m.config.Events = &ChannelEventDelegate{ch}
-
- // Make suspect
- state := m.nodeMap["test"]
- stateTime := state.StateChange
-
- // Should reset to alive now
- a.Incarnation = 2
- m.aliveNode(&a, nil, false)
- if state.State != stateAlive {
- t.Fatalf("non idempotent")
- }
-
- if stateTime != state.StateChange {
- t.Fatalf("should not change state")
- }
-
- // Check for a no join message
- select {
- case <-ch:
- t.Fatalf("got bad join message")
- default:
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 1 {
- t.Fatalf("expected only one queued message")
- }
-}
-
-// Serf Bug: GH-58, Meta data does not update
-func TestMemberList_AliveNode_ChangeMeta(t *testing.T) {
- ch := make(chan NodeEvent, 1)
- m := GetMemberlist(t)
-
- a := alive{
- Node: "test",
- Addr: []byte{127, 0, 0, 1},
- Meta: []byte("val1"),
- Incarnation: 1}
- m.aliveNode(&a, nil, false)
-
- // Listen only after first join
- m.config.Events = &ChannelEventDelegate{ch}
-
- // Make suspect
- state := m.nodeMap["test"]
-
- // Should reset to alive now
- a.Incarnation = 2
- a.Meta = []byte("val2")
- m.aliveNode(&a, nil, false)
-
- // Check updates
- if bytes.Compare(state.Meta, a.Meta) != 0 {
- t.Fatalf("meta did not update")
- }
-
- // Check for a NotifyUpdate
- select {
- case e := <-ch:
- if e.Event != NodeUpdate {
- t.Fatalf("bad event: %v", e)
- }
- if e.Node != &state.Node {
- t.Fatalf("bad event: %v", e)
- }
- if bytes.Compare(e.Node.Meta, a.Meta) != 0 {
- t.Fatalf("meta did not update")
- }
- default:
- t.Fatalf("missing event!")
- }
-
-}
-
-func TestMemberList_AliveNode_Refute(t *testing.T) {
- m := GetMemberlist(t)
- a := alive{Node: m.config.Name, Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a, nil, true)
-
- // Clear queue
- m.broadcasts.Reset()
-
- // Conflicting alive
- s := alive{
- Node: m.config.Name,
- Addr: []byte{127, 0, 0, 1},
- Incarnation: 2,
- Meta: []byte("foo"),
- }
- m.aliveNode(&s, nil, false)
-
- state := m.nodeMap[m.config.Name]
- if state.State != stateAlive {
- t.Fatalf("should still be alive")
- }
- if state.Meta != nil {
- t.Fatalf("meta should still be nil")
- }
-
- // Check a broad cast is queued
- if num := m.broadcasts.NumQueued(); num != 1 {
- t.Fatalf("expected only one queued message: %d",
- num)
- }
-
- // Should be alive mesg
- if messageType(m.broadcasts.bcQueue[0].b.Message()[0]) != aliveMsg {
- t.Fatalf("expected queued alive msg")
- }
-}
-
-func TestMemberList_SuspectNode_NoNode(t *testing.T) {
- m := GetMemberlist(t)
- s := suspect{Node: "test", Incarnation: 1}
- m.suspectNode(&s)
- if len(m.nodes) != 0 {
- t.Fatalf("don't expect nodes")
- }
-}
-
-func TestMemberList_SuspectNode(t *testing.T) {
- m := GetMemberlist(t)
- m.config.ProbeInterval = time.Millisecond
- m.config.SuspicionMult = 1
- a := alive{Node: "test", Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a, nil, false)
-
- state := m.nodeMap["test"]
- state.StateChange = state.StateChange.Add(-time.Hour)
-
- s := suspect{Node: "test", Incarnation: 1}
- m.suspectNode(&s)
-
- if state.State != stateSuspect {
- t.Fatalf("Bad state")
- }
-
- change := state.StateChange
- if time.Now().Sub(change) > time.Second {
- t.Fatalf("bad change delta")
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 1 {
- t.Fatalf("expected only one queued message")
- }
-
- // Check its a suspect message
- if messageType(m.broadcasts.bcQueue[0].b.Message()[0]) != suspectMsg {
- t.Fatalf("expected queued suspect msg")
- }
-
- // Wait for the timeout
- time.Sleep(10 * time.Millisecond)
-
- if state.State != stateDead {
- t.Fatalf("Bad state")
- }
-
- if time.Now().Sub(state.StateChange) > time.Second {
- t.Fatalf("bad change delta")
- }
- if !state.StateChange.After(change) {
- t.Fatalf("should increment time")
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 1 {
- t.Fatalf("expected only one queued message")
- }
-
- // Check its a suspect message
- if messageType(m.broadcasts.bcQueue[0].b.Message()[0]) != deadMsg {
- t.Fatalf("expected queued dead msg")
- }
-}
-
-func TestMemberList_SuspectNode_DoubleSuspect(t *testing.T) {
- m := GetMemberlist(t)
- a := alive{Node: "test", Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a, nil, false)
-
- state := m.nodeMap["test"]
- state.StateChange = state.StateChange.Add(-time.Hour)
-
- s := suspect{Node: "test", Incarnation: 1}
- m.suspectNode(&s)
-
- if state.State != stateSuspect {
- t.Fatalf("Bad state")
- }
-
- change := state.StateChange
- if time.Now().Sub(change) > time.Second {
- t.Fatalf("bad change delta")
- }
-
- // clear the broadcast queue
- m.broadcasts.Reset()
-
- // Suspect again
- m.suspectNode(&s)
-
- if state.StateChange != change {
- t.Fatalf("unexpected state change")
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 0 {
- t.Fatalf("expected only one queued message")
- }
-
-}
-
-func TestMemberList_SuspectNode_OldSuspect(t *testing.T) {
- m := GetMemberlist(t)
- a := alive{Node: "test", Addr: []byte{127, 0, 0, 1}, Incarnation: 10}
- m.aliveNode(&a, nil, false)
-
- state := m.nodeMap["test"]
- state.StateChange = state.StateChange.Add(-time.Hour)
-
- // Clear queue
- m.broadcasts.Reset()
-
- s := suspect{Node: "test", Incarnation: 1}
- m.suspectNode(&s)
-
- if state.State != stateAlive {
- t.Fatalf("Bad state")
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 0 {
- t.Fatalf("expected only one queued message")
- }
-}
-
-func TestMemberList_SuspectNode_Refute(t *testing.T) {
- m := GetMemberlist(t)
- a := alive{Node: m.config.Name, Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a, nil, true)
-
- // Clear queue
- m.broadcasts.Reset()
-
- // Make sure health is in a good state
- if score := m.GetHealthScore(); score != 0 {
- t.Fatalf("bad: %d", score)
- }
-
- s := suspect{Node: m.config.Name, Incarnation: 1}
- m.suspectNode(&s)
-
- state := m.nodeMap[m.config.Name]
- if state.State != stateAlive {
- t.Fatalf("should still be alive")
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 1 {
- t.Fatalf("expected only one queued message")
- }
-
- // Should be alive mesg
- if messageType(m.broadcasts.bcQueue[0].b.Message()[0]) != aliveMsg {
- t.Fatalf("expected queued alive msg")
- }
-
- // Health should have been dinged
- if score := m.GetHealthScore(); score != 1 {
- t.Fatalf("bad: %d", score)
- }
-}
-
-func TestMemberList_DeadNode_NoNode(t *testing.T) {
- m := GetMemberlist(t)
- d := dead{Node: "test", Incarnation: 1}
- m.deadNode(&d)
- if len(m.nodes) != 0 {
- t.Fatalf("don't expect nodes")
- }
-}
-
-func TestMemberList_DeadNode(t *testing.T) {
- ch := make(chan NodeEvent, 1)
- m := GetMemberlist(t)
- m.config.Events = &ChannelEventDelegate{ch}
- a := alive{Node: "test", Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a, nil, false)
-
- // Read the join event
- <-ch
-
- state := m.nodeMap["test"]
- state.StateChange = state.StateChange.Add(-time.Hour)
-
- d := dead{Node: "test", Incarnation: 1}
- m.deadNode(&d)
-
- if state.State != stateDead {
- t.Fatalf("Bad state")
- }
-
- change := state.StateChange
- if time.Now().Sub(change) > time.Second {
- t.Fatalf("bad change delta")
- }
-
- select {
- case leave := <-ch:
- if leave.Event != NodeLeave || leave.Node.Name != "test" {
- t.Fatalf("bad node name")
- }
- default:
- t.Fatalf("no leave message")
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 1 {
- t.Fatalf("expected only one queued message")
- }
-
- // Check its a suspect message
- if messageType(m.broadcasts.bcQueue[0].b.Message()[0]) != deadMsg {
- t.Fatalf("expected queued dead msg")
- }
-}
-
-func TestMemberList_DeadNode_Double(t *testing.T) {
- ch := make(chan NodeEvent, 1)
- m := GetMemberlist(t)
- a := alive{Node: "test", Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a, nil, false)
-
- state := m.nodeMap["test"]
- state.StateChange = state.StateChange.Add(-time.Hour)
-
- d := dead{Node: "test", Incarnation: 1}
- m.deadNode(&d)
-
- // Clear queue
- m.broadcasts.Reset()
-
- // Notify after the first dead
- m.config.Events = &ChannelEventDelegate{ch}
-
- // Should do nothing
- d.Incarnation = 2
- m.deadNode(&d)
-
- select {
- case <-ch:
- t.Fatalf("should not get leave")
- default:
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 0 {
- t.Fatalf("expected only one queued message")
- }
-}
-
-func TestMemberList_DeadNode_OldDead(t *testing.T) {
- m := GetMemberlist(t)
- a := alive{Node: "test", Addr: []byte{127, 0, 0, 1}, Incarnation: 10}
- m.aliveNode(&a, nil, false)
-
- state := m.nodeMap["test"]
- state.StateChange = state.StateChange.Add(-time.Hour)
-
- d := dead{Node: "test", Incarnation: 1}
- m.deadNode(&d)
-
- if state.State != stateAlive {
- t.Fatalf("Bad state")
- }
-}
-
-func TestMemberList_DeadNode_AliveReplay(t *testing.T) {
- m := GetMemberlist(t)
- a := alive{Node: "test", Addr: []byte{127, 0, 0, 1}, Incarnation: 10}
- m.aliveNode(&a, nil, false)
-
- d := dead{Node: "test", Incarnation: 10}
- m.deadNode(&d)
-
- // Replay alive at same incarnation
- m.aliveNode(&a, nil, false)
-
- // Should remain dead
- state, ok := m.nodeMap["test"]
- if ok && state.State != stateDead {
- t.Fatalf("Bad state")
- }
-}
-
-func TestMemberList_DeadNode_Refute(t *testing.T) {
- m := GetMemberlist(t)
- a := alive{Node: m.config.Name, Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a, nil, true)
-
- // Clear queue
- m.broadcasts.Reset()
-
- // Make sure health is in a good state
- if score := m.GetHealthScore(); score != 0 {
- t.Fatalf("bad: %d", score)
- }
-
- d := dead{Node: m.config.Name, Incarnation: 1}
- m.deadNode(&d)
-
- state := m.nodeMap[m.config.Name]
- if state.State != stateAlive {
- t.Fatalf("should still be alive")
- }
-
- // Check a broad cast is queued
- if m.broadcasts.NumQueued() != 1 {
- t.Fatalf("expected only one queued message")
- }
-
- // Should be alive mesg
- if messageType(m.broadcasts.bcQueue[0].b.Message()[0]) != aliveMsg {
- t.Fatalf("expected queued alive msg")
- }
-
- // We should have been dinged
- if score := m.GetHealthScore(); score != 1 {
- t.Fatalf("bad: %d", score)
- }
-}
-
-func TestMemberList_MergeState(t *testing.T) {
- m := GetMemberlist(t)
- a1 := alive{Node: "test1", Addr: []byte{127, 0, 0, 1}, Incarnation: 1}
- m.aliveNode(&a1, nil, false)
- a2 := alive{Node: "test2", Addr: []byte{127, 0, 0, 2}, Incarnation: 1}
- m.aliveNode(&a2, nil, false)
- a3 := alive{Node: "test3", Addr: []byte{127, 0, 0, 3}, Incarnation: 1}
- m.aliveNode(&a3, nil, false)
-
- s := suspect{Node: "test1", Incarnation: 1}
- m.suspectNode(&s)
-
- remote := []pushNodeState{
- pushNodeState{
- Name: "test1",
- Addr: []byte{127, 0, 0, 1},
- Incarnation: 2,
- State: stateAlive,
- },
- pushNodeState{
- Name: "test2",
- Addr: []byte{127, 0, 0, 2},
- Incarnation: 1,
- State: stateSuspect,
- },
- pushNodeState{
- Name: "test3",
- Addr: []byte{127, 0, 0, 3},
- Incarnation: 1,
- State: stateDead,
- },
- pushNodeState{
- Name: "test4",
- Addr: []byte{127, 0, 0, 4},
- Incarnation: 2,
- State: stateAlive,
- },
- }
-
- // Listen for changes
- eventCh := make(chan NodeEvent, 1)
- m.config.Events = &ChannelEventDelegate{eventCh}
-
- // Merge remote state
- m.mergeState(remote)
-
- // Check the states
- state := m.nodeMap["test1"]
- if state.State != stateAlive || state.Incarnation != 2 {
- t.Fatalf("Bad state %v", state)
- }
-
- state = m.nodeMap["test2"]
- if state.State != stateSuspect || state.Incarnation != 1 {
- t.Fatalf("Bad state %v", state)
- }
-
- state = m.nodeMap["test3"]
- if state.State != stateSuspect {
- t.Fatalf("Bad state %v", state)
- }
-
- state = m.nodeMap["test4"]
- if state.State != stateAlive || state.Incarnation != 2 {
- t.Fatalf("Bad state %v", state)
- }
-
- // Check the channels
- select {
- case e := <-eventCh:
- if e.Event != NodeJoin || e.Node.Name != "test4" {
- t.Fatalf("bad node %v", e)
- }
- default:
- t.Fatalf("Expect join")
- }
-
- select {
- case e := <-eventCh:
- t.Fatalf("Unexpect event: %v", e)
- default:
- }
-}
-
-func TestMemberlist_Gossip(t *testing.T) {
- ch := make(chan NodeEvent, 3)
-
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
-
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.GossipInterval = time.Millisecond
- })
- m2 := HostMemberlist(addr2.String(), t, func(c *Config) {
- c.Events = &ChannelEventDelegate{ch}
- c.GossipInterval = time.Millisecond
- })
-
- defer m1.Shutdown()
- defer m2.Shutdown()
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
- a3 := alive{Node: "172.0.0.1", Addr: []byte{172, 0, 0, 1}, Incarnation: 1}
- m1.aliveNode(&a3, nil, false)
-
- // Gossip should send all this to m2
- m1.gossip()
-
- for i := 0; i < 3; i++ {
- select {
- case <-ch:
- case <-time.After(50 * time.Millisecond):
- t.Fatalf("timeout")
- }
- }
-}
-
-func TestMemberlist_GossipToDead(t *testing.T) {
- ch := make(chan NodeEvent, 2)
-
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
-
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.GossipInterval = time.Millisecond
- c.GossipToTheDeadTime = 100 * time.Millisecond
- })
- m2 := HostMemberlist(addr2.String(), t, func(c *Config) {
- c.Events = &ChannelEventDelegate{ch}
- })
-
- defer m1.Shutdown()
- defer m2.Shutdown()
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
-
- // Shouldn't send anything to m2 here, node has been dead for 2x the GossipToTheDeadTime
- m1.nodeMap[addr2.String()].State = stateDead
- m1.nodeMap[addr2.String()].StateChange = time.Now().Add(-200 * time.Millisecond)
- m1.gossip()
-
- select {
- case <-ch:
- t.Fatalf("shouldn't get gossip")
- case <-time.After(50 * time.Millisecond):
- }
-
- // Should gossip to m2 because its state has changed within GossipToTheDeadTime
- m1.nodeMap[addr2.String()].StateChange = time.Now().Add(-20 * time.Millisecond)
- m1.gossip()
-
- for i := 0; i < 2; i++ {
- select {
- case <-ch:
- case <-time.After(50 * time.Millisecond):
- t.Fatalf("timeout")
- }
- }
-}
-
-func TestMemberlist_PushPull(t *testing.T) {
- addr1 := getBindAddr()
- addr2 := getBindAddr()
- ip1 := []byte(addr1)
- ip2 := []byte(addr2)
-
- ch := make(chan NodeEvent, 3)
-
- m1 := HostMemberlist(addr1.String(), t, func(c *Config) {
- c.GossipInterval = 10 * time.Second
- c.PushPullInterval = time.Millisecond
- })
- m2 := HostMemberlist(addr2.String(), t, func(c *Config) {
- c.GossipInterval = 10 * time.Second
- c.Events = &ChannelEventDelegate{ch}
- })
-
- defer m1.Shutdown()
- defer m2.Shutdown()
-
- a1 := alive{Node: addr1.String(), Addr: ip1, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a1, nil, true)
- a2 := alive{Node: addr2.String(), Addr: ip2, Port: 7946, Incarnation: 1}
- m1.aliveNode(&a2, nil, false)
-
- // Gossip should send all this to m2
- m1.pushPull()
-
- for i := 0; i < 2; i++ {
- select {
- case <-ch:
- case <-time.After(10 * time.Millisecond):
- t.Fatalf("timeout")
- }
- }
-}
-
-func TestVerifyProtocol(t *testing.T) {
- cases := []struct {
- Anodes [][3]uint8
- Bnodes [][3]uint8
- expected bool
- }{
- // Both running identical everything
- {
- Anodes: [][3]uint8{
- {0, 0, 0},
- },
- Bnodes: [][3]uint8{
- {0, 0, 0},
- },
- expected: true,
- },
-
- // One can understand newer, but speaking same protocol
- {
- Anodes: [][3]uint8{
- {0, 0, 0},
- },
- Bnodes: [][3]uint8{
- {0, 1, 0},
- },
- expected: true,
- },
-
- // One is speaking outside the range
- {
- Anodes: [][3]uint8{
- {0, 0, 0},
- },
- Bnodes: [][3]uint8{
- {1, 1, 1},
- },
- expected: false,
- },
-
- // Transitively outside the range
- {
- Anodes: [][3]uint8{
- {0, 1, 0},
- {0, 2, 1},
- },
- Bnodes: [][3]uint8{
- {1, 3, 1},
- },
- expected: false,
- },
-
- // Multi-node
- {
- Anodes: [][3]uint8{
- {0, 3, 2},
- {0, 2, 0},
- },
- Bnodes: [][3]uint8{
- {0, 2, 1},
- {0, 5, 0},
- },
- expected: true,
- },
- }
-
- for _, tc := range cases {
- aCore := make([][6]uint8, len(tc.Anodes))
- aApp := make([][6]uint8, len(tc.Anodes))
- for i, n := range tc.Anodes {
- aCore[i] = [6]uint8{n[0], n[1], n[2], 0, 0, 0}
- aApp[i] = [6]uint8{0, 0, 0, n[0], n[1], n[2]}
- }
-
- bCore := make([][6]uint8, len(tc.Bnodes))
- bApp := make([][6]uint8, len(tc.Bnodes))
- for i, n := range tc.Bnodes {
- bCore[i] = [6]uint8{n[0], n[1], n[2], 0, 0, 0}
- bApp[i] = [6]uint8{0, 0, 0, n[0], n[1], n[2]}
- }
-
- // Test core protocol verification
- testVerifyProtocolSingle(t, aCore, bCore, tc.expected)
- testVerifyProtocolSingle(t, bCore, aCore, tc.expected)
-
- // Test app protocol verification
- testVerifyProtocolSingle(t, aApp, bApp, tc.expected)
- testVerifyProtocolSingle(t, bApp, aApp, tc.expected)
- }
-}
-
-func testVerifyProtocolSingle(t *testing.T, A [][6]uint8, B [][6]uint8, expect bool) {
- m := GetMemberlist(t)
- defer m.Shutdown()
-
- m.nodes = make([]*nodeState, len(A))
- for i, n := range A {
- m.nodes[i] = &nodeState{
- Node: Node{
- PMin: n[0],
- PMax: n[1],
- PCur: n[2],
- DMin: n[3],
- DMax: n[4],
- DCur: n[5],
- },
- }
- }
-
- remote := make([]pushNodeState, len(B))
- for i, n := range B {
- remote[i] = pushNodeState{
- Name: fmt.Sprintf("node %d", i),
- Vsn: []uint8{n[0], n[1], n[2], n[3], n[4], n[5]},
- }
- }
-
- err := m.verifyProtocol(remote)
- if (err == nil) != expect {
- t.Fatalf("bad:\nA: %v\nB: %v\nErr: %s", A, B, err)
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/suspicion_test.go b/vendor/github.com/hashicorp/memberlist/suspicion_test.go
deleted file mode 100644
index 1b5ca8a5a..000000000
--- a/vendor/github.com/hashicorp/memberlist/suspicion_test.go
+++ /dev/null
@@ -1,198 +0,0 @@
-package memberlist
-
-import (
- "testing"
- "time"
-)
-
-func TestSuspicion_remainingSuspicionTime(t *testing.T) {
- cases := []struct {
- n int32
- k int32
- elapsed time.Duration
- min time.Duration
- max time.Duration
- expected time.Duration
- }{
- {0, 3, 0, 2 * time.Second, 30 * time.Second, 30 * time.Second},
- {1, 3, 2 * time.Second, 2 * time.Second, 30 * time.Second, 14 * time.Second},
- {2, 3, 3 * time.Second, 2 * time.Second, 30 * time.Second, 4810 * time.Millisecond},
- {3, 3, 4 * time.Second, 2 * time.Second, 30 * time.Second, -2 * time.Second},
- {4, 3, 5 * time.Second, 2 * time.Second, 30 * time.Second, -3 * time.Second},
- {5, 3, 10 * time.Second, 2 * time.Second, 30 * time.Second, -8 * time.Second},
- }
- for i, c := range cases {
- remaining := remainingSuspicionTime(c.n, c.k, c.elapsed, c.min, c.max)
- if remaining != c.expected {
- t.Errorf("case %d: remaining %9.6f != expected %9.6f", i, remaining.Seconds(), c.expected.Seconds())
- }
- }
-}
-
-func TestSuspicion_Timer(t *testing.T) {
- const k = 3
- const min = 500 * time.Millisecond
- const max = 2 * time.Second
-
- type pair struct {
- from string
- newInfo bool
- }
- cases := []struct {
- numConfirmations int
- from string
- confirmations []pair
- expected time.Duration
- }{
- {
- 0,
- "me",
- []pair{},
- max,
- },
- {
- 1,
- "me",
- []pair{
- pair{"me", false},
- pair{"foo", true},
- },
- 1250 * time.Millisecond,
- },
- {
- 1,
- "me",
- []pair{
- pair{"me", false},
- pair{"foo", true},
- pair{"foo", false},
- pair{"foo", false},
- },
- 1250 * time.Millisecond,
- },
- {
- 2,
- "me",
- []pair{
- pair{"me", false},
- pair{"foo", true},
- pair{"bar", true},
- },
- 810 * time.Millisecond,
- },
- {
- 3,
- "me",
- []pair{
- pair{"me", false},
- pair{"foo", true},
- pair{"bar", true},
- pair{"baz", true},
- },
- min,
- },
- {
- 3,
- "me",
- []pair{
- pair{"me", false},
- pair{"foo", true},
- pair{"bar", true},
- pair{"baz", true},
- pair{"zoo", false},
- },
- min,
- },
- }
- for i, c := range cases {
- ch := make(chan time.Duration, 1)
- start := time.Now()
- f := func(numConfirmations int) {
- if numConfirmations != c.numConfirmations {
- t.Errorf("case %d: bad %d != %d", i, numConfirmations, c.numConfirmations)
- }
-
- ch <- time.Now().Sub(start)
- }
-
- // Create the timer and add the requested confirmations. Wait
- // the fudge amount to help make sure we calculate the timeout
- // overall, and don't accumulate extra time.
- s := newSuspicion(c.from, k, min, max, f)
- fudge := 25 * time.Millisecond
- for _, p := range c.confirmations {
- time.Sleep(fudge)
- if s.Confirm(p.from) != p.newInfo {
- t.Fatalf("case %d: newInfo mismatch for %s", i, p.from)
- }
- }
-
- // Wait until right before the timeout and make sure the
- // timer hasn't fired.
- already := time.Duration(len(c.confirmations)) * fudge
- time.Sleep(c.expected - already - fudge)
- select {
- case d := <-ch:
- t.Fatalf("case %d: should not have fired (%9.6f)", i, d.Seconds())
- default:
- }
-
- // Wait through the timeout and a little after and make sure it
- // fires.
- time.Sleep(2 * fudge)
- select {
- case <-ch:
- default:
- t.Fatalf("case %d: should have fired", i)
- }
-
- // Confirm after to make sure it handles a negative remaining
- // time correctly and doesn't fire again.
- s.Confirm("late")
- time.Sleep(c.expected + 2*fudge)
- select {
- case d := <-ch:
- t.Fatalf("case %d: should not have fired (%9.6f)", i, d.Seconds())
- default:
- }
- }
-}
-
-func TestSuspicion_Timer_ZeroK(t *testing.T) {
- ch := make(chan struct{}, 1)
- f := func(int) {
- ch <- struct{}{}
- }
-
- // This should select the min time since there are no expected
- // confirmations to accelerate the timer.
- s := newSuspicion("me", 0, 25*time.Millisecond, 30*time.Second, f)
- if s.Confirm("foo") {
- t.Fatalf("should not provide new information")
- }
-
- select {
- case <-ch:
- case <-time.After(50 * time.Millisecond):
- t.Fatalf("should have fired")
- }
-}
-
-func TestSuspicion_Timer_Immediate(t *testing.T) {
- ch := make(chan struct{}, 1)
- f := func(int) {
- ch <- struct{}{}
- }
-
- // This should underflow the timeout and fire immediately.
- s := newSuspicion("me", 1, 100*time.Millisecond, 30*time.Second, f)
- time.Sleep(200 * time.Millisecond)
- s.Confirm("foo")
-
- // Wait a little while since the function gets called in a goroutine.
- select {
- case <-ch:
- case <-time.After(25 * time.Millisecond):
- t.Fatalf("should have fired")
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/test/setup_subnet.sh b/vendor/github.com/hashicorp/memberlist/test/setup_subnet.sh
deleted file mode 100755
index 6651c8ce4..000000000
--- a/vendor/github.com/hashicorp/memberlist/test/setup_subnet.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-#
-# This script makes sure that 127.0.0.x is routable. On Darwin, there
-# is a bug that it isn't routable and this causes errors.
-#
-
-# Check if loopback is setup
-ping -c 1 -W 10 127.0.0.2 > /dev/null 2>&1
-if [ $? -eq 0 ]
-then
- exit
-fi
-
-# If we're not on OS X, then error
-case $OSTYPE in
- darwin*)
- ;;
- *)
- echo "Can't setup interfaces on non-Mac. Error!"
- exit 1
- ;;
-esac
-
-# Setup loopback
-for ((i=2;i<256;i++))
-do
- sudo ifconfig lo0 alias 127.0.0.$i up
-done
diff --git a/vendor/github.com/hashicorp/memberlist/transport_test.go b/vendor/github.com/hashicorp/memberlist/transport_test.go
deleted file mode 100644
index b5249eb5f..000000000
--- a/vendor/github.com/hashicorp/memberlist/transport_test.go
+++ /dev/null
@@ -1,124 +0,0 @@
-package memberlist
-
-import (
- "bytes"
- "testing"
- "time"
-)
-
-func TestTransport_Join(t *testing.T) {
- net := &MockNetwork{}
-
- t1 := net.NewTransport()
-
- c1 := DefaultLANConfig()
- c1.Name = "node1"
- c1.Transport = t1
- m1, err := Create(c1)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- c2 := DefaultLANConfig()
- c2.Name = "node2"
- c2.Transport = net.NewTransport()
- m2, err := Create(c2)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- m2.setAlive()
- m2.schedule()
- defer m2.Shutdown()
-
- num, err := m2.Join([]string{t1.addr.String()})
- if num != 1 {
- t.Fatalf("bad: %d", num)
- }
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- if len(m2.Members()) != 2 {
- t.Fatalf("bad: %v", m2.Members())
- }
- if m2.estNumNodes() != 2 {
- t.Fatalf("bad: %v", m2.Members())
- }
-
-}
-
-func TestTransport_Send(t *testing.T) {
- net := &MockNetwork{}
-
- t1 := net.NewTransport()
- d1 := &MockDelegate{}
-
- c1 := DefaultLANConfig()
- c1.Name = "node1"
- c1.Transport = t1
- c1.Delegate = d1
- m1, err := Create(c1)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- m1.setAlive()
- m1.schedule()
- defer m1.Shutdown()
-
- c2 := DefaultLANConfig()
- c2.Name = "node2"
- c2.Transport = net.NewTransport()
- m2, err := Create(c2)
- if err != nil {
- t.Fatalf("err: %v", err)
- }
- m2.setAlive()
- m2.schedule()
- defer m2.Shutdown()
-
- num, err := m2.Join([]string{t1.addr.String()})
- if num != 1 {
- t.Fatalf("bad: %d", num)
- }
- if err != nil {
- t.Fatalf("err: %v", err)
- }
-
- if err := m2.SendTo(t1.addr, []byte("SendTo")); err != nil {
- t.Fatalf("err: %v", err)
- }
-
- var n1 *Node
- for _, n := range m2.Members() {
- if n.Name == c1.Name {
- n1 = n
- break
- }
- }
- if n1 == nil {
- t.Fatalf("bad")
- }
-
- if err := m2.SendToUDP(n1, []byte("SendToUDP")); err != nil {
- t.Fatalf("err: %v", err)
- }
- if err := m2.SendToTCP(n1, []byte("SendToTCP")); err != nil {
- t.Fatalf("err: %v", err)
- }
- if err := m2.SendBestEffort(n1, []byte("SendBestEffort")); err != nil {
- t.Fatalf("err: %v", err)
- }
- if err := m2.SendReliable(n1, []byte("SendReliable")); err != nil {
- t.Fatalf("err: %v", err)
- }
- time.Sleep(100 * time.Millisecond)
-
- received := bytes.Join(d1.msgs, []byte("|"))
- expected := []byte("SendTo|SendToUDP|SendToTCP|SendBestEffort|SendReliable")
- if !bytes.Equal(received, expected) {
- t.Fatalf("bad: %s", received)
- }
-}
diff --git a/vendor/github.com/hashicorp/memberlist/util_test.go b/vendor/github.com/hashicorp/memberlist/util_test.go
deleted file mode 100644
index b7f2b4199..000000000
--- a/vendor/github.com/hashicorp/memberlist/util_test.go
+++ /dev/null
@@ -1,358 +0,0 @@
-package memberlist
-
-import (
- "fmt"
- "reflect"
- "testing"
- "time"
-)
-
-func TestUtil_PortFunctions(t *testing.T) {
- tests := []struct {
- addr string
- hasPort bool
- ensurePort string
- }{
- {"1.2.3.4", false, "1.2.3.4:8301"},
- {"1.2.3.4:1234", true, "1.2.3.4:1234"},
- {"2600:1f14:e22:1501:f9a:2e0c:a167:67e8", false, "[2600:1f14:e22:1501:f9a:2e0c:a167:67e8]:8301"},
- {"[2600:1f14:e22:1501:f9a:2e0c:a167:67e8]", false, "[2600:1f14:e22:1501:f9a:2e0c:a167:67e8]:8301"},
- {"[2600:1f14:e22:1501:f9a:2e0c:a167:67e8]:1234", true, "[2600:1f14:e22:1501:f9a:2e0c:a167:67e8]:1234"},
- {"localhost", false, "localhost:8301"},
- {"localhost:1234", true, "localhost:1234"},
- {"hashicorp.com", false, "hashicorp.com:8301"},
- {"hashicorp.com:1234", true, "hashicorp.com:1234"},
- }
- for _, tt := range tests {
- t.Run(tt.addr, func(t *testing.T) {
- if got, want := hasPort(tt.addr), tt.hasPort; got != want {
- t.Fatalf("got %v want %v", got, want)
- }
- if got, want := ensurePort(tt.addr, 8301), tt.ensurePort; got != want {
- t.Fatalf("got %v want %v", got, want)
- }
- })
- }
-}
-
-func TestEncodeDecode(t *testing.T) {
- msg := &ping{SeqNo: 100}
- buf, err := encode(pingMsg, msg)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- var out ping
- if err := decode(buf.Bytes()[1:], &out); err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- if msg.SeqNo != out.SeqNo {
- t.Fatalf("bad sequence no")
- }
-}
-
-func TestRandomOffset(t *testing.T) {
- vals := make(map[int]struct{})
- for i := 0; i < 100; i++ {
- offset := randomOffset(2 << 30)
- if _, ok := vals[offset]; ok {
- t.Fatalf("got collision")
- }
- vals[offset] = struct{}{}
- }
-}
-
-func TestRandomOffset_Zero(t *testing.T) {
- offset := randomOffset(0)
- if offset != 0 {
- t.Fatalf("bad offset")
- }
-}
-
-func TestSuspicionTimeout(t *testing.T) {
- timeouts := map[int]time.Duration{
- 5: 1000 * time.Millisecond,
- 10: 1000 * time.Millisecond,
- 50: 1698 * time.Millisecond,
- 100: 2000 * time.Millisecond,
- 500: 2698 * time.Millisecond,
- 1000: 3000 * time.Millisecond,
- }
- for n, expected := range timeouts {
- timeout := suspicionTimeout(3, n, time.Second) / 3
- if timeout != expected {
- t.Fatalf("bad: %v, %v", expected, timeout)
- }
- }
-}
-
-func TestRetransmitLimit(t *testing.T) {
- lim := retransmitLimit(3, 0)
- if lim != 0 {
- t.Fatalf("bad val %v", lim)
- }
- lim = retransmitLimit(3, 1)
- if lim != 3 {
- t.Fatalf("bad val %v", lim)
- }
- lim = retransmitLimit(3, 99)
- if lim != 6 {
- t.Fatalf("bad val %v", lim)
- }
-}
-
-func TestShuffleNodes(t *testing.T) {
- orig := []*nodeState{
- &nodeState{
- State: stateDead,
- },
- &nodeState{
- State: stateAlive,
- },
- &nodeState{
- State: stateAlive,
- },
- &nodeState{
- State: stateDead,
- },
- &nodeState{
- State: stateAlive,
- },
- &nodeState{
- State: stateAlive,
- },
- &nodeState{
- State: stateDead,
- },
- &nodeState{
- State: stateAlive,
- },
- }
- nodes := make([]*nodeState, len(orig))
- copy(nodes[:], orig[:])
-
- if !reflect.DeepEqual(nodes, orig) {
- t.Fatalf("should match")
- }
-
- shuffleNodes(nodes)
-
- if reflect.DeepEqual(nodes, orig) {
- t.Fatalf("should not match")
- }
-}
-
-func TestPushPullScale(t *testing.T) {
- sec := time.Second
- for i := 0; i <= 32; i++ {
- if s := pushPullScale(sec, i); s != sec {
- t.Fatalf("Bad time scale: %v", s)
- }
- }
- for i := 33; i <= 64; i++ {
- if s := pushPullScale(sec, i); s != 2*sec {
- t.Fatalf("Bad time scale: %v", s)
- }
- }
- for i := 65; i <= 128; i++ {
- if s := pushPullScale(sec, i); s != 3*sec {
- t.Fatalf("Bad time scale: %v", s)
- }
- }
-}
-
-func TestMoveDeadNodes(t *testing.T) {
- nodes := []*nodeState{
- &nodeState{
- State: stateDead,
- StateChange: time.Now().Add(-20 * time.Second),
- },
- &nodeState{
- State: stateAlive,
- StateChange: time.Now().Add(-20 * time.Second),
- },
- // This dead node should not be moved, as its state changed
- // less than the specified GossipToTheDead time ago
- &nodeState{
- State: stateDead,
- StateChange: time.Now().Add(-10 * time.Second),
- },
- &nodeState{
- State: stateAlive,
- StateChange: time.Now().Add(-20 * time.Second),
- },
- &nodeState{
- State: stateDead,
- StateChange: time.Now().Add(-20 * time.Second),
- },
- &nodeState{
- State: stateAlive,
- StateChange: time.Now().Add(-20 * time.Second),
- },
- }
-
- idx := moveDeadNodes(nodes, (15 * time.Second))
- if idx != 4 {
- t.Fatalf("bad index")
- }
- for i := 0; i < idx; i++ {
- switch i {
- case 2:
- // Recently dead node remains at index 2,
- // since nodes are swapped out to move to end.
- if nodes[i].State != stateDead {
- t.Fatalf("Bad state %d", i)
- }
- default:
- if nodes[i].State != stateAlive {
- t.Fatalf("Bad state %d", i)
- }
- }
- }
- for i := idx; i < len(nodes); i++ {
- if nodes[i].State != stateDead {
- t.Fatalf("Bad state %d", i)
- }
- }
-}
-
-func TestKRandomNodes(t *testing.T) {
- nodes := []*nodeState{}
- for i := 0; i < 90; i++ {
- // Half the nodes are in a bad state
- state := stateAlive
- switch i % 3 {
- case 0:
- state = stateAlive
- case 1:
- state = stateSuspect
- case 2:
- state = stateDead
- }
- nodes = append(nodes, &nodeState{
- Node: Node{
- Name: fmt.Sprintf("test%d", i),
- },
- State: state,
- })
- }
-
- filterFunc := func(n *nodeState) bool {
- if n.Name == "test0" || n.State != stateAlive {
- return true
- }
- return false
- }
-
- s1 := kRandomNodes(3, nodes, filterFunc)
- s2 := kRandomNodes(3, nodes, filterFunc)
- s3 := kRandomNodes(3, nodes, filterFunc)
-
- if reflect.DeepEqual(s1, s2) {
- t.Fatalf("unexpected equal")
- }
- if reflect.DeepEqual(s1, s3) {
- t.Fatalf("unexpected equal")
- }
- if reflect.DeepEqual(s2, s3) {
- t.Fatalf("unexpected equal")
- }
-
- for _, s := range [][]*nodeState{s1, s2, s3} {
- if len(s) != 3 {
- t.Fatalf("bad len")
- }
- for _, n := range s {
- if n.Name == "test0" {
- t.Fatalf("Bad name")
- }
- if n.State != stateAlive {
- t.Fatalf("Bad state")
- }
- }
- }
-}
-
-func TestMakeCompoundMessage(t *testing.T) {
- msg := &ping{SeqNo: 100}
- buf, err := encode(pingMsg, msg)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- msgs := [][]byte{buf.Bytes(), buf.Bytes(), buf.Bytes()}
- compound := makeCompoundMessage(msgs)
-
- if compound.Len() != 3*buf.Len()+3*compoundOverhead+compoundHeaderOverhead {
- t.Fatalf("bad len")
- }
-}
-
-func TestDecodeCompoundMessage(t *testing.T) {
- msg := &ping{SeqNo: 100}
- buf, err := encode(pingMsg, msg)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- msgs := [][]byte{buf.Bytes(), buf.Bytes(), buf.Bytes()}
- compound := makeCompoundMessage(msgs)
-
- trunc, parts, err := decodeCompoundMessage(compound.Bytes()[1:])
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- if trunc != 0 {
- t.Fatalf("should not truncate")
- }
- if len(parts) != 3 {
- t.Fatalf("bad parts")
- }
- for _, p := range parts {
- if len(p) != buf.Len() {
- t.Fatalf("bad part len")
- }
- }
-}
-
-func TestDecodeCompoundMessage_Trunc(t *testing.T) {
- msg := &ping{SeqNo: 100}
- buf, err := encode(pingMsg, msg)
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- msgs := [][]byte{buf.Bytes(), buf.Bytes(), buf.Bytes()}
- compound := makeCompoundMessage(msgs)
-
- trunc, parts, err := decodeCompoundMessage(compound.Bytes()[1:38])
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
- if trunc != 1 {
- t.Fatalf("truncate: %d", trunc)
- }
- if len(parts) != 2 {
- t.Fatalf("bad parts")
- }
- for _, p := range parts {
- if len(p) != buf.Len() {
- t.Fatalf("bad part len")
- }
- }
-}
-
-func TestCompressDecompressPayload(t *testing.T) {
- buf, err := compressPayload([]byte("testing"))
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- decomp, err := decompressPayload(buf.Bytes()[1:])
- if err != nil {
- t.Fatalf("unexpected err: %s", err)
- }
-
- if !reflect.DeepEqual(decomp, []byte("testing")) {
- t.Fatalf("bad payload: %v", decomp)
- }
-}