diff options
Diffstat (limited to 'tests')
46 files changed, 1171 insertions, 210 deletions
diff --git a/tests/Makefile.am b/tests/Makefile.am index 42ef32e3..d3871e3a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,12 +1,19 @@ if ENABLE_TESTBENCH TESTRUNS = rt_init rscript -check_PROGRAMS = $(TESTRUNS) ourtail nettester tcpflood chkseq +check_PROGRAMS = $(TESTRUNS) ourtail nettester tcpflood chkseq msleep randomgen diagtalker uxsockrcvr inputfilegen TESTS = $(TESTRUNS) cfg.sh \ validation-run.sh \ imtcp-multiport.sh \ diskqueue.sh \ diskqueue-fsync.sh \ manytcp.sh \ + rsf_getenv.sh \ + manyptcp.sh \ + imptcp_large.sh \ + imptcp_addtlframedelim.sh \ + imptcp_conndrop.sh \ + imtcp_conndrop.sh \ + imtcp_addtlframedelim.sh \ sndrcv.sh \ sndrcv_gzip.sh \ asynwr_simple.sh \ @@ -25,7 +32,8 @@ TESTS = $(TESTRUNS) cfg.sh \ dynfile_invalid2.sh \ complex1.sh \ queue-persist.sh \ - pipeaction.sh + pipeaction.sh \ + uxsock_simple.sh \ execonlyonce.sh \ queue-persist.sh @@ -40,12 +48,18 @@ TESTS += omod-if-array.sh \ fieldtest.sh endif -check_JAVA = DiagTalker.java +if ENABLE_EXTENDED_TESTS +TESTS += random.sh +endif + +if ENABLE_IMFILE +TESTS += imfile-basic.sh +endif endif # if ENABLE_TESTBENCH TESTS_ENVIRONMENT = RSYSLOG_MODDIR='$(abs_top_builddir)'/runtime/.libs/ -DISTCLEANFILES=rsyslog.pid '$(abs_top_builddir)'/DiagTalker.class +DISTCLEANFILES=rsyslog.pid test_files = testbench.h runtime-dummy.c EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ @@ -109,6 +123,7 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ testsuites/parse3.conf \ testsuites/reallife.parse3 \ testsuites/parse-nodate.conf \ + testsuites/samples.parse-nodate \ testsuites/parse_invld_regex.conf \ testsuites/samples.parse_invld_regex \ testsuites/parse-3164-buggyday.conf \ @@ -123,6 +138,8 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ killrsyslog.sh \ parsertest.sh \ fieldtest.sh \ + rsf_getenv.sh \ + testsuites/rsf_getenv.conf \ diskqueue.sh \ testsuites/diskqueue.conf \ diskqueue-fsync.sh \ @@ -131,6 +148,18 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ testsuites/imtcp-multiport.conf \ manytcp.sh \ testsuites/manytcp.conf \ + manyptcp.sh \ + testsuites/manyptcp.conf \ + imptcp_large.sh \ + testsuites/imptcp_large.conf \ + imptcp_addtlframedelim.sh \ + testsuites/imptcp_addtlframedelim.conf \ + imptcp_conndrop.sh \ + testsuites/imptcp_conndrop.conf \ + imtcp_conndrop.sh \ + testsuites/imtcp_conndrop.conf \ + imtcp_addtlframedelim.sh \ + testsuites/imtcp_addtlframedelim.conf \ inputname.sh \ testsuites/inputname_imtcp.conf \ testsuites/1.inputname_imtcp_12514 \ @@ -156,6 +185,8 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ testsuites/sndrcv_gzip_rcvr.conf \ pipeaction.sh \ testsuites/pipeaction.conf \ + uxsock_simple.sh \ + testsuites/uxsock_simple.conf \ asynwr_simple.sh \ testsuites/asynwr_simple.conf \ asynwr_timeout.sh \ @@ -180,6 +211,10 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ testsuites/gzipwr_large_dynfile.conf \ complex1.sh \ testsuites/complex1.conf \ + random.sh \ + testsuites/random.conf \ + imfile-basic.sh \ + testsuites/imfile-basic.conf \ dynfile_invld_async.sh \ dynfile_invld_sync.sh \ dynfile_cachemiss.sh \ @@ -194,15 +229,25 @@ EXTRA_DIST= 1.rstest 2.rstest 3.rstest err1.rstest \ execonlyonce.sh \ testsuites/execonlyonce.conf \ testsuites/execonlyonce.data \ - DiagTalker.java \ cfg.sh +uxsockrcvr_SOURCES = uxsockrcvr.c ourtail_SOURCES = ourtail.c +msleep_SOURCES = msleep.c chkseq_SOURCES = chkseq.c tcpflood_SOURCES = tcpflood.c tcpflood_LDADD = $(SOL_LIBS) +diagtalker_SOURCES = diagtalker.c +diagtalker_LDADD = $(SOL_LIBS) + +randomgen_SOURCES = randomgen.c +randomgen_LDADD = $(SOL_LIBS) + +inputfilegen_SOURCES = inputfilegen.c +inputfilegen_LDADD = $(SOL_LIBS) + nettester_SOURCES = nettester.c getline.c nettester_LDADD = $(SOL_LIBS) diff --git a/tests/cfg4.testin b/tests/cfg4.testin index a49c0fb6..2dc0e830 100644 --- a/tests/cfg4.testin +++ b/tests/cfg4.testin @@ -12,48 +12,6 @@ # If you do not load inputs, nothing happens! # You may need to set the module load path if modules are not found. -#$ModLoad immark # provides --MARK-- message capability -#$ModLoad imuxsock # provides support for local system logging (e.g. via logger command) -#$ModLoad imklog # kernel logging (formerly provided by rklogd) - -# Log all kernel messages to the console. -# Logging much else clutters up the screen. -#kern.* /dev/console - -# Log anything (except mail) of level info or higher. -# Don't log private authentication messages! -*.info;mail.none;authpriv.none;cron.none -/var/log/messages - -# The authpriv file has restricted access. -authpriv.* /var/log/secure - -# Log all the mail messages in one place. -mail.* -/var/log/maillog - - -# Log cron stuff -cron.* -/var/log/cron - -# Everybody gets emergency messages -*.emerg * - -# Save news errors of level crit and higher in a special file. -uucp,news.crit -/var/log/spooler - -# Save boot messages also to boot.log -local7.* /var/log/boot.log - -# Remote Logging (we use TCP for reliable delivery) -# An on-disk queue is created for this action. If the remote host is -# down, messages are spooled to disk and sent when it is up again. -#$WorkDirectory /rsyslog/spool # where to place spool files -#$ActionQueueFileName uniqName # unique name prefix for spool files -#$ActionQueueMaxDiskSpace 1g # 1gb space limit (use as much as possible) -#$ActionQueueSaveOnShutdown on # save messages to disk on shutdown -#$ActionQueueType LinkedList # run asynchronously -#$ActionResumeRetryCount -1 # infinite retries if host is down -# remote host is: name/ip:port, e.g. 192.168.0.1:514, port optional -#*.* @@remote-host:514 # ######### Receiving Messages from Remote Hosts ########## @@ -63,5 +21,11 @@ local7.* /var/log/boot.log #$InputTCPServerRun 514 # start up TCP listener at port 514 # UDP Syslog Server: -#$ModLoad imudp.so # provides UDP syslog reception -#$UDPServerRun 514 # start a UDP syslog server at standard port 514 +$ModLoad imudp.so # provides UDP syslog reception +$ModLoad omoracle.so +$UDPServerRun 514 # start a UDP syslog server at standard port 514 + +$IncludeConfig /home/munoz/logging/rsyslog/20*conf +$IncludeConfig /home/munoz/logging/rsyslog/30*conf + +#*.* ~ diff --git a/tests/complex1.sh b/tests/complex1.sh index b5dc2c9d..e138bff5 100755 --- a/tests/complex1.sh +++ b/tests/complex1.sh @@ -7,15 +7,16 @@ echo =========================================================================== echo TEST: \[complex1.sh\]: complex test with gzip and multiple action queues source $srcdir/diag.sh init # uncomment for debugging support: -export RSYSLOG_DEBUG="debug nostdout" -export RSYSLOG_DEBUGLOG="log" +#export RSYSLOG_DEBUG="debug nostdout" +#export RSYSLOG_DEBUGLOG="log" source $srcdir/diag.sh startup complex1.conf -# send 30,000 messages of 400 bytes plus header max, via three dest ports +# send 40,000 messages of 400 bytes plus header max, via three dest ports source $srcdir/diag.sh tcpflood -m40000 -rd400 -P129 -f5 -n3 -c15 -i1 -sleep 2 # due to large messages, we need this time for the tcp receiver to settle... +sleep 4 # due to large messages, we need this time for the tcp receiver to settle... source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages source $srcdir/diag.sh wait-shutdown # and wait for it to terminate ls rsyslog.out.*.log -zcat rsyslog.out.*.log > rsyslog.out.log +source $srcdir/diag.sh setzcat # find out which zcat to use +$ZCAT rsyslog.out.*.log > rsyslog.out.log source $srcdir/diag.sh seq-check 1 40000 -E source $srcdir/diag.sh exit diff --git a/tests/diag.sh b/tests/diag.sh index 8f268a5e..b0460f72 100755 --- a/tests/diag.sh +++ b/tests/diag.sh @@ -10,26 +10,28 @@ #valgrind="valgrind --tool=helgrind --log-fd=1" #valgrind="valgrind --tool=exp-ptrcheck --log-fd=1" #set -o xtrace -#export RSYSLOG_DEBUG="debug nostdout printmutexaction" +#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" #export RSYSLOG_DEBUGLOG="log" case $1 in 'init') $srcdir/killrsyslog.sh # kill rsyslogd if it runs for some reason cp $srcdir/testsuites/diag-common.conf diag-common.conf cp $srcdir/testsuites/diag-common2.conf diag-common2.conf rm -f rsyslog.action.*.include - rm -f rsyslogd.started work-*.conf + rm -f rsyslogd.started work-*.conf rsyslog.random.data rm -f rsyslogd2.started work-*.conf rm -f work rsyslog.out.log rsyslog.out.log.save # common work files - rm -f rsyslog.out.*.log - rm -rf test-spool + rm -f rsyslog.out.*.log work-presort + rm -rf test-spool stat-file1 + rm -f rsyslog.input rm -f core.* vgcore.* mkdir test-spool ;; 'exit') rm -f rsyslogd.started work-*.conf diag-common.conf rm -f rsyslogd2.started diag-common2.conf rsyslog.action.*.include rm -f work rsyslog.out.log rsyslog.out.log.save # common work files - rm -f rsyslog.out.*.log - rm -rf test-spool + rm -f rsyslog.out.*.log rsyslog.random.data work-presort + rm -rf test-spool stat-file1 + rm -f rsyslog.input ;; 'startup') # start rsyslogd with default params. $2 is the config file name to use # returns only after successful startup, $3 is the instance (blank or 2!) @@ -37,25 +39,26 @@ case $1 in $srcdir/diag.sh wait-startup $3 ;; 'wait-startup') # wait for rsyslogd startup ($2 is the instance) + while test ! -f rsyslog$2.pid; do + ./msleep 100 # wait 100 milliseconds + done while test ! -f rsyslogd$2.started; do - #true - sleep 0.1 # if this is not supported by all platforms, use above! + ./msleep 100 # wait 100 milliseconds done echo "rsyslogd$2 started with pid " `cat rsyslog$2.pid` ;; 'wait-shutdown') # actually, we wait for rsyslog.pid to be deleted. $2 is the # instance while test -f rsyslog$2.pid; do - #true - sleep 0.1 # if this is not supported by all platforms, use above! + ./msleep 100 # wait 100 milliseconds done ;; 'wait-queueempty') # wait for main message queue to be empty. $2 is the instance. if [ "$2" == "2" ] then - echo WaitMainQueueEmpty | java -classpath $abs_top_builddir DiagTalker + echo WaitMainQueueEmpty | ./diagtalker else - echo WaitMainQueueEmpty | java -classpath $abs_top_builddir DiagTalker 13501 + echo WaitMainQueueEmpty | ./diagtalker fi ;; 'shutdown-when-empty') # shut rsyslogd down when main queue is empty. $2 is the instance. @@ -77,7 +80,7 @@ case $1 in ;; 'injectmsg') # inject messages via our inject interface (imdiag) echo injecting $3 messages - echo injectmsg $2 $3 $4 $5 | java -classpath $abs_top_builddir DiagTalker + echo injectmsg $2 $3 $4 $5 | ./diagtalker # TODO: some return state checking? (does it really make sense here?) ;; 'check-mainq-spool') # check if mainqueue spool files exist, if not abort (we just check .qi). @@ -131,5 +134,12 @@ case $1 in exit 1 fi ;; + 'setzcat') # find out name of zcat tool + if [ `uname` == SunOS ]; then + ZCAT=gzcat + else + ZCAT=zcat + fi + ;; *) echo "invalid argument" $1 esac diff --git a/tests/diagtalker.c b/tests/diagtalker.c new file mode 100644 index 00000000..6a721e47 --- /dev/null +++ b/tests/diagtalker.c @@ -0,0 +1,157 @@ +/* A yet very simple tool to talk to imdiag (this replaces the + * previous Java implementation in order to get fewer dependencies). + * + * Copyright 2010 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>. + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <arpa/inet.h> +#include <sys/types.h> +#include <sys/socket.h> + + +static char *targetIP = "127.0.0.1"; +static int targetPort = 13500; + + +/* open a single tcp connection + */ +int openConn(int *fd) +{ + int sock; + struct sockaddr_in addr; + int port; + int retries = 0; + + if((sock=socket(AF_INET, SOCK_STREAM, 0))==-1) { + perror("socket()"); + exit(1); + } + + port = targetPort; + memset((char *) &addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + if(inet_aton(targetIP, &addr.sin_addr)==0) { + fprintf(stderr, "inet_aton() failed\n"); + exit(1); + } + while(1) { /* loop broken inside */ + if(connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == 0) { + break; + } else { + if(retries++ == 50) { + perror("connect()"); + fprintf(stderr, "connect() failed\n"); + exit(1); + } else { + fprintf(stderr, "connect failed, retrying...\n"); + usleep(100000); /* ms = 1000 us! */ + } + } + } + + *fd = sock; + return 0; +} + + +/* send a string + */ +static void +sendCmd(int fd, char *buf, int len) +{ + int lenSend; + + lenSend = send(fd, buf, len, 0); + if(lenSend != len) { + perror("sending string"); + exit(1); + } +} + + +/* wait for a response from remote system + */ +static void +waitRsp(int fd, char *buf, int len) +{ + int ret; + + ret = recv(fd, buf, len - 1, 0); + if(ret < 0) { + perror("receiving response"); + exit(1); + } + /* we assume the message was complete, it may be better to wait + * for a LF... + */ + buf[ret] = '\0'; +} + + +/* do the actual processing + */ +static void +doProcessing() +{ + int fd; + int len; + char line[2048]; + + openConn(&fd); + while(!feof(stdin)) { + if(fgets(line, sizeof(line) - 1, stdin) == NULL) + break; + len = strlen(line); + sendCmd(fd, line, len); + waitRsp(fd, line, sizeof(line)); + printf("imdiag: %s", line); + } +} + + +/* Run the test. + * rgerhards, 2009-04-03 + */ +int main(int argc, char *argv[]) +{ + int ret = 0; + int opt; + + while((opt = getopt(argc, argv, "f:t:p:c:C:m:i:I:P:d:n:M:rB")) != -1) { + switch (opt) { + case 't': targetIP = optarg; + break; + case 'p': targetPort = atoi(optarg); + break; + default: printf("invalid option '%c' or value missing - terminating...\n", opt); + exit (1); + break; + } + } + + doProcessing(); + + exit(ret); +} diff --git a/tests/dynfile_invalid2.sh b/tests/dynfile_invalid2.sh index b6fb3945..cb3ef51e 100755 --- a/tests/dynfile_invalid2.sh +++ b/tests/dynfile_invalid2.sh @@ -9,8 +9,8 @@ echo =========================================================================== echo TEST: \[dynfile_invalid2.sh\]: test open fail for dynafiles source $srcdir/diag.sh init # uncomment for debugging support: -export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" -export RSYSLOG_DEBUGLOG="log" +#export RSYSLOG_DEBUG="debug nostdout noprintmutexaction" +#export RSYSLOG_DEBUGLOG="log" source $srcdir/diag.sh startup dynfile_invalid2.conf # we send handcrafted message. We have a dynafile cache of 4, and now send one message # each to fill up the cache. diff --git a/tests/gzipwr_large_dynfile.sh b/tests/gzipwr_large_dynfile.sh index ebd4c558..73d44796 100755 --- a/tests/gzipwr_large_dynfile.sh +++ b/tests/gzipwr_large_dynfile.sh @@ -18,8 +18,8 @@ echo =========================================================================== echo TEST: \[gzipwr_large_dynfile.sh\]: test for gzip file writing for large message sets source $srcdir/diag.sh init # uncomment for debugging support: -export RSYSLOG_DEBUG="debug nostdout" -export RSYSLOG_DEBUGLOG="log" +#export RSYSLOG_DEBUG="debug nostdout" +#export RSYSLOG_DEBUGLOG="log" source $srcdir/diag.sh startup gzipwr_large_dynfile.conf # send 4000 messages of 10.000bytes plus header max, randomized source $srcdir/diag.sh tcpflood -m4000 -r -d10000 -P129 -f5 diff --git a/tests/DiagTalker.java b/tests/historical/DiagTalker.java index 5a6f7dd5..147cec34 100644 --- a/tests/DiagTalker.java +++ b/tests/historical/DiagTalker.java @@ -1,3 +1,4 @@ +This tool has been replaced by ./tests/diagtalker.c in release 4.7.1 /* A yet very simple tool to talk to imdiag. * * Copyright 2009 Rainer Gerhards and Adiscon GmbH. diff --git a/tests/historical/README b/tests/historical/README new file mode 100644 index 00000000..5f10ecef --- /dev/null +++ b/tests/historical/README @@ -0,0 +1,2 @@ +This directory contains tools that are currently not being used, but are +kept because they may be used again in the future. diff --git a/tests/imfile-basic.sh b/tests/imfile-basic.sh new file mode 100755 index 00000000..ca6a5d3a --- /dev/null +++ b/tests/imfile-basic.sh @@ -0,0 +1,14 @@ +# This is part of the rsyslog testbench, licensed under GPLv3 +echo [imfile-basic.sh] +source $srcdir/diag.sh init +# generate input file first. Note that rsyslog processes it as +# soon as it start up (so the file should exist at that point). +./inputfilegen 50000 > rsyslog.input +ls -l rsyslog.input +source $srcdir/diag.sh startup imfile-basic.conf +# sleep a little to give rsyslog a chance to begin processing +sleep 1 +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown # we need to wait until rsyslogd is finished! +source $srcdir/diag.sh seq-check 0 49999 +source $srcdir/diag.sh exit diff --git a/tests/imptcp_addtlframedelim.sh b/tests/imptcp_addtlframedelim.sh new file mode 100755 index 00000000..b26fc85b --- /dev/null +++ b/tests/imptcp_addtlframedelim.sh @@ -0,0 +1,14 @@ +# added 2010-08-11 by Rgerhards +# +# This file is part of the rsyslog project, released under GPLv3 +echo ==================================================================================== +echo TEST: \[imptcp_addtlframedelim.sh\]: test imptcp additional frame delimiter +cat rsyslog.action.1.include +source $srcdir/diag.sh init +source $srcdir/diag.sh startup imptcp_addtlframedelim.conf +source $srcdir/diag.sh tcpflood -m20000 -F0 -P129 +#sleep 2 # due to large messages, we need this time for the tcp receiver to settle... +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown # and wait for it to terminate +source $srcdir/diag.sh seq-check 0 19999 +source $srcdir/diag.sh exit diff --git a/tests/imptcp_conndrop.sh b/tests/imptcp_conndrop.sh new file mode 100755 index 00000000..684de6b5 --- /dev/null +++ b/tests/imptcp_conndrop.sh @@ -0,0 +1,16 @@ +# Test imptcp with many dropping connections +# added 2010-08-10 by Rgerhards +# +# This file is part of the rsyslog project, released under GPLv3 +echo ==================================================================================== +echo TEST: \[imptcp_conndrop.sh\]: test imptcp with random connection drops +cat rsyslog.action.1.include +source $srcdir/diag.sh init +source $srcdir/diag.sh startup imptcp_large.conf +# 100 byte messages to gain more practical data use +source $srcdir/diag.sh tcpflood -c20 -m50000 -r -d100 -P129 -D +sleep 4 # due to large messages, we need this time for the tcp receiver to settle... +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown # and wait for it to terminate +source $srcdir/diag.sh seq-check 0 49999 -E +source $srcdir/diag.sh exit diff --git a/tests/imptcp_large.sh b/tests/imptcp_large.sh new file mode 100755 index 00000000..b4d130bb --- /dev/null +++ b/tests/imptcp_large.sh @@ -0,0 +1,16 @@ +# Test imptcp with large messages +# added 2010-08-10 by Rgerhards +# +# This file is part of the rsyslog project, released under GPLv3 +echo ==================================================================================== +echo TEST: \[imptcp_large.sh\]: test imptcp with large-size messages +cat rsyslog.action.1.include +source $srcdir/diag.sh init +source $srcdir/diag.sh startup imptcp_large.conf +# send 4000 messages of 10.000bytes plus header max, randomized +source $srcdir/diag.sh tcpflood -c5 -m20000 -r -d10000 -P129 +sleep 2 # due to large messages, we need this time for the tcp receiver to settle... +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown # and wait for it to terminate +source $srcdir/diag.sh seq-check 0 19999 -E +source $srcdir/diag.sh exit diff --git a/tests/imtcp_addtlframedelim.sh b/tests/imtcp_addtlframedelim.sh new file mode 100755 index 00000000..8de7ca58 --- /dev/null +++ b/tests/imtcp_addtlframedelim.sh @@ -0,0 +1,14 @@ +# added 2010-08-11 by Rgerhards +# +# This file is part of the rsyslog project, released under GPLv3 +echo ==================================================================================== +echo TEST: \[imtcp_addtlframedelim.sh\]: test imtcp additional frame delimiter +cat rsyslog.action.1.include +source $srcdir/diag.sh init +source $srcdir/diag.sh startup imtcp_addtlframedelim.conf +source $srcdir/diag.sh tcpflood -m20000 -F0 -P129 +#sleep 2 # due to large messages, we need this time for the tcp receiver to settle... +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown # and wait for it to terminate +source $srcdir/diag.sh seq-check 0 19999 +source $srcdir/diag.sh exit diff --git a/tests/imtcp_conndrop.sh b/tests/imtcp_conndrop.sh new file mode 100755 index 00000000..2caa0ce2 --- /dev/null +++ b/tests/imtcp_conndrop.sh @@ -0,0 +1,16 @@ +# Test imtcp with many dropping connections +# added 2010-08-10 by Rgerhards +# +# This file is part of the rsyslog project, released under GPLv3 +echo ==================================================================================== +echo TEST: \[imtcp_conndrop.sh\]: test imtcp with random connection drops +cat rsyslog.action.1.include +source $srcdir/diag.sh init +source $srcdir/diag.sh startup imptcp_large.conf +# 100 byte messages to gain more practical data use +source $srcdir/diag.sh tcpflood -c20 -m50000 -r -d100 -P129 -D +sleep 4 # due to large messages, we need this time for the tcp receiver to settle... +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown # and wait for it to terminate +source $srcdir/diag.sh seq-check 0 49999 -E +source $srcdir/diag.sh exit diff --git a/tests/inputfilegen.c b/tests/inputfilegen.c new file mode 100644 index 00000000..26fb79af --- /dev/null +++ b/tests/inputfilegen.c @@ -0,0 +1,23 @@ +/* generate an input file suitable for use by the testbench + * Copyright (C) 2011 by Rainer Gerhards and Adiscon GmbH. + * Part of rsyslog, licensed under GPLv3 + */ +#include <stdio.h> +#include <stdlib.h> + +int main(int argc, char* argv[]) +{ + int nmsgs; + int i; + + if(argc != 2) { + fprintf(stderr, "usage: inputfilegen num-messages\n"); + return 1; + } + + nmsgs = atoi(argv[1]); + for(i = 0 ; i < nmsgs ; ++i) { + printf("msgnum:%8.8d:\n", i); + } + return 0; +} diff --git a/tests/manyptcp.sh b/tests/manyptcp.sh new file mode 100755 index 00000000..3ed5493b --- /dev/null +++ b/tests/manyptcp.sh @@ -0,0 +1,13 @@ +# test many concurrent tcp connections +echo ==================================================================================== +echo TEST: \[manyptcp.sh\]: test imptcp with large connection count +source $srcdir/diag.sh init +source $srcdir/diag.sh startup manyptcp.conf +# the config file specifies exactly 1100 connections +source $srcdir/diag.sh tcpflood -c1000 -m40000 +# the sleep below is needed to prevent too-early termination of the tcp listener +sleep 1 +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown # we need to wait until rsyslogd is finished! +source $srcdir/diag.sh seq-check 0 39999 +source $srcdir/diag.sh exit diff --git a/tests/msleep.c b/tests/msleep.c new file mode 100644 index 00000000..36fa01b5 --- /dev/null +++ b/tests/msleep.c @@ -0,0 +1,51 @@ +/* sleeps for the specified number of MILLIseconds. + * Primarily meant as a portable tool available everywhere for the + * testbench (sleep 0.1 does not work on all platforms). + * + * Part of the testbench for rsyslog. + * + * Copyright 2010 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>. + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +int main(int argc, char *argv[]) +{ + struct timeval tvSelectTimeout; + long sleepTime; + + if(argc != 2) { + fprintf(stderr, "usage: msleep <milliseconds>\n"); + exit(1); + } + + sleepTime = atoi(argv[1]); + tvSelectTimeout.tv_sec = sleepTime / 1000; + tvSelectTimeout.tv_usec = (sleepTime % 1000) * 1000; /* micro seconds */ + if(select(0, NULL, NULL, NULL, &tvSelectTimeout) == -1) { + perror("select"); + exit(1); + } + + return 0; +} + diff --git a/tests/nettester.c b/tests/nettester.c index e1ecbcb5..609f586e 100644 --- a/tests/nettester.c +++ b/tests/nettester.c @@ -62,7 +62,7 @@ static char *testSuite = NULL; /* name of current test suite */ static int iPort = 12514; /* port which shall be used for sending data */ static char* pszCustomConf = NULL; /* custom config file, use -c conf to specify */ static int verbose = 0; /* verbose output? -v option */ -static int useDebugEnv = 0; /* activate debugging environment (for rsyslog debug log)? */ +static char **ourEnvp; /* these two are quick hacks... */ int iFailed = 0; @@ -117,6 +117,10 @@ void readLine(int fd, char *ln) * We use traditional framing '\n' at EOR for this tester. It may be * worth considering additional framing modes. * rgerhards, 2009-04-08 + * Note: we re-create the socket within the retry loop, because this + * seems to be needed under Solaris. If we do not do that, we run + * into troubles (maybe something wrongly initialized then?) + * -- rgerhards, 2010-04-12 */ int tcpSend(char *buf, int lenBuf) @@ -124,30 +128,34 @@ tcpSend(char *buf, int lenBuf) static int sock = INVALID_SOCKET; struct sockaddr_in addr; int retries; + int ret; + int iRet = 0; /* 0 OK, anything else error */ if(sock == INVALID_SOCKET) { /* first time, need to connect to target */ - if((sock=socket(AF_INET, SOCK_STREAM, 0))==-1) { - perror("socket()"); - return(1); - } - - memset((char *) &addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(iPort); - if(inet_aton("127.0.0.1", &addr.sin_addr)==0) { - fprintf(stderr, "inet_aton() failed\n"); - return(1); - } retries = 0; while(1) { /* loop broken inside */ - if(connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == 0) { + /* first time, need to connect to target */ + if((sock=socket(AF_INET, SOCK_STREAM, 0))==-1) { + perror("socket()"); + iRet = 1; + goto finalize_it; + } + memset((char *) &addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(iPort); + if(inet_aton("127.0.0.1", &addr.sin_addr)==0) { + fprintf(stderr, "inet_aton() failed\n"); + iRet = 1; + goto finalize_it; + } + if((ret = connect(sock, (struct sockaddr*)&addr, sizeof(addr))) == 0) { break; } else { if(retries++ == 50) { - ++iFailed; fprintf(stderr, "connect() failed\n"); - return(1); + iRet = 1; + goto finalize_it; } else { usleep(100000); /* 0.1 sec, these are us! */ } @@ -156,20 +164,32 @@ tcpSend(char *buf, int lenBuf) } /* send test data */ - if(send(sock, buf, lenBuf, 0) != lenBuf) { + if((ret = send(sock, buf, lenBuf, 0)) != lenBuf) { perror("send test data"); - fprintf(stderr, "send() failed\n"); - return(1); + fprintf(stderr, "send() failed, sock=%d, ret=%d\n", sock, ret); + iRet = 1; + goto finalize_it; } /* send record terminator */ if(send(sock, "\n", 1, 0) != 1) { perror("send record terminator"); fprintf(stderr, "send() failed\n"); - return(1); + iRet = 1; + goto finalize_it; } - return 0; +finalize_it: + if(iRet != 0) { + /* need to do some (common) cleanup */ + if(sock != INVALID_SOCKET) { + close(sock); + sock = INVALID_SOCKET; + } + ++iFailed; + } + + return iRet; } @@ -218,9 +238,6 @@ int openPipe(char *configFile, pid_t *pid, int *pfd) char *newargv[] = {"../tools/rsyslogd", "dummy", "-c4", "-u2", "-n", "-irsyslog.pid", "-M../runtime/.libs:../.libs", NULL }; char confFile[1024]; - char *newenviron[] = { NULL }; - char *newenvironDeb[] = { "RSYSLOG_DEBUG=debug nostdout", - "RSYSLOG_DEBUGLOG=log", NULL }; sprintf(confFile, "-f%s/testsuites/%s.conf", srcdir, (pszCustomConf == NULL) ? configFile : pszCustomConf); @@ -243,8 +260,9 @@ int openPipe(char *configFile, pid_t *pid, int *pfd) close(pipefd[1]); close(pipefd[0]); fclose(stdin); - execve("../tools/rsyslogd", newargv, (useDebugEnv) ? newenvironDeb : newenviron); + execve("../tools/rsyslogd", newargv, ourEnvp); } else { + usleep(10000); close(pipefd[1]); *pid = cpid; *pfd = pipefd[0]; @@ -364,11 +382,12 @@ processTestFile(int fd, char *pszFileName) expected[strlen(expected)-1] = '\0'; /* remove \n */ /* pull response from server and then check if it meets our expectation */ +//printf("try pull pipe...\n"); readLine(fd, buf); if(strcmp(expected, buf)) { ++iFailed; - printf("\nExpected Response:\n'%s'\nActual Response:\n'%s'\n", - expected, buf); + printf("\nFile %s:\nExpected Response:\n'%s'\nActual Response:\n'%s'\n", + pszFileName, expected, buf); ret = 1; } /* we need to free buffers, as we have potentially modified them! */ @@ -426,7 +445,8 @@ doTests(int fd, char *files) printf("Error: no test cases found, no tests executed.\n"); iFailed = 1; } else { - printf("Number of tests run: %d, number of failures: %d\n", iTests, iFailed); + printf("Number of tests run: %3d, number of failures: %d, test: %s/%s\n", + iTests, iFailed, testSuite, inputMode2Str(inputMode)); } return(iFailed); @@ -450,7 +470,7 @@ void doAtExit(void) * of this file. * rgerhards, 2009-04-03 */ -int main(int argc, char *argv[]) +int main(int argc, char *argv[], char *envp[]) { int fd; int opt; @@ -459,14 +479,12 @@ int main(int argc, char *argv[]) char buf[4096]; char testcases[4096]; + ourEnvp = envp; while((opt = getopt(argc, argv, "dc:i:p:t:v")) != EOF) { switch((char)opt) { case 'c': pszCustomConf = optarg; break; - case 'd': - useDebugEnv = 1; - break; case 'i': if(!strcmp(optarg, "udp")) inputMode = inputUDP; @@ -520,6 +538,11 @@ int main(int argc, char *argv[]) } fclose(fp); + /* make sure we do not abort if there is an issue with pipes. + * our code does the necessary error handling. + */ + sigset(SIGPIPE, SIG_IGN); + /* start to be tested rsyslogd */ openPipe(testSuite, &rsyslogdPid, &fd); readLine(fd, buf); diff --git a/tests/random.sh b/tests/random.sh new file mode 100755 index 00000000..969d720c --- /dev/null +++ b/tests/random.sh @@ -0,0 +1,18 @@ +# Test if rsyslog survives sending truely random data to it... +# +# added 2010-04-01 by Rgerhards +# This file is part of the rsyslog project, released under GPLv3 +echo =============================================================================== +echo TEST: \[random.sh\]: testing random data +source $srcdir/diag.sh init +source $srcdir/diag.sh startup random.conf +# generate random data +./randomgen -f rsyslog.random.data -s 100000 +ls -l rsyslog.random.data +source $srcdir/diag.sh tcpflood -B -I rsyslog.random.data -c5 -C10 +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown # and wait for it to terminate +# we do not check anything yet, the point is if rsyslog survived ;) +# TODO: check for exit message, but we'll notice an abort anyhow, so not that important +rm -f random.data +source $srcdir/diag.sh exit diff --git a/tests/randomgen.c b/tests/randomgen.c new file mode 100644 index 00000000..9ba56954 --- /dev/null +++ b/tests/randomgen.c @@ -0,0 +1,130 @@ +/* generates random data for later use in test cases. Of course, + * we could generate random data during the testcase itself, but + * the core idea is that we record the random data so that we have + * a chance to reproduce a problem should it occur. IMHO this + * provides the best compromise, by a) having randomness but + * b) knowing what was used during the test. + * + * Params + * -f output file name (stdout if not given) + * -s size of test data, plain number is size in k, 1MB default + * -u uses /dev/urandom instead of libc random number generator + * (when available). Note that this is usually much slower. + * + * Part of the testbench for rsyslog. + * + * Copyright 2010 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>. + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <assert.h> +#include <unistd.h> +#include <string.h> +#include <netinet/in.h> + +#define EXIT_FAILURE 1 + +static char *fileName = NULL; /* name of output file */ +static int tryUseURandom = 0; /* try to use /dev/urandom? */ +static long long fileSize = 1024*1024; /* file size in K, 1MB default */ + + +/* generate the random file. This code really can be improved (e.g. read /dev/urandom + * when available) + */ +static inline void +genFile() +{ + long i; + FILE *fp; + FILE *rfp = NULL; + + if(fileName == NULL) { + fp = stdout; + } else { + if((fp = fopen(fileName, "w")) == NULL) { + perror(fileName); + } + } + + /* try to use /dev/urandom, if available */ + if(tryUseURandom) + rfp = fopen("/dev/urandom", "r"); + + if(rfp == NULL) { + /* fallback, use libc random number generator */ + for(i = 0 ; i < fileSize ; ++i) { + if(fputc((char) rand(), fp) == EOF) { + perror(fileName); + exit(1); + } + } + } else { + /* use /dev/urandom */ + printf("using /dev/urandom"); + for(i = 0 ; i < fileSize ; ++i) { + if(fputc(fgetc(rfp), fp) == EOF) { + perror(fileName); + exit(1); + } + } + } + + if(fileName != NULL) + fclose(fp); +} + + +/* Run the test. + * rgerhards, 2009-04-03 + */ +int main(int argc, char *argv[]) +{ + int ret = 0; + int opt; + + srand(time(NULL)); /* seed is good enough for our needs */ + + while((opt = getopt(argc, argv, "f:s:u")) != -1) { + switch (opt) { + case 'f': fileName = optarg; + break; + case 's': fileSize = atol(optarg) * 1024; + break; + case 'u': tryUseURandom = 1; + break; + default: printf("invalid option '%c' or value missing - terminating...\n", opt); + exit (1); + break; + } + } + + printf("generating random data file '%s' of %ldkb - may take a short while...\n", + fileName, (long) (fileSize / 1024)); + genFile(); + + exit(ret); +} diff --git a/tests/rsf_getenv.sh b/tests/rsf_getenv.sh new file mode 100755 index 00000000..fd083bce --- /dev/null +++ b/tests/rsf_getenv.sh @@ -0,0 +1,17 @@ +# Test for the getenv() rainerscript function +# this is a quick test, but it gurantees that the code path is +# at least progressed (but we do not check for unset envvars!) +# added 2009-11-03 by Rgerhards +# This file is part of the rsyslog project, released under GPLv3 +# uncomment for debugging support: +echo =============================================================================== +echo \[rsf_getenv.sh\]: testing RainerScript getenv\(\) function +export MSGNUM="msgnum:" +source $srcdir/diag.sh init +source $srcdir/diag.sh startup rsf_getenv.conf +source $srcdir/diag.sh tcpflood -m10000 +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown +source $srcdir/diag.sh seq-check 0 9999 +unset MSGNUM +source $srcdir/diag.sh exit diff --git a/tests/rt-init.c b/tests/rt-init.c index 66a9ad32..dbe94b4a 100644 --- a/tests/rt-init.c +++ b/tests/rt-init.c @@ -39,6 +39,6 @@ ENDExit BEGINTest CODESTARTTest -finalize_it: +/*finalize_it:*/ /* room for custom error reporter, leave blank if not needed */ ENDTest diff --git a/tests/tcpflood.c b/tests/tcpflood.c index 32bf959d..c34f87c9 100644 --- a/tests/tcpflood.c +++ b/tests/tcpflood.c @@ -20,6 +20,17 @@ * one field to the right. Zero (default) disables this functionality. * -M the message to be sent. Disables all message format options, as * only that exact same message is sent. + * -I read specified input file, do NOT generate own test data. The test + * completes when eof is reached. + * -B The specified file (-I) is binary. No data processing is done by + * tcpflood. If multiple connections are specified, data is read in + * chunks and spread across the connections without taking any record + * delemiters into account. + * -C when input from a file is read, this file is transmitted -C times + * (C like cycle, running out of meaningful option switches ;)) + * -D randomly drop and re-establish connections. Useful for stress-testing + * the TCP receiver. + * -F USASCII value for frame delimiter (in octet-stuffing mode), default LF * * Part of the testbench for rsyslog. * @@ -54,6 +65,7 @@ #include <unistd.h> #include <string.h> #include <netinet/in.h> +#include <sys/resource.h> #define EXIT_FAILURE 1 #define INVALID_SOCKET -1 @@ -74,7 +86,14 @@ static int numConnections = 1; /* number of connections to create */ static int *sockArray; /* array of sockets to use */ static int msgNum = 0; /* initial message number to start with */ static int bShowProgress = 1; /* show progress messages */ +static int bRandConnDrop = 0; /* randomly drop connections? */ static char *MsgToSend = NULL; /* if non-null, this is the actual message to send */ +static int bBinaryFile = 0; /* is -I file binary */ +static char *dataFile = NULL; /* name of data file, if NULL, generate own data */ +static int numFileIterations = 1;/* how often is file data to be sent? */ +static char frameDelim = '\n'; /* default frame delimiter */ +FILE *dataFP = NULL; /* file pointer for data file, if used */ +static long nConnDrops = 0; /* counter: number of time connection was dropped (-D option) */ /* open a single tcp connection @@ -141,8 +160,6 @@ int openConnections(void) if(i % 10 == 0) { if(bShowProgress) printf("\r%5.5d", i); - //lenMsg = sprintf(msgBuf, "\r%5.5d", i); - //write(1, msgBuf, lenMsg); } if(openConn(&(sockArray[i])) != 0) { printf("error in trying to open connection i=%d\n", i); @@ -166,8 +183,9 @@ int openConnections(void) void closeConnections(void) { int i; - char msgBuf[128]; size_t lenMsg; + struct linger ling; + char msgBuf[128]; if(bShowProgress) write(1, " close connections", sizeof(" close connections")-1); @@ -178,7 +196,15 @@ void closeConnections(void) write(1, msgBuf, lenMsg); } } - close(sockArray[i]); + if(sockArray[i] != -1) { + /* we try to not overrun the receiver by trying to flush buffers + * *during* close(). -- rgerhards, 2010-08-10 + */ + ling.l_onoff = 1; + ling.l_linger = 1; + setsockopt(sockArray[i], SOL_SOCKET, SO_LINGER, &ling, sizeof(ling)); + close(sockArray[i]); + } } lenMsg = sprintf(msgBuf, "\r%5.5d close connections\n", i); write(1, msgBuf, lenMsg); @@ -186,6 +212,62 @@ void closeConnections(void) } +/* generate the message to be sent according to program command line parameters. + * this has been moved to its own function as we now have various different ways + * of constructing test messages. -- rgerhards, 2010-03-31 + */ +static inline void +genMsg(char *buf, size_t maxBuf, int *pLenBuf) +{ + int edLen; /* actual extra data length to use */ + char extraData[MAX_EXTRADATA_LEN + 1]; + char dynFileIDBuf[128] = ""; + static int numMsgsGen = 0; + int done; + + if(dataFP != NULL) { + /* get message from file */ + do { + done = 1; + *pLenBuf = fread(buf, 1, 1024, dataFP); + if(feof(dataFP)) { + if(--numFileIterations > 0) { + rewind(dataFP); + done = 0; /* need new iteration */ + } else { + *pLenBuf = 0; + goto finalize_it; + } + } + } while(!done); /* Attention: do..while()! */ + } else if(MsgToSend == NULL) { + if(dynFileIDs > 0) { + snprintf(dynFileIDBuf, maxBuf, "%d:", rand() % dynFileIDs); + } + if(extraDataLen == 0) { + *pLenBuf = snprintf(buf, maxBuf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:%c", + msgPRI, dynFileIDBuf, msgNum, frameDelim); + } else { + if(bRandomizeExtraData) + edLen = ((long) rand() + extraDataLen) % extraDataLen + 1; + else + edLen = extraDataLen; + memset(extraData, 'X', edLen); + extraData[edLen] = '\0'; + *pLenBuf = snprintf(buf, maxBuf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:%d:%s%c", + msgPRI, dynFileIDBuf, msgNum, edLen, extraData, frameDelim); + } + } else { + /* use fixed message format from command line */ + *pLenBuf = snprintf(buf, maxBuf, "%s\n", MsgToSend); + } + + if(numMsgsGen++ >= numMsgsToSend) + *pLenBuf = 0; /* indicate end of run */ + +finalize_it: ; +} + /* send messages to the tcp connections we keep open. We use * a very basic format that helps identify the message * (via msgnum:<number>: e.g. msgnum:00000001:). This format is suitable @@ -196,52 +278,48 @@ void closeConnections(void) */ int sendMessages(void) { - int i; + int i = 0; int socknum; int lenBuf; int lenSend; - int edLen; /* actual extra data length to use */ - char dynFileIDBuf[128] = ""; + char *statusText; char buf[MAX_EXTRADATA_LEN + 1024]; - char extraData[MAX_EXTRADATA_LEN + 1]; - printf("Sending %d messages.\n", numMsgsToSend); + if(dataFile == NULL) { + printf("Sending %d messages.\n", numMsgsToSend); + statusText = "messages"; + } else { + printf("Sending file '%s' %d times.\n", dataFile, numFileIterations); + statusText = "kb"; + } if(bShowProgress) - printf("\r%8.8d messages sent", 0); - for(i = 0 ; i < numMsgsToSend ; ++i) { + printf("\r%8.8d %s sent", 0, statusText); + while(1) { /* broken inside loop! */ if(i < numConnections) socknum = i; else if(i >= numMsgsToSend - numConnections) socknum = i - (numMsgsToSend - numConnections); - else - socknum = rand() % numConnections; - if(MsgToSend == NULL) { - if(dynFileIDs > 0) { - sprintf(dynFileIDBuf, "%d:", rand() % dynFileIDs); - } - if(extraDataLen == 0) { - lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:\n", - msgPRI, dynFileIDBuf, msgNum); - } else { - if(bRandomizeExtraData) - edLen = ((long) rand() + extraDataLen) % extraDataLen + 1; - else - edLen = extraDataLen; - memset(extraData, 'X', edLen); - extraData[edLen] = '\0'; - lenBuf = sprintf(buf, "<%s>Mar 1 01:00:00 172.20.245.8 tag msgnum:%s%8.8d:%d:%s\n", - msgPRI, dynFileIDBuf, msgNum, edLen, extraData); + else { + int rnd = rand(); + socknum = rnd % numConnections; + } + genMsg(buf, sizeof(buf), &lenBuf); /* generate the message to send according to params */ + if(lenBuf == 0) + break; /* end of processing! */ + if(sockArray[socknum] == -1) { + /* connection was dropped, need to re-establish */ + if(openConn(&(sockArray[socknum])) != 0) { + printf("error in trying to re-open connection %d\n", socknum); + exit(1); } - } else { - /* use fixed message format from command line */ - lenBuf = sprintf(buf, "%s\n", MsgToSend); } lenSend = send(sockArray[socknum], buf, lenBuf, 0); if(lenSend != lenBuf) { printf("\r%5.5d\n", i); fflush(stdout); perror("send test data"); - printf("send() failed at socket %d, index %d, msgNum %d\n", socknum, i, msgNum); + printf("send() failed at socket %d, index %d, msgNum %d\n", + sockArray[socknum], i, msgNum); fflush(stderr); return(1); } @@ -249,62 +327,20 @@ int sendMessages(void) if(bShowProgress) printf("\r%8.8d", i); } - ++msgNum; - } - printf("\r%8.8d messages sent\n", i); - - return 0; -} - - -/* send a message via TCP - * We open the connection on the initial send, and never close it - * (let the OS do that). If a conneciton breaks, we do NOT try to - * recover, so all test after that one will fail (and the test - * driver probably hang. returns 0 if ok, something else otherwise. - * We use traditional framing '\n' at EOR for this tester. It may be - * worth considering additional framing modes. - * rgerhards, 2009-04-08 - */ -int -tcpSend(char *buf, int lenBuf) -{ - static int sock = INVALID_SOCKET; - struct sockaddr_in addr; - - if(sock == INVALID_SOCKET) { - /* first time, need to connect to target */ - if((sock=socket(AF_INET, SOCK_STREAM, 0))==-1) { - perror("socket()"); - return(1); - } - - memset((char *) &addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(13514); - if(inet_aton("127.0.0.1", &addr.sin_addr)==0) { - fprintf(stderr, "inet_aton() failed\n"); - return(1); - } - if(connect(sock, (struct sockaddr*)&addr, sizeof(addr)) != 0) { - fprintf(stderr, "connect() failed\n"); - return(1); + if(bRandConnDrop) { + /* if we need to randomly drop connections, see if we + * are a victim + */ + if(rand() > (int) (RAND_MAX * 0.95)) { + ++nConnDrops; + close(sockArray[socknum]); + sockArray[socknum] = -1; + } } + ++msgNum; + ++i; } - - /* send test data */ - if(send(sock, buf, lenBuf, 0) != lenBuf) { - perror("send test data"); - fprintf(stderr, "send() failed\n"); - return(1); - } - - /* send record terminator */ - if(send(sock, "\n", 1, 0) != 1) { - perror("send record terminator"); - fprintf(stderr, "send() failed\n"); - return(1); - } + printf("\r%8.8d %s sent\n", i, statusText); return 0; } @@ -318,6 +354,7 @@ int main(int argc, char *argv[]) int ret = 0; int opt; struct sigaction sigAct; + struct rlimit maxFiles; static char buf[1024]; srand(time(NULL)); /* seed is good enough for our needs */ @@ -335,7 +372,7 @@ int main(int argc, char *argv[]) if(!isatty(1)) bShowProgress = 0; - while((opt = getopt(argc, argv, "f:t:p:c:m:i:P:d:n:M:r")) != -1) { + while((opt = getopt(argc, argv, "f:F:t:p:c:C:m:i:I:P:d:Dn:M:rB")) != -1) { switch (opt) { case 't': targetIP = optarg; break; @@ -345,6 +382,8 @@ int main(int argc, char *argv[]) break; case 'c': numConnections = atoi(optarg); break; + case 'C': numFileIterations = atoi(optarg); + break; case 'm': numMsgsToSend = atoi(optarg); break; case 'i': msgNum = atoi(optarg); @@ -358,18 +397,54 @@ int main(int argc, char *argv[]) exit(1); } break; + case 'D': bRandConnDrop = 1; + break; case 'r': bRandomizeExtraData = 1; break; case 'f': dynFileIDs = atoi(optarg); break; + case 'F': frameDelim = atoi(optarg); + break; case 'M': MsgToSend = optarg; break; + case 'I': dataFile = optarg; + /* in this mode, we do not know the num messages to send, so + * we set a (high) number to keep the code happy. + */ + numMsgsToSend = 1000000; + break; + case 'B': bBinaryFile = 1; + break; default: printf("invalid option '%c' or value missing - terminating...\n", opt); exit (1); break; } } + if(numConnections > 20) { + /* if we use many (whatever this means, 20 is randomly picked) + * connections, we need to make sure we have a high enough + * limit. -- rgerhards, 2010-03-25 + */ + struct rlimit maxFiles; + maxFiles.rlim_cur = numConnections + 20; + maxFiles.rlim_max = numConnections + 20; + if(setrlimit(RLIMIT_NOFILE, &maxFiles) < 0) { + perror("setrlimit to increase file handles failed"); + fprintf(stderr, + "could net set sufficiently large number of " + "open files for required connection count!\n"); + exit(1); + } + } + + if(dataFile != NULL) { + if((dataFP = fopen(dataFile, "r")) == NULL) { + perror(dataFile); + exit(1); + } + } + if(openConnections() != 0) { printf("error opening connections\n"); exit(1); @@ -380,7 +455,10 @@ int main(int argc, char *argv[]) exit(1); } + if(nConnDrops > 0) + printf("-D option initiated %ld connection closures\n", nConnDrops); printf("End of tcpflood Run\n"); + closeConnections(); /* this is important so that we do not finish too early! */ exit(ret); } diff --git a/tests/testsuites/imfile-basic.conf b/tests/testsuites/imfile-basic.conf new file mode 100644 index 00000000..9fb9b5ca --- /dev/null +++ b/tests/testsuites/imfile-basic.conf @@ -0,0 +1,12 @@ +$IncludeConfig diag-common.conf + +$ModLoad ../plugins/imfile/.libs/imfile +$InputFileName ./rsyslog.input +$InputFileTag file: +$InputFileStateFile stat-file1 +$InputFileSeverity error +$InputFileFacility local7 +$InputRunFileMonitor + +$template outfmt,"%msg:F,58:2%\n" +:msg, contains, "msgnum:" ./rsyslog.out.log;outfmt diff --git a/tests/testsuites/imptcp_addtlframedelim.conf b/tests/testsuites/imptcp_addtlframedelim.conf new file mode 100644 index 00000000..eb7ed0c4 --- /dev/null +++ b/tests/testsuites/imptcp_addtlframedelim.conf @@ -0,0 +1,13 @@ +$IncludeConfig diag-common.conf + +$ModLoad ../plugins/imptcp/.libs/imptcp +$MainMsgQueueTimeoutShutdown 10000 +$InputPTCPServerAddtlFrameDelimiter 0 +$InputPTCPServerRun 13514 + +$template outfmt,"%msg:F,58:2%\n" +$OMFileFlushOnTXEnd off +$OMFileFlushInterval 2 +$OMFileIOBufferSize 256k +$IncludeConfig rsyslog.action.1.include +local0.* ./rsyslog.out.log;outfmt diff --git a/tests/testsuites/imptcp_conndrop.conf b/tests/testsuites/imptcp_conndrop.conf new file mode 100644 index 00000000..677e33f6 --- /dev/null +++ b/tests/testsuites/imptcp_conndrop.conf @@ -0,0 +1,16 @@ +# simple async writing test +# rgerhards, 2010-03-09 +$MaxMessageSize 10k +$IncludeConfig diag-common.conf + +$ModLoad ../plugins/imptcp/.libs/imptcp +$MainMsgQueueTimeoutShutdown 10000 +$InputPTCPServerRun 13514 + +$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n" +$template dynfile,"rsyslog.out.log" # trick to use relative path names! +$OMFileFlushOnTXEnd off +$OMFileFlushInterval 2 +$OMFileIOBufferSize 256k +$IncludeConfig rsyslog.action.1.include +local0.* ?dynfile;outfmt diff --git a/tests/testsuites/imptcp_large.conf b/tests/testsuites/imptcp_large.conf new file mode 100644 index 00000000..677e33f6 --- /dev/null +++ b/tests/testsuites/imptcp_large.conf @@ -0,0 +1,16 @@ +# simple async writing test +# rgerhards, 2010-03-09 +$MaxMessageSize 10k +$IncludeConfig diag-common.conf + +$ModLoad ../plugins/imptcp/.libs/imptcp +$MainMsgQueueTimeoutShutdown 10000 +$InputPTCPServerRun 13514 + +$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n" +$template dynfile,"rsyslog.out.log" # trick to use relative path names! +$OMFileFlushOnTXEnd off +$OMFileFlushInterval 2 +$OMFileIOBufferSize 256k +$IncludeConfig rsyslog.action.1.include +local0.* ?dynfile;outfmt diff --git a/tests/testsuites/imtcp_addtlframedelim.conf b/tests/testsuites/imtcp_addtlframedelim.conf new file mode 100644 index 00000000..3b4759c5 --- /dev/null +++ b/tests/testsuites/imtcp_addtlframedelim.conf @@ -0,0 +1,13 @@ +$IncludeConfig diag-common.conf + +$ModLoad ../plugins/imtcp/.libs/imtcp +$MainMsgQueueTimeoutShutdown 10000 +$InputTCPServerAddtlFrameDelimiter 0 +$InputTCPServerRun 13514 + +$template outfmt,"%msg:F,58:2%\n" +$OMFileFlushOnTXEnd off +$OMFileFlushInterval 2 +$OMFileIOBufferSize 256k +$IncludeConfig rsyslog.action.1.include +local0.* ./rsyslog.out.log;outfmt diff --git a/tests/testsuites/imtcp_conndrop.conf b/tests/testsuites/imtcp_conndrop.conf new file mode 100644 index 00000000..b64f132b --- /dev/null +++ b/tests/testsuites/imtcp_conndrop.conf @@ -0,0 +1,16 @@ +# simple async writing test +# rgerhards, 2010-03-09 +$MaxMessageSize 10k +$IncludeConfig diag-common.conf + +$ModLoad ../plugins/imtcp/.libs/imtcp +$MainMsgQueueTimeoutShutdown 10000 +$InputTCPServerRun 13514 + +$template outfmt,"%msg:F,58:2%,%msg:F,58:3%,%msg:F,58:4%\n" +$template dynfile,"rsyslog.out.log" # trick to use relative path names! +$OMFileFlushOnTXEnd off +$OMFileFlushInterval 2 +$OMFileIOBufferSize 256k +$IncludeConfig rsyslog.action.1.include +local0.* ?dynfile;outfmt diff --git a/tests/testsuites/manyptcp.conf b/tests/testsuites/manyptcp.conf new file mode 100644 index 00000000..4069f977 --- /dev/null +++ b/tests/testsuites/manyptcp.conf @@ -0,0 +1,12 @@ +# Test for tcp "flood" testing +# rgerhards, 2009-04-08 +$IncludeConfig diag-common.conf + +$ModLoad ../plugins/imptcp/.libs/imptcp +$MainMsgQueueTimeoutShutdown 10000 +$MaxOpenFiles 2000 +$InputPTCPServerRun 13514 + +$template outfmt,"%msg:F,58:2%\n" +$template dynfile,"rsyslog.out.log" # trick to use relative path names! +:msg, contains, "msgnum:" ?dynfile;outfmt diff --git a/tests/testsuites/parse1.conf b/tests/testsuites/parse1.conf index 947a05a8..094cd762 100644 --- a/tests/testsuites/parse1.conf +++ b/tests/testsuites/parse1.conf @@ -2,6 +2,7 @@ $ModLoad ../plugins/omstdout/.libs/omstdout $IncludeConfig nettest.input.conf # This picks the to be tested input from the test driver! $ErrorMessagesToStderr off +$LocalHostName localhost # use a special format that we can easily parse in expect $template expect,"%PRI%,%syslogfacility-text%,%syslogseverity-text%,%timestamp%,%hostname%,%programname%,%syslogtag%,%msg%\n" diff --git a/tests/testsuites/parse3.conf b/tests/testsuites/parse3.conf index d5cf77d9..8a3cb317 100644 --- a/tests/testsuites/parse3.conf +++ b/tests/testsuites/parse3.conf @@ -1,8 +1,10 @@ +# note: we need to strip off the TZ designator in the rfc3339 timestamp +# as this test otherwise fails in different timezones! $ModLoad ../plugins/omstdout/.libs/omstdout $IncludeConfig nettest.input.conf # This picks the to be tested input from the test driver! $ErrorMessagesToStderr off # use a special format that we can easily parse in expect -$Template output,"%timereported:1:$:date-rfc3339,csv%, %hostname:::csv%, %programname:::csv%, %syslogtag:R,ERE,0,BLANK:[0-9]+--end:csv%, %syslogseverity:::csv%, %msg:::drop-last-lf,csv%\n" +$Template output,"%timereported:1:19:date-rfc3339,csv%, %hostname:::csv%, %programname:::csv%, %syslogtag:R,ERE,0,BLANK:[0-9]+--end:csv%, %syslogseverity:::csv%, %msg:::drop-last-lf,csv%\n" *.* :omstdout:;output diff --git a/tests/testsuites/parse_invld_regex.conf b/tests/testsuites/parse_invld_regex.conf index 736aae59..d18a2b3c 100644 --- a/tests/testsuites/parse_invld_regex.conf +++ b/tests/testsuites/parse_invld_regex.conf @@ -1,8 +1,10 @@ +# note: we need to strip off the TZ designator in the rfc3339 timestamp +# as this test otherwise fails in different timezones! $ModLoad ../plugins/omstdout/.libs/omstdout $IncludeConfig nettest.input.conf # This picks the to be tested input from the test driver! $ErrorMessagesToStderr off # use a special format that we can easily parse in expect -$Template output,"%timereported:1:$:date-rfc3339,csv%, %hostname:::csv%, %programname:::csv%, %syslogtag:R,ERE,0,BLANK:[0-9+--end:csv%, %syslogseverity:::csv%, %msg:::drop-last-lf,csv%\n" +$Template output,"%timereported:1:19:date-rfc3339,csv%, %hostname:::csv%, %programname:::csv%, %syslogtag:R,ERE,0,BLANK:[0-9+--end:csv%, %syslogseverity:::csv%, %msg:::drop-last-lf,csv%\n" *.* :omstdout:;output diff --git a/tests/testsuites/random.conf b/tests/testsuites/random.conf new file mode 100644 index 00000000..a7079df1 --- /dev/null +++ b/tests/testsuites/random.conf @@ -0,0 +1,13 @@ +# we write to /dev/null, as we have no chance to verify the output +# in any case. What we really check is that rsyslogd does not +# segfault or otherwise abort. +# rgerhards, 2010-04-01 +$IncludeConfig diag-common.conf + +$ModLoad ../plugins/imtcp/.libs/imtcp +$MainMsgQueueTimeoutShutdown 10000 +$InputTCPServerRun 13514 + +$template outfmt,"%rawmsg%\n" +$template dynfile,"rsyslog.out.log" # trick to use relative path names! +*.* /dev/null diff --git a/tests/testsuites/reallife.parse3 b/tests/testsuites/reallife.parse3 index 465635bd..dad3f56e 100644 --- a/tests/testsuites/reallife.parse3 +++ b/tests/testsuites/reallife.parse3 @@ -9,7 +9,7 @@ # documentation by IANA. # rgerhards, 2009-10-19 <175>Oct 16 2009 23:47:31 hostname tag This is a message -"2009-10-16T23:47:31+01:00", "hostname", "tag", "", "7", " This is a message" +"2009-10-16T23:47:31", "hostname", "tag", "", "7", " This is a message" # <175>Oct 16 2009 23:47:31 hostname tag[1234] This is a message -"2009-10-16T23:47:31+01:00", "hostname", "tag", "1234", "7", " This is a message" +"2009-10-16T23:47:31", "hostname", "tag", "1234", "7", " This is a message" diff --git a/tests/testsuites/rsf_getenv.conf b/tests/testsuites/rsf_getenv.conf new file mode 100644 index 00000000..2f2eb58c --- /dev/null +++ b/tests/testsuites/rsf_getenv.conf @@ -0,0 +1,17 @@ +# Test for RainerScript getenv() function (see .sh file for details) +# Note envvar MSGNUM must be set to "msgnum:" +# rgerhards, 2009-11-03 +$IncludeConfig diag-common.conf + +$ModLoad ../plugins/imtcp/.libs/imtcp +$MainMsgQueueTimeoutShutdown 10000 +$InputTCPServerRun 13514 + +# set spool locations and switch queue to disk-only mode +$WorkDirectory test-spool +$MainMsgQueueFilename mainq +$MainMsgQueueType disk + +$template outfmt,"%msg:F,58:2%\n" +$template dynfile,"rsyslog.out.log" # trick to use relative path names! +if $msg contains getenv('MSGNUM') then ?dynfile;outfmt diff --git a/tests/testsuites/samples.parse-nodate b/tests/testsuites/samples.parse-nodate index 7f16181c..5432bcac 100644 --- a/tests/testsuites/samples.parse-nodate +++ b/tests/testsuites/samples.parse-nodate @@ -1,5 +1,5 @@ <27>xapi: [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (supressing future logging of this message) -27,daemon,err,localhost,xapi,xapi:, [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (supressing future logging of this message) +27,daemon,err,localhost.localdomain,xapi,xapi:, [error|xen3|15|Guest liveness monitor D:bca30ab3f1c1|master_connection] Connection to master died. I will continue to retry indefinitely (supressing future logging of this message) # a message with just text (as permitted by rfc 3164) # it is questionable if the current sample result is really correct as of 3164! This is a message! diff --git a/tests/testsuites/samples.parse_invld_regex b/tests/testsuites/samples.parse_invld_regex index 9ac2c3aa..0d0e4ce3 100644 --- a/tests/testsuites/samples.parse_invld_regex +++ b/tests/testsuites/samples.parse_invld_regex @@ -13,4 +13,4 @@ # configured format. # rgerhards, 2010-02-08 <175>Feb 08 2008 23:47:31 hostname tag This is a message -"2008-02-08T23:47:31+01:00", "hostname", "tag", **NO MATCH** **BAD REGULAR EXPRESSION**, "7", " This is a message" +"2008-02-08T23:47:31", "hostname", "tag", **NO MATCH** **BAD REGULAR EXPRESSION**, "7", " This is a message" diff --git a/tests/testsuites/samples.snare_ccoff_udp b/tests/testsuites/samples.snare_ccoff_udp index 010e44d5..1ae7e8b4 100644 --- a/tests/testsuites/samples.snare_ccoff_udp +++ b/tests/testsuites/samples.snare_ccoff_udp @@ -3,7 +3,7 @@ # *real* cases (just mangled to anonymize them...) # Sample 1 - note the absence of PRI! windowsserver MSWinEventLog 1 Security 1167 Fri Mar 19 15:33:30 2010 540 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Successful Network Logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Logon Type: 3 Logon Process: Kerberos Authentication Package: Kerberos Workstation Name: Logon GUID: {79b6eb79-7bcc-8a2e-7dad-953c51dc00fd} Caller User Name: - Caller Domain: - Caller Logon ID: - Caller Process ID: - Transited Services: - Source Network Address: 10.11.11.3 Source Port: 3306 733\n -13,user,notice,localhost,windowsserver,windowsserver MSWinEventLog 1 Security 1167 Fri, Mar 19 15:33:30 2010 540 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Successful Network Logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Logon Type: 3 Logon Process: Kerberos Authentication Package: Kerberos Workstation Name: Logon GUID: {79b6eb79-7bcc-8a2e-7dad-953c51dc00fd} Caller User Name: - Caller Domain: - Caller Logon ID: - Caller Process ID: - Transited Services: - Source Network Address: 10.11.11.3 Source Port: 3306 733 +13,user,notice,localhost.localdomain,windowsserver,windowsserver MSWinEventLog 1 Security 1167 Fri, Mar 19 15:33:30 2010 540 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Successful Network Logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Logon Type: 3 Logon Process: Kerberos Authentication Package: Kerberos Workstation Name: Logon GUID: {79b6eb79-7bcc-8a2e-7dad-953c51dc00fd} Caller User Name: - Caller Domain: - Caller Logon ID: - Caller Process ID: - Transited Services: - Source Network Address: 10.11.11.3 Source Port: 3306 733 # Sample 2 # the samples below need to be disabled for the "workaround patch" for the message # parser to work. They need to be re-enabled once a final solution has been crafted diff --git a/tests/testsuites/samples.snare_ccoff_udp2 b/tests/testsuites/samples.snare_ccoff_udp2 index 7837b820..da3a2b14 100644 --- a/tests/testsuites/samples.snare_ccoff_udp2 +++ b/tests/testsuites/samples.snare_ccoff_udp2 @@ -9,14 +9,18 @@ # to be adapted. We do NOT try to preserve misbehaviour on such seriously malformed # messages. # +# this is a very simple test, though not snare-based +test +insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values ('', 1, 'test',5, '20100321185328', '20100321185328', 1, '') +# and yet another one we have seen in practice +UX=Abcd-efg-hij-klmno; XXXXX=1111111111, Z123=192.12.231.245:11111, S1234=123456789, XXXXXX=111111111 +insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (' XXXXX=1111111111, Z123=192.12.231.245:11111, S1234=123456789, XXXXXX=111111111', 1, 'localhost.localdomain',5, '20100321185328', '20100321185328', 1, 'UX=Abcd-efg-hij-klmno;') # Sample 1 - note the absence of PRI! windowsserver MSWinEventLog 1 Security 1167 Fri Mar 19 15:33:30 2010 540 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Successful Network Logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Logon Type: 3 Logon Process: Kerberos Authentication Package: Kerberos Workstation Name: Logon GUID: {79b6eb79-7bcc-8a2e-7dad-953c51dc00fd} Caller User Name: - Caller Domain: - Caller Logon ID: - Caller Process ID: - Transited Services: - Source Network Address: 10.11.11.3 Source Port: 3306 733\n -insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (' Mar 19 15:33:30 2010 540 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Successful Network Logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Logon Type: 3 Logon Process: Kerberos Authentication Package: Kerberos Workstation Name: Logon GUID: {79b6eb79-7bcc-8a2e-7dad-953c51dc00fd} Caller User Name: - Caller Domain: - Caller Logon ID: - Caller Process ID: - Transited Services: - Source Network Address: 10.11.11.3 Source Port: 3306 733 ', 1, 'localhost',5, '20100321185328', '20100321185328', 1, 'windowsserver MSWinEventLog 1 Security 1167 Fri') +insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (' Mar 19 15:33:30 2010 540 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Successful Network Logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Logon Type: 3 Logon Process: Kerberos Authentication Package: Kerberos Workstation Name: Logon GUID: {79b6eb79-7bcc-8a2e-7dad-953c51dc00fd} Caller User Name: - Caller Domain: - Caller Logon ID: - Caller Process ID: - Transited Services: - Source Network Address: 10.11.11.3 Source Port: 3306 733', 1, 'localhost.localdomain',5, '20100321185328', '20100321185328', 1, 'windowsserver MSWinEventLog 1 Security 1167 Fri') # Sample 2 -# the samples below need to be disabled for the "workaround patch" for the message -# parser to work. They need to be re-enabled once a final solution has been crafted -#windowsserver MSWinEventLog 1 Security 1166 Fri Mar 19 15:33:30 2010 576 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Special privileges assigned to new logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Privileges: SeSecurityPrivilege SeBackupPrivilege SeRestorePrivilege SeTakeOwnershipPrivilege SeDebugPrivilege SeSystemEnvironmentPrivilege SeLoadDriverPrivilege SeImpersonatePrivilege SeEnableDelegationPrivilege 732\n -#insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (' Mar 19 15:33:30 2010 576 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Special privileges assigned to new logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Privileges: SeSecurityPrivilege SeBackupPrivilege SeRestorePrivilege SeTakeOwnershipPrivilege SeDebugPrivilege SeSystemEnvironmentPrivilege SeLoadDriverPrivilege SeImpersonatePrivilege SeEnableDelegationPrivilege 732', 1, 'localhost',5, '20100321185328', '20100321185328', 1, 'windowsserver MSWinEventLog 1 Security 1166 Fri') +windowsserver MSWinEventLog 1 Security 1166 Fri Mar 19 15:33:30 2010 576 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Special privileges assigned to new logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Privileges: SeSecurityPrivilege SeBackupPrivilege SeRestorePrivilege SeTakeOwnershipPrivilege SeDebugPrivilege SeSystemEnvironmentPrivilege SeLoadDriverPrivilege SeImpersonatePrivilege SeEnableDelegationPrivilege 732\n +insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (' Mar 19 15:33:30 2010 576 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff Special privileges assigned to new logon: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF88396) Privileges: SeSecurityPrivilege SeBackupPrivilege SeRestorePrivilege SeTakeOwnershipPrivilege SeDebugPrivilege SeSystemEnvironmentPrivilege SeLoadDriverPrivilege SeImpersonatePrivilege SeEnableDelegationPrivilege 732', 1, 'localhost.localdomain',5, '20100321185328', '20100321185328', 1, 'windowsserver MSWinEventLog 1 Security 1166 Fri') # Sample 3 -#windowsserver MSWinEventLog 1 Security 1165 Fri Mar 19 15:33:30 2010 538 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff User Logoff: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF8830B) Logon Type: 3 731\n -#insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (' Mar 19 15:33:30 2010 538 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff User Logoff: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF8830B) Logon Type: 3 731', 1, 'localhost',5, '20100321185328', '20100321185328', 1, 'windowsserver MSWinEventLog 1 Security 1165 Fri') +windowsserver MSWinEventLog 1 Security 1165 Fri Mar 19 15:33:30 2010 538 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff User Logoff: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF8830B) Logon Type: 3 731\n +insert into windows (Message, Facility,FromHost, Priority, DeviceReportedTime, ReceivedAt, InfoUnitID, SysLogTag) values (' Mar 19 15:33:30 2010 538 Security SYSTEM User Success Audit WINDOWSSERVER Logon/Logoff User Logoff: User Name: WINDOWSSERVER$ Domain: DOMX Logon ID: (0x0,0xF8830B) Logon Type: 3 731', 1, 'localhost.localdomain',5, '20100321185328', '20100321185328', 1, 'windowsserver MSWinEventLog 1 Security 1165 Fri') diff --git a/tests/testsuites/uxsock_simple.conf b/tests/testsuites/uxsock_simple.conf new file mode 100644 index 00000000..efffdd90 --- /dev/null +++ b/tests/testsuites/uxsock_simple.conf @@ -0,0 +1,10 @@ +# Test for pipe output action (see .sh file for details) +# rgerhards, 2009-11-05 +$IncludeConfig diag-common.conf + +$MainMsgQueueTimeoutShutdown 10000 + +$ModLoad ../plugins/omuxsock/.libs/omuxsock +$template outfmt,"%msg:F,58:2%\n" +$OMUXSockSocket rsyslog-testbench-dgram-uxsock +:msg, contains, "msgnum:" :omuxsock:;outfmt diff --git a/tests/testsuites/weird.parse1 b/tests/testsuites/weird.parse1 index e8b90c74..907198a1 100644 --- a/tests/testsuites/weird.parse1 +++ b/tests/testsuites/weird.parse1 @@ -11,10 +11,10 @@ 14,user,info,Aug 30 23:00:05,X4711,,, # there is a SP at the end of the line <14>Aug 30 23:00:05 -14,user,info,Aug 30 23:00:05,localhost,,, +14,user,info,Aug 30 23:00:05,localhost.localdomain,,, # and here is no SP at the end of the line <14>Aug 30 23:00:05 -14,user,info,Aug 30 23:00:05,localhost,,, +14,user,info,Aug 30 23:00:05,localhost.localdomain,,, # unfortunately, I can not test missing dates with this test suite, because # we would have the current date in the response, which we can not check against # @@ -31,7 +31,7 @@ 14,user,info,Aug 30 23:00:05,X4711,,, # there is a SP at the end of the line <14>2010-08-30T23:00:05Z -14,user,info,Aug 30 23:00:05,localhost,,, +14,user,info,Aug 30 23:00:05,localhost.localdomain,,, # and here is no SP at the end of the line <14>2010-08-30T23:00:05Z -14,user,info,Aug 30 23:00:05,localhost,,, +14,user,info,Aug 30 23:00:05,localhost.localdomain,,, diff --git a/tests/threadingmqaq.sh b/tests/threadingmqaq.sh index b7764821..0104be00 100755 --- a/tests/threadingmqaq.sh +++ b/tests/threadingmqaq.sh @@ -12,6 +12,9 @@ source $srcdir/diag.sh startup threadingmqaq.conf #source $srcdir/diag.sh tcpflood -c2 -m100000 #source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages source $srcdir/diag.sh injectmsg 0 100000 +# we need to sleep a bit on some environments, as imdiag can not correctly +# diagnose when the action queues are empty... +sleep 3 source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages source $srcdir/diag.sh wait-shutdown source $srcdir/diag.sh seq-check 0 99999 diff --git a/tests/uxsock_simple.sh b/tests/uxsock_simple.sh new file mode 100755 index 00000000..7f00f4bc --- /dev/null +++ b/tests/uxsock_simple.sh @@ -0,0 +1,31 @@ +# This tests basic omuxsock functionality. A socket receiver is started which sends +# all data to an output file, then a rsyslog instance is started which generates +# messages and sends them to the unix socket. Datagram sockets are being used. +# added 2010-08-06 by Rgerhards +echo =============================================================================== +echo \[uxsock_simple.sh\]: simple tests for omuxsock functionality + +# create the pipe and start a background process that copies data from +# it to the "regular" work file +source $srcdir/diag.sh init +./uxsockrcvr -srsyslog-testbench-dgram-uxsock -orsyslog.out.log & +BGPROCESS=$! +echo background uxsockrcvr process id is $BGPROCESS + +# now do the usual run +source $srcdir/diag.sh startup uxsock_simple.conf +# 10000 messages should be enough +source $srcdir/diag.sh injectmsg 0 10000 +source $srcdir/diag.sh shutdown-when-empty # shut down rsyslogd when done processing messages +source $srcdir/diag.sh wait-shutdown + +# wait for the cp process to finish, do pipe-specific cleanup +echo shutting down uxsockrcvr... +# TODO: we should do this more reliable in the long run! (message counter? timeout?) +kill $BGPROCESS +wait $BGPROCESS +echo background process has terminated, continue test... + +# and continue the usual checks +source $srcdir/diag.sh seq-check 0 9999 +source $srcdir/diag.sh exit diff --git a/tests/uxsockrcvr.c b/tests/uxsockrcvr.c new file mode 100644 index 00000000..551f0ef3 --- /dev/null +++ b/tests/uxsockrcvr.c @@ -0,0 +1,157 @@ +/* receives messages from a specified unix sockets and writes + * output to specfied file. + * + * Command line options: + * -s name of socket (required) + * -o name of output file (stdout if not given) + * -l add newline after each message received (default: do not add anything) + * + * Part of the testbench for rsyslog. + * + * Copyright 2010 Rainer Gerhards and Adiscon GmbH. + * + * This file is part of rsyslog. + * + * Rsyslog is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Rsyslog is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Rsyslog. If not, see <http://www.gnu.org/licenses/>. + * + * A copy of the GPL can be found in the file "COPYING" in this distribution. + */ +#include "config.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <getopt.h> +#include <sys/un.h> +#include <netdb.h> + +char *sockName = NULL; +int sock; +int addNL = 0; + + +/* called to clean up on exit + */ +void +cleanup(void) +{ + unlink(sockName); + close(sock); +} + + +void +doTerm(int __attribute__((unused)) signum) +{ + exit(1); +} + + +void +usage(void) +{ + fprintf(stderr, "usage: uxsockrcvr -s /socket/name -o /output/file -l\n" + "-l adds newline after each message received\n" + "-s MUST be specified\n" + "if -o ist not specified, stdout is used\n"); + exit(1); +} + + +int +main(int argc, char *argv[]) +{ + int opt; + int rlen; + FILE *fp = stdout; + unsigned char data[128*1024]; + struct sockaddr_un addr; /* address of server */ + struct sockaddr from; + socklen_t fromlen; + + if(argc < 2) { + fprintf(stderr, "error: too few arguments!\n"); + usage(); + } + + while((opt = getopt(argc, argv, "s:o:l")) != EOF) { + switch((char)opt) { + case 'l': + addNL = 1; + break; + case 's': + sockName = optarg; + break; + case 'o': + if((fp = fopen(optarg, "w")) == NULL) { + perror(optarg); + exit(1); + } + break; + default:usage(); + } + } + + if(sockName == NULL) { + fprintf(stderr, "error: -s /socket/name must be specified!\n"); + exit(1); + } + + if(signal(SIGTERM, doTerm) == SIG_ERR) { + perror("signal(SIGTERM, ...)"); + exit(1); + } + if(signal(SIGINT, doTerm) == SIG_ERR) { + perror("signal(SIGINT, ...)"); + exit(1); + } + + /* Create a UNIX datagram socket for server */ + if ((sock = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) { + perror("server: socket"); + exit(1); + } + + atexit(cleanup); + + /* Set up address structure for server socket */ + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, sockName); + + if (bind(sock, (struct sockaddr*) &addr, sizeof(addr)) < 0) { + close(sock); + perror("server: bind"); + exit(1); + } + + /* we now run in an endless loop. We do not check who sends us + * data. This should be no problem for our testbench use. + */ + while(1) { + fromlen = sizeof(from); + rlen = recvfrom(sock, data, 2000, 0, &from, &fromlen); + if(rlen == -1) { + perror("uxsockrcvr : recv\n"); + exit(1); + } else { + fwrite(data, 1, rlen, fp); + if(addNL) + fputc('\n', fp); + } + } + + return 0; +} |