From e811446b39de2cb880dfe1afe7515a8304a91e35 Mon Sep 17 00:00:00 2001 From: David Dick Date: Sun, 3 Jul 2022 19:00:12 +1000 Subject: [PATCH] Initial upload to github --- Changes | 19 +++ MANIFEST | 12 ++ META.json | 56 +++++++ META.yml | 37 +++++ Makefile.PL | 44 +++++ README | 176 ++++++++++++++++++++ lib/Test/Rsyslog.pm | 388 ++++++++++++++++++++++++++++++++++++++++++++ t/00-load.t | 13 ++ t/01-rsyslog.t | 88 ++++++++++ t/manifest.t | 15 ++ t/pod-coverage.t | 24 +++ t/pod.t | 16 ++ 12 files changed, 888 insertions(+) create mode 100644 Changes create mode 100644 MANIFEST create mode 100644 META.json create mode 100644 META.yml create mode 100644 Makefile.PL create mode 100644 README create mode 100644 lib/Test/Rsyslog.pm create mode 100644 t/00-load.t create mode 100644 t/01-rsyslog.t create mode 100644 t/manifest.t create mode 100644 t/pod-coverage.t create mode 100644 t/pod.t diff --git a/Changes b/Changes new file mode 100644 index 0000000..f7edb95 --- /dev/null +++ b/Changes @@ -0,0 +1,19 @@ +Revision history for Test-Rsyslog + +0.06 Fri Mar 31 18:46:00 2017 + Lowering minimum perl version + +0.05 Thu Mar 30 17:40:00 2017 + Fixing failing test to wait for rsyslog to output log entries + +0.04 Tue Mar 21 06:14:00 2017 + Adding additional methods to improve test results + +0.03 Thu Mar 09 22:10:00 2017 + Added README. + +0.02 Thu Mar 09 21:36:00 2017 + Re-release for testing. + +0.01 Sat Mar 04 16:07:00 2017 + Initial release. diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..956db14 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,12 @@ +Changes +lib/Test/Rsyslog.pm +Makefile.PL +MANIFEST This list of files +README +t/00-load.t +t/01-rsyslog.t +t/manifest.t +t/pod-coverage.t +t/pod.t +META.yml Module YAML meta-data (added by MakeMaker) +META.json Module JSON meta-data (added by MakeMaker) diff --git a/META.json b/META.json new file mode 100644 index 0000000..66c17a7 --- /dev/null +++ b/META.json @@ -0,0 +1,56 @@ +{ + "abstract" : "Creates a temporary instance of rsyslog to run tests against", + "author" : [ + "David Dick " + ], + "dynamic_config" : 1, + "generated_by" : "ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150005", + "license" : [ + "perl_5" + ], + "meta-spec" : { + "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", + "version" : "2" + }, + "name" : "Test-Rsyslog", + "no_index" : { + "directory" : [ + "t", + "inc" + ] + }, + "prereqs" : { + "build" : { + "requires" : { + "Sys::Syslog" : "0", + "Test::More" : "0" + } + }, + "configure" : { + "requires" : { + "ExtUtils::MakeMaker" : "0", + "File::Spec" : "0", + "strict" : "0", + "warnings" : "0" + } + }, + "runtime" : { + "requires" : { + "Carp" : "0", + "Config" : "0", + "English" : "0", + "Fcntl" : "0", + "File::Spec" : "0", + "File::Temp" : "0", + "FileHandle" : "0", + "POSIX" : "0", + "perl" : "5.006", + "strict" : "0", + "warnings" : "0" + } + } + }, + "release_status" : "stable", + "version" : "0.06", + "x_serialization_backend" : "JSON::PP version 2.27400" +} diff --git a/META.yml b/META.yml new file mode 100644 index 0000000..072f08e --- /dev/null +++ b/META.yml @@ -0,0 +1,37 @@ +--- +abstract: 'Creates a temporary instance of rsyslog to run tests against' +author: + - 'David Dick ' +build_requires: + Sys::Syslog: '0' + Test::More: '0' +configure_requires: + ExtUtils::MakeMaker: '0' + File::Spec: '0' + strict: '0' + warnings: '0' +dynamic_config: 1 +generated_by: 'ExtUtils::MakeMaker version 7.24, CPAN::Meta::Converter version 2.150005' +license: perl +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: '1.4' +name: Test-Rsyslog +no_index: + directory: + - t + - inc +requires: + Carp: '0' + Config: '0' + English: '0' + Fcntl: '0' + File::Spec: '0' + File::Temp: '0' + FileHandle: '0' + POSIX: '0' + perl: '5.006' + strict: '0' + warnings: '0' +version: '0.06' +x_serialization_backend: 'CPAN::Meta::YAML version 0.018' diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..60a5cba --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,44 @@ +use 5.006; +use strict; +use warnings; +use ExtUtils::MakeMaker; +use File::Spec(); + +my $dev_null = File::Spec->devnull(); + +my $binary = 'rsyslogd'; +system("$binary -v 2>$dev_null >$dev_null") and die "Please install the $binary executable\n"; + +WriteMakefile( + NAME => 'Test::Rsyslog', + AUTHOR => q{David Dick }, + VERSION_FROM => 'lib/Test/Rsyslog.pm', + ABSTRACT_FROM => 'lib/Test/Rsyslog.pm', + LICENSE => 'perl_5', + PL_FILES => {}, + MIN_PERL_VERSION => 5.006, + CONFIGURE_REQUIRES => { + 'ExtUtils::MakeMaker' => 0, + 'File::Spec' => 0, + 'strict' => 0, + 'warnings' => 0, + }, + BUILD_REQUIRES => { + 'Test::More' => 0, + 'Sys::Syslog' => 0, + }, + PREREQ_PM => { + 'Carp' => 0, + 'Config' => 0, + 'English' => 0, + 'FileHandle' => 0, + 'File::Temp' => 0, + 'Fcntl' => 0, + 'File::Spec' => 0, + 'POSIX' => 0, + 'strict' => 0, + 'warnings' => 0, + }, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'Test-Rsyslog-*' }, +); diff --git a/README b/README new file mode 100644 index 0000000..b365662 --- /dev/null +++ b/README @@ -0,0 +1,176 @@ +NAME + + Test::Rsyslog - Creates a temporary instance of rsyslog to run tests + against + +VERSION + + Version 0.06 + +SYNOPSIS + + my $rsyslog = Test::Rsyslog->new(); + + Sys::Syslog::setlogsock({ type => 'unix', path => $rsyslog->socket_path() }); + # or "Sys::Syslog::setlogsock('unix', $rsyslog->socket_path());" for older Sys::Syslogs + Sys::Syslog::openlog('program[' . $$ . ']','cons','LOG_LOCAL7'); + Sys::Syslog::syslog('info|LOG_LOCAL7','This is a test message'); + Sys::Syslog::closelog(); + + ok($rsyslog->find('This is a test message'), 'Rsyslog is okay'); + + +DESCRIPTION + + This module allows easy creation and tear down of a rsyslog instance. + When the variable goes out of scope, the rsyslog instance is torn down + and the file system objects it relies on are removed. + +SUBROUTINES/METHODS + + new + + This method will setup and start the rsyslog instance. It currently has + no parameters, but this may change in response to feature requests + + socket_path + + This method returns that path to the UNIX file system socket that is + connected to the current running instance of rsyslog + + find($string) + + This method searches the existing logs that rsyslog has processed to + see if a message has been found matching $string. It will return a list + of every line in the log file that matches $string. + + start + + This method starts the rsyslog instance + + stop + + This method stops the rsyslog instance + + alive + + This method checks to make sure that the rsyslogd instance is still + running + + messages + + This method returns the content of the rsyslogd log file + + scrub + + This method truncates the rsyslogd log file. Rsyslogd must be stopped + to truncate the log file + +DIAGNOSTICS + + Failed to open %s for reading + + There has been a file system error trying to read from the rsyslog + logfile. + + Failed to print to %s + + There has been a file system error trying to write to the rsyslog + configuration file. + + Failed to fork + + The operating system was unable to fork a subprocess for use by the + rsyslog daemon. + + Failed to rmdir %s + + There has been a file system error trying to remove the temporary + directory. + + Failed to unlink %s + + There has been a file system error trying to unlink a temporary file + + Failed to close %s + + There has been a file system error trying to close a temporary file + + Failed to mkdir %s + + There has been a file system error trying to make the temporary + directory + + Temporary rsyslog daemon is already running... + + The rsyslog daemon has already started + + Unable to truncate while rsyslogd is still running + + This module will not truncate the messages file while rsyslogd could + still be writing to it + + Unable to untaint the directory path + + The module generated an unrecognisable temporary path for rsyslogd + +CONFIGURATION AND ENVIRONMENT + + Test::Rsyslog requires no configuration files or environment variables. + +DEPENDENCIES + + Test::Rsyslog requires Perl 5.6 or better. + +INCOMPATIBILITIES + + None reported + +BUGS AND LIMITATIONS + + Please report any bugs or feature requests to bug-test-rsyslog at + rt.cpan.org, or through the web interface at + http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Test-Rsyslog. I will be + notified, and then you'll automatically be notified of progress on your + bug as I make changes. + +SUPPORT + + You can find documentation for this module with the perldoc command. + + perldoc Test::Rsyslog + + You can also look for information at: + + * RT: CPAN's request tracker (report bugs here) + + http://rt.cpan.org/NoAuth/Bugs.html?Dist=Test-Rsyslog + + * AnnoCPAN: Annotated CPAN documentation + + http://annocpan.org/dist/Test-Rsyslog + + * CPAN Ratings + + http://cpanratings.perl.org/d/Test-Rsyslog + + * Search CPAN + + http://search.cpan.org/dist/Test-Rsyslog/ + +AUTHOR + + David Dick, + +ACKNOWLEDGEMENTS + +LICENSE AND COPYRIGHT + + Copyright 2017 David Dick. + + This program is free software; you can redistribute it and/or modify it + under the terms of either: the GNU General Public License as published + by the Free Software Foundation; or the Artistic License. + + See http://dev.perl.org/licenses/ for more information. + diff --git a/lib/Test/Rsyslog.pm b/lib/Test/Rsyslog.pm new file mode 100644 index 0000000..83fdb82 --- /dev/null +++ b/lib/Test/Rsyslog.pm @@ -0,0 +1,388 @@ +package Test::Rsyslog; + +use strict; +use warnings; +use File::Temp(); +use Fcntl(); +use File::Spec(); +use FileHandle(); +use English qw( -no_match_vars ); +use Carp(); +use POSIX(); +use Config; + +our $VERSION = '0.06'; + +sub _USER_READ_WRITE_PERMISSIONS { return 600 } +sub _USER_READ_WRITE_EXECUTE_PERMISSIONS { return 700 } + +sub socket_path { + my ($self) = @_; + return $self->{_socket_path}; +} + +sub messages { + my ($self) = @_; + my @messages; + my $handle = FileHandle->new( $self->{_messages_path}, Fcntl::O_RDONLY() ); + if ($handle) { + binmode $handle, ':encoding(UTF-8)'; + while ( my $line = <$handle> ) { + chomp $line; + push @messages, $line; + } + } + elsif ( $OS_ERROR == POSIX::ENOENT() ) { + } + else { + Carp::croak( +"Failed to open $self->{_messages_path} for reading:$EXTENDED_OS_ERROR" + ); + } + return @messages; +} + +sub find { + my ( $self, $string ) = @_; + $string =~ s/([\x00-\x1F])/'#' . sprintf '%03o', ord $1/smxeg; + my $quoted = quotemeta $string; + my @found; + foreach my $line ( $self->messages() ) { + if ( $line =~ /$quoted/smx ) { + push @found, $line; + } + } + return @found; +} + +sub new { + my ($class) = @_; + my $self = bless {}, $class; + my $root_directory = File::Temp::mktemp( + File::Spec->catfile( + File::Spec->tmpdir(), 'perl_test_rsyslog_XXXXXXXXXXX' + ) + ); + if ( $root_directory =~ /^(.*perl_test_rsyslog_.*)$/smx ) { + $self->{_root_directory} = $1; + } + else { + Carp::croak("Unable to untaint the directory path of $root_directory"); + } + mkdir $self->{_root_directory}, oct _USER_READ_WRITE_EXECUTE_PERMISSIONS() + or Carp::croak( + "Failed to mkdir $self->{_root_directory}:$EXTENDED_OS_ERROR"); + $self->{_socket_path} = + File::Spec->catfile( $self->{_root_directory}, 'rsyslog.sock' ); + $self->{_messages_path} = + File::Spec->catfile( $self->{_root_directory}, 'messages' ); + $self->{_pid_path} = File::Spec->catfile( $self->{_root_directory}, 'pid' ); + $self->{_config_path} = + File::Spec->catfile( $self->{_root_directory}, 'rsyslog.conf' ); + my $config_handle = FileHandle->new( + $self->{_config_path}, + Fcntl::O_WRONLY() | Fcntl::O_CREAT() | Fcntl::O_EXCL(), + oct _USER_READ_WRITE_PERMISSIONS() + ) + or Carp::croak( + "Failed to open $self->{_config_path} for writing:$EXTENDED_OS_ERROR"); + $config_handle->print( + <<"_CONF_") or Carp::croak("Failed to print to $self->{_config_path}:$EXTENDED_OS_ERROR"); +\$ModLoad imuxsock +\$InputUnixListenSocketCreatePath on +\$AddUnixListenSocket $self->{_socket_path} +\$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat +\$OmitLocalLogging off +*.* $self->{_messages_path} +_CONF_ + $config_handle->close() + or + Carp::croak("Failed to close $self->{_config_path}:$EXTENDED_OS_ERROR"); + $self->start(); + return $self; +} + +sub scrub { + my ($self) = @_; + if ( $self->alive() ) { + Carp::croak('Unable to truncate while rsyslogd is still running'); + } + truncate $self->{_messages_path}, 0 + or Carp::croak( + "Failed to truncate $self->{_messages_path}:$EXTENDED_OS_ERROR"); + return; +} + +sub start { + my ($self) = @_; + my $dev_null = File::Spec->devnull(); + if ( ( defined $self->{_pid} ) && ( kill 0, $self->{_pid} ) ) { + Carp::cluck('Temporary rsyslog daemon is already running...'); + return; + } + if ( $self->{_pid} = fork ) { + while ( not -e $self->{_socket_path} ) { + sleep 1; + } + } + elsif ( defined $self->{_pid} ) { + + eval { + # clear any possible tainted environment variables + local %ENV = %ENV; + local $ENV{'PATH'} = '/usr/bin:/usr/sbin:/sbin:/bin:'; + delete $ENV{'BASH_ENV'}; + delete $ENV{'ENV'}; + delete $ENV{'IFS'}; + delete $ENV{'CDPATH'}; + open STDERR, q[>], $dev_null + or die "Failed to redirect STDERR:$EXTENDED_OS_ERROR\n"; + open STDOUT, q[>], $dev_null + or die "Failed to redirect STDOUT:$EXTENDED_OS_ERROR\n"; + exec {'rsyslogd'} 'rsyslogd', '-n', '-d', + '-f' => $self->{_config_path}, + '-i' => $self->{_pid_path} + or die "Failed to exec 'rsyslogd':$EXTENDED_OS_ERROR\n"; + } or do { + chomp $EVAL_ERROR; + warn "$EVAL_ERROR\n"; + }; + exit 1; + } + else { + Carp::croak("Failed to fork:$EXTENDED_OS_ERROR"); + } + return; +} + +sub alive { + my ($self) = @_; + if ( $self->{_pid} ) { + waitpid $self->{_pid}, POSIX::WNOHANG(); + if ( kill 0, $self->{_pid} ) { + return 1; + } + } + return 0; +} + +sub stop { + my ($self) = @_; + if ( $self->{_pid} ) { + my @signal_numbers = split q[ ], $Config{'sig_num'}; + my @signal_names = split q[ ], $Config{'sig_name'}; + my %signals_by_name; + my $signal_index = 0; + foreach my $signal_name (@signal_names) { + $signals_by_name{$signal_name} = $signal_numbers[$signal_index]; + $signal_index += 1; + } + if ( kill $signals_by_name{'TERM'}, $self->{_pid} ) { + waitpid $self->{_pid}, 0; + } + elsif ( $OS_ERROR == POSIX::ESRCH() ) { + } + else { + Carp::croak("Failed to kill $self->{_pid}:$EXTENDED_OS_ERROR"); + } + } + return; +} + +sub DESTROY { + my ($self) = @_; + $self->stop(); + foreach my $key ( sort { $a cmp $b } keys %{$self} ) { + if ( $key =~ /_path$/smx ) { + unlink $self->{$key} + or ( $OS_ERROR == POSIX::ENOENT() ) + or + Carp::croak("Failed to unlink $self->{$key}:$EXTENDED_OS_ERROR"); + } + } + rmdir $self->{_root_directory} + or ( $OS_ERROR == POSIX::ENOENT() ) + or Carp::croak( + "Failed to rmdir $self->{_root_directory}:$EXTENDED_OS_ERROR"); + return; +} + +1; +__END__ +=head1 NAME + +Test::Rsyslog - Creates a temporary instance of rsyslog to run tests against + +=head1 VERSION + +Version 0.06 + +=head1 SYNOPSIS + + my $rsyslog = Test::Rsyslog->new(); + + Sys::Syslog::setlogsock({ type => 'unix', path => $rsyslog->socket_path() }); + # or "Sys::Syslog::setlogsock('unix', $rsyslog->socket_path());" for older Sys::Syslogs + Sys::Syslog::openlog('program[' . $$ . ']','cons','LOG_LOCAL7'); + Sys::Syslog::syslog('info|LOG_LOCAL7','This is a test message'); + Sys::Syslog::closelog(); + + ok($rsyslog->find('This is a test message'), 'Rsyslog is okay'); + +=head1 DESCRIPTION + +This module allows easy creation and tear down of a rsyslog instance. When the variable goes +out of scope, the rsyslog instance is torn down and the file system objects it relies on are removed. + +=head1 SUBROUTINES/METHODS + +=head2 new + +This method will setup and start the rsyslog instance. It currently has no parameters, but this may change in response to feature requests + +=head2 socket_path + +This method returns that path to the UNIX file system socket that is connected to the current running instance of rsyslog + +=head2 find($string) + +This method searches the existing logs that rsyslog has processed to see if a message has been found matching $string. It will return a list of every line in the log file that matches $string. + +=head2 start + +This method starts the rsyslog instance + +=head2 stop + +This method stops the rsyslog instance + +=head2 alive + +This method checks to make sure that the rsyslogd instance is still running + +=head2 messages + +This method returns the content of the rsyslogd log file + +=head2 scrub + +This method truncates the rsyslogd log file. Rsyslogd must be stopped to truncate the log file + +=head1 DIAGNOSTICS + +=over + +=item C<< Failed to open %s for reading >> + +There has been a file system error trying to read from the rsyslog logfile. + +=item C<< Failed to print to %s >> + +There has been a file system error trying to write to the rsyslog configuration file. + +=item C<< Failed to fork >> + +The operating system was unable to fork a subprocess for use by the rsyslog daemon. + +=item C<< Failed to rmdir %s >> + +There has been a file system error trying to remove the temporary directory. + +=item C<< Failed to unlink %s >> + +There has been a file system error trying to unlink a temporary file + +=item C<< Failed to close %s >> + +There has been a file system error trying to close a temporary file + +=item C<< Failed to mkdir %s >> + +There has been a file system error trying to make the temporary directory + +=item C<< Temporary rsyslog daemon is already running... >> + +The rsyslog daemon has already started + +=item C<< Unable to truncate while rsyslogd is still running >> + +This module will not truncate the messages file while rsyslogd could still be writing to it + +=item C<< Unable to untaint the directory path >> + +The module generated an unrecognisable temporary path for rsyslogd + +=back + +=head1 CONFIGURATION AND ENVIRONMENT + +Test::Rsyslog requires no configuration files or environment variables. + +=head1 DEPENDENCIES + +Test::Rsyslog requires Perl 5.6 or better. + +=head1 INCOMPATIBILITIES + +None reported + +=head1 BUGS AND LIMITATIONS + +Please report any bugs or feature requests to C, or through +the web interface at L. I will be notified, and then you'll +automatically be notified of progress on your bug as I make changes. + + + + +=head1 SUPPORT + +You can find documentation for this module with the perldoc command. + + perldoc Test::Rsyslog + + +You can also look for information at: + +=over 4 + +=item * RT: CPAN's request tracker (report bugs here) + +L + +=item * AnnoCPAN: Annotated CPAN documentation + +L + +=item * CPAN Ratings + +L + +=item * Search CPAN + +L + +=back + + +=head1 AUTHOR + +David Dick, C<< >> + +=head1 ACKNOWLEDGEMENTS + + +=head1 LICENSE AND COPYRIGHT + +Copyright 2017 David Dick. + +This program is free software; you can redistribute it and/or modify it +under the terms of either: the GNU General Public License as published +by the Free Software Foundation; or the Artistic License. + +See L for more information. + + +=cut + +1; # End of Test::Rsyslog diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..f30502c --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,13 @@ +#!perl -T +use 5.006; +use strict; +use warnings; +use Test::More; + +plan tests => 1; + +BEGIN { + use_ok( 'Test::Rsyslog' ) || print "Bail out!\n"; +} + +diag( "Testing Test::Rsyslog $Test::Rsyslog::VERSION, Perl $], $^X" ); diff --git a/t/01-rsyslog.t b/t/01-rsyslog.t new file mode 100644 index 0000000..59d7fee --- /dev/null +++ b/t/01-rsyslog.t @@ -0,0 +1,88 @@ +#!perl -T +use 5.006; +use strict; +use warnings; +use Test::More; +use Test::Rsyslog(); +use Sys::Syslog(); + +plan tests => 13; + +{ + local %ENV = %ENV; + local $ENV{'PATH'} = '/usr/bin:/usr/sbin:/sbin:/bin:'; + delete $ENV{'BASH_ENV'}; + delete $ENV{'ENV'}; + delete $ENV{'IFS'}; + delete $ENV{'CDPATH'}; + diag(`rsyslogd -v`); +} +my $rsyslog = Test::Rsyslog->new(); +ok($rsyslog, "Created Test Rsyslog object"); + +if ($Sys::Syslog::VERSION ge 0.28) { + diag("Sys::Syslog VERSION is $Sys::Syslog::VERSION, using new interface"); + Sys::Syslog::setlogsock({ type => 'unix', path => $rsyslog->socket_path() }); +} else { + diag("Sys::Syslog VERSION is $Sys::Syslog::VERSION, using old interface"); + Sys::Syslog::setlogsock('unix', $rsyslog->socket_path()); +} +Sys::Syslog::openlog($0 . '[' . $$ . ']','cons','LOG_LOCAL7'); +my $plain = 'This is a test message'; +my @messages = $rsyslog->messages(); +ok(Sys::Syslog::syslog('info|LOG_LOCAL7', $plain), "Sent '$plain' to rsyslog"); +Sys::Syslog::closelog(); +while(($rsyslog->alive()) && (@messages == $rsyslog->messages())) { + diag("Waiting for rsyslog to output log message"); + sleep 1; +} +$rsyslog->stop(); +ok(!$rsyslog->alive(), "Rsyslogd has been stopped"); +@messages = $rsyslog->find($plain); +ok(scalar @messages == 1, "Found 1 matching log message"); +my $quoted = quotemeta $plain; +ok($messages[0] =~ /$quoted/smx, q[Found '] . (join q[, ], @messages) . q[']); +foreach my $line ($rsyslog->messages()) { + diag(Encode::encode('UTF-8', $line, 1)); +} +$rsyslog->scrub(); +$rsyslog->start(); +Sys::Syslog::openlog($0 . '[' . $$ . ']','cons','LOG_LOCAL0'); +@messages = $rsyslog->messages(); +my $unicode = 'This is a ' . (chr 1606) . ' unicode ' . (chr 29399) . ' message'; +my $copy = $unicode; +my $encoded = Encode::encode('UTF-8', $copy, 1); +ok(Sys::Syslog::syslog('LOG_INFO|LOG_LOCAL0', $encoded), "Sent '$encoded' to rsyslog"); +Sys::Syslog::closelog(); +while(($rsyslog->alive()) && (@messages == $rsyslog->messages())) { + diag("Waiting for rsyslog to output log message"); + sleep 1; +} +$rsyslog->stop(); +ok(!$rsyslog->alive(), "Rsyslogd has been stopped"); +@messages = $rsyslog->find($unicode); +ok(scalar @messages == 1, "Found 1 matching log message"); +$quoted = quotemeta $unicode; +ok($messages[0] =~ /$quoted/smx, q[Found '] . (join q[, ], map { Encode::encode('UTF-8', $_, 1) } @messages) . q[']); +foreach my $line ($rsyslog->messages()) { + diag(Encode::encode('UTF-8', $line, 1)); +} +$rsyslog->scrub(); +$rsyslog->start(); +Sys::Syslog::openlog($0 . '[' . $$ . ']','cons','LOG_USER'); +my $special = "This is a \x05message\r\n with special @\b characters" . (join q[ ], map { chr $_ } 0 .. 40); +@messages = $rsyslog->messages(); +ok(Sys::Syslog::syslog('LOG_INFO|LOG_USER',$special), 'Sent a message containing every known special character to rsyslog'); +Sys::Syslog::closelog(); +while(($rsyslog->alive()) && (@messages == $rsyslog->messages())) { + diag("Waiting for rsyslog to output log message"); + sleep 1; +} +$rsyslog->stop(); +ok(!$rsyslog->alive(), "Rsyslogd has been stopped"); +@messages = $rsyslog->find($special); +ok(scalar @messages == 1, "Found 1 matching log message"); +ok($messages[0] =~ /special/smx, q[Found '] . (join q[, ], @messages) . q[']); +foreach my $line ($rsyslog->messages()) { + diag(Encode::encode('UTF-8', $line, 1)); +} diff --git a/t/manifest.t b/t/manifest.t new file mode 100644 index 0000000..e0b558e --- /dev/null +++ b/t/manifest.t @@ -0,0 +1,15 @@ +#!perl -T +use 5.006; +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +my $min_tcm = 0.9; +eval "use Test::CheckManifest $min_tcm"; +plan skip_all => "Test::CheckManifest $min_tcm required" if $@; + +ok_manifest(); diff --git a/t/pod-coverage.t b/t/pod-coverage.t new file mode 100644 index 0000000..f5728a5 --- /dev/null +++ b/t/pod-coverage.t @@ -0,0 +1,24 @@ +#!perl -T +use 5.006; +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +# Ensure a recent version of Test::Pod::Coverage +my $min_tpc = 1.08; +eval "use Test::Pod::Coverage $min_tpc"; +plan skip_all => "Test::Pod::Coverage $min_tpc required for testing POD coverage" + if $@; + +# Test::Pod::Coverage doesn't require a minimum Pod::Coverage version, +# but older versions don't recognize some common documentation styles +my $min_pc = 0.18; +eval "use Pod::Coverage $min_pc"; +plan skip_all => "Pod::Coverage $min_pc required for testing POD coverage" + if $@; + +all_pod_coverage_ok(); diff --git a/t/pod.t b/t/pod.t new file mode 100644 index 0000000..4d3a0ce --- /dev/null +++ b/t/pod.t @@ -0,0 +1,16 @@ +#!perl -T +use 5.006; +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +# Ensure a recent version of Test::Pod +my $min_tp = 1.22; +eval "use Test::Pod $min_tp"; +plan skip_all => "Test::Pod $min_tp required for testing POD" if $@; + +all_pod_files_ok();