1b39c5158Smillert#!perl -T 2b39c5158Smillert 3b39c5158Smillertuse strict; 4b39c5158Smillertuse Config; 55759b3d2Safresh1use FileHandle; 6b39c5158Smillertuse File::Spec; 7b39c5158Smillertuse Test::More; 8b39c5158Smillert 9b39c5158Smillert# we enable all Perl warnings, but we don't "use warnings 'all'" because 10b39c5158Smillert# we want to disable the warnings generated by Sys::Syslog 11b39c5158Smillertno warnings; 12b39c5158Smillertuse warnings qw(closure deprecated exiting glob io misc numeric once overflow 13b39c5158Smillert pack portable recursion redefine regexp severe signal substr 14b39c5158Smillert syntax taint uninitialized unpack untie utf8 void); 15b39c5158Smillert 16b39c5158Smillert# if someone is using warnings::compat, the previous trick won't work, so we 17b39c5158Smillert# must manually disable warnings 18b39c5158Smillert$^W = 0 if $] < 5.006; 19b39c5158Smillert 20b39c5158Smillertmy $is_Win32 = $^O =~ /win32/i; 21b39c5158Smillertmy $is_Cygwin = $^O =~ /cygwin/i; 22b39c5158Smillert 23b39c5158Smillert# if testing in core, check that the module is at least available 24b39c5158Smillertif ($ENV{PERL_CORE}) { 25b39c5158Smillert plan skip_all => "Sys::Syslog was not build" 26b39c5158Smillert unless $Config{'extensions'} =~ /\bSyslog\b/; 27b39c5158Smillert} 28b39c5158Smillert 29b39c5158Smillert# we also need Socket 30b39c5158Smillertplan skip_all => "Socket was not build" 31b39c5158Smillert unless $Config{'extensions'} =~ /\bSocket\b/; 32b39c5158Smillert 33b39c5158Smillertmy $tests; 34b39c5158Smillertplan tests => $tests; 35b39c5158Smillert 36b39c5158Smillert# any remaining warning should be severly punished 37b39c5158SmillertBEGIN { eval "use Test::NoWarnings"; $tests = $@ ? 0 : 1; } 38b39c5158Smillert 39b39c5158SmillertBEGIN { $tests += 1 } 40b39c5158Smillert# ok, now loads them 41b39c5158Smillerteval 'use Socket'; 42b39c5158Smillertuse_ok('Sys::Syslog', ':standard', ':extended', ':macros'); 43b39c5158Smillert 44b39c5158SmillertBEGIN { $tests += 1 } 45b39c5158Smillert# check that the documented functions are correctly provided 46b39c5158Smillertcan_ok( 'Sys::Syslog' => qw(openlog syslog syslog setlogmask setlogsock closelog) ); 47b39c5158Smillert 48b39c5158Smillert 49898184e3SsthenBEGIN { $tests += 4 } 50b39c5158Smillert# check the diagnostics 51b39c5158Smillert# setlogsock() 52b39c5158Smillerteval { setlogsock() }; 53898184e3Ssthenlike( $@, qr/^setlogsock\(\): Invalid number of arguments/, 54b39c5158Smillert "calling setlogsock() with no argument" ); 55b39c5158Smillert 56898184e3Sstheneval { setlogsock(undef) }; 57898184e3Ssthenlike( $@, qr/^setlogsock\(\): Invalid type; must be one of /, 58898184e3Ssthen "calling setlogsock() with undef" ); 59898184e3Ssthen 60898184e3Sstheneval { setlogsock(\"") }; 61898184e3Ssthenlike( $@, qr/^setlogsock\(\): Unexpected scalar reference/, 62898184e3Ssthen "calling setlogsock() with a scalar reference" ); 63898184e3Ssthen 64898184e3Sstheneval { setlogsock({}) }; 65898184e3Ssthenlike( $@, qr/^setlogsock\(\): No argument given/, 66898184e3Ssthen "calling setlogsock() with an empty hash reference" ); 67898184e3Ssthen 68b39c5158SmillertBEGIN { $tests += 3 } 69b39c5158Smillert# syslog() 70b39c5158Smillerteval { syslog() }; 71b39c5158Smillertlike( $@, qr/^syslog: expecting argument \$priority/, 72b39c5158Smillert "calling syslog() with no argument" ); 73b39c5158Smillert 74b39c5158Smillerteval { syslog(undef) }; 75b39c5158Smillertlike( $@, qr/^syslog: expecting argument \$priority/, 76b39c5158Smillert "calling syslog() with one undef argument" ); 77b39c5158Smillert 78b39c5158Smillerteval { syslog('') }; 79b39c5158Smillertlike( $@, qr/^syslog: expecting argument \$format/, 80b39c5158Smillert "calling syslog() with one empty argument" ); 81b39c5158Smillert 82b39c5158Smillert 83b39c5158Smillertmy $test_string = "uid $< is testing Perl $] syslog(3) capabilities"; 84b39c5158Smillertmy $r = 0; 85b39c5158Smillert 86b39c5158SmillertBEGIN { $tests += 8 } 87b39c5158Smillert# try to open a syslog using a Unix or stream socket 88b39c5158SmillertSKIP: { 89b39c5158Smillert skip "can't connect to Unix socket: _PATH_LOG unavailable", 8 90b39c5158Smillert unless -e Sys::Syslog::_PATH_LOG(); 91b39c5158Smillert 92b39c5158Smillert # The only known $^O eq 'svr4' that needs this is NCR MP-RAS, 93b39c5158Smillert # but assuming 'stream' in SVR4 is probably not that bad. 94b39c5158Smillert my $sock_type = $^O =~ /^(solaris|irix|svr4|powerux)$/ ? 'stream' : 'unix'; 95b39c5158Smillert 96b39c5158Smillert eval { setlogsock($sock_type) }; 97b39c5158Smillert is( $@, '', "setlogsock() called with '$sock_type'" ); 98b39c5158Smillert TODO: { 99b39c5158Smillert local $TODO = "minor bug"; 10091f110e0Safresh1 SKIP: { skip "TODO $TODO", 1 if $] < 5.006002; 101b39c5158Smillert ok( $r, "setlogsock() should return true: '$r'" ); 102b39c5158Smillert } 10391f110e0Safresh1 } 104b39c5158Smillert 105*de8cc8edSafresh1 106b39c5158Smillert # open syslog with a "local0" facility 107b39c5158Smillert SKIP: { 108b39c5158Smillert # openlog() 109b39c5158Smillert $r = eval { openlog('perl', 'ndelay', 'local0') } || 0; 110b39c5158Smillert skip "can't connect to syslog", 6 if $@ =~ /^no connection to syslog available/; 111b39c5158Smillert is( $@, '', "openlog() called with facility 'local0'" ); 112b39c5158Smillert ok( $r, "openlog() should return true: '$r'" ); 113b39c5158Smillert 114b39c5158Smillert # syslog() 115b39c5158Smillert $r = eval { syslog('info', "$test_string by connecting to a $sock_type socket") } || 0; 116b39c5158Smillert is( $@, '', "syslog() called with level 'info'" ); 117b39c5158Smillert ok( $r, "syslog() should return true: '$r'" ); 118b39c5158Smillert 119b39c5158Smillert # closelog() 120b39c5158Smillert $r = eval { closelog() } || 0; 121b39c5158Smillert is( $@, '', "closelog()" ); 122b39c5158Smillert ok( $r, "closelog() should return true: '$r'" ); 123b39c5158Smillert } 124b39c5158Smillert} 125b39c5158Smillert 126b39c5158Smillert# try to open a syslog using all the available connection methods 127*de8cc8edSafresh1# handle inet and udp in a separate test file 128*de8cc8edSafresh1 129b39c5158Smillertmy @passed = (); 130*de8cc8edSafresh1 131*de8cc8edSafresh1BEGIN { $tests += 22 * 6 } 132*de8cc8edSafresh1for my $sock_type (qw(native eventlog unix pipe stream tcp )) { 133b39c5158Smillert SKIP: { 134b39c5158Smillert skip "the 'stream' mechanism because a previous mechanism with similar interface succeeded", 22 135b39c5158Smillert if $sock_type eq 'stream' and grep {/pipe|unix/} @passed; 136b39c5158Smillert # setlogsock() called with an arrayref 137b39c5158Smillert $r = eval { setlogsock([$sock_type]) } || 0; 138b39c5158Smillert skip "can't use '$sock_type' socket", 22 unless $r; 139b39c5158Smillert is( $@, '', "[$sock_type] setlogsock() called with ['$sock_type']" ); 140b39c5158Smillert ok( $r, "[$sock_type] setlogsock() should return true: '$r'" ); 141b39c5158Smillert 142b39c5158Smillert # setlogsock() called with a single argument 143b39c5158Smillert $r = eval { setlogsock($sock_type) } || 0; 144b39c5158Smillert skip "can't use '$sock_type' socket", 20 unless $r; 145b39c5158Smillert is( $@, '', "[$sock_type] setlogsock() called with '$sock_type'" ); 146b39c5158Smillert ok( $r, "[$sock_type] setlogsock() should return true: '$r'" ); 147b39c5158Smillert 148b39c5158Smillert # openlog() without option NDELAY 149b39c5158Smillert $r = eval { openlog('perl', '', 'local0') } || 0; 150b39c5158Smillert skip "can't connect to syslog", 18 if $@ =~ /^no connection to syslog available/; 151b39c5158Smillert is( $@, '', "[$sock_type] openlog() called with facility 'local0' and without option 'ndelay'" ); 152b39c5158Smillert ok( $r, "[$sock_type] openlog() should return true: '$r'" ); 153b39c5158Smillert 154b39c5158Smillert # openlog() with the option NDELAY 155b39c5158Smillert $r = eval { openlog('perl', 'ndelay', 'local0') } || 0; 156b39c5158Smillert skip "can't connect to syslog", 16 if $@ =~ /^no connection to syslog available/; 157b39c5158Smillert is( $@, '', "[$sock_type] openlog() called with facility 'local0' with option 'ndelay'" ); 158b39c5158Smillert ok( $r, "[$sock_type] openlog() should return true: '$r'" ); 159b39c5158Smillert 160b39c5158Smillert # syslog() with negative level, should fail 161b39c5158Smillert $r = eval { syslog(-1, "$test_string by connecting to a $sock_type socket") } || 0; 162b39c5158Smillert like( $@, '/^syslog: invalid level\/facility: /', "[$sock_type] syslog() called with level -1" ); 163b39c5158Smillert ok( !$r, "[$sock_type] syslog() should return false: '$r'" ); 164b39c5158Smillert 165b39c5158Smillert # syslog() with invalid level, should fail 166b39c5158Smillert $r = eval { syslog("plonk", "$test_string by connecting to a $sock_type socket") } || 0; 167b39c5158Smillert like( $@, '/^syslog: invalid level\/facility: /', "[$sock_type] syslog() called with level plonk" ); 168b39c5158Smillert ok( !$r, "[$sock_type] syslog() should return false: '$r'" ); 169b39c5158Smillert 170b39c5158Smillert # syslog() with levels "info" and "notice" (as a strings), should fail 171b39c5158Smillert $r = eval { syslog('info,notice', "$test_string by connecting to a $sock_type socket") } || 0; 172b39c5158Smillert like( $@, '/^syslog: too many levels given: notice/', "[$sock_type] syslog() called with level 'info,notice'" ); 173b39c5158Smillert ok( !$r, "[$sock_type] syslog() should return false: '$r'" ); 174b39c5158Smillert 175b39c5158Smillert # syslog() with facilities "local0" and "local1" (as a strings), should fail 176b39c5158Smillert $r = eval { syslog('local0,local1', "$test_string by connecting to a $sock_type socket") } || 0; 177b39c5158Smillert like( $@, '/^syslog: too many facilities given: local1/', "[$sock_type] syslog() called with level 'local0,local1'" ); 178b39c5158Smillert ok( !$r, "[$sock_type] syslog() should return false: '$r'" ); 179b39c5158Smillert 180b39c5158Smillert # syslog() with level "info" (as a string), should pass 181b39c5158Smillert $r = eval { syslog('info', "$test_string by connecting to a $sock_type socket") } || 0; 182b39c5158Smillert is( $@, '', "[$sock_type] syslog() called with level 'info' (string)" ); 183b39c5158Smillert ok( $r, "[$sock_type] syslog() should return true: '$r'" ); 184b39c5158Smillert 185b39c5158Smillert # syslog() with level "info" (as a macro), should pass 186b39c5158Smillert { local $! = 1; 187b39c5158Smillert $r = eval { syslog(LOG_INFO(), "$test_string by connecting to a $sock_type socket, setting a fake errno: %m") } || 0; 188b39c5158Smillert } 189b39c5158Smillert is( $@, '', "[$sock_type] syslog() called with level 'info' (macro)" ); 190b39c5158Smillert ok( $r, "[$sock_type] syslog() should return true: '$r'" ); 191b39c5158Smillert 192b39c5158Smillert push @passed, $sock_type; 193b39c5158Smillert 194b39c5158Smillert SKIP: { 195b39c5158Smillert skip "skipping closelog() tests for 'console'", 2 if $sock_type eq 'console'; 196b39c5158Smillert # closelog() 197b39c5158Smillert $r = eval { closelog() } || 0; 198b39c5158Smillert is( $@, '', "[$sock_type] closelog()" ); 199b39c5158Smillert ok( $r, "[$sock_type] closelog() should return true: '$r'" ); 200b39c5158Smillert } 201b39c5158Smillert } 202b39c5158Smillert} 203b39c5158Smillert 204b39c5158SmillertBEGIN { $tests += 10 } 205b39c5158SmillertSKIP: { 206b39c5158Smillert skip "not testing setlogsock('stream') on Win32", 10 if $is_Win32; 207b39c5158Smillert skip "the 'unix' mechanism works, so the tests will likely fail with the 'stream' mechanism", 10 208b39c5158Smillert if grep {/unix/} @passed; 209b39c5158Smillert 210b39c5158Smillert skip "not testing setlogsock('stream'): _PATH_LOG unavailable", 10 211b39c5158Smillert unless -e Sys::Syslog::_PATH_LOG(); 212b39c5158Smillert 213b39c5158Smillert # setlogsock() with "stream" and an undef path 214b39c5158Smillert $r = eval { setlogsock("stream", undef ) } || ''; 215b39c5158Smillert is( $@, '', "setlogsock() called, with 'stream' and an undef path" ); 216b39c5158Smillert if ($is_Cygwin) { 217b39c5158Smillert if (-x "/usr/sbin/syslog-ng") { 218b39c5158Smillert ok( $r, "setlogsock() on Cygwin with syslog-ng should return true: '$r'" ); 219b39c5158Smillert } 220b39c5158Smillert else { 221b39c5158Smillert ok( !$r, "setlogsock() on Cygwin without syslog-ng should return false: '$r'" ); 222b39c5158Smillert } 223b39c5158Smillert } 224b39c5158Smillert else { 225b39c5158Smillert ok( $r, "setlogsock() should return true: '$r'" ); 226b39c5158Smillert } 227b39c5158Smillert 228b39c5158Smillert # setlogsock() with "stream" and an empty path 229b39c5158Smillert $r = eval { setlogsock("stream", '' ) } || ''; 230b39c5158Smillert is( $@, '', "setlogsock() called, with 'stream' and an empty path" ); 231b39c5158Smillert ok( !$r, "setlogsock() should return false: '$r'" ); 232b39c5158Smillert 233b39c5158Smillert # setlogsock() with "stream" and /dev/null 234b39c5158Smillert $r = eval { setlogsock("stream", '/dev/null' ) } || ''; 235b39c5158Smillert is( $@, '', "setlogsock() called, with 'stream' and '/dev/null'" ); 236b39c5158Smillert ok( $r, "setlogsock() should return true: '$r'" ); 237b39c5158Smillert 238b39c5158Smillert # setlogsock() with "stream" and a non-existing file 239b39c5158Smillert $r = eval { setlogsock("stream", 'test.log' ) } || ''; 240b39c5158Smillert is( $@, '', "setlogsock() called, with 'stream' and 'test.log' (file does not exist)" ); 241b39c5158Smillert ok( !$r, "setlogsock() should return false: '$r'" ); 242b39c5158Smillert 243b39c5158Smillert # setlogsock() with "stream" and a local file 244b39c5158Smillert SKIP: { 245b39c5158Smillert my $logfile = "test.log"; 2465759b3d2Safresh1 my $fh = FileHandle->new; 2475759b3d2Safresh1 open $fh, ">$logfile" or skip "can't create file '$logfile': $!", 2; 2485759b3d2Safresh1 close $fh; 249b39c5158Smillert $r = eval { setlogsock("stream", $logfile ) } || ''; 250b39c5158Smillert is( $@, '', "setlogsock() called, with 'stream' and '$logfile' (file exists)" ); 251b39c5158Smillert ok( $r, "setlogsock() should return true: '$r'" ); 252b39c5158Smillert unlink($logfile); 253b39c5158Smillert } 254b39c5158Smillert} 255b39c5158Smillert 256b39c5158Smillert 257b39c5158SmillertBEGIN { $tests += 3 + 4 * 3 } 258b39c5158Smillert# setlogmask() 259b39c5158Smillert{ 260b39c5158Smillert my $oldmask = 0; 261b39c5158Smillert 262b39c5158Smillert $oldmask = eval { setlogmask(0) } || 0; 263b39c5158Smillert is( $@, '', "setlogmask() called with a null mask" ); 264b39c5158Smillert $r = eval { setlogmask(0) } || 0; 265b39c5158Smillert is( $@, '', "setlogmask() called with a null mask (second time)" ); 266b39c5158Smillert is( $r, $oldmask, "setlogmask() must return the same mask as previous call"); 267b39c5158Smillert 268b39c5158Smillert my @masks = ( 269b39c5158Smillert LOG_MASK(LOG_ERR()), 270b39c5158Smillert ~LOG_MASK(LOG_INFO()), 271b39c5158Smillert LOG_MASK(LOG_CRIT()) | LOG_MASK(LOG_ERR()) | LOG_MASK(LOG_WARNING()), 272b39c5158Smillert ); 273b39c5158Smillert 274b39c5158Smillert for my $newmask (@masks) { 275b39c5158Smillert $r = eval { setlogmask($newmask) } || 0; 276b39c5158Smillert is( $@, '', "setlogmask() called with a new mask" ); 277b39c5158Smillert is( $r, $oldmask, "setlogmask() must return the same mask as previous call"); 278b39c5158Smillert $r = eval { setlogmask(0) } || 0; 279b39c5158Smillert is( $@, '', "setlogmask() called with a null mask" ); 280b39c5158Smillert is( $r, $newmask, "setlogmask() must return the new mask"); 281b39c5158Smillert setlogmask($oldmask); 282b39c5158Smillert } 283b39c5158Smillert} 28491f110e0Safresh1 28591f110e0Safresh1BEGIN { $tests += 4 } 28691f110e0Safresh1SKIP: { 28791f110e0Safresh1 # case: test the return value of setlogsock() 28891f110e0Safresh1 28991f110e0Safresh1 # setlogsock("stream") on a non-existent file must fail 29091f110e0Safresh1 eval { $r = setlogsock("stream", "plonk/log") }; 29191f110e0Safresh1 is( $@, '', "setlogsock() didn't croak"); 29291f110e0Safresh1 ok( !$r, "setlogsock() correctly failed with a non-existent stream path"); 29391f110e0Safresh1 29491f110e0Safresh1 # setlogsock("tcp") must fail if the service is not declared 29591f110e0Safresh1 my $service = getservbyname("syslog", "tcp") || getservbyname("syslogng", "tcp"); 29691f110e0Safresh1 skip "can't test setlogsock() tcp failure", 2 if $service; 29791f110e0Safresh1 eval { $r = setlogsock("tcp") }; 29891f110e0Safresh1 is( $@, '', "setlogsock() didn't croak"); 29991f110e0Safresh1 ok( !$r, "setlogsock() correctly failed when tcp services can't be resolved"); 30091f110e0Safresh1} 30191f110e0Safresh1 30291f110e0Safresh1BEGIN { $tests += 3 } 30391f110e0Safresh1SKIP: { 30491f110e0Safresh1 # case: configure Sys::Syslog to use the stream mechanism on a 30591f110e0Safresh1 # given file, but remove the file before openlog() is called, 30691f110e0Safresh1 # so it fails. 30791f110e0Safresh1 30891f110e0Safresh1 # create the log file 30991f110e0Safresh1 my $log = "t/stream"; 3105759b3d2Safresh1 my $fh = FileHandle->new; 3115759b3d2Safresh1 open $fh, ">$log" or skip "can't write file '$log': $!", 3; 31291f110e0Safresh1 close $fh; 31391f110e0Safresh1 31491f110e0Safresh1 # configure Sys::Syslog to use it 31591f110e0Safresh1 $r = eval { setlogsock("stream", $log) }; 31691f110e0Safresh1 is( $@, "", "setlogsock('stream', '$log') -> $r" ); 31791f110e0Safresh1 skip "can't test openlog() failure with a missing stream", 2 if !$r; 31891f110e0Safresh1 31991f110e0Safresh1 # remove the log and check that openlog() fails 32091f110e0Safresh1 unlink $log; 32191f110e0Safresh1 $r = eval { openlog('perl', 'ndelay', 'local0') }; 32291f110e0Safresh1 ok( !$r, "openlog() correctly failed with a non-existent stream" ); 32391f110e0Safresh1 like( $@, '/not writable/', "openlog() correctly croaked with a non-existent stream" ); 32491f110e0Safresh1} 32591f110e0Safresh1 326