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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
|
use strict;
use warnings FATAL => 'all';
use POE qw(Wheel::SocketFactory Wheel::ReadWrite Filter::Line);
use POE::Component::IRC;
use Test::More;
my $tests = 4;
BEGIN {
my $GOT_SOCKET6;
eval {
Socket->import(qw(AF_INET6 unpack_sockaddr_in6 inet_pton));
$GOT_SOCKET6 = 1;
};
if (!$GOT_SOCKET6) {
eval {
require Socket6;
Socket6->import(qw(AF_INET6 unpack_sockaddr_in6 inet_pton));
$GOT_SOCKET6 = 1;
};
plan skip_all => 'Socket6 is needed for IPv6 tests' if !$GOT_SOCKET6;
}
}
# Argh, we need to be "smart" and see if we need GAI or not...
# Perl-5.14.0 will core getaddrinfo() in it's Socket.pm
eval { Socket->import('getaddrinfo') };
if ($@) {
eval { require Socket::GetAddrInfo; Socket::GetAddrInfo->import(qw(:newapi getaddrinfo)) };
if ($@) {
plan skip_all => 'Socket::GetAddrInfo is needed for IPv6 tests';
}
}
my $addr = eval { inet_pton(AF_INET6, "::1"); };
if (!defined $addr) {
plan skip_all => "IPv6 tests require a configured localhost address ('::1')";
}
plan tests => $tests;
my $bot = POE::Component::IRC->spawn();
POE::Session->create(
package_states => [
main => [qw(
_start
accept_client
factory_failed
client_input
client_error
irc_connected
irc_socketerr
irc_001
)]
]
);
$poe_kernel->run();
sub _start {
my ($heap) = $_[HEAP];
$heap->{sockfactory} = POE::Wheel::SocketFactory->new(
SocketDomain => AF_INET6,
BindAddress => '::1',
BindPort => 0,
SuccessEvent => 'accept_client',
FailureEvent => 'factory_failed',
);
my $packed_socket = $heap->{sockfactory}->getsockname;
if (!$packed_socket) {
diag("ERROR: Couldn't get the packed socket");
return;
}
eval { ($heap->{bindport}) = unpack_sockaddr_in6($packed_socket) };
if ($@) {
diag("ERROR: $@");
return;
}
if ($heap->{bindport} == 0) {
delete $heap->{sockfactory};
_skip_rest('$heap->{bindport} == 0');
return;
}
$bot->yield(register => 'all');
$bot->yield(connect => {
Nick => 'testbot',
Server => '::1',
useipv6 => 1,
Port => $heap->{bindport},
Username => 'testbot',
Ircname => 'testbot 1.1',
});
}
sub accept_client {
my ($heap, $socket) = @_[HEAP, ARG0];
my $wheel = POE::Wheel::ReadWrite->new(
Handle => $socket,
InputEvent => 'client_input',
ErrorEvent => 'client_error',
Filter => POE::Filter::Line->new( Literal => "\x0D\x0A" ),
);
$heap->{client} = $wheel;
}
sub factory_failed {
my ($heap, $syscall, $errno, $error) = @_[HEAP, ARG0..ARG2];
delete $_[HEAP]->{sockfactory};
_skip_rest("syscall error $errno: $error") if $tests;
}
sub client_input {
my ($heap, $input) = @_[HEAP, ARG0];
SWITCH: {
if ($input =~ /^NICK /) {
pass('Server got NICK');
$tests--;
$heap->{got_nick} = 1;
last SWITCH;
}
if ($input =~ /^USER /) {
pass('Server got USER');
$tests--;
$heap->{got_user} = 1;
last SWITCH;
}
if ($input =~ /^QUIT/ ) {
delete $heap->{client};
delete $heap->{sockfactory};
return;
}
}
if ($heap->{got_nick} && $heap->{got_user}) {
# Send back irc_001
$heap->{client}->put(':test.script 001 testbot :Welcome to poconet Internet Relay Chat Network testbot!testbot@127.0.0.1');
}
}
sub client_error {
my ($heap) = $_[HEAP];
delete $heap->{client};
delete $heap->{sockfactory};
}
sub irc_connected {
pass('Connected');
$tests--;
}
sub irc_socketerr {
_skip_rest($_[ARG0]) if $tests;
}
sub irc_001 {
pass('Logged in');
$bot->yield('shutdown');
}
sub _skip_rest {
my ($error) = @_;
SKIP: {
skip "AF_INET6 probably not supported ($error)", $tests;
}
$tests = 0;
$bot->yield('shutdown');
}
|