Reorganized tests into matching subfolders.
Signed-off-by: Jonas Bonér <jonas@jonasboner.com>
This commit is contained in:
parent
a0abd5ef57
commit
15addf2b87
49 changed files with 24 additions and 706 deletions
|
|
@ -497,7 +497,7 @@ trait ClusterNode {
|
|||
|
||||
private[cluster] def failOverConnections(from: InetSocketAddress, to: InetSocketAddress)
|
||||
|
||||
private[cluster] def automaticMigrationFromFailedNodes()
|
||||
private[cluster] def automaticMigrationFromFailedNodes](currentSetOfClusterNodes: List[String])
|
||||
|
||||
private[cluster] def membershipPathFor(node: String): String
|
||||
|
||||
|
|
|
|||
|
|
@ -812,9 +812,7 @@ class DefaultClusterNode private[akka] (
|
|||
*/
|
||||
def useActorOnNode(node: String, uuid: UUID) {
|
||||
isConnected ifOn {
|
||||
|
||||
connectToAllNewlyArrivedMembershipNodesInCluster()
|
||||
|
||||
nodeConnections.get(node) foreach {
|
||||
case (_, connection) ⇒
|
||||
val command = RemoteDaemonMessageProtocol.newBuilder
|
||||
|
|
@ -1356,9 +1354,9 @@ class DefaultClusterNode private[akka] (
|
|||
}
|
||||
|
||||
// FIXME makes use of automaticMigrationFromFailedNodes method, why is it not used?
|
||||
private[cluster] def automaticMigrationFromFailedNodes() {
|
||||
private[cluster] def automaticMigrationFromFailedNodes](currentSetOfClusterNodes: List[String]) {
|
||||
connectToAllNewlyArrivedMembershipNodesInCluster()
|
||||
findFailedNodes(membershipNodes.toList).foreach { failedNodeName ⇒
|
||||
findFailedNodes(currentSetOfClusterNodes).foreach { failedNodeName ⇒
|
||||
|
||||
val allNodes = locallyCachedMembershipNodes.toList
|
||||
val myIndex = allNodes.indexWhere(_.endsWith(nodeAddress.nodeName))
|
||||
|
|
|
|||
|
|
@ -1,320 +0,0 @@
|
|||
/*
|
||||
package akka.cluster
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
import org.scalatest.{ BeforeAndAfterAll, BeforeAndAfterEach, Spec }
|
||||
|
||||
import org.I0Itec.zkclient._
|
||||
|
||||
import akka.actor._
|
||||
import akka.actor.Actor._
|
||||
import akka.serialization.{ Serializers, SerializerBasedActorFormat }
|
||||
import akka.util.Helpers._
|
||||
import akka.actor.DeploymentConfig._
|
||||
|
||||
import java.util.concurrent.{ CyclicBarrier, TimeUnit }
|
||||
|
||||
import scala.collection.JavaConversions._
|
||||
|
||||
class MyJavaSerializableActor extends Actor with Serializable {
|
||||
var count = 0
|
||||
|
||||
def receive = {
|
||||
case "hello" ⇒
|
||||
count = count + 1
|
||||
self.reply("world " + count)
|
||||
}
|
||||
}
|
||||
|
||||
object BinaryFormatMyJavaSerializableActor {
|
||||
implicit object MyJavaSerializableActorFormat extends SerializerBasedActorFormat[MyJavaSerializableActor] with Serializable {
|
||||
val serializer = Serializers.Java
|
||||
}
|
||||
}
|
||||
class ClusterSpec extends WordSpec with MustMatchers with BeforeAndAfterAll with BeforeAndAfterEach {
|
||||
import Cluster._
|
||||
|
||||
val dataPath = "_akka_cluster/data"
|
||||
val logPath = "_akka_cluster/log"
|
||||
|
||||
var zkServer: ZkServer = _
|
||||
|
||||
"A ClusterNode" should {
|
||||
|
||||
"be able to migrate an actor between two nodes using address" in {
|
||||
val node1 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "migrate-id-1", port = 9001))
|
||||
val node2 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "migrate-id-2", port = 9002))
|
||||
node1.start
|
||||
node2.start
|
||||
|
||||
// create actors
|
||||
val actorRef1 = actorOf[MyJavaSerializableActor]("actor-address").start
|
||||
val actorRef2 = actorOf[MyJavaSerializableActor]("actor-address").start
|
||||
|
||||
// register actors
|
||||
var serializeMailbox = true
|
||||
import BinaryFormatMyJavaSerializableActor._
|
||||
node1.store(actorRef1, serializeMailbox)
|
||||
node1.store(actorRef2, serializeMailbox)
|
||||
|
||||
node1.isClustered(actorRef1.address) must be(true)
|
||||
node1.addressesForClusteredActors.exists(_ == actorRef1.address) must be(true)
|
||||
|
||||
// check out actor
|
||||
val actorRef1_2 = node1.use(actorRef1.address).head
|
||||
val actorRef2_2 = node1.use(actorRef2.address).head
|
||||
(actorRef1_2 !! "hello").getOrElse("_") must equal("world 1")
|
||||
(actorRef2_2 !! "hello").getOrElse("_") must equal("world 1")
|
||||
|
||||
node1.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-id-1")) must be(true)
|
||||
node1.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-id-1")) must be(true)
|
||||
|
||||
node1.addressesForActorsInUse.exists(_ == actorRef1.address) must be(true)
|
||||
node1.addressesForActorsInUse.exists(_ == actorRef2.address) must be(true)
|
||||
node1.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-id-1")) must be(true)
|
||||
node1.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-id-1")) must be(true)
|
||||
node1.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-id-1")) must be(true)
|
||||
node1.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-id-1")) must be(true)
|
||||
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef1.address) must be(false)
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef2.address) must be(false)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-id-2")) must be(false)
|
||||
|
||||
// migrate to node2
|
||||
node1.migrate(node1.nodeAddress, node2.nodeAddress, actorRef1_2.address)
|
||||
|
||||
val actorRef1_3 = node2.use(actorRef1.address).head
|
||||
val actorRef2_3 = node2.use(actorRef2.address).head
|
||||
(actorRef1_3 !! "hello").getOrElse("_") must equal("world 1")
|
||||
(actorRef2_3 !! "hello").getOrElse("_") must equal("world 1")
|
||||
|
||||
node1.addressesForActorsInUse.exists(_ == actorRef1.address) must be(false)
|
||||
node1.addressesForActorsInUse.exists(_ == actorRef2.address) must be(false)
|
||||
node1.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-id-1")) must be(false)
|
||||
node1.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-id-1")) must be(false)
|
||||
node1.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-id-1")) must be(false)
|
||||
node1.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-id-1")) must be(false)
|
||||
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef1.address) must be(true)
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef2.address) must be(true)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-id-2")) must be(true)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-id-2")) must be(true)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-id-2")) must be(true)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-id-2")) must be(true)
|
||||
|
||||
actorRef1.stop
|
||||
actorRef2.stop
|
||||
actorRef1_2.stop
|
||||
actorRef2_2.stop
|
||||
|
||||
node1.stop
|
||||
node2.stop
|
||||
}
|
||||
|
||||
"automatically migrate actors of a failed node in a cluster of two nodes using address" in {
|
||||
val node1 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "migrate-2-id-1", port = 9001))
|
||||
val node2 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "migrate-2-id-2", port = 9002))
|
||||
node1.start
|
||||
node2.start
|
||||
|
||||
// create actors
|
||||
val actorRef1 = actorOf[MyJavaSerializableActor]("actor-address").start
|
||||
val actorRef2 = actorOf[MyJavaSerializableActor]("actor-address").start
|
||||
|
||||
// register actors
|
||||
var serializeMailbox = true
|
||||
import BinaryFormatMyJavaSerializableActor._
|
||||
node1.store(actorRef1, serializeMailbox)
|
||||
node1.store(actorRef2, serializeMailbox)
|
||||
|
||||
node1.isClustered(actorRef1.address) must be(true)
|
||||
node1.addressesForClusteredActors.exists(_ == actorRef1.address) must be(true)
|
||||
|
||||
// check out actor
|
||||
val actorRef1_2 = node1.use(actorRef1.address).head
|
||||
val actorRef2_2 = node1.use(actorRef2.address).head
|
||||
|
||||
(actorRef1_2 !! "hello").getOrElse("_") must equal("world 1")
|
||||
(actorRef2_2 !! "hello").getOrElse("_") must equal("world 1")
|
||||
|
||||
node1.addressesForActorsInUse.exists(_ == actorRef1.address) must be(true)
|
||||
node1.addressesForActorsInUse.exists(_ == actorRef2.address) must be(true)
|
||||
node1.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-2-id-1")) must be(true)
|
||||
node1.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-2-id-1")) must be(true)
|
||||
node1.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-2-id-1")) must be(true)
|
||||
node1.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-2-id-1")) must be(true)
|
||||
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef1.address) must be(false)
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef2.address) must be(false)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-2-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-2-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-2-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-2-id-2")) must be(false)
|
||||
|
||||
// should migrate to node2
|
||||
node1.stop
|
||||
node1.isRunning must be(false)
|
||||
Thread.sleep(500)
|
||||
|
||||
val actorRef1_3 = node2.use(actorRef1.address).head
|
||||
val actorRef2_3 = node2.use(actorRef2.address).head
|
||||
(actorRef1_3 !! "hello").getOrElse("_") must equal("world 1")
|
||||
(actorRef2_3 !! "hello").getOrElse("_") must equal("world 1")
|
||||
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef1.address) must be(true)
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef2.address) must be(true)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-2-id-2")) must be(true)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-2-id-2")) must be(true)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-2-id-2")) must be(true)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-2-id-2")) must be(true)
|
||||
|
||||
actorRef1.stop
|
||||
actorRef2.stop
|
||||
actorRef1_2.stop
|
||||
actorRef2_2.stop
|
||||
|
||||
node2.stop
|
||||
}
|
||||
|
||||
"automatically migrate actors of a failed node in a cluster of three nodes using address" in {
|
||||
val node1 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "migrate-3-id-1", port = 9001))
|
||||
val node2 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "migrate-3-id-2", port = 9002))
|
||||
val node3 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "migrate-3-id-3", port = 9003))
|
||||
node1.start
|
||||
node2.start
|
||||
node3.start
|
||||
|
||||
// create actors
|
||||
val actorRef1 = actorOf[MyJavaSerializableActor]("actor-address").start
|
||||
val actorRef2 = actorOf[MyJavaSerializableActor]("actor-address").start
|
||||
|
||||
// register actors
|
||||
var serializeMailbox = true
|
||||
import BinaryFormatMyJavaSerializableActor._
|
||||
node1.store(actorRef1, serializeMailbox)
|
||||
node1.store(actorRef2, serializeMailbox)
|
||||
|
||||
node1.isClustered(actorRef1.address) must be(true)
|
||||
node1.addressesForClusteredActors.exists(_ == actorRef1.address) must be(true)
|
||||
|
||||
// check out actor
|
||||
val actorRef1_2 = node1.use(actorRef1.address).head
|
||||
val actorRef2_2 = node1.use(actorRef2.address).head
|
||||
(actorRef1_2 !! "hello").getOrElse("_") must equal("world 1")
|
||||
(actorRef2_2 !! "hello").getOrElse("_") must equal("world 1")
|
||||
|
||||
node1.addressesForActorsInUse.exists(_ == actorRef1.address) must be(true)
|
||||
node1.addressesForActorsInUse.exists(_ == actorRef2.address) must be(true)
|
||||
node1.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-3-id-1")) must be(true)
|
||||
node1.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-3-id-1")) must be(true)
|
||||
node1.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-3-id-1")) must be(true)
|
||||
node1.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-3-id-1")) must be(true)
|
||||
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef1.address) must be(false)
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef2.address) must be(false)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-3-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-3-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-3-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-3-id-2")) must be(false)
|
||||
|
||||
node3.addressesForActorsInUse.exists(_ == actorRef1.address) must be(false)
|
||||
node3.addressesForActorsInUse.exists(_ == actorRef2.address) must be(false)
|
||||
node3.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-3-id-3")) must be(false)
|
||||
node3.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-3-id-3")) must be(false)
|
||||
node3.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-3-id-3")) must be(false)
|
||||
node3.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-3-id-3")) must be(false)
|
||||
|
||||
// should migrate to node2
|
||||
node1.stop
|
||||
node1.isRunning must be(false)
|
||||
Thread.sleep(500)
|
||||
|
||||
val actorRef1_3 = node3.use(actorRef1.address).head
|
||||
val actorRef2_3 = node3.use(actorRef2.address).head
|
||||
(actorRef1_3 !! "hello").getOrElse("_") must equal("world 1")
|
||||
(actorRef2_3 !! "hello").getOrElse("_") must equal("world 1")
|
||||
|
||||
node3.addressesForActorsInUse.exists(_ == actorRef1.address) must be(true)
|
||||
node3.addressesForActorsInUse.exists(_ == actorRef2.address) must be(true)
|
||||
node3.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-3-id-3")) must be(true)
|
||||
node3.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-3-id-3")) must be(true)
|
||||
node3.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-3-id-3")) must be(true)
|
||||
node3.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-3-id-3")) must be(true)
|
||||
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef1.address) must be(false)
|
||||
node2.addressesForActorsInUse.exists(_ == actorRef2.address) must be(false)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-3-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef1.address, node = NodeAddress("test-cluster", "migrate-3-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-3-id-2")) must be(false)
|
||||
node2.isInUseOnNode(actorRef2.address, node = NodeAddress("test-cluster", "migrate-3-id-2")) must be(false)
|
||||
|
||||
actorRef1.stop
|
||||
actorRef2.stop
|
||||
actorRef1_2.stop
|
||||
actorRef2_2.stop
|
||||
|
||||
node2.stop
|
||||
node3.stop
|
||||
}
|
||||
|
||||
"be able to migrate an actor between two nodes using address and see that 'ref' to it is redirected and continue to work" in {
|
||||
val node1 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "migrate-id-and-see-ref-failover-1", port = 9001))
|
||||
val node2 = Cluster.newNode(nodeAddress = NodeAddress("test-cluster", "migrate-id-and-see-ref-failover-2", port = 9002))
|
||||
node1.start
|
||||
node2.start
|
||||
|
||||
// create actors
|
||||
Deployer.deploy(Deploy(
|
||||
"actor-address", Direct,
|
||||
Clustered(Home("localhost", 2552), NoReplicas, Stateless)))
|
||||
val actorRef1 = actorOf[MyJavaSerializableActor]("actor-address").start
|
||||
|
||||
Thread.sleep(500)
|
||||
|
||||
// register actors
|
||||
import BinaryFormatMyJavaSerializableActor._
|
||||
node1.store(actorRef1)
|
||||
|
||||
Thread.sleep(500)
|
||||
|
||||
// use on node1
|
||||
node1.use(actorRef1.address)
|
||||
|
||||
node1.isInUseOnNode(actorRef1.address, node = node1.nodeAddress) must be(true)
|
||||
|
||||
// check out actor ref on node2
|
||||
val actorRef1_2 = node2.ref(actorRef1.address, router = Router.Direct)
|
||||
|
||||
(actorRef1_2 !! "hello").getOrElse("_") must equal("world 1")
|
||||
|
||||
// migrate to node2
|
||||
node1.migrate(node1.nodeAddress, node2.nodeAddress, actorRef1.address)
|
||||
|
||||
Thread.sleep(500)
|
||||
|
||||
(actorRef1_2 !! "hello").getOrElse("_") must equal("world 2")
|
||||
|
||||
actorRef1.stop
|
||||
actorRef1_2.stop
|
||||
|
||||
node1.stop
|
||||
node2.stop
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override def beforeAll() = {
|
||||
zkServer = Cluster.startLocalCluster(dataPath, logPath)
|
||||
}
|
||||
|
||||
override def afterAll() = {
|
||||
Cluster.shutdownLocalCluster
|
||||
Actor.registry.local.shutdownAll
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package sample.cluster
|
||||
|
||||
import akka.cluster._
|
||||
import akka.dispatch.Futures
|
||||
|
||||
/**
|
||||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||
*/
|
||||
object ComputeGridSample {
|
||||
//sample.cluster.ClusteredFunctions.fun2
|
||||
|
||||
// FIXME rewrite as multi-jvm test
|
||||
|
||||
/*
|
||||
// run all
|
||||
def run {
|
||||
fun1
|
||||
fun2
|
||||
fun3
|
||||
fun4
|
||||
}
|
||||
|
||||
// Send Function0[Unit]
|
||||
def fun1 = {
|
||||
Cluster.startLocalCluster()
|
||||
val node = Cluster newNode (NodeAddress("test", "local", port = 9991)) start
|
||||
val remote1 = Cluster newNode (NodeAddress("test", "remote1", port = 9992)) start
|
||||
|
||||
Thread.sleep(100)
|
||||
val fun = () ⇒ println("=============>>> AKKA ROCKS <<<=============")
|
||||
node send (fun, 2) // send and invoke function on to two cluster nodes
|
||||
|
||||
node.stop
|
||||
remote1.stop
|
||||
Cluster.shutdownLocalCluster()
|
||||
}
|
||||
|
||||
// Send Function0[Any]
|
||||
def fun2 = {
|
||||
Cluster.startLocalCluster()
|
||||
val local = Cluster newNode (NodeAddress("test", "local", port = 9991)) start
|
||||
val remote1 = Cluster newNode (NodeAddress("test", "remote1", port = 9992)) start
|
||||
|
||||
Thread.sleep(100)
|
||||
val fun = () ⇒ "AKKA ROCKS"
|
||||
val futures = local send (fun, 2) // send and invoke function on to two cluster nodes and get result
|
||||
|
||||
val result = Futures.fold("")(futures)(_ + " - " + _).await.resultOrException
|
||||
println("===================>>> Cluster says [" + result + "]")
|
||||
|
||||
local.stop
|
||||
remote1.stop
|
||||
Cluster.shutdownLocalCluster()
|
||||
}
|
||||
|
||||
// Send Function1[Any, Unit]
|
||||
def fun3 = {
|
||||
Cluster.startLocalCluster()
|
||||
val local = Cluster newNode (NodeAddress("test", "local", port = 9991)) start
|
||||
val remote1 = Cluster newNode (NodeAddress("test", "remote1", port = 9992)) start
|
||||
|
||||
val fun = ((s: String) ⇒ println("=============>>> " + s + " <<<=============")).asInstanceOf[Function1[Any, Unit]]
|
||||
local send (fun, "AKKA ROCKS", 2) // send and invoke function on to two cluster nodes
|
||||
|
||||
local.stop
|
||||
remote1.stop
|
||||
Cluster.shutdownLocalCluster()
|
||||
}
|
||||
|
||||
// Send Function1[Any, Any]
|
||||
def fun4 = {
|
||||
Cluster.startLocalCluster()
|
||||
val local = Cluster newNode (NodeAddress("test", "local", port = 9991)) start
|
||||
val remote1 = Cluster newNode (NodeAddress("test", "remote1", port = 9992)) start
|
||||
|
||||
val fun = ((i: Int) ⇒ i * i).asInstanceOf[Function1[Any, Any]]
|
||||
|
||||
val future1 = local send (fun, 2, 1) head // send and invoke function on one cluster node and get result
|
||||
val future2 = local send (fun, 2, 1) head // send and invoke function on one cluster node and get result
|
||||
|
||||
// grab the result from the first one that returns
|
||||
val result = Futures.firstCompletedOf(List(future1, future2)).await.resultOrException
|
||||
println("===================>>> Cluster says [" + result.get + "]")
|
||||
|
||||
local.stop
|
||||
remote1.stop
|
||||
Cluster.shutdownLocalCluster()
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
|
@ -1,251 +0,0 @@
|
|||
package akka.cluster
|
||||
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
import org.scalatest.WordSpec
|
||||
import akka.cluster.StorageTestUtils._
|
||||
|
||||
class InMemoryStorageSpec extends WordSpec with MustMatchers {
|
||||
|
||||
"unversioned load" must {
|
||||
"throw MissingDataException if non existing key" in {
|
||||
val store = new InMemoryStorage()
|
||||
|
||||
try {
|
||||
store.load("foo")
|
||||
fail()
|
||||
} catch {
|
||||
case e: MissingDataException ⇒
|
||||
}
|
||||
}
|
||||
|
||||
"return VersionedData if key existing" in {
|
||||
val storage = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
val value = "somevalue".getBytes
|
||||
storage.insert(key, value)
|
||||
|
||||
val result = storage.load(key)
|
||||
//todo: strange that the implicit store is not found
|
||||
assertContent(key, value, result.version)(storage)
|
||||
}
|
||||
}
|
||||
|
||||
"exist" must {
|
||||
"return true if value exists" in {
|
||||
val store = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
store.insert(key, "somevalue".getBytes)
|
||||
store.exists(key) must be(true)
|
||||
}
|
||||
|
||||
"return false if value not exists" in {
|
||||
val store = new InMemoryStorage()
|
||||
store.exists("somekey") must be(false)
|
||||
}
|
||||
}
|
||||
|
||||
"versioned load" must {
|
||||
"throw MissingDataException if non existing key" in {
|
||||
val store = new InMemoryStorage()
|
||||
|
||||
try {
|
||||
store.load("foo", 1)
|
||||
fail()
|
||||
} catch {
|
||||
case e: MissingDataException ⇒
|
||||
}
|
||||
}
|
||||
|
||||
"return VersionedData if key existing and exact version match" in {
|
||||
val storage = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
val value = "somevalue".getBytes
|
||||
val stored = storage.insert(key, value)
|
||||
|
||||
val result = storage.load(key, stored.version)
|
||||
assert(result.version == stored.version)
|
||||
assert(result.data == stored.data)
|
||||
}
|
||||
|
||||
"throw VersioningException is version too new" in {
|
||||
val storage = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
val value = "somevalue".getBytes
|
||||
val stored = storage.insert(key, value)
|
||||
|
||||
try {
|
||||
storage.load(key, stored.version + 1)
|
||||
fail()
|
||||
} catch {
|
||||
case e: VersioningException ⇒
|
||||
}
|
||||
}
|
||||
|
||||
"throw VersioningException is version too old" in {
|
||||
val storage = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
val value = "somevalue".getBytes
|
||||
val stored = storage.insert(key, value)
|
||||
|
||||
try {
|
||||
storage.load(key, stored.version - 1)
|
||||
fail()
|
||||
} catch {
|
||||
case e: VersioningException ⇒
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"insert" must {
|
||||
|
||||
"place a new value when non previously existed" in {
|
||||
val storage = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
val oldValue = "oldvalue".getBytes
|
||||
storage.insert(key, oldValue)
|
||||
|
||||
val result = storage.load(key)
|
||||
assertContent(key, oldValue)(storage)
|
||||
assert(InMemoryStorage.InitialVersion == result.version)
|
||||
}
|
||||
|
||||
"throw MissingDataException when there already exists an entry with the same key" in {
|
||||
val storage = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
val oldValue = "oldvalue".getBytes
|
||||
|
||||
val oldVersionedData = storage.insert(key, oldValue)
|
||||
|
||||
val newValue = "newValue".getBytes
|
||||
|
||||
try {
|
||||
storage.insert(key, newValue)
|
||||
fail()
|
||||
} catch {
|
||||
case e: DataExistsException ⇒
|
||||
}
|
||||
|
||||
//make sure that the old value was not changed
|
||||
assert(oldVersionedData == storage.load(key))
|
||||
}
|
||||
}
|
||||
|
||||
"update" must {
|
||||
|
||||
"throw MissingDataException when no node exists" in {
|
||||
val storage = new InMemoryStorage()
|
||||
|
||||
val key = "somekey"
|
||||
|
||||
try {
|
||||
storage.update(key, new VersionedData("somevalue".getBytes, 1))
|
||||
fail()
|
||||
} catch {
|
||||
case e: MissingDataException ⇒
|
||||
}
|
||||
}
|
||||
|
||||
"replace if previous value exists and no other updates have been done" in {
|
||||
val storage = new InMemoryStorage()
|
||||
|
||||
//do the initial insert
|
||||
val key = "foo"
|
||||
val oldValue = "insert".getBytes
|
||||
val insert = storage.insert(key, oldValue)
|
||||
|
||||
//do the update the will be the cause of the conflict.
|
||||
val updateValue = "update".getBytes
|
||||
val update = insert.createUpdate(updateValue)
|
||||
storage.update(key, update)
|
||||
|
||||
assertContent(key, update.data, update.version)(storage)
|
||||
}
|
||||
|
||||
"throw VersioningException when already overwritten" in {
|
||||
val storage = new InMemoryStorage()
|
||||
|
||||
//do the initial insert
|
||||
val key = "foo"
|
||||
val oldValue = "insert".getBytes
|
||||
val insert = storage.insert(key, oldValue)
|
||||
|
||||
//do the update the will be the cause of the conflict.
|
||||
val otherUpdateValue = "otherupdate".getBytes
|
||||
val otherUpdate = insert.createUpdate(otherUpdateValue)
|
||||
storage.update(key, otherUpdate)
|
||||
|
||||
val update = insert.createUpdate("update".getBytes)
|
||||
|
||||
try {
|
||||
storage.update(key, update)
|
||||
fail()
|
||||
} catch {
|
||||
case e: VersioningException ⇒
|
||||
}
|
||||
|
||||
assertContent(key, otherUpdate.data, otherUpdate.version)(storage)
|
||||
}
|
||||
}
|
||||
|
||||
"overwrite" must {
|
||||
|
||||
"throw MissingDataException when no node exists" in {
|
||||
val storage = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
|
||||
try {
|
||||
storage.overwrite(key, "somevalue".getBytes)
|
||||
fail()
|
||||
} catch {
|
||||
case e: MissingDataException ⇒
|
||||
}
|
||||
|
||||
storage.exists(key) must be(false)
|
||||
}
|
||||
|
||||
"succeed if previous value exist" in {
|
||||
val storage = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
val oldValue = "oldvalue".getBytes
|
||||
val newValue: Array[Byte] = "somevalue".getBytes
|
||||
|
||||
val initialInsert: VersionedData = storage.insert(key, oldValue)
|
||||
|
||||
val result: VersionedData = storage.overwrite(key, newValue)
|
||||
|
||||
assert(result.version == initialInsert.version + 1)
|
||||
assert(result.data == newValue)
|
||||
storage.load(key) must be eq (result)
|
||||
}
|
||||
}
|
||||
|
||||
"insertOrOverwrite" must {
|
||||
"insert if nothing was inserted before" in {
|
||||
val storage = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
val value = "somevalue".getBytes
|
||||
|
||||
val result = storage.insertOrOverwrite(key, value)
|
||||
|
||||
assert(result.version == InMemoryStorage.InitialVersion)
|
||||
assert(result.data == value)
|
||||
storage.load(key) must be eq (result)
|
||||
}
|
||||
|
||||
"overwrite of something existed before" in {
|
||||
val storage = new InMemoryStorage()
|
||||
val key = "somekey"
|
||||
val oldValue = "oldvalue".getBytes
|
||||
val newValue = "somevalue".getBytes
|
||||
|
||||
val initialInsert = storage.insert(key, oldValue)
|
||||
|
||||
val result = storage.insertOrOverwrite(key, newValue)
|
||||
|
||||
assert(result.version == initialInsert.version + 1)
|
||||
assert(result.data == newValue)
|
||||
storage.load(key) must be eq (result)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
package akka.cluster
|
||||
|
||||
object StorageTestUtils {
|
||||
|
||||
def assertContent(key: String, expectedData: Array[Byte], expectedVersion: Long)(implicit storage: InMemoryStorage) {
|
||||
val found = storage.load(key)
|
||||
assert(found.version == expectedVersion)
|
||||
assert(expectedData == found.data) //todo: structural equals
|
||||
}
|
||||
|
||||
def assertContent(key: String, expectedData: Array[Byte])(implicit storage: InMemoryStorage) {
|
||||
val found = storage.load(key)
|
||||
assert(expectedData == found.data) //todo: structural equals
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package akka.cluster.changelisteners.newleader
|
||||
package akka.cluster.api.changelisteners.newleader
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package akka.cluster.changelisteners.nodeconnected
|
||||
package akka.cluster.api.changelisteners.nodeconnected
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package akka.cluster.changelisteners.nodedisconnected
|
||||
package akka.cluster.api.changelisteners.nodedisconnected
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package akka.cluster.configuration
|
||||
package akka.cluster.api.configuration
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package akka.cluster.leader.election
|
||||
package akka.cluster.api.leader.election
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
|
|
@ -73,4 +73,4 @@ class LeaderElectionMultiJvmNode2 extends WordSpec with MustMatchers {
|
|||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package akka.cluster.migration.api
|
||||
package akka.cluster.api.migration.explicit
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
|
|
@ -18,7 +18,7 @@ import akka.serialization.Serialization
|
|||
|
||||
import java.util.concurrent._
|
||||
|
||||
object MigrationApiMultiJvmSpec {
|
||||
object MigrationExplicitMultiJvmSpec {
|
||||
var NrOfNodes = 2
|
||||
|
||||
class HelloWorld extends Actor with Serializable {
|
||||
|
|
@ -29,8 +29,8 @@ object MigrationApiMultiJvmSpec {
|
|||
}
|
||||
}
|
||||
|
||||
class MigrationApiMultiJvmNode1 extends WordSpec with MustMatchers with BeforeAndAfterAll {
|
||||
import MigrationApiMultiJvmSpec._
|
||||
class MigrationExplicitMultiJvmNode1 extends WordSpec with MustMatchers with BeforeAndAfterAll {
|
||||
import MigrationExplicitMultiJvmSpec._
|
||||
|
||||
"A cluster" must {
|
||||
|
||||
|
|
@ -73,8 +73,8 @@ class MigrationApiMultiJvmNode1 extends WordSpec with MustMatchers with BeforeAn
|
|||
}
|
||||
}
|
||||
|
||||
class MigrationApiMultiJvmNode2 extends WordSpec with MustMatchers {
|
||||
import MigrationApiMultiJvmSpec._
|
||||
class MigrationExplicitMultiJvmNode2 extends WordSpec with MustMatchers {
|
||||
import MigrationExplicitMultiJvmSpec._
|
||||
|
||||
"A cluster" must {
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package akka.cluster.registry
|
||||
package akka.cluster.api.registry
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package akka.cluster.sample
|
||||
package akka.cluster.multijvmtestsample
|
||||
|
||||
import org.scalatest.WordSpec
|
||||
import org.scalatest.matchers.MustMatchers
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package sample.cluster
|
||||
package akka.cluster.sample
|
||||
|
||||
import akka.cluster._
|
||||
|
||||
|
|
@ -131,4 +131,4 @@ object ClusteredPingPongSample {
|
|||
Cluster.shutdownLocalCluster()
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package sample.cluster
|
||||
package akka.cluster.sample
|
||||
|
||||
import akka.cluster._
|
||||
import akka.dispatch.Futures
|
||||
|
|
@ -10,8 +10,8 @@ import akka.dispatch.Futures
|
|||
/**
|
||||
* @author <a href="http://jonasboner.com">Jonas Bonér</a>
|
||||
*/
|
||||
object ClusteredFunctions {
|
||||
//sample.cluster.ClusteredFunctions.fun2
|
||||
object ComputeGridSample {
|
||||
//sample.cluster.ComputeGridSample.fun2
|
||||
|
||||
// FIXME rewrite as multi-jvm test
|
||||
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* Copyright (C) 2009-2011 Scalable Solutions AB <http://scalablesolutions.se>
|
||||
*/
|
||||
|
||||
package example.cluster
|
||||
package akka.cluster.sample
|
||||
|
||||
import akka.cluster._
|
||||
|
||||
|
|
@ -224,4 +224,4 @@ class PongNode(number: Int) {
|
|||
node.stop
|
||||
}
|
||||
}
|
||||
*/
|
||||
*/
|
||||
Loading…
Add table
Add a link
Reference in a new issue