Test::TCP(3)
π NAME π
Okay bestie, welcome to Test::TCP(3) β the User Contributed Perl Documentation page for Test::TCP, and it is literally a test utility for testing TCP/IP-based server programs. The NAME is simple and iconic: Test::TCP β testing TCP program β¨
β¨ SYNOPSIS β¨
First up, the object-oriented vibe:
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 you're using a server that can only accept a port number, e.g. memcached, then it's giving very much "here's a port, go wild":
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. Not me being dramatic β that is literally the warning, bestie. π
And yes, there's also a functional interface 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. That's the whole main-character premise, and honestly? Slay. π
πΈ METHODS πΈ
π test_tcp π
This is the functional interface. Obsessed with the flexibility.
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. Very "we found a free port, it's yours now" energy. π«Ά
π wait_port π
wait_port(8080);
Waits for a particular port is available for connect. It's literally the "are we there yet?" method. β³
π§Έ Object Oriented interface π§Έ
π«Ά my $server = Test::TCP->new(%args);
Create new instance of Test::TCP. The arguments are following, bestie:
$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_waitseconds before checking port. See alsoNet::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. It's giving "auto_start already handles it, but okay, go off." β¨
π $server->stop()
Stop the server process. Bye bestie, shut it down. π
π my $pid = $server->pid();
Get the pid of child process. Very useful, very demure. π
β my $port = $server->port();
Get the port number of child process. The port is the moment. π
π FAQ π
π How to invoke two servers?
You can call test_tcp() twice! Nested chaos, but make it organized:
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. Equally iconic:
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. Very "let the binary cook" of you:
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. It's giving "I choose my own address, actually":
# 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. IPv6 bestie, we are checking first. π¦
use Net::EmptyPort qw(can_bind);
plan skip_all => "IPv6 not available"
unless can_bind('::1');
test_tcp(
client => sub {
...
},
server => sub {
...
},
host => '::1',
);
π AUTHOR π
Tokuhiro Matsuno <tokuhirom@gmail.com> β iconic author behavior. β¨
π«Ά THANKS TO π«Ά
kazuhookudragon3charsbarTatsuhiko Miyagawalestrrat
The whole thank-you list is here, no one left out. π
π SEE ALSO π
Crickets. No entries are listed here in the original β it goes straight to LICENSE, bestie. π
π LICENSE π
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Periodt. π
And that's the page, bestie β source/version perl v5.42.0, dated 2019-10-09, signing off with maximum sparkle. Mwah πβ¨
π¦ where this page comes from
- opensuse-leap 16.0: perl-Test-TCP 2.22-160000.2.2 Β· Artistic-1.0 OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms