Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tokuhirom/test-tcp
Test::TCP for perl
https://github.com/tokuhirom/test-tcp
Last synced: 20 days ago
JSON representation
Test::TCP for perl
- Host: GitHub
- URL: https://github.com/tokuhirom/test-tcp
- Owner: tokuhirom
- License: other
- Created: 2009-03-26T04:06:45.000Z (over 15 years ago)
- Default Branch: master
- Last Pushed: 2024-05-23T04:16:37.000Z (6 months ago)
- Last Synced: 2024-10-11T20:58:08.997Z (about 1 month ago)
- Language: Perl
- Homepage:
- Size: 292 KB
- Stars: 33
- Watchers: 10
- Forks: 33
- Open Issues: 18
-
Metadata Files:
- Readme: README.md
- Changelog: Changes
- License: LICENSE
Awesome Lists containing this project
README
# 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 DESTROYIf 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](https://metacpan.org/pod/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 of `listen`.This parameter is required.
- $args{max\_wait} : Number
Will wait for at most `$max_wait` seconds before checking port.
See also [Net::EmptyPort](https://metacpan.org/pod/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](https://metacpan.org/pod/Net::EmptyPort#can_bind) function to check if the program can bind to the loopback address of IPv6, as well as the `host` parameter of the ["test\_tcp"](#test_tcp) function to specify the same address as the bind address.
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
# 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.