File: 51loop-connect.t

package info (click to toggle)
libio-async-perl 0.29-1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 684 kB
  • ctags: 239
  • sloc: perl: 6,439; makefile: 2
file content (124 lines) | stat: -rw-r--r-- 3,401 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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#!/usr/bin/perl -w

use strict;

use IO::Async::Test;

use Test::More tests => 8;

use IO::Socket::INET;
use POSIX qw( ENOENT );
use Socket qw( AF_UNIX pack_sockaddr_un );

use IO::Async::Loop::Poll;

my $loop = IO::Async::Loop::Poll->new();

testing_loop( $loop );

# Try connect()ing to a socket we've just created
my $listensock = IO::Socket::INET->new( LocalAddr => 'localhost', Listen => 1 ) or
   die "Cannot create listensock - $!";

my $addr = $listensock->sockname;

my $sock;

$loop->connect(
   addr => [ AF_INET, SOCK_STREAM, 0, $addr ],
   on_connected => sub { $sock = shift; },
   on_connect_error => sub { die "Test died early - connect error $_[0]\n"; },
);

wait_for { $sock };

isa_ok( $sock, "IO::Socket::INET", 'by addr: $sock isa IO::Socket::INET' );
is_deeply( [ unpack_sockaddr_in $sock->peername ],
           [ unpack_sockaddr_in $addr ], 'by addr: $sock->getpeername is $addr' );

$listensock->accept; # Throw it away
undef $sock; # This too

# Now try by name

$loop->connect(
   host     => $listensock->sockhost,
   service  => $listensock->sockport,
   socktype => $listensock->socktype,
   on_connected => sub { $sock = shift; },
   on_resolve_error => sub { die "Test died early - resolve error $_[0]\n"; },
   on_connect_error => sub { die "Test died early - connect error $_[0]\n"; },
);

wait_for { $sock };

isa_ok( $sock, "IO::Socket::INET", 'by host/service: $sock isa IO::Socket::INET' );
is_deeply( [ unpack_sockaddr_in $sock->peername ],
           [ unpack_sockaddr_in $addr ], 'by host/service: $sock->getpeername is $addr' );

$listensock->accept; # Throw it away
undef $sock; # This too

SKIP: {
   # Now try an address we know to be invalid - a UNIX socket that doesn't exist

   socket( my $dummy, AF_UNIX, SOCK_STREAM, 0 ) or
      skip "Cannot create AF_UNIX sockets - $!", 2;

   my $error;

   my $failop;
   my $failerr;

   $loop->connect(
      addr => [ AF_UNIX, SOCK_STREAM, 0, pack_sockaddr_un( "/some/path/we/know/breaks" ) ],
      on_connected => sub { die "Test died early - connect succeeded\n"; },
      on_fail => sub { $failop = shift @_; $failerr = pop @_; },
      on_connect_error => sub { $error = 1 },
   );

   wait_for { $error };

   is( $failop, "connect", '$failop is connect' );
   is( $failerr+0, ENOENT, '$failerr is ENOENT' );
}

# UNIX sockets always connect() synchronously, meaning if they fail, the error
# is available immediately. The above has therefore not properly tested
# asynchronous connect() failures. INET sockets should do this.

# First off we need a local socket that isn't listening - at lease one of the
# first 100 is likely not to be

my $port;
my $failure;

foreach ( 1 .. 100 ) {
   IO::Socket::INET->new( PeerHost => "127.0.0.1", PeerPort => $_ ) and next;

   $failure = "$!";
   $port = $_;

   last;
}

SKIP: {
   skip "Cannot find an un-connect()able socket on 127.0.0.1", 2 unless defined $port;

   my $failop;
   my $failerr;

   my $error = 0;

   $loop->connect(
      addr => [ AF_INET, SOCK_STREAM, 0, pack_sockaddr_in( $port, inet_aton("127.0.0.1") ) ],
      on_connected => sub { die "Test died early - connect succeeded\n"; },
      on_fail => sub { $failop = shift @_; $failerr = pop @_; },
      on_connect_error => sub { $error = 1 },
   );

   wait_for { $error };

   is( $failop, "connect", '$failop is connect' );
   is( "$failerr", $failure, "\$failerr is '$failure'" );
}