2018-10-29 17:19:37 +08:00
|
|
|
/*
|
2019-01-02 18:55:26 +08:00
|
|
|
* Copyright (C) 2017-2019 Lightbend Inc. <https://www.lightbend.com>
|
2017-11-02 08:17:24 +00:00
|
|
|
*/
|
2018-03-13 23:45:55 +09:00
|
|
|
|
2017-11-02 08:17:24 +00:00
|
|
|
package akka.cluster
|
|
|
|
|
|
|
|
|
|
import akka.actor.Address
|
|
|
|
|
import akka.cluster.MemberStatus.Up
|
|
|
|
|
import org.scalatest.{ Matchers, WordSpec }
|
|
|
|
|
|
|
|
|
|
import scala.collection.immutable.SortedSet
|
|
|
|
|
|
|
|
|
|
class MembershipStateSpec extends WordSpec with Matchers {
|
|
|
|
|
// DC-a is in reverse age order
|
2019-05-15 18:01:34 +02:00
|
|
|
val a1 = TestMember(Address("akka", "sys", "a4", 2552), Up, 1, "dc-a")
|
|
|
|
|
val a2 = TestMember(Address("akka", "sys", "a3", 2552), Up, 2, "dc-a")
|
|
|
|
|
val a3 = TestMember(Address("akka", "sys", "a2", 2552), Up, 3, "dc-a")
|
|
|
|
|
val a4 = TestMember(Address("akka", "sys", "a1", 2552), Up, 4, "dc-a")
|
2017-11-02 08:17:24 +00:00
|
|
|
|
|
|
|
|
// DC-b it is the first and the last that are the oldest
|
2019-05-15 18:01:34 +02:00
|
|
|
val b1 = TestMember(Address("akka", "sys", "b3", 2552), Up, 1, "dc-b")
|
|
|
|
|
val b3 = TestMember(Address("akka", "sys", "b2", 2552), Up, 3, "dc-b")
|
2017-11-02 08:17:24 +00:00
|
|
|
// Won't be replaced by b3
|
2019-05-15 18:01:34 +02:00
|
|
|
val b2 = TestMember(Address("akka", "sys", "b1", 2552), Up, 2, "dc-b")
|
2017-11-02 08:17:24 +00:00
|
|
|
// for the case that we don't replace it ever
|
2019-05-15 18:01:34 +02:00
|
|
|
val bOldest = TestMember(Address("akka", "sys", "b0", 2552), Up, 0, "dc-b")
|
2017-11-02 08:17:24 +00:00
|
|
|
|
|
|
|
|
"Membership state" must {
|
|
|
|
|
"sort by upNumber for oldest top members" in {
|
|
|
|
|
val gossip = Gossip(SortedSet(a1, a2, a3, a4, b1, b2, b3, bOldest))
|
2019-03-11 10:38:24 +01:00
|
|
|
val membershipState = MembershipState(gossip, a1.uniqueAddress, "dc-a", 2)
|
2017-11-02 08:17:24 +00:00
|
|
|
|
2019-03-11 10:38:24 +01:00
|
|
|
membershipState.ageSortedTopOldestMembersPerDc should equal(
|
|
|
|
|
Map("dc-a" -> SortedSet(a1, a2), "dc-b" -> SortedSet(bOldest, b1)))
|
2017-11-02 08:17:24 +00:00
|
|
|
}
|
2018-11-09 09:42:48 +01:00
|
|
|
|
|
|
|
|
"find two oldest as targets for Exiting change" in {
|
|
|
|
|
val a1Exiting = a1.copy(MemberStatus.Leaving).copy(MemberStatus.Exiting)
|
|
|
|
|
val gossip = Gossip(SortedSet(a1Exiting, a2, a3, a4))
|
2019-03-11 10:38:24 +01:00
|
|
|
val membershipState = MembershipState(gossip, a1.uniqueAddress, "dc-a", 2)
|
2018-11-09 09:42:48 +01:00
|
|
|
|
|
|
|
|
membershipState.gossipTargetsForExitingMembers(Set(a1Exiting)) should ===(Set(a1Exiting, a2))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"find two oldest in DC as targets for Exiting change" in {
|
|
|
|
|
val a4Exiting = a4.copy(MemberStatus.Leaving).copy(MemberStatus.Exiting)
|
|
|
|
|
val gossip = Gossip(SortedSet(a2, a3, a4Exiting, b1, b2))
|
2019-03-11 10:38:24 +01:00
|
|
|
val membershipState = MembershipState(gossip, a1.uniqueAddress, "dc-a", 2)
|
2018-11-09 09:42:48 +01:00
|
|
|
|
|
|
|
|
membershipState.gossipTargetsForExitingMembers(Set(a4Exiting)) should ===(Set(a2, a3))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
"find two oldest per role as targets for Exiting change" in {
|
2019-03-13 10:56:20 +01:00
|
|
|
val a5 = TestMember(
|
2019-05-15 18:01:34 +02:00
|
|
|
Address("akka", "sys", "a5", 2552),
|
2019-03-13 10:56:20 +01:00
|
|
|
MemberStatus.Exiting,
|
|
|
|
|
roles = Set("role1", "role2"),
|
|
|
|
|
upNumber = 5,
|
|
|
|
|
dataCenter = "dc-a")
|
|
|
|
|
val a6 = TestMember(
|
2019-05-15 18:01:34 +02:00
|
|
|
Address("akka", "sys", "a6", 2552),
|
2019-03-13 10:56:20 +01:00
|
|
|
MemberStatus.Exiting,
|
|
|
|
|
roles = Set("role1", "role3"),
|
|
|
|
|
upNumber = 6,
|
|
|
|
|
dataCenter = "dc-a")
|
|
|
|
|
val a7 = TestMember(
|
2019-05-15 18:01:34 +02:00
|
|
|
Address("akka", "sys", "a7", 2552),
|
2019-03-13 10:56:20 +01:00
|
|
|
MemberStatus.Exiting,
|
|
|
|
|
roles = Set("role1"),
|
|
|
|
|
upNumber = 7,
|
|
|
|
|
dataCenter = "dc-a")
|
|
|
|
|
val a8 = TestMember(
|
2019-05-15 18:01:34 +02:00
|
|
|
Address("akka", "sys", "a8", 2552),
|
2019-03-13 10:56:20 +01:00
|
|
|
MemberStatus.Exiting,
|
|
|
|
|
roles = Set("role1"),
|
|
|
|
|
upNumber = 8,
|
|
|
|
|
dataCenter = "dc-a")
|
|
|
|
|
val a9 = TestMember(
|
2019-05-15 18:01:34 +02:00
|
|
|
Address("akka", "sys", "a9", 2552),
|
2019-03-13 10:56:20 +01:00
|
|
|
MemberStatus.Exiting,
|
|
|
|
|
roles = Set("role2"),
|
|
|
|
|
upNumber = 9,
|
|
|
|
|
dataCenter = "dc-a")
|
|
|
|
|
val b5 = TestMember(
|
2019-05-15 18:01:34 +02:00
|
|
|
Address("akka", "sys", "b5", 2552),
|
2019-03-13 10:56:20 +01:00
|
|
|
MemberStatus.Exiting,
|
|
|
|
|
roles = Set("role1"),
|
|
|
|
|
upNumber = 5,
|
|
|
|
|
dataCenter = "dc-b")
|
|
|
|
|
val b6 = TestMember(
|
2019-05-15 18:01:34 +02:00
|
|
|
Address("akka", "sys", "b6", 2552),
|
2019-03-13 10:56:20 +01:00
|
|
|
MemberStatus.Exiting,
|
|
|
|
|
roles = Set("role2"),
|
|
|
|
|
upNumber = 6,
|
|
|
|
|
dataCenter = "dc-b")
|
2018-11-09 09:42:48 +01:00
|
|
|
val theExiting = Set(a5, a6)
|
|
|
|
|
val gossip = Gossip(SortedSet(a1, a2, a3, a4, a5, a6, a7, a8, a9, b1, b2, b3, b5, b6))
|
2019-03-11 10:38:24 +01:00
|
|
|
val membershipState = MembershipState(gossip, a1.uniqueAddress, "dc-a", 2)
|
2018-11-09 09:42:48 +01:00
|
|
|
|
|
|
|
|
membershipState.gossipTargetsForExitingMembers(theExiting) should ===(Set(a1, a2, a5, a6, a9))
|
|
|
|
|
}
|
2017-11-02 08:17:24 +00:00
|
|
|
}
|
|
|
|
|
}
|