pekko/akka-actor-tests/src/test/scala/akka/io/UdpIntegrationSpec.scala

154 lines
4.8 KiB
Scala
Raw Normal View History

/*
* Copyright (C) 2009-2019 Lightbend Inc. <https://www.lightbend.com>
*/
package akka.io
2013-06-14 14:45:43 +02:00
import java.net.InetSocketAddress
import akka.testkit.{ AkkaSpec, ImplicitSender, TestProbe }
import akka.util.ByteString
import akka.actor.ActorRef
2013-06-14 14:45:43 +02:00
import akka.io.Udp._
import akka.io.Inet._
Various scala-2.13.0-M5 fixes fix akka-actor-tests compile errors some tests still fail though Fix test failures in akka-actor-test Manually work arround missing implicit Factory[Nothing, Seq[Nothing]] see https://github.com/scala/scala-collection-compat/issues/137 akka-remote scalafix changes Fix shutdownAll compile error test:akka-remote scalafix changes akka-multi-node-testkit scalafix Fix akka-remote-tests multi-jvm compile errors akka-stream-tests/test:scalafix Fix test:akka-stream-tests Crude implementation of ByteString.map scalafix akka-actor-typed, akka-actor-typed-tests akka-actor-typed-tests compile and succeed scalafix akka-camel scalafix akka-cluster akka-cluster compile & test scalafix akka-cluster-metrics Fix akka-cluster-metrics scalafix akka-cluster-tools akka-cluster-tools compile and test scalafix akka-distributed-data akka-distributed-data fixes scalafix akka-persistence scalafix akka-cluster-sharding fix akka-cluster-sharding scalafix akka-contrib Fix akka-cluster-sharding-typed test scalafix akka-docs Use scala-stm 0.9 (released for M5) akka-docs Remove dependency on collections-compat Cherry-pick the relevant constructs to our own private utils Shorten 'scala.collections.immutable' by importing it Duplicate 'immutable' imports Use 'foreach' on futures Replace MapLike with regular Map Internal API markers Simplify ccompat by moving PackageShared into object Since we don't currently need to differentiate between 2.11 and Avoid relying on 'union' (and ++) being left-biased Fix akka-actor/doc by removing -Ywarn-unused Make more things more private Copyright headers Use 'unsorted' to go from SortedSet to Set Duplicate import Use onComplete rather than failed.foreach Clarify why we partly duplicate scala-collection-compat
2018-11-22 16:18:10 +01:00
import akka.testkit.SocketUtil.temporaryServerAddresses
import java.net.DatagramSocket
class UdpIntegrationSpec extends AkkaSpec("""
akka.loglevel = INFO
# tests expect to be able to mutate messages
akka.actor.serialize-messages = off
akka.actor.serialize-creators = on""") with ImplicitSender {
def bindUdp(handler: ActorRef): InetSocketAddress = {
val commander = TestProbe()
commander.send(IO(Udp), Bind(handler, new InetSocketAddress("127.0.0.1", 0)))
commander.expectMsgType[Bound].localAddress
}
def bindUdp(address: InetSocketAddress, handler: ActorRef): ActorRef = {
val commander = TestProbe()
commander.send(IO(Udp), Bind(handler, address))
commander.expectMsg(Bound(address))
commander.sender()
}
def createSimpleSender(): ActorRef = {
val commander = TestProbe()
commander.send(IO(Udp), SimpleSender)
commander.expectMsg(SimpleSenderReady)
commander.sender()
}
"The UDP Fire-and-Forget implementation" must {
"be able to send without binding" in {
val serverAddress = bindUdp(testActor)
val data = ByteString("To infinity and beyond!")
val simpleSender = createSimpleSender()
simpleSender ! Send(data, serverAddress)
2015-01-16 11:09:59 +01:00
expectMsgType[Received].data should ===(data)
}
"be able to deliver subsequent messages after address resolution failure" in {
val unresolvableServerAddress = new InetSocketAddress("some-unresolvable-host", 10000)
val cmd = Send(ByteString("Can't be delivered"), unresolvableServerAddress)
val simpleSender = createSimpleSender()
simpleSender ! cmd
expectMsgType[CommandFailed].cmd should ===(cmd)
val serverAddress = bindUdp(testActor)
val data = ByteString("To infinity and beyond!")
simpleSender ! Send(data, serverAddress)
expectMsgType[Received].data should ===(data)
}
"be able to send several packet back and forth with binding" in {
val Seq(serverAddress, clientAddress) = temporaryServerAddresses(2, udp = true)
val server = bindUdp(serverAddress, testActor)
val client = bindUdp(clientAddress, testActor)
val data = ByteString("Fly little packet!")
def checkSendingToClient(): Unit = {
server ! Send(data, clientAddress)
expectMsgPF() {
case Received(d, a) =>
2015-01-16 11:09:59 +01:00
d should ===(data)
a should ===(serverAddress)
}
}
def checkSendingToServer(): Unit = {
client ! Send(data, serverAddress)
expectMsgPF() {
case Received(d, a) =>
2015-01-16 11:09:59 +01:00
d should ===(data)
a should ===(clientAddress)
}
}
(0 until 20).foreach(_ => checkSendingToServer())
(0 until 20).foreach(_ => checkSendingToClient())
(0 until 20).foreach { i =>
if (i % 2 == 0) checkSendingToServer()
else checkSendingToClient()
}
}
"call SocketOption.beforeBind method before bind." in {
val commander = TestProbe()
val assertOption = AssertBeforeBind()
commander.send(IO(Udp), Bind(testActor, new InetSocketAddress("127.0.0.1", 0), options = List(assertOption)))
commander.expectMsgType[Bound]
assert(assertOption.beforeCalled === 1)
}
"call SocketOption.afterConnect method after binding." in {
val commander = TestProbe()
val assertOption = AssertAfterChannelBind()
commander.send(IO(Udp), Bind(testActor, new InetSocketAddress("127.0.0.1", 0), options = List(assertOption)))
commander.expectMsgType[Bound]
assert(assertOption.afterCalled === 1)
}
"call DatagramChannelCreator.create method when opening channel" in {
val commander = TestProbe()
val assertOption = AssertOpenDatagramChannel()
commander.send(IO(Udp), Bind(testActor, new InetSocketAddress("127.0.0.1", 0), options = List(assertOption)))
commander.expectMsgType[Bound]
assert(assertOption.openCalled === 1)
}
}
}
private case class AssertBeforeBind() extends SocketOption {
@volatile
var beforeCalled = 0
override def beforeDatagramBind(ds: DatagramSocket): Unit = {
assert(!ds.isBound)
beforeCalled += 1
}
}
private case class AssertAfterChannelBind() extends SocketOptionV2 {
@volatile
var afterCalled = 0
override def afterBind(s: DatagramSocket) = {
assert(s.isBound)
afterCalled += 1
}
}
private case class AssertOpenDatagramChannel() extends DatagramChannelCreator {
@volatile
var openCalled = 0
override def create() = {
openCalled += 1
super.create()
}
}