//
// Copyright (c) 2007, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 9 Feb 07 Brian Frank Creation
//
using concurrent
class TcpListenerTest : Test
{
//////////////////////////////////////////////////////////////////////////
// Make
//////////////////////////////////////////////////////////////////////////
Void testMake()
{
s := TcpListener.make
verifyEq(s.isBound, false)
verifyEq(s.isClosed, false)
verifyEq(s.localAddr, null)
verifyEq(s.localPort, null)
s.close
}
//////////////////////////////////////////////////////////////////////////
// Bind
//////////////////////////////////////////////////////////////////////////
Void testBind()
{
verifyBind(null, null)
verifyBind(IpAddr.local, null)
verifyBind(null, 1872)
verifyBind(IpAddr.local, 1873)
}
Void verifyBind(IpAddr? addr, Int? port)
{
s := TcpListener.make
verifySame(s.bind(addr, port), s)
// state
verifyEq(s.isBound, true)
verifyEq(s.isClosed, false)
// local address
if (addr == null)
verify(s.localAddr!= null)
else
verifyEq(s.localAddr, addr)
// local port
if (port == null)
verify(s.localPort > 0)
else
verifyEq(s.localPort, port)
// duplicate port
/* On Windows7 this doesn't fail?
x := TcpSocket.make
verifyErr(IOErr#) { x.bind(null, s.localPort) }
x.close
*/
// cleanup
s.close
verifyEq(s.isClosed, true)
}
//////////////////////////////////////////////////////////////////////////
// Accept
//////////////////////////////////////////////////////////////////////////
Void testAccept()
{
listener := TcpListener.make.bind(null, null)
port := listener.localPort
t1 := Duration.now
listener.options.receiveTimeout = 100ms
verifyErr(IOErr#) { listener.accept }
t2 := Duration.now
verify(50ms < t2-t1 && t2-t1 < 200ms, (t2-t1).toLocale)
actor := Actor(ActorPool()) { runClient(port) }
future := actor.send(null)
// accept
trace("s: accept...")
s := listener.accept
trace("s: accepted!")
verifyEq(s.isConnected, true)
// read req line
req := s.in.readLine
trace("s: req = $req")
verifyEq(req, "hello")
// write response and verify it is returned back on join
s.out.printLine("how you doing?").flush
res := future.get(5sec)
trace("s: response = $res")
verifyEq(res, "how you doing?")
// cleanup
s.close
listener.close
}
static Obj runClient(Int port)
{
trace("c: connecting...")
s := TcpSocket.make.connect(IpAddr.local, port)
trace("c: connected!")
s.out.printLine("hello").flush
res := s.in.readLine
trace("c: response $res")
s.close
return res
}
static Void trace(Str s)
{
// echo(s)
}
//////////////////////////////////////////////////////////////////////////
// Options
//////////////////////////////////////////////////////////////////////////
Void testOptions()
{
s := TcpListener.make
so := s.options
receive := so.receiveBufferSize
so.receiveBufferSize = receive*2
verifyEq(so.receiveBufferSize, receive*2)
reuse := so.reuseAddr
so.reuseAddr = !reuse
verifyEq(so.reuseAddr, !reuse)
so.receiveTimeout = 100ms
verifyEq(so.receiveTimeout, 100ms)
so.receiveTimeout = null
verifyEq(so.receiveTimeout, null)
verifyErr(UnsupportedErr#) { echo(so.broadcast) }
verifyErr(UnsupportedErr#) { so.broadcast = false }
verifyErr(UnsupportedErr#) { echo(so.inBufferSize) }
verifyErr(UnsupportedErr#) { so.inBufferSize = 88 }
verifyErr(UnsupportedErr#) { echo(so.outBufferSize) }
verifyErr(UnsupportedErr#) { so.outBufferSize = 99 }
verifyErr(UnsupportedErr#) { echo(so.keepAlive) }
verifyErr(UnsupportedErr#) { so.keepAlive = false }
verifyErr(UnsupportedErr#) { echo(so.sendBufferSize) }
verifyErr(UnsupportedErr#) { so.sendBufferSize = 100 }
verifyErr(UnsupportedErr#) { echo(so.linger) }
verifyErr(UnsupportedErr#) { so.linger = null }
verifyErr(UnsupportedErr#) { echo(so.noDelay) }
verifyErr(UnsupportedErr#) { so.noDelay = true }
verifyErr(UnsupportedErr#) { echo(so.trafficClass) }
verifyErr(UnsupportedErr#) { so.trafficClass = 0 }
s.close
}
//////////////////////////////////////////////////////////////////////////
// Utils
//////////////////////////////////////////////////////////////////////////
Void dump(TcpListener s)
{
echo("---------")
echo("bound = $s.isBound")
echo("closed = $s.isClosed")
echo("localAddr = $s.localAddr")
echo("localPort = $s.localPort")
echo("receive = $s.options.receiveBufferSize")
echo("reuseAddr = $s.options.reuseAddr")
echo("timeout = $s.options.receiveTimeout")
}
}