pekko/akka-cluster/src/multi-jvm/scala/akka/cluster/MultiDcSplitBrainSpec.scala

135 lines
3.9 KiB
Scala
Raw Normal View History

/**
* Copyright (C) 2009-2017 Lightbend Inc. <http://www.lightbend.com>
*/
package akka.cluster
2017-07-05 11:08:55 +02:00
import akka.remote.testconductor.RoleName
import akka.remote.testkit.{ MultiNodeConfig, MultiNodeSpec }
import akka.remote.transport.ThrottlerTransportAdapter.Direction
import com.typesafe.config.ConfigFactory
import scala.concurrent.duration._
2017-07-04 17:11:21 +02:00
object MultiDcSplitBrainMultiJvmSpec extends MultiNodeConfig {
val first = role("first")
val second = role("second")
val third = role("third")
val fourth = role("fourth")
2017-07-05 11:08:55 +02:00
commonConfig(ConfigFactory.parseString(
"""
akka.loglevel = INFO
akka.cluster.run-coordinated-shutdown-when-down = off
""").withFallback(MultiNodeClusterSpec.clusterConfig))
nodeConfig(first, second)(ConfigFactory.parseString(
"""
2017-07-04 17:11:21 +02:00
akka.cluster.data-center = "dc1"
"""))
nodeConfig(third, fourth)(ConfigFactory.parseString(
"""
2017-07-04 17:11:21 +02:00
akka.cluster.data-center = "dc2"
"""))
testTransport(on = true)
}
2017-07-05 11:08:55 +02:00
class MultiDcSplitBrainMultiJvmNode1 extends MultiDcSplitBrainSpec
class MultiDcSplitBrainMultiJvmNode2 extends MultiDcSplitBrainSpec
class MultiDcSplitBrainMultiJvmNode3 extends MultiDcSplitBrainSpec
class MultiDcSplitBrainMultiJvmNode4 extends MultiDcSplitBrainSpec
2017-07-04 17:11:21 +02:00
abstract class MultiDcSplitBrainSpec
extends MultiNodeSpec(MultiDcSplitBrainMultiJvmSpec)
with MultiNodeClusterSpec {
2017-07-04 17:11:21 +02:00
import MultiDcSplitBrainMultiJvmSpec._
val dc1 = List(first, second)
val dc2 = List(third, fourth)
2017-07-05 11:08:55 +02:00
def splitDataCenters(dc1: Seq[RoleName], dc2: Seq[RoleName]): Unit = {
runOn(first) {
for {
dc1Node dc1
dc2Node dc2
} {
testConductor.blackhole(dc1Node, dc2Node, Direction.Both).await
}
}
}
2017-07-05 11:08:55 +02:00
def unsplitDataCenters(dc1: Seq[RoleName], dc2: Seq[RoleName]): Unit = {
runOn(first) {
for {
dc1Node dc1
dc2Node dc2
} {
testConductor.passThrough(dc1Node, dc2Node, Direction.Both).await
}
}
}
2017-07-04 17:11:21 +02:00
"A cluster with multiple data centers" must {
"be able to form two data centers" in {
awaitClusterUp(first, second, third)
}
2017-07-04 17:11:21 +02:00
"be able to have a data center member join while there is inter data center split" in within(20.seconds) {
// introduce a split between data centers
2017-07-05 11:08:55 +02:00
splitDataCenters(dc1 = List(first, second), dc2 = List(third))
2017-07-04 17:11:21 +02:00
enterBarrier("data-center-split-1")
runOn(fourth) {
cluster.join(third)
}
2017-07-04 17:11:21 +02:00
enterBarrier("inter-data-center unreachability")
// should be able to join and become up since the
// split is between dc1 and dc2
runOn(third, fourth) {
awaitAssert(clusterView.members.collect {
2017-07-04 17:11:21 +02:00
case m if m.dataCenter == "dc2" && m.status == MemberStatus.Up m.address
2017-07-05 11:08:55 +02:00
} should ===(Set(address(third), address(fourth))))
}
enterBarrier("dc2-join-completed")
2017-07-05 11:08:55 +02:00
unsplitDataCenters(dc1 = List(first, second), dc2 = List(third))
2017-07-04 17:11:21 +02:00
enterBarrier("data-center-unsplit-1")
runOn(dc1: _*) {
awaitAssert(clusterView.members.collect {
2017-07-04 17:11:21 +02:00
case m if m.dataCenter == "dc2" && m.status == MemberStatus.Up m.address
2017-07-05 11:08:55 +02:00
} should ===(Set(address(third), address(fourth))))
}
2017-07-04 17:11:21 +02:00
enterBarrier("inter-data-center-split-1-done")
}
2017-07-04 17:11:21 +02:00
"be able to have data center member leave while there is inter data center split" in within(20.seconds) {
2017-07-05 11:08:55 +02:00
splitDataCenters(dc1, dc2)
2017-07-04 17:11:21 +02:00
enterBarrier("data-center-split-2")
runOn(fourth) {
2017-07-05 11:08:55 +02:00
cluster.leave(fourth)
}
2017-07-05 11:08:55 +02:00
runOn(third) {
awaitAssert(clusterView.members.filter(_.address == address(fourth)) should ===(Set.empty))
}
enterBarrier("node-4-left")
2017-07-05 11:08:55 +02:00
unsplitDataCenters(dc1, List(third))
2017-07-04 17:11:21 +02:00
enterBarrier("data-center-unsplit-2")
runOn(first, second) {
awaitAssert(clusterView.members.filter(_.address == address(fourth)) should ===(Set.empty))
}
2017-07-04 17:11:21 +02:00
enterBarrier("inter-data-center-split-2-done")
}
}
}