2017-12-18 20:26:35 +00:00
|
|
|
package autopilot
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"net"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/serf/serf"
|
2019-12-16 22:35:13 +00:00
|
|
|
"github.com/stretchr/testify/require"
|
2017-12-18 20:26:35 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestMinRaftProtocol(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
makeMember := func(version string) serf.Member {
|
|
|
|
return serf.Member{
|
|
|
|
Name: "foo",
|
|
|
|
Addr: net.IP([]byte{127, 0, 0, 1}),
|
|
|
|
Tags: map[string]string{
|
|
|
|
"role": "consul",
|
|
|
|
"dc": "dc1",
|
|
|
|
"port": "10000",
|
|
|
|
"vsn": "1",
|
|
|
|
"raft_vsn": version,
|
|
|
|
},
|
|
|
|
Status: serf.StatusAlive,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
members []serf.Member
|
|
|
|
expected int
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
// No servers, error
|
|
|
|
{
|
|
|
|
members: []serf.Member{},
|
|
|
|
expected: -1,
|
|
|
|
err: errors.New("No servers found"),
|
|
|
|
},
|
|
|
|
// One server
|
|
|
|
{
|
|
|
|
members: []serf.Member{
|
|
|
|
makeMember("1"),
|
|
|
|
},
|
|
|
|
expected: 1,
|
|
|
|
},
|
|
|
|
// One server, bad version formatting
|
|
|
|
{
|
|
|
|
members: []serf.Member{
|
|
|
|
makeMember("asdf"),
|
|
|
|
},
|
|
|
|
expected: -1,
|
|
|
|
err: errors.New(`strconv.Atoi: parsing "asdf": invalid syntax`),
|
|
|
|
},
|
|
|
|
// Multiple servers, different versions
|
|
|
|
{
|
|
|
|
members: []serf.Member{
|
|
|
|
makeMember("1"),
|
|
|
|
makeMember("2"),
|
|
|
|
},
|
|
|
|
expected: 1,
|
|
|
|
},
|
|
|
|
// Multiple servers, same version
|
|
|
|
{
|
|
|
|
members: []serf.Member{
|
|
|
|
makeMember("2"),
|
|
|
|
makeMember("2"),
|
|
|
|
},
|
|
|
|
expected: 2,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
serverFunc := func(m serf.Member) (*ServerInfo, error) {
|
|
|
|
return &ServerInfo{}, nil
|
|
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
|
|
result, err := minRaftProtocol(tc.members, serverFunc)
|
|
|
|
if result != tc.expected {
|
|
|
|
t.Fatalf("bad: %v, %v, %v", result, tc.expected, tc)
|
|
|
|
}
|
|
|
|
if tc.err != nil {
|
|
|
|
if err == nil || tc.err.Error() != err.Error() {
|
|
|
|
t.Fatalf("bad: %v, %v, %v", err, tc.err, tc)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-12-16 22:35:13 +00:00
|
|
|
|
|
|
|
func TestAutopilot_canRemoveServers(t *testing.T) {
|
|
|
|
type test struct {
|
|
|
|
peers int
|
|
|
|
minQuorum int
|
|
|
|
deadServers int
|
|
|
|
ok bool
|
|
|
|
}
|
|
|
|
|
|
|
|
tests := []test{
|
|
|
|
{1, 1, 1, false},
|
|
|
|
{3, 3, 1, false},
|
|
|
|
{4, 3, 3, false},
|
|
|
|
{5, 3, 3, false},
|
|
|
|
{5, 3, 2, true},
|
|
|
|
{5, 3, 1, true},
|
|
|
|
{9, 3, 5, false},
|
|
|
|
}
|
|
|
|
for _, test := range tests {
|
|
|
|
ok, msg := canRemoveServers(test.peers, test.minQuorum, test.deadServers)
|
|
|
|
require.Equal(t, test.ok, ok)
|
|
|
|
t.Logf("%+v: %s", test, msg)
|
|
|
|
}
|
|
|
|
}
|