191f110e0Safresh1#!perl -w 291f110e0Safresh1# -------------------------------------------------------------------- 391f110e0Safresh1# Try to send messages with all combinations of facilities and levels 491f110e0Safresh1# to a POE syslog server. 591f110e0Safresh1# -------------------------------------------------------------------- 691f110e0Safresh1use strict; 791f110e0Safresh1use warnings; 891f110e0Safresh1 991f110e0Safresh1use Test::More; 1091f110e0Safresh1use Socket; 1191f110e0Safresh1use Sys::Syslog 0.30 qw< :standard :extended :macros >; 1291f110e0Safresh1 1391f110e0Safresh1 1491f110e0Safresh1# check than POE is available 1591f110e0Safresh1plan skip_all => "POE is not available" unless eval "use POE; 1"; 1691f110e0Safresh1 1791f110e0Safresh1# check than POE::Component::Server::Syslog is available and recent enough 1891f110e0Safresh1plan skip_all => "POE::Component::Server::Syslog is not available" 1991f110e0Safresh1 unless eval "use POE::Component::Server::Syslog; 1"; 2091f110e0Safresh1plan skip_all => "POE::Component::Server::Syslog is too old" 2191f110e0Safresh1 if POE::Component::Server::Syslog->VERSION < 1.14; 2291f110e0Safresh1 2391f110e0Safresh1 2491f110e0Safresh1my $host = "127.0.0.1"; 2591f110e0Safresh1my $port = 5140; 2691f110e0Safresh1my $proto = "udp"; 2791f110e0Safresh1my $ident = "pocosyslog"; 2891f110e0Safresh1 2991f110e0Safresh1my @levels = qw< emerg alert crit err warning notice info debug >; 3091f110e0Safresh1my @facilities = qw< 3191f110e0Safresh1 auth cron daemon ftp kern lpr mail news syslog user uucp 3291f110e0Safresh1 local0 local1 local2 local3 local4 local5 local6 local7 3391f110e0Safresh1>; 3491f110e0Safresh1 3591f110e0Safresh1my %received; 3691f110e0Safresh1my $parent_pid = $$; 3791f110e0Safresh1my $child_pid = fork(); 3891f110e0Safresh1 3991f110e0Safresh1if ($child_pid) { 4091f110e0Safresh1 # parent: setup a syslog server 4191f110e0Safresh1 POE::Component::Server::Syslog->spawn( 4291f110e0Safresh1 Alias => 'syslog', 4391f110e0Safresh1 Type => $proto, 4491f110e0Safresh1 BindAddress => $host, 4591f110e0Safresh1 BindPort => $port, 4691f110e0Safresh1 4791f110e0Safresh1 InputState => \&client_input, 4891f110e0Safresh1 ErrorState => \&client_error, 4991f110e0Safresh1 ); 5091f110e0Safresh1 5191f110e0Safresh1 # signal handlers 5291f110e0Safresh1 POE::Kernel->sig_child($child_pid, sub { wait() }); 5391f110e0Safresh1 $SIG{TERM} = sub { 5491f110e0Safresh1 POE::Kernel->post(syslog => "shutdown"); 5591f110e0Safresh1 POE::Kernel->stop; 5691f110e0Safresh1 }; 5791f110e0Safresh1 5891f110e0Safresh1 # run everything 5991f110e0Safresh1 plan tests => @facilities * @levels * 2; 6091f110e0Safresh1 POE::Kernel->run; 6191f110e0Safresh1 6291f110e0Safresh1 # check if some messages are missing 63*6fb12b70Safresh1 my @miss = sort grep { $received{$_} < 2 } keys %received; 6491f110e0Safresh1 diag "@miss" if @miss; 6591f110e0Safresh1} 6691f110e0Safresh1else { 6791f110e0Safresh1 # child: send messages to the syslog server 6891f110e0Safresh1 sleep 2; 69*6fb12b70Safresh1 my $delay = .01; 7091f110e0Safresh1 setlogsock({ host => $host, type => $proto, port => $port }); 7191f110e0Safresh1 7291f110e0Safresh1 # first way, set the facility each time with openlog() 7391f110e0Safresh1 for my $facility (@facilities) { 7491f110e0Safresh1 openlog($ident, "ndelay,pid", $facility); 7591f110e0Safresh1 7691f110e0Safresh1 for my $level (@levels) { 7791f110e0Safresh1 eval { syslog($level => "<$facility\:$level>") } 7891f110e0Safresh1 or warn "error: syslog($level => '<$facility\:$level>'): $@"; 79*6fb12b70Safresh1 select undef, undef, undef, $delay; 8091f110e0Safresh1 } 8191f110e0Safresh1 } 8291f110e0Safresh1 8391f110e0Safresh1 # second way, set the facility once with openlog(), then set 8491f110e0Safresh1 # the message facility with syslog() 8591f110e0Safresh1 openlog($ident, "ndelay,pid", "user"); 8691f110e0Safresh1 8791f110e0Safresh1 for my $facility (@facilities) { 8891f110e0Safresh1 for my $level (@levels) { 8991f110e0Safresh1 eval { syslog("$facility.$level" => "<$facility\:$level>") } 9091f110e0Safresh1 or warn "error: syslog('$facility.$level' => '<$facility\:$level>'): $@"; 91*6fb12b70Safresh1 select undef, undef, undef, $delay; 9291f110e0Safresh1 } 9391f110e0Safresh1 } 9491f110e0Safresh1 9591f110e0Safresh1 sleep 2; 9691f110e0Safresh1 9791f110e0Safresh1 # send SIGTERM to the parent 9891f110e0Safresh1 kill 15 => $parent_pid; 9991f110e0Safresh1} 10091f110e0Safresh1 10191f110e0Safresh1 10291f110e0Safresh1sub client_input { 10391f110e0Safresh1 my $message = $_[&ARG0]; 10491f110e0Safresh1 10591f110e0Safresh1 # extract the sent facility and level from the message text 10691f110e0Safresh1 my ($sent_facility, $sent_level) = $message->{msg} =~ /<(\w+):(\w+)>/; 10791f110e0Safresh1 $received{"$sent_facility\:$sent_level"}++; 10891f110e0Safresh1 10991f110e0Safresh1 # resolve their numeric values 11091f110e0Safresh1 my ($sent_fac_num, $sent_lev_num); 11191f110e0Safresh1 { 11291f110e0Safresh1 no strict "refs"; 11391f110e0Safresh1 $sent_fac_num = eval { my $n = uc "LOG_$sent_facility"; &$n } >> 3; 11491f110e0Safresh1 $sent_lev_num = eval { my $n = uc "LOG_$sent_level"; &$n }; 11591f110e0Safresh1 } 11691f110e0Safresh1 11791f110e0Safresh1 is_deeply( 11891f110e0Safresh1 { # received message 11991f110e0Safresh1 facility => $message->{facility}, 12091f110e0Safresh1 severity => $message->{severity}, 12191f110e0Safresh1 }, 12291f110e0Safresh1 { # sent message 12391f110e0Safresh1 facility => $sent_fac_num, 12491f110e0Safresh1 severity => $sent_lev_num, 12591f110e0Safresh1 }, 12691f110e0Safresh1 "sent<facility=$sent_facility($sent_fac_num), level=$sent_level" . 12791f110e0Safresh1 "($sent_lev_num)> - rcvd<facility=$message->{facility}, " . 12891f110e0Safresh1 "level=$message->{severity}>" 12991f110e0Safresh1 ); 13091f110e0Safresh1} 13191f110e0Safresh1 13291f110e0Safresh1 13391f110e0Safresh1sub client_error { 13491f110e0Safresh1 my $message = $_[&ARG0]; 13591f110e0Safresh1 13691f110e0Safresh1 require Data::Dumper; 13791f110e0Safresh1 $Data::Dumper::Indent = 0; $Data::Dumper::Indent = 0; 13891f110e0Safresh1 $Data::Dumper::Sortkeys = 1; $Data::Dumper::Sortkeys = 1; 13991f110e0Safresh1 fail "checking syslog message"; 14091f110e0Safresh1 diag "[client_error] message = ", Data::Dumper::Dumper($message); 14191f110e0Safresh1 14291f110e0Safresh1 kill 15 => $child_pid; 14391f110e0Safresh1 POE::Kernel->post(syslog => "shutdown"); 14491f110e0Safresh1 POE::Kernel->stop; 14591f110e0Safresh1} 14691f110e0Safresh1 147