Reputation: 1689
i'm trying to develop a simple unit test to bind a port on my machine, test that the port is bound, then release the port and test that it is release. Currently I'm using this naive approach
class ServerTest extends FlatSpec with MustMatchers {
"Server" must "bind a tcp server to an address on our machine" in {
//if this fails this means that the port is in use before our test case is run
val port = 18333
isBound(port) must be (false)
val actor = Server()
actor ! Tcp.Bind(actor, new InetSocketAddress(port))
Thread.sleep(1000)
isBound(port) must be (true)
Thread.sleep(1000)
actor ! Tcp.Unbind
Thread.sleep(1000)
isBound(port) must be (false)
}
/**
* Tests if a specific port number is bound on our machine
* @param port
* @return
*/
def isBound(port : Int) : Boolean = {
val tryBinding : Try[Unit] = Try {
val socket = new java.net.Socket()
socket.connect(new java.net.InetSocketAddress(port),1000)
socket.close()
}
tryBinding.isSuccess
}
}
I would like to test this without using the calls to Thread.sleep
since this is a blocking call. Can anyone provide me with a more idiomatic solution?
Upvotes: 1
Views: 408
Reputation: 10428
When sending TCP.Bind
, you should expect a reply stating either success or failure: http://doc.akka.io/japi/akka/2.3.2/akka/io/Tcp.Bind.html
The Bind message is send to the TCP manager actor, which is obtained via TcpExt.manager() in order to bind to a listening socket. The manager replies either with a Tcp.CommandFailed or the actor handling the listen socket replies with a Tcp.Bound message. If the local port is set to 0 in the Bind message, then the Tcp.Bound message should be inspected to find the actual port which was bound to.
You should use AkkaTestKit (http://doc.akka.io/docs/akka/snapshot/scala/testing.html) and use either ImplicitSender
or a TestProbe
to send the TCP.Bind
, and then wait for the answer.
For example:
val probe = TestProbe()
probe.send(actor, Tcp.Bind(actor, new InetSocketAddress(port)))
probe.expectMsg(Tcp.Bound)
Your test code will either continue when the reply is received, or fail if not received within the timeout (which is configurable in the expectMsg
call).
Upvotes: 2
Reputation: 936
You can use
within (1000 millisends) {
...
}
see https://github.com/RayRoestenburg/AkkaExamples/blob/master/src/test/scala/unit/akka/TestKitUsageSpec.scala for more examples
Upvotes: 1