diff options
author | Rainer Gerhards <rgerhards@adiscon.com> | 2008-11-11 12:54:44 +0100 |
---|---|---|
committer | Rainer Gerhards <rgerhards@adiscon.com> | 2008-11-11 12:54:44 +0100 |
commit | 05bd696ebb7766f33b3ae176b841bcecb0bfedfc (patch) | |
tree | 99437759863ee4b25174f49aa69807c207176a76 /tests | |
parent | 9048c16d90177a0dfa4131266ae73f029a5923c8 (diff) | |
parent | ba201a941435bc5fec2c333155e1a8e16c4a9c05 (diff) | |
download | rsyslog-05bd696ebb7766f33b3ae176b841bcecb0bfedfc.tar.gz rsyslog-05bd696ebb7766f33b3ae176b841bcecb0bfedfc.tar.bz2 rsyslog-05bd696ebb7766f33b3ae176b841bcecb0bfedfc.zip |
Merge branch 'master' into beta
Conflicts:
ChangeLog
configure.ac
doc/manual.html
Diffstat (limited to 'tests')
-rw-r--r-- | tests/.gitignore | 2 | ||||
-rw-r--r-- | tests/1.rstest | 26 | ||||
-rw-r--r-- | tests/2.rstest | 10 | ||||
-rw-r--r-- | tests/DevNull.cfgtest | 3 | ||||
-rw-r--r-- | tests/Makefile.am | 27 | ||||
-rw-r--r-- | tests/NoExistFile.cfgtest | 3 | ||||
-rwxr-xr-x | tests/cfg.sh | 139 | ||||
-rw-r--r-- | tests/cfg1.cfgtest | 3 | ||||
-rw-r--r-- | tests/cfg1.testin | 2 | ||||
-rw-r--r-- | tests/cfg2.cfgtest | 3 | ||||
-rw-r--r-- | tests/cfg2.testin | 1 | ||||
-rw-r--r-- | tests/cfg3.cfgtest | 5 | ||||
-rw-r--r-- | tests/cfg3.testin | 1 | ||||
-rw-r--r-- | tests/cfg4.cfgtest | 1 | ||||
-rw-r--r-- | tests/cfg4.testin | 67 | ||||
-rw-r--r-- | tests/err1.rstest | 7 | ||||
-rw-r--r-- | tests/rscript-parse.c | 100 | ||||
-rw-r--r-- | tests/rscript.c | 259 | ||||
-rw-r--r-- | tests/testbench.h | 3 |
19 files changed, 554 insertions, 108 deletions
diff --git a/tests/.gitignore b/tests/.gitignore index e961c766..a8177ad4 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -1,3 +1,3 @@ -rscript_parse +rscript rt_init tmp diff --git a/tests/1.rstest b/tests/1.rstest new file mode 100644 index 00000000..5c152589 --- /dev/null +++ b/tests/1.rstest @@ -0,0 +1,26 @@ +# a simple RainerScript test +result: 0 +in: +'test 1' <> $var or /* some comment */($SEVERITY == -4 +5 -(3 * - 2) and $fromhost == '127.0.0.1') then +$$$ +out: +00000000: PUSHCONSTANT test 1[cstr] +00000001: PUSHMSGVAR var[cstr] +00000002: != +00000003: PUSHMSGVAR severity[cstr] +00000004: PUSHCONSTANT 4[nbr] +00000005: UNARY_MINUS +00000006: PUSHCONSTANT 5[nbr] +00000007: + +00000008: PUSHCONSTANT 3[nbr] +00000009: PUSHCONSTANT 2[nbr] +00000010: UNARY_MINUS +00000011: * +00000012: - +00000013: == +00000014: PUSHMSGVAR fromhost[cstr] +00000015: PUSHCONSTANT 127.0.0.1[cstr] +00000016: == +00000017: and +00000018: or +$$$ diff --git a/tests/2.rstest b/tests/2.rstest new file mode 100644 index 00000000..7fb5b799 --- /dev/null +++ b/tests/2.rstest @@ -0,0 +1,10 @@ +# a simple RainerScript test +result: 0 +in: +$msg contains 'test' then +$$$ +out: +00000000: PUSHMSGVAR msg[cstr] +00000001: PUSHCONSTANT test[cstr] +00000002: contains +$$$ diff --git a/tests/DevNull.cfgtest b/tests/DevNull.cfgtest new file mode 100644 index 00000000..d30d936b --- /dev/null +++ b/tests/DevNull.cfgtest @@ -0,0 +1,3 @@ +rsyslogd: CONFIG ERROR: there are no active actions configured. Inputs will run, but no output whatsoever is created. [try http://www.rsyslog.com/e/2103 ] +rsyslogd: EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file! +rsyslogd: End of config validation run. Bye. diff --git a/tests/Makefile.am b/tests/Makefile.am index d85a56f8..2cfd5bfb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,14 +1,29 @@ -check_PROGRAMS = rt_init rscript_parse -TESTS = $(check_PROGRAMS) +check_PROGRAMS = rt_init rscript +TESTS = $(check_PROGRAMS) cfg.sh +TESTS_ENVIRONMENT = RSYSLOG_MODDIR='$(abs_top_builddir)'/runtime/.libs/ +#TESTS = $(check_PROGRAMS) test_files = testbench.h runtime-dummy.c +EXTRA_DIST=1.rstest 2.rstest err1.rstest \ + cfg.sh \ + cfg1.cfgtest \ + cfg1.testin \ + cfg2.cfgtest \ + cfg2.testin \ + cfg3.cfgtest \ + cfg3.testin \ + cfg4.cfgtest \ + cfg4.testin \ + DevNull.cfgtest \ + err1.rstest \ + NoExistFile.cfgtest rt_init_SOURCES = rt-init.c $(test_files) rt_init_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags) rt_init_LDADD = $(rsrt_libs) $(zlib_libs) $(pthreads_libs) rt_init_LDFLAGS = -export-dynamic -rscript_parse_SOURCES = rscript-parse.c $(test_files) -rscript_parse_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags) -rscript_parse_LDADD = $(rsrt_libs) $(zlib_libs) $(pthreads_libs) -rscript_parse_LDFLAGS = -export-dynamic +rscript_SOURCES = rscript.c $(test_files) +rscript_CPPFLAGS = -I$(top_srcdir) $(pthreads_cflags) $(rsrt_cflags) +rscript_LDADD = $(rsrt_libs) $(zlib_libs) $(pthreads_libs) +rscript_LDFLAGS = -export-dynamic diff --git a/tests/NoExistFile.cfgtest b/tests/NoExistFile.cfgtest new file mode 100644 index 00000000..4cbcc029 --- /dev/null +++ b/tests/NoExistFile.cfgtest @@ -0,0 +1,3 @@ +rsyslogd: CONFIG ERROR: could not interpret master config file '/This/does/not/exist'. [try http://www.rsyslog.com/e/2013 ] +rsyslogd: EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file! +rsyslogd: End of config validation run. Bye. diff --git a/tests/cfg.sh b/tests/cfg.sh new file mode 100755 index 00000000..99729823 --- /dev/null +++ b/tests/cfg.sh @@ -0,0 +1,139 @@ +# /bin/bash +# This is a simple shell script that carries out some checks against +# configurations we expect from some provided config files. We use +# rsyslogd's verifcation function. Note that modifications to the +# config elements, or even simple text changes, cause these checks to +# fail. However, it should be fairly easy to adapt them to the changed +# environment. And while nothing changed, they permit is to make sure +# that everything works well and is not broken by interim changes. +# Note that we always compare starting with the second output line. +# This is because the first line contains the rsyslog version ;) +# rgerhards, 2008-07-29 +# +# Part of the testbench for rsyslog. +# +# Copyright 2008 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. +#set -x +rm -f tmp +echo "local directory" +# +# check empty config file +# +../tools/rsyslogd -c3 -N1 -f/dev/null 2>&1 |tail --lines=+2 > tmp +cmp tmp $srcdir/DevNull.cfgtest +if [ ! $? -eq 0 ]; then +echo "DevNull.cfgtest failed" +echo "Expected:" +cat $srcdir/DevNull.cfgtest +echo "Received:" +cat tmp +exit 1 +else +echo "DevNull.cfgtest succeeded" +fi; +# +# check missing config file +# +../tools/rsyslogd -c3 -N1 -f/This/does/not/exist 2>&1 |tail --lines=+2 > tmp +cmp tmp $srcdir/NoExistFile.cfgtest +if [ ! $? -eq 0 ]; then +echo "NoExistFile.cfgtest failed" +echo "Expected:" +cat $srcdir/NoExistFile.cfgtest +echo "Received:" +cat tmp +exit 1 +else +echo "NoExistFile.cfgtest succeeded" +fi; + + +# TODO: re-enable the following checks. They need to have support in +# rsyslogd so that the log file name is NOT contained in the error +# messages - this prevents proper comparison in make distcheck +rm -f tmp +exit 0 + +# +# check config with invalid directive +# +../tools/rsyslogd -c3 -u2 -N1 -f$srcdir/cfg1.testin 2>&1 |tail --lines=+2 > tmp +cmp tmp $srcdir/cfg1.cfgtest +if [ ! $? -eq 0 ]; then +echo "cfg1.cfgtest failed" +echo "Expected:" +cat $srcdir/cfg1.cfgtest +echo "Received:" +cat tmp +exit 1 +else +echo "cfg1.cfgtest succeeded" +fi; +# +# now check for included config file. We use a sample similar to +# the one with the invalid config directive, so that we may see +# an effect of the included config ;) +# +../tools/rsyslogd -c3 -u2 -N1 -f$srcdir/cfg2.testin 2>&1 |tail --lines=+2 > tmp +cmp tmp $srcdir/cfg2.cfgtest +if [ ! $? -eq 0 ]; then +echo "cfg2.cfgtest failed" +echo "Expected:" +cat $srcdir/cfg2.cfgtest +echo "Received:" +cat tmp +exit 1 +else +echo "cfg2.cfgtest succeeded" +fi; +# +# check included config file, where included file does not exist +# +../tools/rsyslogd -c3 -u2 -N1 -f$srcdir/cfg3.testin 2>&1 |tail --lines=+2 > tmp +cmp tmp $srcdir/cfg3.cfgtest +if [ ! $? -eq 0 ]; then +echo "cfg3.cfgtest failed" +echo "Expected:" +cat $srcdir/cfg3.cfgtest +echo "Received:" +cat tmp +exit 1 +else +echo "cfg3.cfgtest succeeded" +fi; +# +# check a reasonable complex, but correct, log file +# +../tools/rsyslogd -c3 -u2 -N1 -f$srcdir/cfg4.testin 2>&1 |tail --lines=+2 > tmp +cmp tmp $srcdir/cfg4.cfgtest +if [ ! $? -eq 0 ]; then +echo "cfg4.cfgtest failed" +echo "Expected:" +cat $srcdir/cfg4.cfgtest +echo "Received:" +cat tmp +exit 1 +else +echo "cfg4.cfgtest succeeded" +fi; +# +# done, some cleanup +# +rm -f tmp diff --git a/tests/cfg1.cfgtest b/tests/cfg1.cfgtest new file mode 100644 index 00000000..099ba929 --- /dev/null +++ b/tests/cfg1.cfgtest @@ -0,0 +1,3 @@ +rsyslogd: invalid or yet-unknown config file command - have you forgotten to load a module? [try http://www.rsyslog.com/e/3003 ] +rsyslogd: the last error occured in ./cfg1.testin, line 2 +rsyslogd: End of config validation run. Bye. diff --git a/tests/cfg1.testin b/tests/cfg1.testin new file mode 100644 index 00000000..7d7b594c --- /dev/null +++ b/tests/cfg1.testin @@ -0,0 +1,2 @@ +*.* * +$invaliddirective test diff --git a/tests/cfg2.cfgtest b/tests/cfg2.cfgtest new file mode 100644 index 00000000..b44a487e --- /dev/null +++ b/tests/cfg2.cfgtest @@ -0,0 +1,3 @@ +rsyslogd: invalid or yet-unknown config file command - have you forgotten to load a module? [try http://www.rsyslog.com/e/3003 ] +rsyslogd: the last error occured in cfg1.testin, line 2 +rsyslogd: End of config validation run. Bye. diff --git a/tests/cfg2.testin b/tests/cfg2.testin new file mode 100644 index 00000000..b6d98c8f --- /dev/null +++ b/tests/cfg2.testin @@ -0,0 +1 @@ +$includeconfig cfg1.testin diff --git a/tests/cfg3.cfgtest b/tests/cfg3.cfgtest new file mode 100644 index 00000000..68bc17d4 --- /dev/null +++ b/tests/cfg3.cfgtest @@ -0,0 +1,5 @@ +rsyslogd: error accessing config file or directory 'file-does-not-exist': No such file or directory [try http://www.rsyslog.com/e/2040 ] +rsyslogd: the last error occured in ./cfg3.testin, line 1 +rsyslogd: CONFIG ERROR: there are no active actions configured. Inputs will run, but no output whatsoever is created. [try http://www.rsyslog.com/e/2103 ] +rsyslogd: EMERGENCY CONFIGURATION ACTIVATED - fix rsyslog config file! +rsyslogd: End of config validation run. Bye. diff --git a/tests/cfg3.testin b/tests/cfg3.testin new file mode 100644 index 00000000..9789d939 --- /dev/null +++ b/tests/cfg3.testin @@ -0,0 +1 @@ +$includeconfig file-does-not-exist diff --git a/tests/cfg4.cfgtest b/tests/cfg4.cfgtest new file mode 100644 index 00000000..04acf84f --- /dev/null +++ b/tests/cfg4.cfgtest @@ -0,0 +1 @@ +rsyslogd: End of config validation run. Bye. diff --git a/tests/cfg4.testin b/tests/cfg4.testin new file mode 100644 index 00000000..a49c0fb6 --- /dev/null +++ b/tests/cfg4.testin @@ -0,0 +1,67 @@ +# This is more or less the sample config, but without imklog being +# active. imklog must not always be present and as such may spoil +# our testing result. The core point at this test is that a valid +# config file should not lead to any error messages. +# It may be a good idea to update this file from time to time, so that +# it contains a reasonable complex config sample. + +# if you experience problems, check +# http://www.rsyslog.com/troubleshoot for assistance + +# rsyslog v3: load input modules +# 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 ########## +# TCP Syslog Server: +# provides TCP syslog reception and GSS-API (if compiled to support it) +#$ModLoad imtcp.so # load module +#$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 diff --git a/tests/err1.rstest b/tests/err1.rstest new file mode 100644 index 00000000..8c56887e --- /dev/null +++ b/tests/err1.rstest @@ -0,0 +1,7 @@ +# This test case check for an error condition +result: -2051 +in: +'test 1' <> == $hostname +$$$ +out: +$$$ diff --git a/tests/rscript-parse.c b/tests/rscript-parse.c deleted file mode 100644 index 176f3f7e..00000000 --- a/tests/rscript-parse.c +++ /dev/null @@ -1,100 +0,0 @@ -/* This test checks runtime initialization and exit. Other than that, it - * also serves as the most simplistic sample of how a test can be coded. - * - * Part of the testbench for rsyslog. - * Copyright 2008 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 <stdio.h> - -#include "rsyslog.h" -#include "testbench.h" -#include "ctok.h" -#include "expr.h" - -MODULE_TYPE_TESTBENCH -/* define addtional objects we need for our tests */ -DEFobjCurrIf(expr) -DEFobjCurrIf(ctok) -DEFobjCurrIf(ctok_token) - -BEGINInit -CODESTARTInit - pErrObj = "expr"; CHKiRet(objUse(expr, CORE_COMPONENT)); - pErrObj = "ctok"; CHKiRet(objUse(ctok, CORE_COMPONENT)); - pErrObj = "ctok_token"; CHKiRet(objUse(ctok_token, CORE_COMPONENT)); -ENDInit - -BEGINExit -CODESTARTExit -ENDExit - -BEGINTest - ctok_t *tok; - ctok_token_t *pToken; - expr_t *pExpr; - /* the string below is an expression as defined up to 3.19.x - note that the - * then and the space after it MUST be present! - */ - uchar szExpr[] = " $msg contains 'test' then "; - /*uchar szSynErr[] = "$msg == 1 and syntaxerror ";*/ -CODESTARTTest - /* we first need a tokenizer... */ - CHKiRet(ctok.Construct(&tok)); - CHKiRet(ctok.Setpp(tok, szExpr)); - CHKiRet(ctok.ConstructFinalize(tok)); - - /* now construct our expression */ - CHKiRet(expr.Construct(&pExpr)); - CHKiRet(expr.ConstructFinalize(pExpr)); - - /* ready to go... */ - CHKiRet(expr.Parse(pExpr, tok)); - - /* we now need to parse off the "then" - and note an error if it is - * missing... - * - * rgerhards, 2008-07-01: we disable the check below, because I can not - * find the cause of the misalignment. The problem is that pToken structure has - * a different member alignment inside the runtime library then inside of - * this program. I checked compiler options, but could not find the cause. - * Should anyone have any insight, I'd really appreciate if you drop me - * a line. - */ -#if 0 - CHKiRet(ctok.GetToken(tok, &pToken)); - if(pToken->tok != ctok_THEN) { -//printf("invalid token, probably due to invalid alignment between runtime lib and this program\n"); - ctok_token.Destruct(&pToken); - ABORT_FINALIZE(RS_RET_SYNTAX_ERROR); - } - - ctok_token.Destruct(&pToken); /* no longer needed */ -#endif - - /* we are done, so we now need to restore things */ - CHKiRet(ctok.Destruct(&tok)); -finalize_it: - /* here we may do custom error reporting */ - if(iRet != RS_RET_OK) { - uchar *pp; - ctok.Getpp(tok, &pp); - printf("error on or before '%s'\n", pp); - } -ENDTest diff --git a/tests/rscript.c b/tests/rscript.c new file mode 100644 index 00000000..d4e8caeb --- /dev/null +++ b/tests/rscript.c @@ -0,0 +1,259 @@ +/* This test checks runtime initialization and exit. Other than that, it + * also serves as the most simplistic sample of how a test can be coded. + * + * Part of the testbench for rsyslog. + * + * Copyright 2008 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 <glob.h> +#include <sys/stat.h> + +#include "rsyslog.h" +#include "testbench.h" +#include "ctok.h" +#include "expr.h" + +MODULE_TYPE_TESTBENCH +/* define addtional objects we need for our tests */ +DEFobjCurrIf(expr) +DEFobjCurrIf(ctok) +DEFobjCurrIf(ctok_token) +DEFobjCurrIf(vmprg) + +BEGINInit +CODESTARTInit + pErrObj = "expr"; CHKiRet(objUse(expr, CORE_COMPONENT)); + pErrObj = "ctok"; CHKiRet(objUse(ctok, CORE_COMPONENT)); + pErrObj = "ctok_token"; CHKiRet(objUse(ctok_token, CORE_COMPONENT)); + pErrObj = "vmprg"; CHKiRet(objUse(vmprg, CORE_COMPONENT)); +ENDInit + +BEGINExit +CODESTARTExit +ENDExit + + +/* perform a single test. This involves compiling the test script, + * checking the result of the compilation (iRet) and a check of the + * generated program (via a simple strcmp). The resulting program + * check is only done if the test should not detect a syntax error + * (for obvious reasons, there is no point in checking the result of + * a failed compilation). + * rgerhards, 2008-07--07 + */ +static rsRetVal +PerformTest(cstr_t *pstrIn, rsRetVal iRetExpected, cstr_t *pstrOut) +{ + cstr_t *pstrPrg = NULL; + ctok_t *tok = NULL; + ctok_token_t *pToken = NULL; + expr_t *pExpr; + rsRetVal localRet; + DEFiRet; + + /* we first need a tokenizer... */ + CHKiRet(ctok.Construct(&tok)); + CHKiRet(ctok.Setpp(tok, rsCStrGetSzStr(pstrIn))); + CHKiRet(ctok.ConstructFinalize(tok)); + + /* now construct our expression */ + CHKiRet(expr.Construct(&pExpr)); + CHKiRet(expr.ConstructFinalize(pExpr)); + + /* ready to go... */ + localRet = expr.Parse(pExpr, tok); + + /* check if we expected an error */ + if(localRet != iRetExpected) { + printf("Error in compile return code. Expected %d, received %d\n", + iRetExpected, localRet); + CHKiRet(rsCStrConstruct(&pstrPrg)); + CHKiRet(vmprg.Obj2Str(pExpr->pVmprg, pstrPrg)); + printf("generated vmprg:\n%s\n", rsCStrGetSzStr(pstrPrg)); + ABORT_FINALIZE(iRetExpected == RS_RET_OK ? localRet : RS_RET_ERR); + } + + if(iRetExpected != RS_RET_OK) + FINALIZE; /* if we tested an error case, we are done */ + + /* OK, we got a compiled program, so now let's compare that */ + + CHKiRet(rsCStrConstruct(&pstrPrg)); + CHKiRet(vmprg.Obj2Str(pExpr->pVmprg, pstrPrg)); + + if(strcmp((char*)rsCStrGetSzStr(pstrPrg), (char*)rsCStrGetSzStr(pstrOut))) { + printf("error: compiled program different from expected result!\n"); + printf("generated vmprg:\n%s\n", rsCStrGetSzStr(pstrPrg)); + printf("expected:\n%s\n", rsCStrGetSzStr(pstrOut)); + ABORT_FINALIZE(RS_RET_ERR); + } + +finalize_it: + /* we are done, so we now need to restore things */ + if(pToken != NULL) + ctok_token.Destruct(&pToken); /* no longer needed */ + if(pstrPrg != NULL) + rsCStrDestruct(&pstrPrg); + if(tok != NULL) + ctok.Destruct(&tok); + RETiRet; +} + + +/* a helper macro to generate some often-used code... */ +#define CHKEOF \ + if(feof(fp)) { \ + printf("error: unexpected end of control file %s\n", pszFileName); \ + ABORT_FINALIZE(RS_RET_ERR); \ + } +/* process a single test file + * Note that we do not do a real parser here. The effort is not + * justified by what we need to do. So it is a quick shot. + * rgerhards, 2008-07-07 + */ +static rsRetVal +ProcessTestFile(uchar *pszFileName) +{ + FILE *fp; + char *lnptr = NULL; + size_t lenLn; + cstr_t *pstrIn = NULL; + cstr_t *pstrOut = NULL; + rsRetVal iRetExpected; + DEFiRet; + + if((fp = fopen((char*)pszFileName, "r")) == NULL) { + perror((char*)pszFileName); + ABORT_FINALIZE(RS_RET_FILE_NOT_FOUND); + } + + /* skip comments at start of file */ + + getline(&lnptr, &lenLn, fp); + while(!feof(fp)) { + if(*lnptr == '#') + getline(&lnptr, &lenLn, fp); + else + break; /* first non-comment */ + } + CHKEOF; + + /* once we had a comment, the next line MUST be "result: <nbr>". Anything + * after nbr is simply ignored. + */ + if(sscanf(lnptr, "result: %d", &iRetExpected) != 1) { + printf("error in result line, scanf failed, line: '%s'\n", lnptr); + ABORT_FINALIZE(RS_RET_ERR); + } + getline(&lnptr, &lenLn, fp); CHKEOF; + + /* and now we look for "in:" (and again ignore the rest...) */ + if(strncmp(lnptr, "in:", 3)) { + printf("error: expected 'in:'-line, but got: '%s'\n", lnptr); + ABORT_FINALIZE(RS_RET_ERR); + } + /* if we reach this point, we need to read in the input script. It is + * terminated by a line with three sole $ ($$$\n) + */ + CHKiRet(rsCStrConstruct(&pstrIn)); + getline(&lnptr, &lenLn, fp); CHKEOF; + while(strncmp(lnptr, "$$$\n", 4)) { + CHKiRet(rsCStrAppendStr(pstrIn, (uchar*)lnptr)); + getline(&lnptr, &lenLn, fp); CHKEOF; + } + getline(&lnptr, &lenLn, fp); CHKEOF; /* skip $$$-line */ + + /* and now we look for "out:" (and again ignore the rest...) */ + if(strncmp(lnptr, "out:", 4)) { + printf("error: expected 'out:'-line, but got: '%s'\n", lnptr); + ABORT_FINALIZE(RS_RET_ERR); + } + /* if we reach this point, we need to read in the expected program code. It is + * terminated by a line with three sole $ ($$$\n) + */ + CHKiRet(rsCStrConstruct(&pstrOut)); + getline(&lnptr, &lenLn, fp); CHKEOF; + while(strncmp(lnptr, "$$$\n", 4)) { + CHKiRet(rsCStrAppendStr(pstrOut, (uchar*)lnptr)); + getline(&lnptr, &lenLn, fp); CHKEOF; + } + + /* un-comment for testing: + * printf("iRet: %d, script: %s\n, out: %s\n", iRetExpected, rsCStrGetSzStr(pstrIn),rsCStrGetSzStr(pstrOut)); + */ + if(rsCStrGetSzStr(pstrIn) == NULL) { + printf("error: input script is empty!\n"); + ABORT_FINALIZE(RS_RET_ERR); + } + if(rsCStrGetSzStr(pstrOut) == NULL && iRetExpected == RS_RET_OK) { + printf("error: output script is empty!\n"); + ABORT_FINALIZE(RS_RET_ERR); + } + + CHKiRet(PerformTest(pstrIn, iRetExpected, pstrOut)); + +finalize_it: + if(pstrIn != NULL) + rsCStrDestruct(&pstrIn); + if(pstrOut != NULL) + rsCStrDestruct(&pstrOut); + RETiRet; +} + + +/* This test is parameterized. It search for test control files and + * loads all that it finds. To add tests, simply create new .rstest + * files. + * rgerhards, 2008-07-07 + */ +BEGINTest + uchar *testFile; + glob_t testFiles; + size_t i = 0; + struct stat fileInfo; +CODESTARTTest + glob("*.rstest", GLOB_MARK, NULL, &testFiles); + + for(i = 0; i < testFiles.gl_pathc; i++) { + testFile = (uchar*) testFiles.gl_pathv[i]; + + if(stat((char*) testFile, &fileInfo) != 0) + continue; /* continue with the next file if we can't stat() the file */ + + /* all regular files are run through the test logic. Symlinks don't work. */ + if(S_ISREG(fileInfo.st_mode)) { /* config file */ + printf("processing RainerScript test file '%s'...\n", testFile); + iRet = ProcessTestFile((uchar*) testFile); + if(iRet != RS_RET_OK) { + /* in this case, re-run with debugging on */ + printf("processing test case failed with %d, re-running with debug messages:\n", + iRet); + Debug = 1; /* these two are dirty, but we need them today... */ + debugging_on = 1; + CHKiRet(ProcessTestFile((uchar*) testFile)); + } + } + } + globfree(&testFiles); + +finalize_it: +ENDTest diff --git a/tests/testbench.h b/tests/testbench.h index 6f26724a..12687743 100644 --- a/tests/testbench.h +++ b/tests/testbench.h @@ -40,7 +40,8 @@ int main(int __attribute__((unused)) argc, char __attribute__((unused)) *argv[]) CHKiRet(doTest()); \ CHKiRet(doExit()); \ finalize_it: \ - printf("test returns iRet %d\n", iRet); \ + if(iRet != RS_RET_OK) \ + printf("test returns iRet %d\n", iRet); \ RETiRet; \ } |