2018-04-24 16:03:55 +01:00
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2018 Lightbend Inc. <https://www.lightbend.com>
|
|
|
|
|
*/
|
|
|
|
|
|
2017-02-14 13:10:23 +02:00
|
|
|
package akka.cluster.metrics.sample
|
2012-09-13 10:54:14 +02:00
|
|
|
|
|
|
|
|
import akka.actor.Props
|
|
|
|
|
import akka.cluster.Cluster
|
2017-02-14 13:10:23 +02:00
|
|
|
import akka.cluster.ClusterEvent.{ CurrentClusterState, MemberUp }
|
|
|
|
|
|
|
|
|
|
import scala.concurrent.duration._
|
|
|
|
|
import scala.language.postfixOps
|
2012-09-21 11:47:50 +02:00
|
|
|
|
|
|
|
|
//#MultiNodeConfig
|
2012-09-13 10:54:14 +02:00
|
|
|
import akka.remote.testkit.MultiNodeConfig
|
2012-09-21 11:47:50 +02:00
|
|
|
import com.typesafe.config.ConfigFactory
|
2012-09-13 10:54:14 +02:00
|
|
|
|
2012-09-21 11:47:50 +02:00
|
|
|
object StatsSampleSpecConfig extends MultiNodeConfig {
|
2012-09-13 10:54:14 +02:00
|
|
|
// register the named roles (nodes) of the test
|
|
|
|
|
val first = role("first")
|
|
|
|
|
val second = role("second")
|
2017-01-24 14:20:33 -08:00
|
|
|
val third = role("third")
|
2012-09-13 10:54:14 +02:00
|
|
|
|
2014-12-12 11:49:32 -06:00
|
|
|
def nodeList = Seq(first, second, third)
|
|
|
|
|
|
|
|
|
|
// Extract individual sigar library for every node.
|
2017-02-14 13:10:23 +02:00
|
|
|
nodeList foreach { role ⇒
|
2014-12-12 11:49:32 -06:00
|
|
|
nodeConfig(role) {
|
|
|
|
|
ConfigFactory.parseString(s"""
|
|
|
|
|
# Enable metrics extension in akka-cluster-metrics.
|
|
|
|
|
akka.extensions=["akka.cluster.metrics.ClusterMetricsExtension"]
|
|
|
|
|
# Sigar native library extract location during tests.
|
|
|
|
|
akka.cluster.metrics.native-library-extract-folder=target/native/${role.name}
|
|
|
|
|
""")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-09-13 10:54:14 +02:00
|
|
|
// this configuration will be used for all nodes
|
|
|
|
|
// note that no fixed host names and ports are used
|
|
|
|
|
commonConfig(ConfigFactory.parseString("""
|
2016-09-29 15:01:05 +02:00
|
|
|
akka.actor.provider = cluster
|
2012-09-13 10:54:14 +02:00
|
|
|
akka.remote.log-remote-lifecycle-events = off
|
2013-03-14 20:32:43 +01:00
|
|
|
akka.cluster.roles = [compute]
|
2012-09-13 10:54:14 +02:00
|
|
|
#//#router-lookup-config
|
|
|
|
|
akka.actor.deployment {
|
|
|
|
|
/statsService/workerRouter {
|
2013-09-19 08:00:05 +02:00
|
|
|
router = consistent-hashing-group
|
2013-10-16 11:06:38 +02:00
|
|
|
routees.paths = ["/user/statsWorker"]
|
2012-09-13 10:54:14 +02:00
|
|
|
cluster {
|
|
|
|
|
enabled = on
|
|
|
|
|
allow-local-routees = on
|
2017-08-09 16:06:18 +02:00
|
|
|
use-roles = ["compute"]
|
2012-09-13 10:54:14 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#//#router-lookup-config
|
|
|
|
|
"""))
|
|
|
|
|
|
|
|
|
|
}
|
2012-09-21 11:47:50 +02:00
|
|
|
//#MultiNodeConfig
|
2012-09-13 10:54:14 +02:00
|
|
|
|
2012-09-21 11:47:50 +02:00
|
|
|
//#concrete-tests
|
2012-09-13 10:54:14 +02:00
|
|
|
// need one concrete test class per node
|
2012-09-21 11:47:50 +02:00
|
|
|
class StatsSampleSpecMultiJvmNode1 extends StatsSampleSpec
|
|
|
|
|
class StatsSampleSpecMultiJvmNode2 extends StatsSampleSpec
|
|
|
|
|
class StatsSampleSpecMultiJvmNode3 extends StatsSampleSpec
|
|
|
|
|
//#concrete-tests
|
|
|
|
|
|
|
|
|
|
//#abstract-test
|
|
|
|
|
import akka.remote.testkit.MultiNodeSpec
|
|
|
|
|
import akka.testkit.ImplicitSender
|
2017-02-14 13:10:23 +02:00
|
|
|
import org.scalatest.{ BeforeAndAfterAll, Matchers, WordSpecLike }
|
2012-09-13 10:54:14 +02:00
|
|
|
|
2012-09-21 11:47:50 +02:00
|
|
|
abstract class StatsSampleSpec extends MultiNodeSpec(StatsSampleSpecConfig)
|
2013-12-17 14:25:56 +01:00
|
|
|
with WordSpecLike with Matchers with BeforeAndAfterAll
|
2012-09-21 11:47:50 +02:00
|
|
|
with ImplicitSender {
|
2012-09-13 10:54:14 +02:00
|
|
|
|
2012-09-21 11:47:50 +02:00
|
|
|
import StatsSampleSpecConfig._
|
2012-09-13 10:54:14 +02:00
|
|
|
|
|
|
|
|
override def initialParticipants = roles.size
|
|
|
|
|
|
2012-09-21 11:47:50 +02:00
|
|
|
override def beforeAll() = multiNodeSpecBeforeAll()
|
|
|
|
|
|
|
|
|
|
override def afterAll() = multiNodeSpecAfterAll()
|
|
|
|
|
|
2012-11-22 16:09:19 +01:00
|
|
|
//#abstract-test
|
2012-09-21 11:47:50 +02:00
|
|
|
|
2012-09-13 10:54:14 +02:00
|
|
|
"The stats sample" must {
|
2012-09-21 11:47:50 +02:00
|
|
|
|
|
|
|
|
//#startup-cluster
|
2012-11-15 08:28:35 +01:00
|
|
|
"illustrate how to startup cluster" in within(15 seconds) {
|
2012-09-13 10:54:14 +02:00
|
|
|
Cluster(system).subscribe(testActor, classOf[MemberUp])
|
|
|
|
|
expectMsgClass(classOf[CurrentClusterState])
|
|
|
|
|
|
2012-11-22 16:09:19 +01:00
|
|
|
//#addresses
|
2012-09-21 11:47:50 +02:00
|
|
|
val firstAddress = node(first).address
|
|
|
|
|
val secondAddress = node(second).address
|
|
|
|
|
val thirdAddress = node(third).address
|
|
|
|
|
//#addresses
|
|
|
|
|
|
|
|
|
|
//#join
|
|
|
|
|
Cluster(system) join firstAddress
|
|
|
|
|
//#join
|
|
|
|
|
|
2012-09-13 10:54:14 +02:00
|
|
|
system.actorOf(Props[StatsWorker], "statsWorker")
|
|
|
|
|
system.actorOf(Props[StatsService], "statsService")
|
|
|
|
|
|
2017-02-14 13:10:23 +02:00
|
|
|
receiveN(3).collect { case MemberUp(m) ⇒ m.address }.toSet should be(
|
2013-10-23 16:51:59 +02:00
|
|
|
Set(firstAddress, secondAddress, thirdAddress))
|
2012-09-13 10:54:14 +02:00
|
|
|
|
|
|
|
|
Cluster(system).unsubscribe(testActor)
|
|
|
|
|
|
|
|
|
|
testConductor.enter("all-up")
|
|
|
|
|
}
|
2012-09-21 11:47:50 +02:00
|
|
|
//#startup-cluster
|
2012-09-13 10:54:14 +02:00
|
|
|
|
2012-09-21 11:47:50 +02:00
|
|
|
//#test-statsService
|
2012-11-15 08:28:35 +01:00
|
|
|
"show usage of the statsService from one node" in within(15 seconds) {
|
2012-09-21 11:47:50 +02:00
|
|
|
runOn(second) {
|
2013-03-28 23:45:48 +01:00
|
|
|
assertServiceOk()
|
2012-09-21 11:47:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
testConductor.enter("done-2")
|
|
|
|
|
}
|
2012-11-22 16:09:19 +01:00
|
|
|
|
2013-03-28 23:45:48 +01:00
|
|
|
def assertServiceOk(): Unit = {
|
2013-03-26 18:17:50 +01:00
|
|
|
val service = system.actorSelection(node(third) / "user" / "statsService")
|
2012-11-22 16:09:19 +01:00
|
|
|
// eventually the service should be ok,
|
|
|
|
|
// first attempts might fail because worker actors not started yet
|
2013-03-26 18:17:50 +01:00
|
|
|
awaitAssert {
|
2012-11-22 16:09:19 +01:00
|
|
|
service ! StatsJob("this is the text that will be analyzed")
|
2013-12-17 14:25:56 +01:00
|
|
|
expectMsgType[StatsResult](1.second).meanWordLength should be(
|
|
|
|
|
3.875 +- 0.001)
|
2012-09-13 10:54:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
2012-11-22 16:09:19 +01:00
|
|
|
//#test-statsService
|
2012-09-21 11:47:50 +02:00
|
|
|
|
2012-11-22 16:09:19 +01:00
|
|
|
"show usage of the statsService from all nodes" in within(15 seconds) {
|
2013-03-28 23:45:48 +01:00
|
|
|
assertServiceOk()
|
2012-11-22 16:09:19 +01:00
|
|
|
testConductor.enter("done-3")
|
|
|
|
|
}
|
2012-09-21 11:47:50 +02:00
|
|
|
|
2012-09-13 10:54:14 +02:00
|
|
|
}
|
|
|
|
|
|
2016-06-02 14:06:57 +02:00
|
|
|
}
|