2016-04-28 23:33:59 +10:00
/* *
2017-01-04 17:37:10 +01:00
* Copyright ( C ) 2009 - 2017 Lightbend Inc . < http : //www.lightbend.com>
2016-04-28 23:33:59 +10:00
*/
package akka.remote.serialization
import akka.actor._
2017-03-16 15:12:35 +01:00
import akka.remote. { MessageSerializer , RemoteScope , RemoteWatcher }
2016-04-28 23:33:59 +10:00
import akka.serialization.SerializationExtension
import akka.testkit.AkkaSpec
import com.typesafe.config.ConfigFactory
2016-09-28 16:00:50 +02:00
2016-09-28 11:14:33 +02:00
import scala.util.control.NoStackTrace
2017-03-16 15:12:35 +01:00
import scala.concurrent.duration._
2016-12-01 16:51:39 +01:00
import java.util.Optional
2016-12-16 11:36:04 +01:00
import java.io.NotSerializableException
2016-04-28 23:33:59 +10:00
2017-03-16 15:12:35 +01:00
import akka.remote.routing.RemoteRouterConfig
import akka.routing._
2016-04-28 23:33:59 +10:00
object MiscMessageSerializerSpec {
val serializationTestOverrides =
2016-06-19 17:55:10 +02:00
"" "
2016-09-28 11:14:33 +02:00
akka . actor . serialization - bindings {
"akka.remote.serialization.MiscMessageSerializerSpec$TestException" = akka - misc
}
2016-09-09 09:01:15 +02:00
"" "
2016-04-28 23:33:59 +10:00
val testConfig = ConfigFactory . parseString ( serializationTestOverrides ) . withFallback ( AkkaSpec . testConf )
2016-09-28 11:14:33 +02:00
class TestException ( msg : String , cause : Throwable ) extends RuntimeException ( msg , cause ) {
def this ( msg : String ) = this ( msg , null )
override def equals ( other : Any ) : Boolean = other match {
case e : TestException ⇒
e . getMessage == getMessage && e . stackTrace == stackTrace && e . getCause == getCause
case _ ⇒ false
}
def stackTrace : List [ StackTraceElement ] =
if ( getStackTrace == null ) Nil
else getStackTrace . toList
}
class TestExceptionNoStack ( msg : String ) extends TestException ( msg ) with NoStackTrace {
override def equals ( other : Any ) : Boolean = other match {
case e : TestExceptionNoStack ⇒
e . getMessage == getMessage && e . stackTrace == stackTrace
case _ ⇒ false
}
}
class OtherException ( msg : String ) extends IllegalArgumentException ( msg ) {
override def equals ( other : Any ) : Boolean = other match {
case e : OtherException ⇒ e . getMessage == getMessage
case _ ⇒ false
}
}
2016-04-28 23:33:59 +10:00
}
class MiscMessageSerializerSpec extends AkkaSpec ( MiscMessageSerializerSpec . testConfig ) {
2016-09-28 11:14:33 +02:00
import MiscMessageSerializerSpec._
2016-04-28 23:33:59 +10:00
2016-09-27 15:46:22 +02:00
val ref = system . actorOf ( Props . empty , "hello" )
2016-04-28 23:33:59 +10:00
"MiscMessageSerializer" must {
Seq (
2016-06-02 14:06:57 +02:00
"Identify" → Identify ( "some-message" ) ,
2016-06-19 17:55:10 +02:00
"Identify with None" → Identify ( None ) ,
"Identify with Some" → Identify ( Some ( "value" ) ) ,
"ActorIdentity without actor ref" → ActorIdentity ( "some-message" , ref = None ) ,
"ActorIdentity with actor ref" → ActorIdentity ( "some-message" , ref = Some ( testActor ) ) ,
2016-09-28 11:14:33 +02:00
"TestException" → new TestException ( "err" ) ,
"TestExceptionNoStack" → new TestExceptionNoStack ( "err2" ) ,
"TestException with cause" → new TestException ( "err3" , new TestException ( "cause" ) ) ,
"Status.Success" → Status . Success ( "value" ) ,
"Status.Failure" → Status . Failure ( new TestException ( "err" ) ) ,
"Status.Failure JavaSer" → Status . Failure ( new OtherException ( "exc" ) ) , // exc with JavaSerializer
2016-09-27 15:46:22 +02:00
"ActorRef" → ref ,
2016-06-19 17:55:10 +02:00
"Some" → Some ( "value" ) ,
2016-09-26 15:04:53 +02:00
"None" → None ,
2016-12-01 16:51:39 +01:00
"Optional.present" → Optional . of ( "value2" ) ,
"Optional.empty" → Optional . empty ( ) ,
2016-09-26 15:04:53 +02:00
"Kill" → Kill ,
2016-09-28 16:00:50 +02:00
"PoisonPill" → PoisonPill ,
"RemoteWatcher.Heartbeat" → RemoteWatcher . Heartbeat ,
2017-03-16 15:12:35 +01:00
"RemoteWatcher.HertbeatRsp" → RemoteWatcher . HeartbeatRsp ( 65537 ) ,
"LocalScope" → LocalScope ,
"RemoteScope" → RemoteScope ( Address ( "akka" , "system" , "localhost" , 2525 ) ) ,
"Config" → system . settings . config ,
"Empty Config" → ConfigFactory . empty ( ) ,
"FromConfig" → FromConfig ,
// routers
"DefaultResizer" → DefaultResizer ( ) ,
"BalancingPool" → BalancingPool ( nrOfInstances = 25 ) ,
"BalancingPool with custom dispatcher" → BalancingPool ( nrOfInstances = 25 , routerDispatcher = "my-dispatcher" ) ,
"BroadcastPool" → BroadcastPool ( nrOfInstances = 25 ) ,
"BroadcastPool with custom dispatcher and resizer" → BroadcastPool ( nrOfInstances = 25 , routerDispatcher = "my-dispatcher" , usePoolDispatcher = true , resizer = Some ( DefaultResizer ( ) ) ) ,
"RandomPool" → RandomPool ( nrOfInstances = 25 ) ,
"RandomPool with custom dispatcher" → RandomPool ( nrOfInstances = 25 , routerDispatcher = "my-dispatcher" ) ,
"RoundRobinPool" → RoundRobinPool ( 25 ) ,
"ScatterGatherFirstCompletedPool" → ScatterGatherFirstCompletedPool ( 25 , within = 3. seconds ) ,
"TailChoppingPool" → TailChoppingPool ( 25 , within = 3. seconds , interval = 1. second ) ,
"RemoteRouterConfig" → RemoteRouterConfig ( local = RandomPool ( 25 ) , nodes = List ( Address ( "akka" , "system" , "localhost" , 2525 ) ) )
) . foreach {
2016-04-28 23:33:59 +10:00
case ( scenario , item ) ⇒
s" resolve serializer for $scenario " in {
val serializer = SerializationExtension ( system )
serializer . serializerFor ( item . getClass ) . getClass should === ( classOf [ MiscMessageSerializer ] )
}
s" serialize and de-serialize $scenario " in {
verifySerialization ( item )
}
}
"reject invalid manifest" in {
intercept [ IllegalArgumentException ] {
val serializer = new MiscMessageSerializer ( system . asInstanceOf [ ExtendedActorSystem ] )
serializer . manifest ( "INVALID" )
}
}
"reject deserialization with invalid manifest" in {
2016-12-16 11:36:04 +01:00
intercept [ NotSerializableException ] {
2016-04-28 23:33:59 +10:00
val serializer = new MiscMessageSerializer ( system . asInstanceOf [ ExtendedActorSystem ] )
serializer . fromBinary ( Array . empty [ Byte ] , "INVALID" )
}
}
def verifySerialization ( msg : AnyRef ) : Unit = {
val serializer = new MiscMessageSerializer ( system . asInstanceOf [ ExtendedActorSystem ] )
serializer . fromBinary ( serializer . toBinary ( msg ) , serializer . manifest ( msg ) ) should === ( msg )
}
2016-09-28 16:00:50 +02:00
// Separate tests due to missing equality on ActorInitializationException
"resolve serializer for ActorInitializationException" in {
val serializer = SerializationExtension ( system )
serializer . serializerFor ( classOf [ ActorInitializationException ] ) . getClass should === ( classOf [ MiscMessageSerializer ] )
}
"serialize and deserialze ActorInitializationException" in {
val aiex = ActorInitializationException ( ref , "test" , new TestException ( "err" ) )
val serializer = new MiscMessageSerializer ( system . asInstanceOf [ ExtendedActorSystem ] )
val deserialized = serializer . fromBinary ( serializer . toBinary ( aiex ) , serializer . manifest ( aiex ) )
. asInstanceOf [ ActorInitializationException ]
deserialized . getCause should === ( aiex . getCause )
deserialized . getMessage should === ( aiex . getMessage )
deserialized . getActor should === ( aiex . getActor )
}
"serialize and deserialze ActorInitializationException if ref is null" in {
val aiex = ActorInitializationException ( null , "test" , new TestException ( "err" ) )
val serializer = new MiscMessageSerializer ( system . asInstanceOf [ ExtendedActorSystem ] )
val deserialized = serializer . fromBinary ( serializer . toBinary ( aiex ) , serializer . manifest ( aiex ) )
. asInstanceOf [ ActorInitializationException ]
deserialized . getCause should === ( aiex . getCause )
deserialized . getMessage should === ( aiex . getMessage )
deserialized . getActor should === ( aiex . getActor )
}
"serialize and deserialze ActorInitializationException if cause is null" in {
val aiex = ActorInitializationException ( ref , "test" , null )
val serializer = new MiscMessageSerializer ( system . asInstanceOf [ ExtendedActorSystem ] )
val deserialized = serializer . fromBinary ( serializer . toBinary ( aiex ) , serializer . manifest ( aiex ) )
. asInstanceOf [ ActorInitializationException ]
deserialized . getCause should === ( aiex . getCause )
deserialized . getMessage should === ( aiex . getMessage )
deserialized . getActor should === ( aiex . getActor )
}
2016-04-28 23:33:59 +10:00
}
}