* Implement the join to seed nodes process When a new node is started started it sends a message to all seed nodes and then sends join command to the one that answers first. * Configuration of seed-nodes and auto-join * New JoinSeedNodeSpec that verifies the auto join to seed nodes * In tests seed nodes are configured by overriding seedNodes function, since addresses are not known before start * Deputy nodes are the live members of the seed nodes (not sure if that will be the final solution, see ticket 2252 * Updated cluster.rst with latest info about deputy and seed nodes
76 lines
2.3 KiB
Scala
76 lines
2.3 KiB
Scala
/**
|
|
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
|
*/
|
|
package akka.cluster
|
|
|
|
import com.typesafe.config.ConfigFactory
|
|
import org.scalatest.BeforeAndAfter
|
|
import akka.remote.testkit.MultiNodeConfig
|
|
import akka.remote.testkit.MultiNodeSpec
|
|
import akka.testkit._
|
|
import akka.util.duration._
|
|
import java.util.concurrent.atomic.AtomicReference
|
|
import scala.collection.immutable.SortedSet
|
|
|
|
object SunnyWeatherMultiJvmSpec extends MultiNodeConfig {
|
|
val first = role("first")
|
|
val second = role("second")
|
|
val third = role("third")
|
|
val fourth = role("fourth")
|
|
val fifth = role("fifth")
|
|
|
|
commonConfig(ConfigFactory.parseString("""
|
|
akka.cluster {
|
|
# FIXME remove this (use default) when ticket #2239 has been fixed
|
|
gossip-interval = 400 ms
|
|
}
|
|
akka.loglevel = INFO
|
|
"""))
|
|
}
|
|
|
|
class SunnyWeatherMultiJvmNode1 extends SunnyWeatherSpec with AccrualFailureDetectorStrategy
|
|
class SunnyWeatherMultiJvmNode2 extends SunnyWeatherSpec with AccrualFailureDetectorStrategy
|
|
class SunnyWeatherMultiJvmNode3 extends SunnyWeatherSpec with AccrualFailureDetectorStrategy
|
|
class SunnyWeatherMultiJvmNode4 extends SunnyWeatherSpec with AccrualFailureDetectorStrategy
|
|
class SunnyWeatherMultiJvmNode5 extends SunnyWeatherSpec with AccrualFailureDetectorStrategy
|
|
|
|
abstract class SunnyWeatherSpec
|
|
extends MultiNodeSpec(SunnyWeatherMultiJvmSpec)
|
|
with MultiNodeClusterSpec {
|
|
|
|
import SunnyWeatherMultiJvmSpec._
|
|
|
|
"A normal cluster" must {
|
|
"be healthy" taggedAs LongRunningTest in {
|
|
|
|
// start some
|
|
awaitClusterUp(first, second, third)
|
|
runOn(first, second, third) {
|
|
log.info("3 joined")
|
|
}
|
|
|
|
// add a few more
|
|
awaitClusterUp(roles: _*)
|
|
log.info("5 joined")
|
|
|
|
val unexpected = new AtomicReference[SortedSet[Member]]
|
|
cluster.registerListener(new MembershipChangeListener {
|
|
def notify(members: SortedSet[Member]) {
|
|
// we don't expected any changes to the cluster
|
|
unexpected.set(members)
|
|
}
|
|
})
|
|
|
|
for (n ← 1 to 30) {
|
|
enterBarrier("period-" + n)
|
|
unexpected.get must be(null)
|
|
awaitUpConvergence(roles.size)
|
|
assertLeaderIn(roles)
|
|
if (n % 5 == 0) log.info("Passed period [{}]", n)
|
|
1.seconds.sleep
|
|
}
|
|
|
|
enterBarrier("after")
|
|
}
|
|
}
|
|
}
|