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