|
|
@ -2,8 +2,11 @@ package system
|
|
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"net"
|
|
|
|
"testing"
|
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"github.com/rqlite/rqlite/tcp"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
// Test_JoinLeaderNode tests a join operation between a leader and a new node.
|
|
|
|
// Test_JoinLeaderNode tests a join operation between a leader and a new node.
|
|
|
@ -157,6 +160,69 @@ func Test_MultiNodeCluster(t *testing.T) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Test_MultiNodeClusterRaftAdv tests 3-node cluster with advertised Raft addresses usage.
|
|
|
|
|
|
|
|
func Test_MultiNodeClusterRaftAdv(t *testing.T) {
|
|
|
|
|
|
|
|
ln1 := mustTCPListener("0.0.0.0:0")
|
|
|
|
|
|
|
|
defer ln1.Close()
|
|
|
|
|
|
|
|
ln2 := mustTCPListener("0.0.0.0:0")
|
|
|
|
|
|
|
|
defer ln2.Close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
advAddr := mustGetLocalIPv4Address()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_, port1, err := net.SplitHostPort(ln1.Addr().String())
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Fatalf("failed to get host and port: %s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
_, port2, err := net.SplitHostPort(ln2.Addr().String())
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Fatalf("failed to get host and port: %s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
advAddr1, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(advAddr, port1))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Fatalf("failed to resolve TCP address: %s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
advAddr2, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(advAddr, port2))
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Fatalf("failed to resolve TCP address: %s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mux1, err := tcp.NewMux(ln1, advAddr1)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Fatalf("failed to create node-to-node mux: %s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
go mux1.Serve()
|
|
|
|
|
|
|
|
mux2, err := tcp.NewMux(ln2, advAddr2)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Fatalf("failed to create node-to-node mux: %s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
go mux2.Serve()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Start two nodes, and ensure a cluster can be formed.
|
|
|
|
|
|
|
|
node1 := mustNodeEncrypted(mustTempDir(), true, false, mux1, "1")
|
|
|
|
|
|
|
|
defer node1.Deprovision()
|
|
|
|
|
|
|
|
leader, err := node1.WaitForLeader()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Fatalf("failed waiting for leader on node1: %s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if exp, got := advAddr1.String(), leader; exp != got {
|
|
|
|
|
|
|
|
t.Fatalf("node return wrong leader from leader, exp: %s, got %s", exp, got)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
node2 := mustNodeEncrypted(mustTempDir(), false, false, mux2, "2")
|
|
|
|
|
|
|
|
defer node2.Deprovision()
|
|
|
|
|
|
|
|
if err := node2.Join(node1); err != nil {
|
|
|
|
|
|
|
|
t.Fatalf("node2 failed to join leader: %s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
leader, err = node2.WaitForLeader()
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
t.Fatalf("failed waiting for leader on node2: %s", err.Error())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if exp, got := advAddr1.String(), leader; exp != got {
|
|
|
|
|
|
|
|
t.Fatalf("node return wrong leader from follower, exp: %s, got %s", exp, got)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Test_MultiNodeClusterNodes checks nodes/ endpoint under various situations.
|
|
|
|
// Test_MultiNodeClusterNodes checks nodes/ endpoint under various situations.
|
|
|
|
func Test_MultiNodeClusterNodes(t *testing.T) {
|
|
|
|
func Test_MultiNodeClusterNodes(t *testing.T) {
|
|
|
|
node1 := mustNewLeaderNode()
|
|
|
|
node1 := mustNewLeaderNode()
|
|
|
|