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
|
#!perl -w
# --------------------------------------------------------------------
# Try to send messages with all combinations of facilities and levels
# to a POE syslog server.
# --------------------------------------------------------------------
use strict;
use warnings;
use Test::More;
use Socket;
use Sys::Syslog 0.30 qw< :standard :extended :macros >;
# check than POE is available
plan skip_all => "POE is not available" unless eval "use POE; 1";
# check than POE::Component::Server::Syslog is available and recent enough
plan skip_all => "POE::Component::Server::Syslog is not available"
unless eval "use POE::Component::Server::Syslog; 1";
plan skip_all => "POE::Component::Server::Syslog is too old"
if POE::Component::Server::Syslog->VERSION < 1.14;
my $host = "127.0.0.1";
my $port = 5140;
my $proto = "udp";
my $ident = "pocosyslog";
my @levels = qw< emerg alert crit err warning notice info debug >;
my @facilities = qw<
auth cron daemon ftp kern lpr mail news syslog user uucp
local0 local1 local2 local3 local4 local5 local6 local7
>;
my %received;
my $parent_pid = $$;
my $child_pid = fork();
if ($child_pid) {
# parent: setup a syslog server
POE::Component::Server::Syslog->spawn(
Alias => 'syslog',
Type => $proto,
BindAddress => $host,
BindPort => $port,
InputState => \&client_input,
ErrorState => \&client_error,
);
# signal handlers
POE::Kernel->sig_child($child_pid, sub { wait() });
$SIG{TERM} = sub {
POE::Kernel->post(syslog => "shutdown");
POE::Kernel->stop;
};
# run everything
plan tests => @facilities * @levels * 2;
POE::Kernel->run;
# check if some messages are missing
my @miss = sort grep { $received{$_} < 2 } keys %received;
diag "@miss" if @miss;
}
else {
# child: send messages to the syslog server
sleep 2;
my $delay = .01;
setlogsock({ host => $host, type => $proto, port => $port });
# first way, set the facility each time with openlog()
for my $facility (@facilities) {
openlog($ident, "ndelay,pid", $facility);
for my $level (@levels) {
eval { syslog($level => "<$facility\:$level>") }
or warn "error: syslog($level => '<$facility\:$level>'): $@";
select undef, undef, undef, $delay;
}
}
# second way, set the facility once with openlog(), then set
# the message facility with syslog()
openlog($ident, "ndelay,pid", "user");
for my $facility (@facilities) {
for my $level (@levels) {
eval { syslog("$facility.$level" => "<$facility\:$level>") }
or warn "error: syslog('$facility.$level' => '<$facility\:$level>'): $@";
select undef, undef, undef, $delay;
}
}
sleep 2;
# send SIGTERM to the parent
kill 15 => $parent_pid;
}
sub client_input {
my $message = $_[&ARG0];
# extract the sent facility and level from the message text
my ($sent_facility, $sent_level) = $message->{msg} =~ /<(\w+):(\w+)>/;
$received{"$sent_facility\:$sent_level"}++;
# resolve their numeric values
my ($sent_fac_num, $sent_lev_num);
{
no strict "refs";
$sent_fac_num = eval { my $n = uc "LOG_$sent_facility"; &$n } >> 3;
$sent_lev_num = eval { my $n = uc "LOG_$sent_level"; &$n };
}
is_deeply(
{ # received message
facility => $message->{facility},
severity => $message->{severity},
},
{ # sent message
facility => $sent_fac_num,
severity => $sent_lev_num,
},
"sent<facility=$sent_facility($sent_fac_num), level=$sent_level" .
"($sent_lev_num)> - rcvd<facility=$message->{facility}, " .
"level=$message->{severity}>"
);
}
sub client_error {
my $message = $_[&ARG0];
require Data::Dumper;
$Data::Dumper::Indent = 0; $Data::Dumper::Indent = 0;
$Data::Dumper::Sortkeys = 1; $Data::Dumper::Sortkeys = 1;
fail "checking syslog message";
diag "[client_error] message = ", Data::Dumper::Dumper($message);
kill 15 => $child_pid;
POE::Kernel->post(syslog => "shutdown");
POE::Kernel->stop;
}
|