Run akka-remote tests on Scala 3 (#30415)
* Run akka-remote tests on Scala 3 * Test the same scenario on Scala 2.13 and 3 A case object is `Serializable` on Scala 3 but not on Scala 2.13, so this test would fail because no serializer is found on Scala 2.13, and because the Java serializer is disabled on Scala 3. By using a class instead, which is not `Serializable` both on Scala 2.13 and Scala 3, we test the same thing on both Scala versions.
This commit is contained in:
parent
a71033a78e
commit
42d85a3019
12 changed files with 31 additions and 35 deletions
12
.github/workflows/scala3-build.yml
vendored
12
.github/workflows/scala3-build.yml
vendored
|
|
@ -34,14 +34,16 @@ jobs:
|
||||||
akka-actor-testkit-typed/test \
|
akka-actor-testkit-typed/test \
|
||||||
akka-actor-typed/compile \
|
akka-actor-typed/compile \
|
||||||
akka-actor-typed-tests/test \
|
akka-actor-typed-tests/test \
|
||||||
|
akka-coordination/test \
|
||||||
akka-discovery/test \
|
akka-discovery/test \
|
||||||
akka-pki/test \
|
akka-pki/test \
|
||||||
akka-protobuf/test \
|
akka-protobuf/test \
|
||||||
akka-protobuf-v3/test \
|
akka-protobuf-v3/test \
|
||||||
akka-slf4j/test \akka-stream/test \
|
|
||||||
akka-stream-tests-tck/test \
|
|
||||||
akka-coordination/test \
|
|
||||||
akka-serialization-jackson/test:compile \
|
akka-serialization-jackson/test:compile \
|
||||||
akka-testkit/test \
|
akka-slf4j/test \
|
||||||
|
akka-stream/test \
|
||||||
akka-stream-testkit/test \
|
akka-stream-testkit/test \
|
||||||
akka-remote/compile
|
akka-stream-tests-tck/test \
|
||||||
|
akka-remote/test \
|
||||||
|
akka-remote-tests/test \
|
||||||
|
akka-testkit/test
|
||||||
|
|
|
||||||
|
|
@ -5,16 +5,14 @@
|
||||||
package akka.remote.testkit
|
package akka.remote.testkit
|
||||||
|
|
||||||
import java.net.{ InetAddress, InetSocketAddress }
|
import java.net.{ InetAddress, InetSocketAddress }
|
||||||
|
|
||||||
import scala.collection.immutable
|
import scala.collection.immutable
|
||||||
import scala.concurrent.{ Await, Awaitable }
|
import scala.concurrent.{ Await, Awaitable }
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import scala.util.control.NonFatal
|
import scala.util.control.NonFatal
|
||||||
|
|
||||||
import com.typesafe.config.{ Config, ConfigFactory, ConfigObject }
|
import com.typesafe.config.{ Config, ConfigFactory, ConfigObject }
|
||||||
|
|
||||||
import language.implicitConversions
|
import language.implicitConversions
|
||||||
import org.jboss.netty.channel.ChannelException
|
import org.jboss.netty.channel.ChannelException
|
||||||
|
|
||||||
import akka.actor._
|
import akka.actor._
|
||||||
import akka.actor.RootActorPath
|
import akka.actor.RootActorPath
|
||||||
import akka.event.{ Logging, LoggingAdapter }
|
import akka.event.{ Logging, LoggingAdapter }
|
||||||
|
|
@ -287,7 +285,7 @@ abstract class MultiNodeSpec(
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
val log: LoggingAdapter = Logging(system, this.getClass)
|
val log: LoggingAdapter = Logging(system, this)(_.getClass.getName)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enrich `.await()` onto all Awaitables, using remaining duration from the innermost
|
* Enrich `.await()` onto all Awaitables, using remaining duration from the innermost
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import akka.remote.testconductor.RoleName
|
||||||
/**
|
/**
|
||||||
* INTERNAL API: Support trait allowing trivially recording perf metrics from [[MultiNodeSpec]]s
|
* INTERNAL API: Support trait allowing trivially recording perf metrics from [[MultiNodeSpec]]s
|
||||||
*/
|
*/
|
||||||
private[akka] trait PerfFlamesSupport { _: MultiNodeSpec =>
|
private[akka] trait PerfFlamesSupport { self: MultiNodeSpec =>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs `perf-java-flames` script on given node (JVM process).
|
* Runs `perf-java-flames` script on given node (JVM process).
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,7 @@ private[remote] class Association(
|
||||||
*/
|
*/
|
||||||
@volatile
|
@volatile
|
||||||
@nowarn("msg=never used")
|
@nowarn("msg=never used")
|
||||||
private[this] var _sharedStateDoNotCallMeDirectly: AssociationState = AssociationState()
|
private[artery] var _sharedStateDoNotCallMeDirectly: AssociationState = AssociationState()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method for access to underlying state via Unsafe
|
* Helper method for access to underlying state via Unsafe
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,7 @@ class AckedDeliverySpec extends AkkaSpec {
|
||||||
b8.nonAcked should ===(Vector(msg3, msg4))
|
b8.nonAcked should ===(Vector(msg3, msg4))
|
||||||
|
|
||||||
val b9 = b8.acknowledge(Ack(SeqNo(4)))
|
val b9 = b8.acknowledge(Ack(SeqNo(4)))
|
||||||
b9.nonAcked should ===(Vector.empty)
|
b9.nonAcked should ===(Vector.empty[Sequenced])
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -172,8 +172,8 @@ class AckedDeliverySpec extends AkkaSpec {
|
||||||
b6.nacked should ===(Vector(msg2, msg3))
|
b6.nacked should ===(Vector(msg2, msg3))
|
||||||
|
|
||||||
val b7 = b6.acknowledge(Ack(SeqNo(4)))
|
val b7 = b6.acknowledge(Ack(SeqNo(4)))
|
||||||
b7.nonAcked should ===(Vector.empty)
|
b7.nonAcked should ===(Vector.empty[Sequenced])
|
||||||
b7.nacked should ===(Vector.empty)
|
b7.nacked should ===(Vector.empty[Sequenced])
|
||||||
}
|
}
|
||||||
|
|
||||||
"throw exception if non-buffered sequence number is NACKed" in {
|
"throw exception if non-buffered sequence number is NACKed" in {
|
||||||
|
|
@ -201,7 +201,7 @@ class AckedDeliverySpec extends AkkaSpec {
|
||||||
val msg5 = msg(5)
|
val msg5 = msg(5)
|
||||||
|
|
||||||
val (b1, deliver1, ack1) = b0.receive(msg1).extractDeliverable
|
val (b1, deliver1, ack1) = b0.receive(msg1).extractDeliverable
|
||||||
deliver1 should ===(Vector.empty)
|
deliver1 should ===(Vector.empty[Sequenced])
|
||||||
ack1 should ===(Ack(SeqNo(1), nacks = Set(SeqNo(0))))
|
ack1 should ===(Ack(SeqNo(1), nacks = Set(SeqNo(0))))
|
||||||
|
|
||||||
val (b2, deliver2, ack2) = b1.receive(msg0).extractDeliverable
|
val (b2, deliver2, ack2) = b1.receive(msg0).extractDeliverable
|
||||||
|
|
@ -209,7 +209,7 @@ class AckedDeliverySpec extends AkkaSpec {
|
||||||
ack2 should ===(Ack(SeqNo(1)))
|
ack2 should ===(Ack(SeqNo(1)))
|
||||||
|
|
||||||
val (b3, deliver3, ack3) = b2.receive(msg4).extractDeliverable
|
val (b3, deliver3, ack3) = b2.receive(msg4).extractDeliverable
|
||||||
deliver3 should ===(Vector.empty)
|
deliver3 should ===(Vector.empty[Sequenced])
|
||||||
ack3 should ===(Ack(SeqNo(4), nacks = Set(SeqNo(2), SeqNo(3))))
|
ack3 should ===(Ack(SeqNo(4), nacks = Set(SeqNo(2), SeqNo(3))))
|
||||||
|
|
||||||
val (b4, deliver4, ack4) = b3.receive(msg2).extractDeliverable
|
val (b4, deliver4, ack4) = b3.receive(msg2).extractDeliverable
|
||||||
|
|
@ -217,7 +217,7 @@ class AckedDeliverySpec extends AkkaSpec {
|
||||||
ack4 should ===(Ack(SeqNo(4), nacks = Set(SeqNo(3))))
|
ack4 should ===(Ack(SeqNo(4), nacks = Set(SeqNo(3))))
|
||||||
|
|
||||||
val (b5, deliver5, ack5) = b4.receive(msg5).extractDeliverable
|
val (b5, deliver5, ack5) = b4.receive(msg5).extractDeliverable
|
||||||
deliver5 should ===(Vector.empty)
|
deliver5 should ===(Vector.empty[Sequenced])
|
||||||
ack5 should ===(Ack(SeqNo(5), nacks = Set(SeqNo(3))))
|
ack5 should ===(Ack(SeqNo(5), nacks = Set(SeqNo(3))))
|
||||||
|
|
||||||
val (_, deliver6, ack6) = b5.receive(msg3).extractDeliverable
|
val (_, deliver6, ack6) = b5.receive(msg3).extractDeliverable
|
||||||
|
|
@ -238,7 +238,7 @@ class AckedDeliverySpec extends AkkaSpec {
|
||||||
|
|
||||||
val (_, deliver, ack) = buf3.extractDeliverable
|
val (_, deliver, ack) = buf3.extractDeliverable
|
||||||
|
|
||||||
deliver should ===(Vector.empty)
|
deliver should ===(Vector.empty[Sequenced])
|
||||||
ack should ===(Ack(SeqNo(2)))
|
ack should ===(Ack(SeqNo(2)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,8 +36,8 @@ class ActorRefResolveCacheQuarantineSpec
|
||||||
val remoteSelection1 = clientSystem1.actorSelection(rootActorPath(system) / "user" / "echo")
|
val remoteSelection1 = clientSystem1.actorSelection(rootActorPath(system) / "user" / "echo")
|
||||||
|
|
||||||
// PromiseActorRef (temp) doesn't include a uid in the ActorRef
|
// PromiseActorRef (temp) doesn't include a uid in the ActorRef
|
||||||
val reply1 = remoteSelection1 ? "hello-1"
|
val reply1 = (remoteSelection1 ? "hello-1").futureValue
|
||||||
reply1.futureValue shouldBe "hello-1"
|
reply1 shouldBe "hello-1"
|
||||||
|
|
||||||
shutdown(clientSystem1)
|
shutdown(clientSystem1)
|
||||||
|
|
||||||
|
|
@ -51,8 +51,8 @@ class ActorRefResolveCacheQuarantineSpec
|
||||||
extraConfig = Some(s"akka.remote.artery.canonical.port = $port1"))
|
extraConfig = Some(s"akka.remote.artery.canonical.port = $port1"))
|
||||||
val remoteSelection2 = clientSystem2.actorSelection(rootActorPath(system) / "user" / "echo")
|
val remoteSelection2 = clientSystem2.actorSelection(rootActorPath(system) / "user" / "echo")
|
||||||
|
|
||||||
val reply2 = remoteSelection2 ? "hello-2"
|
val reply2 = (remoteSelection2 ? "hello-2").futureValue
|
||||||
reply2.futureValue shouldBe "hello-2"
|
reply2 shouldBe "hello-2"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,7 @@ class ImmutableLongMapSpec extends AnyWordSpec with Matchers {
|
||||||
|
|
||||||
m1.remove(5L) should be(m1)
|
m1.remove(5L) should be(m1)
|
||||||
|
|
||||||
m1.remove(10L).remove(20L).remove(30L) should be(ImmutableLongMap.empty)
|
m1.remove(10L).remove(20L).remove(30L) should be(ImmutableLongMap.empty[String])
|
||||||
}
|
}
|
||||||
|
|
||||||
"get None when entry doesn't exist" in {
|
"get None when entry doesn't exist" in {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import akka.testkit.TestActors
|
||||||
|
|
||||||
object SerializationErrorSpec {
|
object SerializationErrorSpec {
|
||||||
|
|
||||||
object NotSerializableMsg
|
class NotSerializableMsg
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ class SerializationErrorSpec extends ArteryMultiNodeSpec(ArterySpecSupport.defau
|
||||||
expectMsg("ping")
|
expectMsg("ping")
|
||||||
|
|
||||||
EventFilter[java.io.NotSerializableException](start = "Failed to serialize message", occurrences = 1).intercept {
|
EventFilter[java.io.NotSerializableException](start = "Failed to serialize message", occurrences = 1).intercept {
|
||||||
remoteRef ! NotSerializableMsg
|
remoteRef ! new NotSerializableMsg()
|
||||||
}
|
}
|
||||||
|
|
||||||
remoteRef ! "ping2"
|
remoteRef ! "ping2"
|
||||||
|
|
|
||||||
|
|
@ -425,7 +425,7 @@ class RemotingSpec extends AkkaSpec(RemotingSpec.cfg) with ImplicitSender with D
|
||||||
|
|
||||||
"not fail ask across node boundaries" in within(5.seconds) {
|
"not fail ask across node boundaries" in within(5.seconds) {
|
||||||
import system.dispatcher
|
import system.dispatcher
|
||||||
val f = for (_ <- 1 to 1000) yield (here ? "ping").mapTo(manifest[(String, ActorRef)])
|
val f = for (_ <- 1 to 1000) yield (here ? "ping").mapTo[(String, ActorRef)]
|
||||||
Await.result(Future.sequence(f), timeout.duration).map(_._1).toSet should ===(Set("pong"))
|
Await.result(Future.sequence(f), timeout.duration).map(_._1).toSet should ===(Set("pong"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -281,8 +281,6 @@ class AkkaProtocolSpec extends AkkaSpec("""akka.actor.provider = remote """) wit
|
||||||
h.remoteAddress should ===(remoteAkkaAddress)
|
h.remoteAddress should ===(remoteAkkaAddress)
|
||||||
h.localAddress should ===(localAkkaAddress)
|
h.localAddress should ===(localAkkaAddress)
|
||||||
h
|
h
|
||||||
|
|
||||||
case _ => fail()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wrappedHandle.readHandlerPromise.success(ActorHandleEventListener(testActor))
|
wrappedHandle.readHandlerPromise.success(ActorHandleEventListener(testActor))
|
||||||
|
|
@ -318,8 +316,6 @@ class AkkaProtocolSpec extends AkkaSpec("""akka.actor.provider = remote """) wit
|
||||||
h.remoteAddress should ===(remoteAkkaAddress)
|
h.remoteAddress should ===(remoteAkkaAddress)
|
||||||
h.localAddress should ===(localAkkaAddress)
|
h.localAddress should ===(localAkkaAddress)
|
||||||
h
|
h
|
||||||
|
|
||||||
case _ => fail()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wrappedHandle.readHandlerPromise.success(ActorHandleEventListener(testActor))
|
wrappedHandle.readHandlerPromise.success(ActorHandleEventListener(testActor))
|
||||||
|
|
@ -355,8 +351,6 @@ class AkkaProtocolSpec extends AkkaSpec("""akka.actor.provider = remote """) wit
|
||||||
h.remoteAddress should ===(remoteAkkaAddress)
|
h.remoteAddress should ===(remoteAkkaAddress)
|
||||||
h.localAddress should ===(localAkkaAddress)
|
h.localAddress should ===(localAkkaAddress)
|
||||||
h
|
h
|
||||||
|
|
||||||
case _ => fail()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wrappedHandle.readHandlerPromise.success(ActorHandleEventListener(testActor))
|
wrappedHandle.readHandlerPromise.success(ActorHandleEventListener(testActor))
|
||||||
|
|
@ -395,8 +389,6 @@ class AkkaProtocolSpec extends AkkaSpec("""akka.actor.provider = remote """) wit
|
||||||
h.remoteAddress should ===(remoteAkkaAddress)
|
h.remoteAddress should ===(remoteAkkaAddress)
|
||||||
h.localAddress should ===(localAkkaAddress)
|
h.localAddress should ===(localAkkaAddress)
|
||||||
h
|
h
|
||||||
|
|
||||||
case _ => fail()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
stateActor ! Disassociated(AssociationHandle.Unknown)
|
stateActor ! Disassociated(AssociationHandle.Unknown)
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ trait BindBehavior {
|
||||||
|
|
||||||
s"bind to specified tcp address" in {
|
s"bind to specified tcp address" in {
|
||||||
val address = SocketUtil.temporaryServerAddress(address = "127.0.0.1")
|
val address = SocketUtil.temporaryServerAddress(address = "127.0.0.1")
|
||||||
val bindAddress =
|
val bindAddress: InetSocketAddress =
|
||||||
try SocketUtil.temporaryServerAddress(address = "127.0.1.1")
|
try SocketUtil.temporaryServerAddress(address = "127.0.1.1")
|
||||||
catch {
|
catch {
|
||||||
case e: java.net.BindException =>
|
case e: java.net.BindException =>
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,10 @@ import java.io.NotSerializableException
|
||||||
import java.util.Optional
|
import java.util.Optional
|
||||||
import java.util.concurrent.TimeoutException
|
import java.util.concurrent.TimeoutException
|
||||||
|
|
||||||
|
import scala.annotation.nowarn
|
||||||
import scala.concurrent.duration._
|
import scala.concurrent.duration._
|
||||||
import scala.util.control.NoStackTrace
|
import scala.util.control.NoStackTrace
|
||||||
|
|
||||||
import com.typesafe.config.ConfigFactory
|
import com.typesafe.config.ConfigFactory
|
||||||
import akka.{ Done, NotUsed }
|
import akka.{ Done, NotUsed }
|
||||||
import akka.actor._
|
import akka.actor._
|
||||||
|
|
@ -159,11 +161,13 @@ class MiscMessageSerializerSpec extends AkkaSpec(MiscMessageSerializerSpec.testC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@nowarn("msg=Unused import")
|
||||||
def verifySerialization(msg: AnyRef): Unit = {
|
def verifySerialization(msg: AnyRef): Unit = {
|
||||||
val serializer = new MiscMessageSerializer(system.asInstanceOf[ExtendedActorSystem])
|
val serializer = new MiscMessageSerializer(system.asInstanceOf[ExtendedActorSystem])
|
||||||
val result = serializer.fromBinary(serializer.toBinary(msg), serializer.manifest(msg))
|
val result = serializer.fromBinary(serializer.toBinary(msg), serializer.manifest(msg))
|
||||||
msg match {
|
msg match {
|
||||||
case t: Throwable =>
|
case t: Throwable =>
|
||||||
|
import org.scalactic.TripleEquals.unconstrainedEquality
|
||||||
// typically no equals in exceptions
|
// typically no equals in exceptions
|
||||||
result.getClass should ===(t.getClass)
|
result.getClass should ===(t.getClass)
|
||||||
result.asInstanceOf[Throwable].getMessage should ===(t.getMessage)
|
result.asInstanceOf[Throwable].getMessage should ===(t.getMessage)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue