File: 10_fdleak.t

package info (click to toggle)
libnet-sip-perl 0.838-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,132 kB
  • sloc: perl: 11,988; makefile: 6
file content (100 lines) | stat: -rw-r--r-- 2,898 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/perl
# make sure that ports get closed when using BYE and cleanup, even
# when the other side does not respond to the BYE
# -----------------------------------------------------------------------------
# not done with Test::More, because this allocates some unexpected fd, which
# make this test harder

use strict;
use warnings;
do './testlib.pl' || do './t/testlib.pl' || die "no testlib: $@";
use Net::SIP ':all';

#test_use_config(6);
my ($ssock,$saddr) = create_socket();
my $tfn = fileno( newfd() );
if ( fileno($ssock) != $tfn-1 ) {
    print "1..0 # Platform does not give fds in order fn,fn+1,fn+2...\n";
    exit;
} else {
    print "1..10\n";
}

my $uas = fork_sub( 'uas' );
my $uac = fork_sub( 'uac' );

fd_grep_ok( 'Listening', $uas );
my $match = fd_grep( qr/allocated \d+ sockets/, $uac );
like( $match, qr/ 1 sockets/, "uac allocated 1 socket for SIP" );
fd_grep_ok( 'Established', $uas );
fd_grep_ok( 'Established', $uac );

$match = fd_grep( qr/allocated \d+ sockets/, $uac );
like( $match, qr/ 3 sockets/, "uac allocated 2 sockets for RTP" );
fd_grep_ok( 'Send BYE done', $uac );

$match = fd_grep( qr/allocated \d+ sockets/, $uac );
like( $match, qr/ 1 sockets/, "uac closed RTP socket" );
$match = fd_grep( qr/allocated \d+ sockets/, $uac );
like( $match, qr/ 0 sockets/, "uac closed SIP socket" );

killall();

sub uas {
    my $ua = Simple->new( leg => $ssock, from => "sip:uas\@i$saddr" );
    my $done;
    $ua->listen( cb_established => \$done );
    print "Listening\n";
    $ua->loop( \$done );
    print "Established\n";
}


sub uac {
    ( my $caddr = $saddr ) =~s{:\d+}{:0}; # same ip, port will be picked
    # for some strange reason on glib2.7 or whatever the cause is this not
    # only allocates a new fd, but a pipe too. So just ignore the first fd
    # and use the next
    my $tfd_ignore = newfd();
    my $tfd = newfd();
    my $fnbase = fileno($tfd) +1;
    my $show_diff = sub {
	my $expect = shift;
	my $fd = newfd();
	my $fn = fileno($fd)-1;
	system( "lsof -n -p$$" ) if defined $expect && $fn+1-$fnbase != $expect;
	printf "allocated %d sockets %s\n", $fn+1-$fnbase, $fn == $fnbase ? "($fn)" :
	    $fn > $fnbase  ? "($fnbase..$fn)" : "";
    };

    # this should allocate 1 socket for SIP
    my $ua = Simple->new( leg => $caddr, from => "sip:uac\@$caddr" );
    $show_diff->(1);

    # this should allocate 2 sockets for RTP
    my $call = $ua->invite( "sip:uas\@$saddr" );
    print "Established\n";
    $show_diff->(3);

    # send BYE, but other side is already closed
    sleep(5);
    my $bye_done;
    $call->bye;
    $call->loop(1);
    print "Send BYE done\n";

    # this should close the RTP sockets
    $call->cleanup;
    $show_diff->(1);

    # and this should close the SIP socket too
    $ua->cleanup;
    $show_diff->(0);
}


sub newfd {
    # dup STDOUT to create new fd
    open( my $fd,'>&STDOUT' );
    return $fd;
}