NAME
Test::TCP - testing TCP program
SYNOPSIS
use
Test::TCP;
my
$server
= Test::TCP->new(
listen
=> 1,
code
=>
sub
{
my
$socket
=
shift
;
...
},
);
my
$client
= MyClient->new(
host
=>
'127.0.0.1'
,
port
=>
$server
->port);
undef
$server
;
# kill child process on DESTROY
If using a server that can only accept a port number, e.g. memcached:
use
Test::TCP;
my
$memcached
= Test::TCP->new(
code
=>
sub
{
my
$port
=
shift
;
exec
$bin
,
'-p'
=>
$port
;
die
"cannot execute $bin: $!"
;
},
);
my
$memd
= Cache::Memcached->new({
servers
=> [
'127.0.0.1:'
.
$memcached
->port]});
...
N.B.: This is vulnerable to race conditions, if another process binds to the same port after Net::EmptyPort found it available.
And functional interface is available:
use
Test::TCP;
test_tcp(
listen
=> 1,
client
=>
sub
{
my
(
$port
,
$server_pid
) =
@_
;
# send request to the server
},
server
=>
sub
{
my
$socket
=
shift
;
# run server, calling $socket->accept
},
);
test_tcp(
client
=>
sub
{
my
(
$port
,
$server_pid
) =
@_
;
# send request to the server
},
server
=>
sub
{
my
$port
=
shift
;
# run server, binding to $port
},
);
DESCRIPTION
Test::TCP is a test utility to test TCP/IP-based server programs.
METHODS
- test_tcp
-
Functional interface.
test_tcp(
listen
=> 1,
client
=>
sub
{
my
$port
=
shift
;
# send request to the server
},
server
=>
sub
{
my
$socket
=
shift
;
# run server
},
# optional
host
=>
'127.0.0.1'
,
# specify '::1' to test using IPv6
port
=> 8080,
max_wait
=> 3,
# seconds
);
If
listen
is false,server
is instead passed a port number that was free before it was called. - wait_port
-
wait_port(8080);
Waits for a particular port is available for connect.
Object Oriented interface
- my $server = Test::TCP->new(%args);
-
Create new instance of Test::TCP.
Arguments are following:
- $args{auto_start}: Boolean
-
Call
$server->start()
after create instance.Default: true
- $args{code}: CodeRef
-
The callback function. Argument for callback function is:
$code->($socket)
or$code->($port)
, depending on the value oflisten
.This parameter is required.
- $args{max_wait} : Number
-
Will wait for at most
$max_wait
seconds before checking port.See also Net::EmptyPort.
Default: 10
- $args{listen} : Boolean
-
If true, open a listening socket and pass this to the callback. Otherwise find a free port and pass the number of it to the callback.
- $server->start()
-
Start the server process. Normally, you don't need to call this method.
- $server->stop()
-
Stop the server process.
- my $pid = $server->pid();
-
Get the pid of child process.
- my $port = $server->port();
-
Get the port number of child process.
FAQ
- How to invoke two servers?
-
You can call test_tcp() twice!
test_tcp(
client
=>
sub
{
my
$port1
=
shift
;
test_tcp(
client
=>
sub
{
my
$port2
=
shift
;
# some client code here
},
server
=>
sub
{
my
$port2
=
shift
;
# some server2 code here
},
);
},
server
=>
sub
{
my
$port1
=
shift
;
# some server1 code here
},
);
Or use the OO interface instead.
my
$server1
= Test::TCP->new(
code
=>
sub
{
my
$port1
=
shift
;
...
});
my
$server2
= Test::TCP->new(
code
=>
sub
{
my
$port2
=
shift
;
...
});
# your client code here.
...
- How do you test server program written in other languages like memcached?
-
You can use
exec()
in child process.use
strict;
use
warnings;
use
utf8;
use
Test::More;
use
Test::TCP 1.08;
use
File::Which;
my
$bin
=
scalar
which
'memcached'
;
plan
skip_all
=>
'memcached binary is not found'
unless
defined
$bin
;
my
$memcached
= Test::TCP->new(
code
=>
sub
{
my
$port
=
shift
;
exec
$bin
,
'-p'
=>
$port
;
die
"cannot execute $bin: $!"
;
},
);
use
Cache::Memcached;
my
$memd
= Cache::Memcached->new({
servers
=> [
'127.0.0.1:'
.
$memcached
->port]});
$memd
->set(
foo
=>
'bar'
);
is
$memd
->get(
'foo'
),
'bar'
;
done_testing;
- How do I use address other than "127.0.0.1" for testing?
-
You can use the
host
parameter to specify the bind address.# let the server bind to "0.0.0.0" for testing
test_tcp(
client
=>
sub
{
...
},
server
=>
sub
{
...
},
host
=>
'0.0.0.0'
,
);
- How should I write IPv6 tests?
-
You should use the "can_bind" in Net::EmptyPort function to check if the program can bind to the loopback address of IPv6, as well as the
host
parameter of the "test_tcp" function to specify the same address as the bind address.plan
skip_all
=>
"IPv6 not available"
unless
can_bind(
'::1'
);
test_tcp(
client
=>
sub
{
...
},
server
=>
sub
{
...
},
host
=>
'::1'
,
);
AUTHOR
Tokuhiro Matsuno <tokuhirom@gmail.com>
THANKS TO
kazuhooku
dragon3
charsbar
Tatsuhiko Miyagawa
lestrrat
SEE ALSO
LICENSE
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.