File Coverage

inc/Test/TCP.pm
Criterion Covered Total %
statement 27 58 46.5
branch 0 16 0.0
condition 0 11 0.0
subroutine 9 13 69.2
pod 2 3 66.6
total 38 101 37.6


line stmt bran cond sub pod time code
1             #line 1
2 1     1   876 package Test::TCP;
  1         3  
  1         35  
3 1     1   5 use strict;
  1         2  
  1         293  
4 1     1   27 use warnings;
  1         6  
  1         62  
5             use 5.00800;
6 1     1   6 our $VERSION = '0.08';
  1         2  
  1         8  
7 1     1   1198 use base qw/Exporter/;
  1         33019  
  1         10  
8 1     1   2035 use IO::Socket::INET;
  1         1222  
  1         14  
9 1     1   22 use Test::SharedFork;
  1         1  
  1         19  
10 1     1   6 use Test::More ();
  1         2  
  1         34  
11 1     1   1029 use Config;
  1         8454  
  1         9  
12             use POSIX;
13              
14             our @EXPORT = qw/ empty_port test_tcp wait_port /;
15              
16 0   0 0 0   sub empty_port {
17 0 0 0       my $port = shift || 10000;
18             $port = 19000 unless $port =~ /^[0-9]+$/ && $port < 19000;
19 0            
20 0           while ( $port++ < 20000 ) {
21             my $sock = IO::Socket::INET->new(
22             Listen => 5,
23             LocalAddr => '127.0.0.1',
24             LocalPort => $port,
25             Proto => 'tcp',
26             ReuseAddr => 1,
27 0 0         );
28             return $port if $sock;
29 0           }
30             die "empty port not found";
31             }
32              
33 0     0 1   sub test_tcp {
34 0           my %args = @_;
35 0 0         for my $k (qw/client server/) {
36             die "missing madatory parameter $k" unless exists $args{$k};
37 0   0       }
38             my $port = $args{port} || empty_port();
39 0 0          
    0          
40             if ( my $pid = Test::SharedFork->fork() ) {
41 0           # parent.
42             wait_port($port);
43 0            
44             $args{client}->($port, $pid);
45 0            
46 0           kill TERM => $pid;
47 0 0 0       waitpid( $pid, 0 );
48 0           if (WIFSIGNALED($?) && (split(' ', $Config{sig_name}))[WTERMSIG($?)] eq 'ABRT') {
49             Test::More::diag("your server received SIGABRT");
50             }
51             }
52             elsif ( $pid == 0 ) {
53 0           # child
54             $args{server}->($port);
55             }
56 0           else {
57             die "fork failed: $!";
58             }
59             }
60              
61 0     0     sub _check_port {
62             my ($port) = @_;
63 0            
64             my $remote = IO::Socket::INET->new(
65             Proto => 'tcp',
66             PeerAddr => '127.0.0.1',
67             PeerPort => $port,
68 0 0         );
69 0           if ($remote) {
70 0           close $remote;
71             return 1;
72             }
73 0           else {
74             return 0;
75             }
76             }
77              
78 0     0 1   sub wait_port {
79             my $port = shift;
80 0            
81 0           my $retry = 10;
82 0 0         while ( $retry-- ) {
83 0           return if _check_port($port);
84             sleep 1;
85 0           }
86             die "cannot open port: $port";
87             }
88              
89             1;
90             __END__