Add regression tests where OpenBSD syslogd is sending messages to
authorbluhm <bluhm@openbsd.org>
Sun, 28 Dec 2014 14:08:01 +0000 (14:08 +0000)
committerbluhm <bluhm@openbsd.org>
Sun, 28 Dec 2014 14:08:01 +0000 (14:08 +0000)
rsyslogd from ports.  If the rsyslog package is installed, rsyslogd
is used as drain to test interoperability.  This will be especially
useful for syslog via TCP and TLS.

regress/usr.sbin/syslogd/Makefile
regress/usr.sbin/syslogd/README
regress/usr.sbin/syslogd/RSyslogd.pm [new file with mode: 0644]
regress/usr.sbin/syslogd/Server.pm
regress/usr.sbin/syslogd/Syslogd.pm
regress/usr.sbin/syslogd/args-rsyslog-tcp.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/args-rsyslog-udp.pl [new file with mode: 0644]
regress/usr.sbin/syslogd/funcs.pl
regress/usr.sbin/syslogd/syslogd.pl

index 5647005..a40f36d 100644 (file)
@@ -1,10 +1,13 @@
-#      $OpenBSD: Makefile,v 1.5 2014/09/13 23:38:24 bluhm Exp $
+#      $OpenBSD: Makefile,v 1.6 2014/12/28 14:08:01 bluhm Exp $
 
 # The following ports must be installed for the regression tests:
 # p5-IO-Socket-INET6   object interface for AF_INET and AF_INET6 domain sockets
 # p5-Socket6           Perl defines relating to AF_INET6 sockets
 # p5-IO-Socket-SSL     perl interface to SSL sockets
 #
+# This package enables additional interoperability tests
+# rsyslog              syslog daemon supporting databases, TCP, SSL, RELP
+#
 # Check wether all required perl packages are installed.  If some
 # are missing print a warning and skip the tests, but do not fail.
 
@@ -22,10 +25,14 @@ regress:
 # Automatically generate regress targets from test cases in directory.
 
 ARGS !=                        cd ${.CURDIR} && ls args-*.pl
+.if exists (/usr/local/sbin/rsyslogd)
 TARGETS ?=             ${ARGS}
+.else
+TARGETS ?=             ${ARGS:Nargs-rsyslog*}
+.endif
 REGRESS_TARGETS =      ${TARGETS:S/^/run-regress-/}
-CLEANFILES +=          *.log *.log.? *.pem *.crt *.key syslogd.conf stamp-*
-CLEANFILES +=          *.sock ktrace.out *.ktrace *.fstat
+CLEANFILES +=          *.log *.log.? *.pem *.crt *.key *.conf stamp-*
+CLEANFILES +=          *.out *.sock ktrace.out *.ktrace *.fstat
 
 .MAIN: all
 
index 61092a2..a263a58 100644 (file)
@@ -14,6 +14,9 @@ When invoked with "make libevent", all tests are executed three
 times.  They pass the EVENT_NO...  environment variables over sudo
 into syslogd.  This way the select(2) and poll(2) and kqueue(2)
 backend is tested.
+If the rsyslog package is installed, messages are sent to the
+rsyslogd to test interoperability.  This is especially useful for
+TCP and TLS.
 
 SUDO=sudo
 As syslogd needs root privileges either run the tests as root or
diff --git a/regress/usr.sbin/syslogd/RSyslogd.pm b/regress/usr.sbin/syslogd/RSyslogd.pm
new file mode 100644 (file)
index 0000000..6a1e906
--- /dev/null
@@ -0,0 +1,93 @@
+#      $OpenBSD: RSyslogd.pm,v 1.1 2014/12/28 14:08:01 bluhm Exp $
+
+# Copyright (c) 2010-2014 Alexander Bluhm <bluhm@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+use strict;
+use warnings;
+
+package RSyslogd;
+use parent 'Proc';
+use Carp;
+use Cwd;
+
+sub new {
+       my $class = shift;
+       my %args = @_;
+       $args{logfile} ||= "rsyslogd.log";
+       $args{up} ||= "calling select";
+       $args{down} ||= "Clean shutdown completed";
+       $args{func} = sub { Carp::confess "$class func may not be called" };
+       $args{conffile} ||= "rsyslogd.conf";
+       $args{pidfile} ||= "rsyslogd.pid";
+       $args{outfile} ||= "rsyslogd.out";
+       my $self = Proc::new($class, %args);
+
+       _make_abspath(\$self->{$_}) foreach (qw(conffile pidfile outfile));
+
+       # substitute variables in config file
+       my $listendomain = $self->{listendomain}
+           or croak "$class listen domain not given";
+       my $listenaddr = $self->{listenaddr}
+           or croak "$class listen address not given";
+       my $listenproto = $self->{listenproto}
+           or croak "$class listen protocol not given";
+       my $listenport = $self->{listenport}
+           or croak "$class listen port not given";
+
+       open(my $fh, '>', $self->{conffile})
+           or die ref($self), " create conf file $self->{conffile} failed: $!";
+       if ($listenproto eq "udp") {
+               print $fh "\$ModLoad imudp\n";
+               print $fh "\$UDPServerRun $listenport\n";
+       }
+       if ($listenproto eq "tcp") {
+               print $fh "\$ModLoad imtcp\n";
+               print $fh "\$InputTCPServerRun $listenport\n";
+       }
+       print $fh "*.*  $self->{outfile}\n";
+       print $fh $self->{conf} if $self->{conf};
+       close $fh;
+
+       unlink($self->{outfile});
+       return $self;
+}
+
+sub child {
+       my $self = shift;
+
+       my @cmd = ("rsyslogd", "-dn", "-c4", "-f", $self->{conffile},
+           "-i", $self->{pidfile});
+       print STDERR "execute: @cmd\n";
+       exec @cmd;
+       die ref($self), " exec '@cmd' failed: $!";
+}
+
+sub _make_abspath {
+       my $file = ref($_[0]) ? ${$_[0]} : $_[0];
+       if (substr($file, 0, 1) ne "/") {
+               $file = getcwd(). "/". $file;
+               ${$_[0]} = $file if ref($_[0]);
+       }
+       return $file;
+}
+
+sub down {
+       my $self = shift;
+
+       $self->kill();
+       return Proc::down($self);
+}
+
+1;
index 8bcdf73..818e694 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Server.pm,v 1.2 2014/08/25 17:55:27 bluhm Exp $
+#      $OpenBSD: Server.pm,v 1.3 2014/12/28 14:08:01 bluhm Exp $
 
 # Copyright (c) 2010-2014 Alexander Bluhm <bluhm@openbsd.org>
 #
@@ -33,13 +33,13 @@ sub new {
        $args{logfile} ||= "server.log";
        $args{up} ||= "Accepted";
        my $self = Proc::new($class, %args);
-       $self->{listenprotocol} ||= "udp";
+       $self->{listenproto} ||= "udp";
        defined($self->{listendomain})
            or croak "$class listen domain not given";
        $SSL_ERROR = "";
-       my $iosocket = $self->{listenprotocol} eq "tls" ?
+       my $iosocket = $self->{listenproto} eq "tls" ?
            "IO::Socket::SSL" : "IO::Socket::INET6";
-       my $proto = $self->{listenprotocol};
+       my $proto = $self->{listenproto};
        $proto = "tcp" if $proto eq "tls";
        my $ls = $iosocket->new(
            Proto               => $proto,
@@ -51,7 +51,7 @@ sub new {
            SSL_cert_file       => "server-cert.pem",
            SSL_verify_mode     => SSL_VERIFY_NONE,
        ) or die ref($self), " $iosocket socket listen failed: $!,$SSL_ERROR";
-       if ($self->{listenprotocol} eq "tcp") {
+       if ($self->{listenproto} eq "tcp") {
                listen($ls, 1)
                    or die ref($self), " socket failed: $!";
        }
@@ -68,7 +68,7 @@ sub child {
 
        my $iosocket = $self->{ssl} ? "IO::Socket::SSL" : "IO::Socket::INET6";
        my $as = $self->{ls};
-       if ($self->{listenprotocol} ne "udp") {
+       if ($self->{listenproto} ne "udp") {
                $as = $self->{ls}->accept()
                    or die ref($self), " $iosocket socket accept failed: $!";
                print STDERR "accept sock: ",$as->sockhost()," ",
index 28bf627..b70a8ea 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: Syslogd.pm,v 1.6 2014/10/29 16:42:57 bluhm Exp $
+#      $OpenBSD: Syslogd.pm,v 1.7 2014/12/28 14:08:01 bluhm Exp $
 
 # Copyright (c) 2010-2014 Alexander Bluhm <bluhm@openbsd.org>
 # Copyright (c) 2014 Florian Riehm <mail@friehm.de>
@@ -48,9 +48,9 @@ sub new {
        _make_abspath(\$self->{$_}) foreach (qw(conffile outfile outpipe));
 
        # substitute variables in config file
-       my $connectprotocol = $self->{connectprotocol};
        my $connectdomain = $self->{connectdomain};
        my $connectaddr = $self->{connectaddr};
+       my $connectproto = $self->{connectproto};
        my $connectport = $self->{connectport};
 
        open(my $fh, '>', $self->{conffile})
diff --git a/regress/usr.sbin/syslogd/args-rsyslog-tcp.pl b/regress/usr.sbin/syslogd/args-rsyslog-tcp.pl
new file mode 100644 (file)
index 0000000..499695d
--- /dev/null
@@ -0,0 +1,22 @@
+# Test with rsyslogd as receiver.
+# The client writes a message to Sys::Syslog native method.
+# The syslogd writes it into a file and through a pipe.
+# The syslogd passes it via TCP to the rsyslogd.
+# The rsyslogd receives the message on its TCP socket.
+# Find the message in client, file, pipe, syslogd, rsyslogd log.
+# Check that the message is in the rsyslogd out file.
+
+use strict;
+use warnings;
+
+our %args = (
+    syslogd => {
+       loghost => '@tcp://127.0.0.1:$connectport',
+       late => 1,  # connect after the listen socket has been created
+    },
+    rsyslogd => {
+       listen => { proto => "tcp" },
+    },
+);
+
+1;
diff --git a/regress/usr.sbin/syslogd/args-rsyslog-udp.pl b/regress/usr.sbin/syslogd/args-rsyslog-udp.pl
new file mode 100644 (file)
index 0000000..5d087ec
--- /dev/null
@@ -0,0 +1,16 @@
+# Test with rsyslogd as receiver.
+# The client writes a message to Sys::Syslog native method.
+# The syslogd writes it into a file and through a pipe.
+# The syslogd passes it via UDP to the rsyslogd.
+# The rsyslogd receives the message on its UDP socket.
+# Find the message in client, file, pipe, syslogd, rsyslogd log.
+# Check that the message is in the rsyslogd out file.
+
+use strict;
+use warnings;
+
+our %args = (
+    rsyslogd => {},
+);
+
+1;
index b6e9c28..d71d73b 100644 (file)
@@ -1,4 +1,4 @@
-#      $OpenBSD: funcs.pl,v 1.7 2014/09/13 23:38:24 bluhm Exp $
+#      $OpenBSD: funcs.pl,v 1.8 2014/12/28 14:08:01 bluhm Exp $
 
 # Copyright (c) 2010-2014 Alexander Bluhm <bluhm@openbsd.org>
 #
@@ -28,6 +28,26 @@ my $firstlog = "syslogd regress test first message";
 my $testlog = "syslogd regress test log message";
 my $downlog = "syslogd regress client shutdown";
 
+sub find_ports {
+       my %args = @_;
+       my $num    = delete $args{num}    // 1;
+       my $domain = delete $args{domain} // AF_INET;
+       my $addr   = delete $args{addr}   // "127.0.0.1";
+       my $proto  = delete $args{proto}  // "udp";
+
+       my @sockets = (1..$num);
+       foreach my $s (@sockets) {
+               $s = IO::Socket::INET6->new(
+                   Domain    => $domain,
+                   LocalAddr => $addr,
+                   Proto     => $proto,
+               ) or die "find_ports: create and bind socket failed: $!";
+       }
+       my @ports = map { $_->sockport() } @sockets;
+
+       return wantarray ? @ports : $ports[0];
+}
+
 ########################################################################
 # Client funcs
 ########################################################################
@@ -144,6 +164,10 @@ sub check_logs {
        check_out($r, %args);
        check_stat($r, %args);
        check_kdump($c, $r, $s);
+       if (my $file = $s->{"outfile"}) {
+               my $pattern = $s->{filegrep} || $testlog;
+               check_pattern(ref $s, $file, $pattern, \&filegrep);
+       }
 }
 
 sub compare($$) {
index 80a7085..9c5a852 100644 (file)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl
-#      $OpenBSD: syslogd.pl,v 1.3 2014/09/13 23:38:24 bluhm Exp $
+#      $OpenBSD: syslogd.pl,v 1.4 2014/12/28 14:08:01 bluhm Exp $
 
 # Copyright (c) 2010-2014 Alexander Bluhm <bluhm@openbsd.org>
 #
@@ -24,6 +24,7 @@ use Client;
 use Syslogd;
 use Server;
 use Syslogc;
+use RSyslogd;
 require 'funcs.pl';
 
 sub usage {
@@ -39,16 +40,27 @@ if (@ARGV and -f $ARGV[-1]) {
 }
 @ARGV == 0 or usage();
 
-foreach my $name (qw(client syslogd server)) {
+if ($args{rsyslogd}) {
+       $args{rsyslogd}{listen}{domain} ||= AF_INET;
+       $args{rsyslogd}{listen}{addr}   ||= "127.0.0.1";
+       $args{rsyslogd}{listen}{proto}  ||= "udp";
+}
+foreach my $name (qw(client syslogd server rsyslogd)) {
+       $args{$name} or next;
        foreach my $action (qw(connect listen)) {
                my $h = $args{$name}{$action} or next;
-               foreach my $k (qw(protocol domain addr port)) {
+               foreach my $k (qw(domain addr proto port)) {
                        $args{$name}{"$action$k"} = $h->{$k};
                }
        }
 }
 my($s, $c, $r, @m);
-$s = Server->new(
+$s = RSyslogd->new(
+    %{$args{rsyslogd}},
+    listenport          => scalar find_ports(%{$args{rsyslogd}{listen}}),
+    testfile            => $testfile,
+) if $args{rsyslogd};
+$s ||= Server->new(
     func                => \&read_log,
     listendomain        => AF_INET,
     listenaddr          => "127.0.0.1",
@@ -82,8 +94,9 @@ $c = Client->new(
     server              => \$s,
 ) unless $args{client}{noclient};
 
-$r->run;
+$r->run unless $r->{late};
 $s->run->up unless $args{server}{noserver};
+$r->run if $r->{late};
 $r->up;
 my $control = 0;
 foreach (@m) {